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

Source Code for Module ldaptor.entry

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