File Coverage

blib/lib/Net/DSML/Filter.pm
Criterion Covered Total %
statement 144 223 64.5
branch 62 130 47.6
condition 7 21 33.3
subroutine 18 28 64.2
pod 19 19 100.0
total 250 421 59.3


line stmt bran cond sub pod time code
1             package Net::DSML::Filter;
2              
3 3     3   5017 use warnings;
  3         10  
  3         209  
4 3     3   19 use strict;
  3         6  
  3         112  
5             #use Carp;
6 3     3   1916 use Class::Std::Utils;
  3         16041  
  3         28  
7              
8 3     3   313 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  3         7  
  3         269  
9 3     3   17 use version; $VERSION = version->new('0.002');
  3         6  
  3         20  
10              
11             # Copyright (c) 2007 Clif Harden . All rights reserved.
12             # This program is free software; you can redistribute it and/or
13             # modify it under the same terms as Perl itself.
14              
15             {
16              
17             BEGIN
18             {
19 3     3   473 use Exporter ();
  3         7  
  3         124  
20              
21 3     3   59 @ISA = qw(Exporter);
22 3         16 @EXPORT = qw();
23 3         5 %EXPORT_TAGS = ();
24 3         19302 @EXPORT_OK = ();
25              
26             }
27              
28              
29             #
30             # The class filter provides methods for building ldap dsml search filters.
31             #
32             my %sfilter;
33             my %debug;
34             my %errMsg;
35             my %msg;
36              
37             #
38             # initialize the new object.
39             #
40             # Method new
41             #
42             # The new method initializes a new filter object.
43             #
44             # This method has 1 valid option; debug; value of 1 or 0. This will enable
45             # debug messages to standard out.
46             #
47              
48             sub new
49             {
50 35     35 1 11357 my ($class, $opt) = @_;
51 35         103 my $self = bless anon_scalar(), $class;
52              
53 35         255 $sfilter{ident $self} = ""; # Search filter
54 35 50       125 $debug{ident $self} = $opt->{debug} ? 1 : 0; # debug flag
55 35         85 $errMsg{ident $self} = ""; # error messages, no error this will be a null string.
56 35         77 $msg{ident $self} = ""; # general messages
57 35         91 return $self;
58             }
59              
60             #
61             # inside-out classes have to have a DESTROY subrountine.
62             #
63             sub DESTROY
64             {
65 35     35   1348 my ($dsml) = @_;
66 35         69 my $id = ident($dsml);
67              
68 35         71 delete $sfilter{$id};
69 35         49 delete $debug{$id};
70 35         46 delete $errMsg{$id};
71 35         74 delete $msg{$id};
72 35         501 return;
73             }
74              
75             # Method debug
76             #
77             # The method debug sets or returns the object debug flag.
78             #
79             # If there is one required input option.
80             #
81             # $return = $dsml->debug( 1 );
82             #
83             # Input option: Debug value; 1 or 0. Default is 0.
84             #
85             # Method output; Returns debug value.
86             #
87              
88             sub debug
89             {
90 0     0 1 0 my $dsml = shift;
91 0 0       0 $debug{ident $dsml} = shift if ( @_ >= 1 );
92 0         0 return $debug{ident $dsml};
93             }
94              
95              
96             # Method error
97             #
98             # The error method returns error message that is stored in the
99             # object. Any error message will be associated with the last
100             # filter module operation.
101             #
102             # No input options.
103             #
104             # Example: $filter->error;
105             #
106              
107             sub error
108             {
109 0     0 1 0 my ($dsml) = @_;
110 0         0 return $errMsg{ident $dsml};
111             }
112              
113              
114             # Method getFilter
115             #
116             # The getFilter method returns the last filter string that was
117             # created.
118             #
119             # No input options.
120             #
121             # Example: $filter->getFilter;
122             #
123              
124             sub getFilter
125             {
126 33     33 1 58 my ($dsml) = @_;
127 33         38 my $id;
128 33         70 $id = ident $dsml;
129              
130 33 50       113 if ( !($sfilter{$id} =~ //) )
131             {
132 33         85 $sfilter{$id} = "" . $sfilter{$id} . "";
133             }
134 33         168 return $sfilter{$id};
135             }
136              
137              
138             # 1. & - &
139             # 2. < - <
140             # 3. > - >
141             # 4. " - "
142             # 5. ' - '
143             #
144             # Convert special characters to xml standards.
145             #
146             sub _specialChar
147             {
148 39     39   50 my ($char) = @_;
149              
150 39         64 $$char =~ s/&/&/g;
151 39         50 $$char =~ s/
152 39         47 $$char =~ s/>/>/g;
153 39         43 $$char =~ s/"/"/g;
154 39         91 $$char =~ s/'/'/g;
155              
156             }
157              
158             # Method setFilter
159             #
160             # The setFilter method sets the objects filter string. This
161             # could be used as a base to continue building the filter string.
162             #
163             # Example: $filter->setFilter($value);
164             #
165             # There is 1 input option ($value): filter string.
166             #
167              
168             sub setFilter
169             {
170 0     0 1 0 my ($dsml, $value) = @_;
171 0         0 my $refvalue;
172 0 0       0 $refvalue = (ref($value) ? ${$value} : $value);
  0         0  
173 0 0       0 if ( length($refvalue) > 0 )
174             {
175 0 0       0 _specialChar(\$refvalue) if ( $refvalue =~ /(&||<||>||"||')/);
176 0         0 $sfilter{ident $dsml} = $refvalue;
177 0         0 return 1;
178             }
179            
180 0         0 $errMsg{ident $dsml} = "Method setFilter filter value is not defined.";
181 0         0 return 0;
182              
183             }
184              
185              
186             # Method reset
187             #
188             # The reset method will reset the filter string to a null, or blank,
189             # value.
190             #
191             # No input options.
192             #
193             # Example: $filter->reset;
194             #
195              
196             sub reset
197             {
198 0     0 1 0 my ($dsml) = @_;
199 0         0 $sfilter{ident $dsml} = "";
200 0         0 return 1;
201             }
202              
203             # Method subString
204             #
205             # The method subString sets up a LDAP substring filter.
206             #
207             # There are 3 required input options.
208             #
209             # $return = $filter->subString( type => "initial,
210             # attribute => "cn",
211             # value => "Bugs Bunny" );
212             #
213             # Input option "type": String that contains the type of substring
214             # search that is being preformed; final, any, initial.
215             #
216             # Input option "attribute": String that contains the attribute name
217             # that controls the search.
218             #
219             # Input option "value": String that contains the value of the
220             # attribute.
221             #
222             # Method output; Returns true on success; false on error, error message
223             # can be gotten with error property.
224             #
225              
226             sub subString
227             {
228 18     18 1 1426 my ($dsml, $opt) = @_;
229 18         35 my $id = ident($dsml);
230 18         19 my $attribute;
231             my $value;
232 0         0 my $type;
233 18         33 $errMsg{$id} = "";
234              
235 18 100       1171 $attribute = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  2         5  
236 18 100       39 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  1         3  
237 18 100       41 $type = (ref($opt->{type}) ? ${$opt->{type}} : $opt->{type});
  2         5  
238              
239 18 50 33     140 if ( defined($opt->{attribute}) &&
      33        
240             defined($opt->{value}) &&
241             defined($opt->{type}) )
242             {
243 18 50       100 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
244 18         39 $_ = lc($type);
245 18 50       78 if ( /^(final||initial||any)$/ )
246             {
247 18         84 $sfilter{$id} .= "<" . $1 . ">" . $value . "";
248 18         44 return 1;
249             }
250              
251 0         0 $errMsg{$id} = "Requested substring type does not match final, any or initial.";
252 0         0 return 0;
253              
254             }
255             else
256             {
257             #
258             # Substring error conditions
259             #
260 0 0       0 if ( (@_) < 6 )
    0          
    0          
    0          
261             {
262 0         0 $errMsg{$id} = "Subroutine subString did not have enough parameters defined.";
263             }
264             elsif ( !defined($opt->{attribute}) )
265             {
266 0         0 $errMsg{$id} = "Subroutine subString attribute string is not defined.";
267             }
268             elsif ( !defined($opt->{value}) )
269             {
270 0         0 $errMsg{$id} = "Subroutine subString value string is not defined.";
271             }
272             elsif ( !defined($opt->{type}) )
273             {
274 0         0 $errMsg{$id} = "Subroutine subString type string is not defined.";
275             }
276 0         0 return 0;
277             }
278              
279             }
280              
281              
282             # Method present
283             #
284             # The method present sets up a LDAP present filter.
285             #
286             # There is 1 required input option.
287             #
288             # $return = $filter->present( { attribute => "cn" } );
289             #
290             # Input option "attribute": String that contains the attribute name
291             # that controls the search.
292             #
293             # Method output; Returns true on success; false on error, error message
294             # can be gotten with error property.
295             #
296              
297             sub present
298             {
299 4     4 1 6 my ($dsml, $opt) = @_;
300 4         8 my $id = ident($dsml);
301 4         5 my $refvalue;
302              
303 4         24 $errMsg{$id} = "";
304 4 100       12 $refvalue = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  1         2  
305 4 50       13 if ( !defined($opt->{attribute}) )
306             {
307 0         0 $errMsg{$id} = "Subroutine present attribute string is not defined.";
308 0         0 return 0;
309             }
310 4         10 $sfilter{$id} .= "";
311 4         9 return 1;
312             }
313              
314              
315             # Method equalityMatch
316             #
317             # The method equalityMatch sets up a LDAP equality match filter.
318             #
319             # There are 2 required input options.
320             #
321             # $return = $filter->equalityMatch( { attribute => "sn", value => "Bunny" } );
322             #
323             # Input option "attribute": String that contains the attribute name
324             # that controls the search.
325             #
326             # Input option "value": String that contains the attribute value.
327             #
328             # Method output; Returns true on success; false on error, error message
329             # can be gotten with error property.
330             #
331              
332             sub equalityMatch
333             {
334 2     2 1 4 my ($dsml, $opt) = @_;
335 2         10 my $id = ident($dsml);
336 2         2 my $attribute;
337             my $value;
338 2         5 $errMsg{$id} = "";
339 2 50       9 $attribute = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  0         0  
340 2 50       5 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  0         0  
341              
342 2 50 33     13 if ( defined($opt->{attribute}) && defined($opt->{value}) )
343             {
344 2 50       12 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
345 2         7 $sfilter{$id} .= "" . $value . "";
346              
347             #print $sfilter{$id}, "\n"; # if ( $debug{$id} );
348 2         5 return 1;
349             }
350             else
351             {
352              
353 0 0       0 if ( (@_) < 2 )
    0          
    0          
354             {
355 0         0 $errMsg{$id} = "Subroutine equalityMatch did not have enough parameters defined.";
356             }
357             elsif ( !defined($opt->{attribute}) )
358             {
359 0         0 $errMsg{$id} = "Subroutine equalityMatch attribute string is not defined.";
360             }
361             elsif ( !defined($opt->{value}) )
362             {
363 0         0 $errMsg{$id} = "Subroutine equalityMatch value string is not defined.";
364             }
365 0         0 return 0;
366             }
367             }
368              
369              
370             # Method greaterOrEqual
371             #
372             # The method greaterOrEqual sets up a LDAP greater or equal filter.
373             #
374             # There are 2 required input options.
375             #
376             # $return = $filter->greaterOrEqual( { attribute => "uid", value => "bugs" } );
377             #
378             # Input option "attribute": String that contains the attribute name
379             # that controls the search.
380             #
381             # Input option "value": String that contains the value of the
382             # attribute.
383             #
384             # Method output; Returns true on success; false on error, error message
385             # can be gotten with error property.
386             #
387              
388             sub greaterOrEqual
389             {
390 4     4 1 6 my ($dsml, $opt) = @_;
391 4         10 my $id = ident($dsml);
392 4         5 my $attribute;
393             my $value;
394              
395 4         8 $errMsg{$id} = "";
396 4 100       11 $attribute = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  1         2  
397 4 100       12 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  1         1  
398              
399 4 50 33     25 if ( defined($opt->{attribute}) && defined($opt->{value}) )
400             {
401 4 50       20 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
402 4         14 $sfilter{$id} .= "" . $value . "";
403 4         12 return 1;
404             }
405             else
406             {
407 0 0       0 if ( (@_) < 4 )
    0          
    0          
408             {
409 0         0 $errMsg{$id} = "Subroutine greaterOrEqual did not have enough parameters defined.";
410             }
411             elsif ( !defined($opt->{attribute}) )
412             {
413 0         0 $errMsg{$id} = "Subroutine greaterOrEqual attribute string is not defined.";
414             }
415             elsif ( !defined($opt->{value}) )
416             {
417 0         0 $errMsg{$id} = "Subroutine greaterOrEqual value string is not defined.";
418             }
419 0         0 return 0;
420             }
421             }
422              
423              
424              
425             # Method lessOrEqual
426             #
427             # The method lessOrEqual sets up a LDAP less or equal filter.
428             #
429             # There are 2 required input options.
430             #
431             # $return = $filter->lessOrEqual( { attribute => "uid", value => "turkey" } );
432             #
433             # Input option "attribute": String that contains the attribute name
434             # that controls the search.
435             #
436             # Input option "value": String that contains the value of the
437             # attribute.
438             #
439             # Method output; Returns true on success; false on error, error message
440             # can be gotten with error property.
441             #
442              
443             sub lessOrEqual
444             {
445 4     4 1 7 my ($dsml, $opt) = @_;
446 4         9 my $id = ident($dsml);
447 4         4 my $attribute;
448             my $value;
449 4         8 $errMsg{$id} = "";
450              
451 4 100       11 $attribute = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  1         3  
452 4 100       10 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  1         2  
453              
454 4 50 33     28 if ( defined($opt->{attribute}) && defined($opt->{value}) )
455             {
456 4 50       22 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
457 4         15 $sfilter{$id} .= "" . $value . "";
458 4         10 return 1;
459             }
460             else
461             {
462 0 0       0 if ( (@_) < 4 )
    0          
    0          
463             {
464 0         0 $errMsg{$id} = "Subroutine lessOrEqual did not have enough parameters defined.";
465             }
466             elsif ( !defined($opt->{attribute}) )
467             {
468 0         0 $errMsg{$id} = "Subroutine lessOrEqual attribute string is not defined.";
469             }
470             elsif ( !defined($opt->{value}) )
471             {
472 0         0 $errMsg{$id} = "Subroutine lessOrEqual value string is not defined.";
473             }
474 0         0 return 0;
475             }
476             }
477              
478              
479             # Method approxMatch
480             #
481             # The method approxMatch sets up a LDAP approximate match filter.
482             #
483             # There are 2 required input options.
484             #
485             # $return = $filter->approxMatch( { attribute => "uid", value => "bird" } );
486             #
487             # Input option "attribute": String that contains the attribute name
488             # that controls the search.
489             #
490             # Input option "value": String that contains the value of the
491             # attribute.
492             #
493             # Method output; Returns true on success; false on error, error message
494             # can be gotten with error property.
495             #
496              
497             sub approxMatch
498             {
499 4     4 1 8 my ($dsml, $opt) = @_;
500 4         9 my $id = ident($dsml);
501 4         5 my $attribute;
502             my $value;
503 4         7 $errMsg{$id} = "";
504              
505 4 100       12 $attribute = (ref($opt->{attribute}) ? ${$opt->{attribute}} : $opt->{attribute});
  1         3  
506 4 100       10 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  1         2  
507              
508 4 50 33     24 if ( defined($opt->{attribute}) && defined($opt->{value}) )
509             {
510 4 50       21 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
511 4         16 $sfilter{$id} .= "" . $value . "";
512 4         13 return 1;
513             }
514             else
515             {
516 0 0       0 if ( (@_) < 4 )
    0          
    0          
517             {
518 0         0 $errMsg{$id} = "Subroutine approxMatch did not have enough parameters defined.";
519             }
520             elsif ( !defined($opt->{attribute}) )
521             {
522 0         0 $errMsg{$id} = "Subroutine approxMatch attribute string is not defined.";
523             }
524             elsif ( !defined($opt->{value}) )
525             {
526 0         0 $errMsg{$id} = "Subroutine approxMatch value string is not defined.";
527             }
528 0         0 return 0;
529             }
530             }
531              
532              
533             # Method extensibleMatch
534             #
535             # The method extensibleMatch sets up a LDAP extensibleMatch filter.
536             #
537             # There is 1 required input options.
538             # Input option "value": String that contains the value of the
539             # attribute.
540             # There are 3 optional options.
541             # Input option "matchingRule": String that contains the value of the
542             # matchingRule.
543             # Input option "dnAttributes": String that contains the boolean value
544             # of true or false
545             # Input option "name": String that contains the name string.
546             #
547             #
548             # $return = $filter->extensibleMatch( { value =>" ",
549             # name => " ",
550             # matchingRule => " ",
551             # dnAttributes => " " } );
552             #
553             # Method output; Returns true on success; false on error, error message
554             # can be gotten with error property.
555             #
556              
557             sub extensibleMatch
558             {
559 4     4 1 9 my ($dsml, $opt) = @_;
560 4         9 my $id = ident($dsml);
561 4         6 my $name;
562             my $value;
563 0         0 my $mrule;
564 0         0 my $dnAttributes;
565 4         12 $errMsg{$id} = "";
566              
567 4 100       14 $value = (ref($opt->{value}) ? ${$opt->{value}} : $opt->{value});
  1         3  
568 4 100       18 $name = (ref($opt->{name}) ? ${$opt->{name}} : $opt->{name}) if ( $opt->{name});
  1 100       2  
569 4 0       13 $mrule = (ref($opt->{matchingRule}) ? ${$opt->{matchingRule}} : $opt->{matchingRule}) if ( $opt->{matchingRule});
  0 50       0  
570 4 100       15 $dnAttributes = (ref($opt->{dnAttributes}) ? ${$opt->{dnAttributes}} : $opt->{dnAttributes}) if ( defined($opt->{dnAttributes}) );
  1 100       1  
571              
572 4 50       9 if ( $opt )
573             {
574 4 50       11 if ( !$opt->{value} )
575             {
576 0         0 $errMsg{$id} = "Subroutine extensibleMatch value string is not defined.";
577 0         0 return 0;
578             }
579              
580 4 100       20 $_ = lc($dnAttributes) if ( defined($opt->{dnAttributes}) );
581              
582 4 50 33     98 if ( defined($_) && !(/^(true)||(false)$/) )
583             {
584 0         0 $errMsg{$id} = "Subroutine extensibleMatch dnAttributes string is not properly defined.";
585 0         0 return 0;
586             }
587              
588 4 50       21 _specialChar(\$value) if ( $value =~ /(&||<||>||"||')/);
589              
590 4 100       13 if ( $opt->{name})
591             {
592 3 50       34 _specialChar(\$name) if ( $name =~ /(&||<||>||"||')/);
593             }
594              
595 4 50       10 if ( $opt->{matchingRule})
596             {
597 0 0       0 _specialChar(\$mrule) if ( $mrule =~ /(&||<||>||"||')/);
598             }
599              
600 4         8 $sfilter{$id} .= "
601 4 100       14 $sfilter{$id} .= " name=\"" . $name . "\"" if ($name);
602 4 100       13 $sfilter{$id} .= " dnAttributes=\"" . $dnAttributes . "\"" if ($opt->{dnAttributes});
603 4 50       7 $sfilter{$id} .= " matchingRule=\"" . $mrule . "\"" if ($opt->{matchingRule});
604 4         11 $sfilter{$id} .= ">" . $value . "";
605 4         10 return 1;
606             }
607             else
608             {
609 0           $errMsg{$id} = "Subroutine extensibleMatch had no input options defined.";
610 0           return 0;
611             }
612             }
613              
614             # Method or
615             #
616             # The method or sets up a beginning or element of a LDAP or filter.
617             #
618             # There are no required input options.
619             #
620             # $return = $filter->or();
621             #
622             # Method output; Always returns true for success.
623             #
624              
625             sub or
626             {
627 0     0 1   my ($dsml) = @_;
628 0           $sfilter{ident $dsml} .= "";
629 0           return 1;
630             }
631              
632             # Method endor
633             #
634             # The method endor sets up a ending or element of a LDAP or filter.
635             #
636             # There are no required input options.
637             #
638             # $return = $filter->or();
639             #
640             # Method output; Always returns true for success.
641             #
642              
643             sub endor
644             {
645 0     0 1   my ($dsml) = @_;
646 0           $sfilter{ident $dsml} .= "";
647 0           return 1;
648             }
649              
650              
651             # Method and
652             #
653             # The method and sets up a beginning and element of a LDAP and filter.
654             #
655             # There are no required input options.
656             #
657             # $return = $filter->and();
658             #
659             # Method output; Always return true for success.
660             #
661              
662             sub and
663             {
664 0     0 1   my ($dsml) = @_;
665 0           $sfilter{ident $dsml} .= "";
666 0           return 1;
667             }
668              
669             # Method endand
670             #
671             # The method endand sets up a ending and element of a LDAP and filter.
672             #
673             # There are no required input options.
674             #
675             # $return = $filter->endand();
676             #
677             # Method output; Always returns true for success.
678             #
679              
680             sub endand
681             {
682 0     0 1   my ($dsml) = @_;
683 0           $sfilter{ident $dsml} .= "";
684 0           return 1;
685             }
686              
687             # Method not
688             #
689             # The method not sets up a beginning not element of a LDAP not filter.
690             #
691             # There are no required input options.
692             #
693             # $return = $filter->not();
694             #
695             # Method output; Always return true for success.
696             #
697              
698             sub not
699             {
700 0     0 1   my ($dsml) = @_;
701 0           $sfilter{ident $dsml} .= "";
702 0           return 1;
703             }
704              
705             # Method endnot
706             #
707             # The method endnot sets up the ending not element of a LDAP not filter.
708             #
709             # There are no required input options.
710             #
711             # $return = $filter->endnot();
712             #
713             # Method output; Always returns true for success.
714             #
715              
716             sub endnot
717             {
718 0     0 1   my ($dsml) = @_;
719 0           $sfilter{ident $dsml} .= "";
720 0           return 1;
721             }
722              
723             }
724              
725              
726             1; # Magic true value required at end of module
727              
728             __END__