Package ldaptor :: Module ldapfilter
[hide private]
[frames] | no frames]

Source Code for Module ldaptor.ldapfilter

  1  #!/usr/bin/python 
  2   
  3  from ldaptor.protocols import pureldap 
  4   
  5  """ 
  6   
  7  RFC2254: 
  8   
  9          filter     = "(" filtercomp ")" 
 10          filtercomp = and / or / not / item 
 11          and        = "&" filterlist 
 12          or         = "|" filterlist 
 13          not        = "!" filter 
 14          filterlist = 1*filter 
 15          item       = simple / present / substring / extensible 
 16          simple     = attr filtertype value 
 17          filtertype = equal / approx / greater / less 
 18          equal      = "=" 
 19          approx     = "~=" 
 20          greater    = ">=" 
 21          less       = "<=" 
 22          extensible = attr [":dn"] [":" matchingrule] ":=" value 
 23                       / [":dn"] ":" matchingrule ":=" value 
 24          present    = attr "=*" 
 25          substring  = attr "=" [initial] any [final] 
 26          initial    = value 
 27          any        = "*" *(value "*") 
 28          final      = value 
 29          attr       = AttributeDescription from Section 4.1.5 of [1] 
 30          matchingrule = MatchingRuleId from Section 4.1.9 of [1] 
 31          value      = AttributeValue from Section 4.1.6 of [1] 
 32  """ 
 33   
34 -class InvalidLDAPFilter(Exception):
35 - def __init__(self, msg, loc, text):
36 Exception.__init__(self) 37 self.msg=msg 38 self.loc=loc 39 self.text=text
40
41 - def __str__(self):
42 return "Invalid LDAP filter: %s at point %d in %r" \ 43 % (self.msg, self.loc, self.text)
44
45 -def parseExtensible(attr, s):
46 raise NotImplementedError
47 48 from pyparsing import Word, Literal, Optional, ZeroOrMore, Suppress, \ 49 Group, Forward, OneOrMore, ParseException, \ 50 CharsNotIn, Combine, StringStart, \ 51 StringEnd, delimitedList 52 53 import string 54 55 filter_ = Forward() 56 attr = Word(string.ascii_letters, 57 string.ascii_letters + string.digits + ';-',) 58 attr.leaveWhitespace() 59 attr.setName('attr') 60 hexdigits = Word(string.hexdigits, exact=2) 61 hexdigits.setName('hexdigits') 62 escaped = Suppress(Literal('\\'))+hexdigits 63 escaped.setName('escaped')
64 -def _p_escaped(s,l,t):
65 text=t[0] 66 return chr(int(text, 16))
67 escaped.setParseAction(_p_escaped) 68 value = Combine(OneOrMore(CharsNotIn('*()\\\0') | escaped)) 69 value.setName('value') 70 equal = Literal("=") 71 equal.setParseAction(lambda s,l,t: pureldap.LDAPFilter_equalityMatch) 72 approx = Literal("~=") 73 approx.setParseAction(lambda s,l,t: pureldap.LDAPFilter_approxMatch) 74 greater = Literal(">=") 75 greater.setParseAction(lambda s,l,t: pureldap.LDAPFilter_greaterOrEqual) 76 less = Literal("<=") 77 less.setParseAction(lambda s,l,t: pureldap.LDAPFilter_lessOrEqual) 78 filtertype = equal | approx | greater | less 79 filtertype.setName('filtertype') 80 simple = attr + filtertype + value 81 simple.leaveWhitespace() 82 simple.setName('simple')
83 -def _p_simple(s,l,t):
84 attr, filtertype, value = t 85 return filtertype(attributeDesc=pureldap.LDAPAttributeDescription(attr), 86 assertionValue=pureldap.LDAPAssertionValue(value))
87 simple.setParseAction(_p_simple) 88 present = attr + "=*" 89 present.setParseAction(lambda s,l,t: pureldap.LDAPFilter_present(t[0])) 90 initial = value.copy() 91 initial.setParseAction(lambda s,l,t: pureldap.LDAPFilter_substrings_initial(t[0])) 92 initial.setName('initial') 93 any_value = value + Suppress(Literal("*")) 94 any_value.setParseAction(lambda s,l,t: pureldap.LDAPFilter_substrings_any(t[0])) 95 any = Suppress(Literal("*")) + ZeroOrMore(any_value) 96 any.setName('any') 97 final = value.copy() 98 final.setName('final') 99 final.setParseAction(lambda s,l,t: pureldap.LDAPFilter_substrings_final(t[0])) 100 substring = attr + Suppress(Literal("=")) + Group(Optional(initial) + any + Optional(final)) 101 substring.setName('substring')
102 -def _p_substring(s,l,t):
103 attrtype, substrings = t 104 return pureldap.LDAPFilter_substrings( 105 type=attrtype, 106 substrings=substrings)
107 substring.setParseAction(_p_substring) 108 109 keystring = Word(string.ascii_letters, 110 string.ascii_letters + string.digits + ';-') 111 keystring.setName('keystring') 112 numericoid = delimitedList(Word(string.digits), delim='.', combine=True) 113 numericoid.setName('numericoid') 114 oid = numericoid | keystring 115 oid.setName('oid') 116 matchingrule = oid.copy() 117 matchingrule.setName('matchingrule') 118 119 extensible_dn = Optional(":dn")
120 -def _p_extensible_dn(s,l,t):
121 return bool(t)
122 extensible_dn.setParseAction(_p_extensible_dn) 123 124 matchingrule_or_none = Optional(Suppress(":") + matchingrule)
125 -def _p_matchingrule_or_none(s,l,t):
126 if not t: 127 return [None] 128 else: 129 return t[0]
130 matchingrule_or_none.setParseAction(_p_matchingrule_or_none) 131 132 extensible_attr = attr + extensible_dn + matchingrule_or_none + Suppress(":=") + value 133 extensible_attr.setName('extensible_attr')
134 -def _p_extensible_attr(s,l,t):
135 return list(t)
136 extensible_attr.setParseAction(_p_extensible_attr) 137 138 139 extensible_noattr = extensible_dn + Suppress(":") + matchingrule + Suppress(":=") + value 140 extensible_noattr.setName('extensible_noattr')
141 -def _p_extensible_noattr(s,l,t):
142 return [None]+list(t)
143 extensible_noattr.setParseAction(_p_extensible_noattr) 144 145 extensible = extensible_attr | extensible_noattr 146 extensible.setName('extensible')
147 -def _p_extensible(s,l,t):
148 attr, dn, matchingRule, value = t 149 return pureldap.LDAPFilter_extensibleMatch( 150 matchingRule=matchingRule, 151 type=attr, 152 matchValue=value, 153 dnAttributes=dn)
154 extensible.setParseAction(_p_extensible) 155 item = simple ^ present ^ substring ^ extensible 156 item.setName('item') 157 item.leaveWhitespace() 158 not_ = Suppress(Literal('!')) + filter_ 159 not_.setParseAction(lambda s,l,t: pureldap.LDAPFilter_not(t[0])) 160 not_.setName('not') 161 filterlist = OneOrMore(filter_) 162 or_ = Suppress(Literal('|')) + filterlist 163 or_.setParseAction(lambda s,l,t: pureldap.LDAPFilter_or(t)) 164 or_.setName('or') 165 and_ = Suppress(Literal('&')) + filterlist 166 and_.setParseAction(lambda s,l,t: pureldap.LDAPFilter_and(t)) 167 and_.setName('and') 168 filtercomp = and_ | or_ | not_ | item 169 filtercomp.setName('filtercomp') 170 filter_ << (Suppress(Literal('(').leaveWhitespace()) 171 + filtercomp 172 + Suppress(Literal(')').leaveWhitespace())) 173 filter_.setName('filter') 174 filtercomp.leaveWhitespace() 175 filter_.leaveWhitespace() 176 177 toplevel = (StringStart().leaveWhitespace() 178 + filter_ 179 + StringEnd().leaveWhitespace()) 180 toplevel.leaveWhitespace() 181 toplevel.setName('toplevel') 182
183 -def parseFilter(s):
184 try: 185 x=toplevel.parseString(s) 186 except ParseException, e: 187 raise InvalidLDAPFilter, (e.msg, 188 e.loc, 189 e.line) 190 assert len(x)==1 191 return x[0]
192 193 194 maybeSubString_value = Combine(OneOrMore(CharsNotIn('*\\\0') | escaped)) 195 196 maybeSubString_simple = maybeSubString_value.copy()
197 -def _p_maybeSubString_simple(s,l,t):
198 return (lambda attr: 199 pureldap.LDAPFilter_equalityMatch( 200 attributeDesc=pureldap.LDAPAttributeDescription(attr), 201 assertionValue=pureldap.LDAPAssertionValue(t[0])))
202 maybeSubString_simple.setParseAction(_p_maybeSubString_simple) 203 204 maybeSubString_present = Literal("*")
205 -def _p_maybeSubString_present(s,l,t):
206 return (lambda attr: 207 pureldap.LDAPFilter_present(attr))
208 maybeSubString_present.setParseAction(_p_maybeSubString_present) 209 210 maybeSubString_substring = Optional(initial) + any + Optional(final)
211 -def _p_maybeSubString_substring(s,l,t):
212 return (lambda attr: 213 pureldap.LDAPFilter_substrings( 214 type=attr, 215 substrings=t))
216 maybeSubString_substring.setParseAction(_p_maybeSubString_substring) 217 218 maybeSubString = (maybeSubString_simple 219 ^ maybeSubString_present 220 ^ maybeSubString_substring 221 ) 222
223 -def parseMaybeSubstring(attrType, s):
224 try: 225 x=maybeSubString.parseString(s) 226 except ParseException, e: 227 raise InvalidLDAPFilter, (e.msg, 228 e.loc, 229 e.line) 230 assert len(x)==1 231 fn = x[0] 232 return fn(attrType)
233 234 if __name__=='__main__': 235 import sys 236 for filt in sys.argv[1:]: 237 print repr(parseFilter(filt)) 238 print 239