Package ldaptor :: Package protocols :: Package ldap :: Module distinguishedname
[hide private]
[frames] | no frames]

Source Code for Module ldaptor.protocols.ldap.distinguishedname

  1  # See rfc2253 
  2   
  3  # Note that RFC 2253 sections 2.4 and 3 disagree whether "=" needs to 
  4  # be quoted. Let's trust the syntax, slapd refuses to accept unescaped 
  5  # "=" in RDN values. 
  6  escapedChars = r',+"\<>;=' 
  7  escapedChars_leading = r' #' 
  8  escapedChars_trailing = r' #' 
  9   
10 -def escape(s):
11 r='' 12 r_trailer='' 13 14 if s and s[0] in escapedChars_leading: 15 r='\\'+s[0] 16 s=s[1:] 17 18 if s and s[-1] in escapedChars_trailing: 19 r_trailer='\\'+s[-1] 20 s=s[:-1] 21 22 for c in s: 23 if c in escapedChars: 24 r=r+'\\'+c 25 elif ord(c)<=31: 26 r=r+'\\%02X' % ord(c) 27 else: 28 r=r+c 29 30 return r+r_trailer
31
32 -def unescape(s):
33 r='' 34 while s: 35 if s[0]=='\\': 36 if s[1] in '0123456789abcdef': 37 r=r+chr(int(s[1:3], 16)) 38 s=s[3:] 39 else: 40 r=r+s[1] 41 s=s[2:] 42 else: 43 r=r+s[0] 44 s=s[1:] 45 return r
46
47 -def _splitOnNotEscaped(s, separator):
48 if not s: 49 return [] 50 51 r=[''] 52 while s: 53 if s[0]=='\\': 54 r[-1]=r[-1]+s[:2] 55 s=s[2:] 56 else: 57 if s[0] in separator: 58 r.append('') 59 s=s[1:] 60 while s[0]==' ': 61 s=s[1:] 62 else: 63 r[-1]=r[-1]+s[0] 64 s=s[1:] 65 return r
66
67 -class InvalidRelativeDistinguishedName(Exception):
68 """Invalid relative distinguished name.""" 69
70 - def __init__(self, rdn):
71 Exception.__init__(self) 72 self.rdn = rdn
73
74 - def __str__(self):
75 return "Invalid relative distinguished name %s." \ 76 % repr(self.rdn)
77
78 -class LDAPAttributeTypeAndValue:
79 # TODO I should be used everywhere 80 attributeType = None 81 value = None 82
83 - def __init__(self, stringValue=None, attributeType=None, value=None):
84 if stringValue is None: 85 assert attributeType is not None 86 assert value is not None 87 self.attributeType = attributeType 88 self.value = value 89 else: 90 assert attributeType is None 91 assert value is None 92 if '=' not in stringValue: 93 raise InvalidRelativeDistinguishedName, stringValue 94 self.attributeType, self.value = stringValue.split('=', 1)
95
96 - def __str__(self):
97 return '='.join((escape(self.attributeType), escape(self.value)))
98
99 - def __repr__(self):
100 return (self.__class__.__name__ 101 + '(attributeType=' 102 + repr(self.attributeType) 103 + ', value=' 104 + repr(self.value) 105 + ')')
106
107 - def __hash__(self):
108 return hash((self.attributeType, self.value))
109
110 - def __eq__(self, other):
111 if not isinstance(other, LDAPAttributeTypeAndValue): 112 return NotImplemented 113 return (self.attributeType == other.attributeType 114 and self.value == other.value)
115
116 - def __ne__(self, other):
117 return not (self == other)
118
119 - def __lt__(self, other):
120 if not isinstance(other, self.__class__): 121 return False 122 if self.attributeType != other.attributeType: 123 return self.attributeType < other.attributeType 124 else: 125 return self.value < other.value
126
127 - def __gt__(self, other):
128 return (self != other 129 and self > other)
130
131 - def __le__(self, other):
132 return not self > other
133
134 - def __ge__(self, other):
135 return not self < other
136
137 -class RelativeDistinguishedName:
138 """LDAP Relative Distinguished Name.""" 139 140 attributeTypesAndValues = None 141
142 - def __init__(self, magic=None, stringValue=None, attributeTypesAndValues=None):
143 if magic is not None: 144 assert stringValue is None 145 assert attributeTypesAndValues is None 146 if isinstance(magic, RelativeDistinguishedName): 147 attributeTypesAndValues = magic.split() 148 elif isinstance(magic, basestring): 149 stringValue = magic 150 else: 151 attributeTypesAndValues = magic 152 153 if stringValue is None: 154 assert attributeTypesAndValues is not None 155 import types 156 assert not isinstance(attributeTypesAndValues, types.StringType) 157 self.attributeTypesAndValues = tuple(attributeTypesAndValues) 158 else: 159 assert attributeTypesAndValues is None 160 self.attributeTypesAndValues = tuple([LDAPAttributeTypeAndValue(stringValue=unescape(x)) 161 for x in _splitOnNotEscaped(stringValue, '+')])
162
163 - def split(self):
164 return self.attributeTypesAndValues
165
166 - def __str__(self):
167 return '+'.join([str(x) for x in self.attributeTypesAndValues])
168
169 - def __repr__(self):
170 return (self.__class__.__name__ 171 + '(attributeTypesAndValues=' 172 + repr(self.attributeTypesAndValues) 173 + ')')
174
175 - def __hash__(self):
176 return hash(self.attributeTypesAndValues)
177
178 - def __eq__(self, other):
179 if not isinstance(other, RelativeDistinguishedName): 180 return NotImplemented 181 return self.split() == other.split()
182
183 - def __ne__(self, other):
184 return not (self == other)
185
186 - def __lt__(self, other):
187 if not isinstance(other, self.__class__): 188 return False 189 return self.split() < other.split()
190
191 - def __gt__(self, other):
192 return (self != other 193 and self >= other)
194
195 - def __le__(self, other):
196 return not self > other
197
198 - def __ge__(self, other):
199 return not self < other
200
201 - def count(self):
202 return len(self.attributeTypesAndValues)
203 204
205 -class DistinguishedName:
206 """LDAP Distinguished Name.""" 207 listOfRDNs = None
208 - def __init__(self, magic=None, stringValue=None, listOfRDNs=None):
209 assert (magic is not None 210 or stringValue is not None 211 or listOfRDNs is not None) 212 if magic is not None: 213 assert stringValue is None 214 assert listOfRDNs is None 215 if isinstance(magic, DistinguishedName): 216 listOfRDNs = magic.split() 217 elif isinstance(magic, basestring): 218 stringValue = magic 219 else: 220 listOfRDNs = magic 221 222 if stringValue is None: 223 assert listOfRDNs is not None 224 for x in listOfRDNs: 225 assert isinstance(x, RelativeDistinguishedName) 226 self.listOfRDNs = tuple(listOfRDNs) 227 else: 228 assert listOfRDNs is None 229 self.listOfRDNs = tuple([RelativeDistinguishedName(stringValue=x) 230 for x in _splitOnNotEscaped(stringValue, ',')])
231
232 - def split(self):
233 return self.listOfRDNs
234
235 - def up(self):
237
238 - def __str__(self):
239 return ','.join([str(x) for x in self.listOfRDNs])
240
241 - def __repr__(self):
242 return (self.__class__.__name__ 243 + '(listOfRDNs=' 244 + repr(self.listOfRDNs) 245 + ')')
246
247 - def __hash__(self):
248 return hash(str(self))
249
250 - def __eq__(self, other):
251 if isinstance(other, basestring): 252 return str(self) == other 253 if not isinstance(other, DistinguishedName): 254 return NotImplemented 255 return self.split() == other.split()
256
257 - def __ne__(self, other):
258 return not (self == other)
259
260 - def __cmp__(self, other):
261 if isinstance(other, basestring): 262 return cmp(str(self), other) 263 if not isinstance(other, DistinguishedName): 264 return NotImplemented 265 return cmp(self.split(), other.split())
266
267 - def getDomainName(self):
268 domainParts = [] 269 l=list(self.listOfRDNs) 270 l.reverse() 271 for rdn in l: 272 if rdn.count() != 1: 273 break 274 attributeTypeAndValue = rdn.split()[0] 275 if attributeTypeAndValue.attributeType.upper() != 'DC': 276 break 277 domainParts.insert(0, attributeTypeAndValue.value) 278 if domainParts: 279 return '.'.join(domainParts) 280 else: 281 return None
282
283 - def contains(self, other):
284 """Does the tree rooted at DN contain or equal the other DN.""" 285 if self == other: 286 return 1 287 if not isinstance(other, DistinguishedName): 288 other=DistinguishedName(other) 289 its=list(other.split()) 290 mine=list(self.split()) 291 292 while mine and its: 293 m=mine.pop() 294 i=its.pop() 295 if m!=i: 296 return 0 297 if mine: 298 return 0 299 return 1
300