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

Source Code for Module ldaptor.entry

  1  import random, base64 
  2  from zope.interface import implements 
  3  from twisted.internet import defer 
  4  from twisted.python.util import InsensitiveDict 
  5  from ldaptor import interfaces, attributeset, delta 
  6  from ldaptor.protocols.ldap import distinguishedname, ldif, ldaperrors 
  7   
  8  try: 
  9      from hashlib import sha1 
 10  except ImportError: 
 11      from sha import sha as sha1 
 12   
 13   
14 -def sshaDigest(passphrase, salt=None):
15 if salt is None: 16 salt = '' 17 for i in range(8): 18 salt += chr(random.randint(0, 255)) 19 20 s = sha1() 21 s.update(passphrase) 22 s.update(salt) 23 encoded = base64.encodestring(s.digest()+salt).rstrip() 24 crypt = '{SSHA}' + encoded 25 return crypt
26
27 -class BaseLDAPEntry(object):
28 implements(interfaces.ILDAPEntry) 29 dn = None 30
31 - def __init__(self, dn, attributes={}):
32 """ 33 34 Initialize the object. 35 36 @param dn: Distinguished Name of the object, as a string. 37 38 @param attributes: Attributes of the object. A dictionary of 39 attribute types to list of attribute values. 40 41 """ 42 self._attributes=InsensitiveDict() 43 self.dn = distinguishedname.DistinguishedName(dn) 44 45 for k,vs in attributes.items(): 46 if k not in self._attributes: 47 self._attributes[k] = [] 48 self._attributes[k].extend(vs) 49 50 for k,vs in self._attributes.items(): 51 self._attributes[k] = self.buildAttributeSet(k, vs)
52
53 - def buildAttributeSet(self, key, values):
54 return attributeset.LDAPAttributeSet(key, values)
55
56 - def __getitem__(self, key):
57 return self._attributes[key]
58
59 - def get(self, key, default=None):
60 return self._attributes.get(key, default)
61
62 - def has_key(self, key):
63 return key in self._attributes
64
65 - def __contains__(self, key):
66 return self.has_key(key)
67
68 - def keys(self):
69 a = [] 70 if self.get('objectClass'): 71 a.append('objectClass') 72 l=list(self._attributes.keys()) 73 l.sort() 74 for key in l: 75 if key.lower() != 'objectclass': 76 a.append(key) 77 return a
78
79 - def items(self):
80 a=[] 81 objectClasses = list(self.get('objectClass', [])) 82 objectClasses.sort() 83 if objectClasses: 84 a.append(('objectClass', objectClasses)) 85 86 l=list(self._attributes.items()) 87 l.sort() 88 for key, values in l: 89 if key.lower() != 'objectclass': 90 vs = list(values) 91 vs.sort() 92 a.append((key, vs)) 93 94 return a
95
96 - def __str__(self):
97 a=[] 98 99 objectClasses = list(self.get('objectClass', [])) 100 objectClasses.sort() 101 a.append(('objectClass', objectClasses)) 102 103 l=list(self.items()) 104 l.sort() 105 for key, values in l: 106 if key.lower() != 'objectclass': 107 vs = list(values) 108 vs.sort() 109 a.append((key, vs)) 110 return ldif.asLDIF(self.dn, a)
111
112 - def __eq__(self, other):
113 if not isinstance(other, BaseLDAPEntry): 114 return 0 115 if self.dn != other.dn: 116 return 0 117 118 my=self.keys() 119 my.sort() 120 its=other.keys() 121 its.sort() 122 if my!=its: 123 return 0 124 for key in my: 125 myAttr=self[key] 126 itsAttr=other[key] 127 if myAttr!=itsAttr: 128 return 0 129 return 1
130
131 - def __ne__(self, other):
132 return not self==other
133
134 - def __len__(self):
135 return len(self.keys())
136
137 - def __nonzero__(self):
138 return True
139
140 - def __repr__(self):
141 x={} 142 for key in self.keys(): 143 x[key]=self[key] 144 keys=self.keys() 145 keys.sort() 146 a=[] 147 for key in keys: 148 a.append('%s: %s' % (repr(key), repr(list(self[key])))) 149 attributes=', '.join(a) 150 return '%s(%s, {%s})' % ( 151 self.__class__.__name__, 152 repr(str(self.dn)), 153 attributes)
154
155 - def diff(self, other):
156 """ 157 Compute differences between this and another LDAP entry. 158 159 @param other: An LDAPEntry to compare to. 160 161 @return: None if equal, otherwise a ModifyOp that would make 162 this entry look like other. 163 """ 164 assert self.dn == other.dn 165 if self == other: 166 return None 167 168 r = [] 169 170 myKeys = set(self.keys()) 171 otherKeys = set(other.keys()) 172 173 addedKeys = list(otherKeys - myKeys) 174 addedKeys.sort() # for reproducability only 175 for added in addedKeys: 176 r.append(delta.Add(added, other[added])) 177 178 deletedKeys = list(myKeys - otherKeys) 179 deletedKeys.sort() # for reproducability only 180 for deleted in deletedKeys: 181 r.append(delta.Delete(deleted, self[deleted])) 182 183 sharedKeys = list(myKeys & otherKeys) 184 sharedKeys.sort() # for reproducability only 185 for shared in sharedKeys: 186 187 addedValues = list(other[shared] - self[shared]) 188 if addedValues: 189 addedValues.sort() # for reproducability only 190 r.append(delta.Add(shared, addedValues)) 191 192 deletedValues = list(self[shared] - other[shared]) 193 if deletedValues: 194 deletedValues.sort() # for reproducability only 195 r.append(delta.Delete(shared, deletedValues)) 196 197 return delta.ModifyOp(dn=self.dn, modifications=r)
198
199 - def bind(self, password):
200 return defer.maybeDeferred(self._bind, password)
201
202 - def _bind(self, password):
203 for digest in self.get('userPassword', ()): 204 if digest.startswith('{SSHA}'): 205 raw = base64.decodestring(digest[len('{SSHA}'):]) 206 salt = raw[20:] 207 got = sshaDigest(password, salt) 208 if got == digest: 209 return self 210 raise ldaperrors.LDAPInvalidCredentials
211
212 - def hasMember(self, dn):
213 for memberDN in self.get('member', []): 214 if memberDN == dn: 215 return True 216 return False
217
218 - def __hash__(self):
219 return hash(self.dn)
220
221 -class EditableLDAPEntry(BaseLDAPEntry):
222 implements(interfaces.IEditableLDAPEntry) 223
224 - def __setitem__(self, key, value):
225 new=self.buildAttributeSet(key, value) 226 self._attributes[key] = new
227
228 - def __delitem__(self, key):
229 del self._attributes[key]
230
231 - def undo(self):
232 raise NotImplementedError
233
234 - def commit(self):
235 raise NotImplementedError
236
237 - def move(self, newDN):
238 raise NotImplementedError
239
240 - def delete(self):
241 raise NotImplementedError
242
243 - def setPassword(self, newPasswd, salt=None):
244 crypt = sshaDigest(newPasswd, salt) 245 self['userPassword'] = [crypt]
246