Package easyLDAP :: Module easyLDAP_class_cache
[frames] | no frames]

Source Code for Module easyLDAP.easyLDAP_class_cache

  1  # -*- coding: utf-8 -*- 
  2   
  3  #    easyLDAP - a python library that makes LDAP management easier than before... 
  4  #    Copyright (C) 2004-2010,2020 Mike Gabriel <m.gabriel@das-netzwerkteam.de> 
  5  # 
  6  #    This program is free software: you can redistribute it and/or modify 
  7  #    it under the terms of the GNU General Public License as published by 
  8  #    the Free Software Foundation, either version 3 of the License, or 
  9  #    (at your option) any later version. 
 10  # 
 11  #    This program is distributed in the hope that it will be useful, 
 12  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  #    GNU General Public License for more details. 
 15  # 
 16  #    You should have received a copy of the GNU General Public License 
 17  #    along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 18  # 
 19   
 20  import copy 
 21  import types 
 22  import pprint 
 23   
 24  import easyLDAP_defaults 
 25   
 26  from easyLDAP_exceptions import * 
 27  from easyLDAP_utils import * 
 28   
29 -class easyLDAP_cache_history:
30 31 _caching_object = False 32 _last_ldap_cache_history_size = None 33 ldap_cachetree = None 34 ldap_cache_undo_history = [] 35 ldap_cache_redo_history = [] 36 ldap_cache_history_size = EASY_LDAP['CacheHistorySize'] 37 use_cache_history = True 38 39
40 - def _method_aliases(self):
41 self.clear_cache_stack = self.clear_cache_history 42 self.resize_cache_stack = self.resize_cache_history 43 self.push = self._push_cache_history
44 45
46 - def __init__(self, config_defaults=EASY_LDAP):
47 48 self._method_aliases() 49 self.ldap_cache_undo_history = [] 50 self.ldap_cache_redo_history = [] 51 52 self._default_cache_history_size = config_defaults['CacheHistorySize'] 53 54 # if we cache an ldapobject we have to divert self.ldap_cachetree to self.ldap_cacheobject 55 if self.ldap_cachetree is None: 56 self._caching_object = True 57 58 # use redo/undo functionality 59 if not self.use_cache_history: 60 self.ldap_cache_history_size = 1 61 62 self.CONFIG=config_defaults
63
64 - def __deepcopy__(self,memo):
65 """Creates a deepcopy of the easyLDAP cache class, especially of the undo/redo stack.""" 66 result = self.__class__() 67 memo[id(self)] = result 68 result.ldap_cache_undo_history = copy.deepcopy(self.ldap_cache_undo_history,memo) 69 return result
70 71
72 - def clear_cache_history(self):
73 """ 74 thisClass.clear_cache_stack() 75 76 clears the easyLDAP cache. This method can be used to 77 completely change an existing LDAP object or in order to erase 78 the object entirely from the LDAP directory. Changes will, 79 of course, only be synced to the LDAP directory, when the 80 method thisClass.flush_cache() is called. 81 """ 82 self.ldap_cache_undo_history = [ self.ldap_cache_undo_history[0] ] 83 self.ldap_cache_redo_history = []
84 85
86 - def resize_cache_history(self,size=None):
87 """ 88 thisClass.resize_cache_stack(mySIZE) 89 90 sets a new size for the easyLDAP undo stack. If the new given 91 stack size mySIZE is less than the former one, the undo stack 92 will be reduced with the next thisClass.push() operation. 93 """ 94 if not self.use_cache_history: 95 raise easyLDAP_exceptions.CACHEHISTORY_INACTIVE 96 97 if size is None: 98 if self._last_ldap_cache_history_size: 99 size = self._last_ldap_cache_history_size 100 else: 101 size = self._default_cache_history_size 102 103 if (type(size) is types.IntType) and (size > 0): 104 self._last_ldap_cache_history_size = self.ldap_cache_history_size 105 self.ldap_cache_history_size = size 106 107 # reduce cache history (nothing happens here if cache history size is increased) 108 self.ldap_cache_undo_history = self.ldap_cache_undo_history[:self.ldap_cache_history_size] 109 return True 110 111 else: 112 raise easyLDAP_exceptions.CACHEHISTORY_NATURALNUMBER_EXPECTED
113 114
115 - def _push_cache_history(self):
116 """ 117 thisClass._push_cache_history() 118 119 copies the current status of the easyLDAP object cache to the 120 redo/undo stack and increases the stack index by one. 121 122 In normal cases calling thisClass.push() should not be necessary 123 as the stack is administered by the class's internal code. 124 125 However, it can be used. 126 """ 127 # push the current cache to the history stack 128 if self._caching_object: 129 self.ldap_cache_undo_history = [ copy.deepcopy(self.ldap_cacheobject) ] + self.ldap_cache_undo_history 130 else: 131 self.ldap_cache_undo_history = [ copy.deepcopy(self.ldap_cachetree) ] + self.ldap_cache_undo_history 132 133 self.ldap_cache_undo_history = self.ldap_cache_undo_history[:self.ldap_cache_history_size]
134 135
136 - def undo(self):
137 """ 138 thisClass.undo() 139 140 undoes the last modification to the easyLDAP object cache. 141 """ 142 if len(self.ldap_cache_undo_history) > 1: 143 if self._caching_object: 144 self.ldap_cache_redo_history = [ copy.deepcopy(self.ldap_cacheobject) ] + self.ldap_cache_redo_history 145 self.ldap_cacheobject = self.ldap_cache_undo_history[1] 146 else: 147 self.ldap_cache_redo_history = [ copy.deepcopy(self.ldap_cachetree) ] + self.ldap_cache_redo_history 148 self.ldap_cachetree = self.ldap_cache_undo_history[1] 149 self.ldap_cache_undo_history = self.ldap_cache_undo_history[1:] 150 return True 151 152 else: 153 raise easyLDAP_exceptions.UNDO_IMPOSSIBLE
154 155
156 - def redo(self):
157 """ 158 thisClass.redo() 159 160 redoes the former modification to the easyLDAP object cache (if any). 161 """ 162 if len(self.ldap_cache_redo_history): 163 self._push_cache_history() 164 if self._caching_object: 165 self.ldap_cacheobject = self.ldap_cache_redo_history[0] 166 else: 167 self.ldap_cachetree = self.ldap_cache_redo_history[0] 168 self.ldap_cache_redo_history = self.ldap_cache_redo_history[1:] 169 return True 170 171 else: 172 raise easyLDAP_exceptions.REDO_IMPOSSIBLE
173
174 - def enable_cache_history(self):
175 176 self.use_cache_history = True 177 self.resize_cache_history()
178 179
180 - def disable_cache_history(self):
181 182 self.resize_cache_history(size=1) 183 self.use_cache_history = False
184 185
187 188 self.use_cache_history = True
189 190
192 193 self.use_cache_history = False
194 195
196 -class easyLDAP_cacheobject(easyLDAP_cache_history):
197 """An easyLDAP_cacheobject stores and accesses the python-ldap like 198 LDAP object dictionary. 199 """ 200 201 ldap_cacheobject = [ [ '', {}, ], ] 202 ldap_cacheobject_dn = '' 203
204 - def __init__(self, ldap_cacheobject, use_cache_history=True, config_defaults=EASY_LDAP):
205 if is_pyldapobject(ldap_cacheobject, strict=False): 206 self.set_cacheobject(ldap_cacheobject=ldap_cacheobject) 207 else: 208 raise easyLDAP_exceptions.NOT_A_PYTHON_LDAPOBJECT 209 if self.use_cache_history: 210 easyLDAP_cache_history.__init__(self, config_defaults=config_defaults) 211 if use_cache_history: 212 self.enable_cache_history() 213 else: 214 self.enable_cache_history() 215 216 self.CONFIG = config_defaults
217
218 - def __deepcopy__(self,memo):
219 result = self.__class__(self.ldap_cacheobject) 220 memo[id(self)] = result 221 result.ldap_cacheobject = copy.deepcopy(self.ldap_cacheobject,memo) 222 result.ldap_cache_undo_history = copy.deepcopy(self.ldap_cache_undo_history, memo) 223 result.ldap_cache_redo_history = copy.deepcopy(self.ldap_cache_redo_history, memo) 224 225 return result
226 227
228 - def __len__(self):
229 return len(self.ldap_cacheobject)
230 231
232 - def __call__(self):
233 cacheobject = self.get_cacheobject() 234 for attr in cacheobject[0][1].keys(): 235 if attr in EASY_LDAP['ExcludeFromCharsetEncoding']: 236 cacheobject[0][1][attr] = [ '<binary data, not shown>', ] 237 pprint.pprint(cacheobject[0])
238 239
240 - def get_cacheobject(self):
241 return [(self.ldap_cacheobject[0][0], self.ldap_cacheobject[0][1])]
242 243
244 - def get_cacheobject_dn(self):
245 return self.ldap_cacheobject_dn
246 247
248 - def clear_cacheobject(self):
249 self.ldap_cacheobject = [ [ self.get_cacheobject_dn(), {}, ], ]
250 251
252 - def set_cacheobject(self, ldap_cacheobject):
253 # only one LDAP object allowed 254 if len(ldap_cacheobject) > 1: 255 raise easyLDAP_exceptions.NOT_A_SINGLE_LDAPOBJECT 256 257 # convert tuple to list... 258 self.ldap_cacheobject = [[ldap_cacheobject[0][0].lower(),ldap_cacheobject[0][1]]] 259 260 # DNs are lower case in easyLDAP 261 self.ldap_cacheobject_dn = self.ldap_cacheobject[0][0] 262 263 if self.use_cache_history: 264 easyLDAP_cache_history._push_cache_history(self)
265 266
267 - def set_cacheobject_dn(self, dn):
268 269 # check if the RDN attribute type is set in the LDAP cache object 270 dn = dn.lower() 271 rdn = dn.split(',') 272 rdn_attrtype = rdn[0].split('=') 273 if rdn_attrtype[0].lower() in [key.lower() for key in self.ldap_cacheobject[0][1].keys()]: 274 self.ldap_cacheobject_dn = dn 275 self.ldap_cacheobject[0][0] = dn 276 else: 277 # otherwise throw an exception 278 raise easyLDAP_exceptions.ATTRDESC_NOT_SET 279 280 if self.use_cache_history: 281 easyLDAP_cache_history._push_cache_history(self)
282
283 - def _get_cacheobject_data(self):
284 return self.ldap_cacheobject[0][1]
285
286 - def _set_cacheobject_data(self, ldap_cacheobject_data):
287 288 # TODO: we need to check data structure here... 289 self.ldap_cacheobject[0][1] = {} 290 for attrdesc in ldap_cacheobject_data.keys(): 291 self.ldap_cacheobject[0][1][attrdesc] = ldap_cacheobject_data[attrdesc] 292 293 if self.use_cache_history: 294 easyLDAP_cache_history._push_cache_history(self)
295
296 - def get_cacheobject_attrdesc(self, attrdesc, ignore_case=False):
297 ldap_cacheobject_data = self._get_cacheobject_data() 298 299 if not ignore_case: 300 if ldap_cacheobject_data.has_key(attrdesc): 301 return ldap_cacheobject_data[attrdesc] 302 else: 303 for key in ldap_cacheobject_data.keys(): 304 if attrdesc.lower() == key.lower(): 305 return ldap_cacheobject_data[key] 306 307 raise easyLDAP_exceptions.ATTRDESC_NOT_SET
308
309 - def has_cacheobject_attrdesc_set(self, attrdesc, ignore_case=False):
310 311 try: 312 test = self.get_cacheobject_attrdesc(attrdesc, ignore_case=ignore_case) 313 return True 314 except easyLDAP_exceptions.ATTRDESC_NOT_SET: 315 return False
316 317
318 - def set_cacheobject_attrdesc(self, attrdesc, values):
319 320 if type(attrdesc) is not types.StringType: 321 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 322 323 values = to_list_of_strings(values) 324 325 ldap_cacheobject_data = self._get_cacheobject_data() 326 ldap_cacheobject_data[attrdesc] = values 327 self._set_cacheobject_data(ldap_cacheobject_data)
328 329
330 - def del_cacheobject_attrdesc(self, attrdesc):
331 332 if type(attrdesc) is not types.StringType: 333 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 334 335 ldap_cacheobject_data = self._get_cacheobject_data() 336 del ldap_cacheobject_data[attrdesc] 337 338 self._set_cacheobject_data(ldap_cacheobject_data)
339 340
341 - def get_cacheobject_attrtype(self, attrtype):
342 343 if type(attrtype) is not types.StringType: 344 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 345 346 ldap_cacheobject_data = self._get_cacheobject_data() 347 348 result = {} 349 for attrdesc in ldap_cacheobject_data.keys(): 350 if attrdesc.startswith(attrtype): 351 result[attrdesc] = ldap_cacheobject_data[attrdesc] 352 353 return result
354 355
356 - def has_cacheobject_attrtype_set(self, attrtype):
357 358 if self.get_cacheobject_attrtype(attrtype): 359 return True 360 361 return False
362 363
364 - def del_cacheobject_attrtype(self, attrtype):
365 366 if type(attrtype) is not types.StringType: 367 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 368 369 ldap_cacheobject_data = self._get_cacheobject_data() 370 371 for attrdesc in ldap_cacheobject_data.keys(): 372 if attrdesc.startswith(attrtype): 373 del ldap_cacheobject_data[attrdesc] 374 375 self._set_cacheobject_data(ldap_cacheobject_data)
376 377
378 - def has_cacheobject_attrdesc_value_set_in_values(self, attrdesc, value):
379 380 if type(attrdesc) is not types.StringType: 381 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 382 383 if type(value) is not types.StringType: 384 raise easyLDAP_exceptions.VALUE_NOT_A_STRING 385 386 ldap_cacheobject_data = self._get_cacheobject_data() 387 if value in self.ldap_cacheobject_data[attrdesc]: 388 return True 389 390 return False
391 392
393 - def has_cacheobject_attrdesc_values_set(self, attrdesc, values):
394 395 if type(attrdesc) is not types.StringType: 396 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 397 398 values = to_list_of_strings(values) 399 400 ldap_cacheobject_data = self._get_cacheobject_data() 401 return (ldap_cacheobject_data[attrdesc] == values)
402 403
404 - def add_cacheobject_attrdesc_values(self, attrdesc, values):
405 406 if type(attrdesc) is not types.StringType: 407 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 408 409 values = to_list_of_strings(values) 410 411 ldap_cacheobject_data[attrdesc].extend(values) 412 413 self._set_cacheobject_data(ldap_cacheobject_data)
414 415
416 - def del_cacheobject_attrdesc_values(self, attrdesc, values, ignore_case=False):
417 418 if type(attrdesc) is not types.StringType: 419 raise easyLDAP_exceptions.ATTRIBUTE_NOT_A_STRING 420 421 values = to_list_of_strings(values) 422 423 ldap_cacheobject_data = self._get_cacheobject_data() 424 for value in values: 425 if ignore_case is False: 426 while value in ldap_cacheobject_data[attrdesc]: 427 ldap_cacheobject_data[attrdesc].remove(value) 428 else: 429 while value.lower() in [ icase_val.lower() for icase_val in ldap_cacheobject_data[attrdesc] ]: 430 ldap_cacheobject_data[attrdesc].remove(value) 431 432 if len(ldap_cacheobject_data[attrdesc]) == 0: 433 del ldap_cacheobject_data[attrdesc] 434 435 self._set_cacheobject_data(ldap_cacheobject_data)
436 437
438 -class easyLDAP_cachetree(easyLDAP_cache_history):
439 """An easyLDAP_cachetree object stores and accesses the python-ldap like 440 LDAP object dictionary. 441 """ 442 443 _raw_ldap_data_on_construction = [] 444 _last_linear_ldap_cachetree =[] 445 _last_linear_ldap_cachetree_basedn = '' 446 ldap_server_basedn = '' 447 ldap_cachetree_basedn = None 448 449
450 - def _method_aliases(self):
451 452 pass
453 454
455 - def __init__(self, ldap_cachetree_linear_or_recursive, basedn=None, use_cache_history=True, config_defaults=EASY_LDAP):
456 457 self._method_aliases() 458 if basedn is None: 459 basedn = config_defaults['BaseDN'] 460 461 self.ldap_server_basedn = basedn.lower() 462 463 if self.is_ldap_cachetree(ldap_cachetree_linear_or_recursive): 464 465 # wrap easyLDAP_cachetree class around an ldap_cachetree (e.g. a subtree), changes in this class will affect the data 466 # of the ,,parent'' class... 467 self.ldap_cachetree = ldap_cachetree_linear_or_recursive 468 469 # reconstruct raw LDAP data from passed on recursive cachetree (this is a compat hack for methods that need this kind of data) 470 self._raw_ldap_data_on_construction = self.get_cachetree_pyldap() 471 472 else: 473 474 self._raw_ldap_data_on_construction = [ [ldap_object[0].lower(), ldap_object[1]] for ldap_object in ldap_cachetree_linear_or_recursive ] 475 # transform raw LDAP data into the recursive LDAP cachetree 476 self.ldap_cachetree = self._build_recursive_ldap_cachetree(self._raw_ldap_data_on_construction) 477 478 self.ldap_cachetree_basedn = self.get_cachetree_basedn() 479 480 if self.use_cache_history: 481 easyLDAP_cache_history.__init__(self, config_defaults=config_defaults) 482 if use_cache_history: 483 self.enable_cache_history() 484 else: 485 self.enable_cache_history() 486 487 easyLDAP_cache_history.__init__(self)
488 489
490 - def __len__(self):
491 return len(self.get_cachetree(linear=True, retrieve_data=False))
492 493
494 - def __deepcopy__(self,memo):
495 result = self.__class__(self.get_cachetree(linear=True, retrieve_data=True)) 496 memo[id(self)] = result 497 result.ldap_cachetree = copy.deepcopy(self.ldap_cachetree,memo) 498 result.ldap_cache_undo_history = copy.deepcopy(self.ldap_cache_undo_history, memo) 499 result.ldap_cache_redo_history = copy.deepcopy(self.ldap_cache_redo_history, memo) 500 return result
501 502
503 - def __call__(self, linear=False, retrieve_data=False):
504 cachetree = self.get_cachetree(linear=linear, retrieve_data=retrieve_data) 505 pprint.pprint(cachetree)
506 507
508 - def __delitem__(self, dn):
509 510 dn_split = split_dn(dn, basedn=self.ldap_server_basedn) 511 dn_split.reverse() 512 if len(dn_split) > 0: 513 last_rdn = dn_split[0] 514 subtree = self.ldap_cachetree[last_rdn][1] 515 for rdn in dn_split[1:]: 516 if rdn != dn_split[-1]: 517 subtree = subtree[rdn][1] 518 del subtree[rdn] 519 else: 520 raise easyLDAP_exceptions.CANNOT_DELETE_BASEDN_OBJECT
521 522
523 - def _find_object_in_raw_ldap_data(self, dn):
524 """ 525 """ 526 for i in self._raw_ldap_data_on_construction: 527 if i[0] == dn.lower(): return [i]
528
529 - def is_ldap_cachetree(self, cachetree):
530 """ 531 """ 532 # TODO: this is a very simple check!!! 533 if type(cachetree) is types.DictType: 534 return True 535 536 return False
537 538
539 - def _build_recursive_ldap_cachetree(self, pyldap_listofobjects):
540 541 _cache_tree = {} 542 543 # Build the DN tree dictionary (_dn_tree). 544 # NOTE: the cache base DN is stripped off of every DN before the tree is built! 545 # The DN tree dictionary has the recursive form (using an example): 546 # { 'ou=people': [ easyLDAP_cachobject(of ou=people), 547 # { 'uid=foo': [ easyLDAP_cacheobject(of uid=foo), {} ], 548 # 'uid=bar': [ easyLDAP_cacheobject(of uid=bar), {} ], 549 # ], 550 # 'ou=groups': [ easyLDAP_cacheobject(of ou=groups), 551 # { 'cn=users': [ easyLDAP_cacheobject(of cn=users), {} ], 552 # 'cn=gurus': [ easyLDAP_cacheobject(of cn=gurus), {} ], 553 # 'cn=nogroup': [ easyLDAP_cacheobject(of cn=nogroup), {} ], 554 # }, 555 # ], 556 # } 557 _cachetree_basedn = self._get_ldapserver_basedn() 558 try: 559 _ldap_basedn_object = self._find_object_in_raw_ldap_data(_cachetree_basedn) 560 _cache_tree[_cachetree_basedn] = [ easyLDAP_cacheobject(_ldap_basedn_object, use_cache_history=False), {'_ldap_parent_dn': None} ] 561 except easyLDAP_exceptions.NOT_A_PYTHON_LDAPOBJECT: 562 _cache_tree[_cachetree_basedn] = [ None, {'_ldap_parent_dn': None} ] 563 564 for dn, obj_data in [ ( ldap_cacheextract[0].lower(), ldap_cacheextract[1]) for ldap_cacheextract in pyldap_listofobjects ]: 565 566 rel_dn = self.strip_off_dn_from_dn(_cachetree_basedn, dn) 567 if self.is_childdn_of_cachetree_basedn(dn): 568 569 if not rel_dn: continue 570 rel_dn_nodes = rel_dn.split(',') 571 rel_dn_nodes.reverse() 572 573 _recurse_tree = _cache_tree[_cachetree_basedn][1] 574 _recurse_tree_basedn = _cachetree_basedn 575 576 # create first level DN nodes here 577 if not _recurse_tree.has_key(rel_dn_nodes[0]): 578 try: 579 _recurse_tree[rel_dn_nodes[0]] = [ easyLDAP_cacheobject(self._find_object_in_raw_ldap_data('%s,%s' % (rel_dn_nodes[0], _recurse_tree_basedn)), use_cache_history=False), {'_ldap_parent_dn': _recurse_tree_basedn} ] 580 except easyLDAP_exceptions.NOT_A_PYTHON_LDAPOBJECT: 581 _recurse_tree[rel_dn_nodes[0]] = [ None, {'_ldap_parent_dn': _recurse_tree_basedn} ] 582 583 # now walk through the deeper DN node levels 584 for i, j in zip(iter(rel_dn_nodes[:-1]), iter(rel_dn_nodes[1:])): 585 if not _recurse_tree[i][1].has_key(j): 586 _ldap_object = '%s,%s,%s' % (j, i, _recurse_tree_basedn) 587 _ldap_object = _ldap_object.lstrip(',').rstrip(',') 588 try: 589 _recurse_tree[i][1][j] = [ easyLDAP_cacheobject(self._find_object_in_raw_ldap_data(_ldap_object), use_cache_history=False), { '_ldap_parent_dn': '%s,%s' % (i, _recurse_tree_basedn)} ] 590 except easyLDAP_exceptions.NOT_A_PYTHON_LDAPOBJECT: 591 _recurse_tree[i][1][j] = [ None, {'_ldap_parent_dn': '%s,%s' % (i, _recurse_tree_basedn)} ] 592 593 _recurse_tree_basedn = '%s,%s' % (i, _recurse_tree_basedn) 594 _recurse_tree = _recurse_tree[i][1] 595 596 else: 597 raise easyLDAP_exceptions.DN_NOT_A_CHILD_OF_BASEDN 598 599 return _cache_tree
600 601
602 - def _get_linear_ldap_cachetree(self, ldap_cachetree_recursive, recursive_call=False):
603 604 if not ldap_cachetree_recursive.has_key('_ldap_parent_dn'): 605 self._last_linear_ldap_cachetree = [] 606 607 for i in [ key for key in ldap_cachetree_recursive.keys() if key != '_ldap_parent_dn' ]: 608 609 if ldap_cachetree_recursive[i][1]['_ldap_parent_dn']: 610 # nearly every ldap object in cachetree 611 dn = '%s,%s' % (i, ldap_cachetree_recursive[i][1]['_ldap_parent_dn']) 612 else: 613 # for BaseDN=RootDSE 614 dn = i 615 616 if ldap_cachetree_recursive[i][0] is not None: 617 self._last_linear_ldap_cachetree.append((dn,ldap_cachetree_recursive[i][0])) 618 619 if ldap_cachetree_recursive[i][1].keys(): 620 self._get_linear_ldap_cachetree(ldap_cachetree_recursive[i][1], recursive_call=True) 621 622 if not recursive_call: 623 return self._last_linear_ldap_cachetree
624 625
626 - def _get_ldapserver_basedn(self):
627 """ 628 """ 629 return self.ldap_server_basedn
630 631
632 - def get_cachetree_basedn(self):
633 """ 634 """ 635 if self.ldap_cachetree_basedn is None: 636 637 # we will do this just once 638 639 # we will find the LDAP cachetree base DN by the string length of the DN... (this is dirty, I know!) 640 # presume it is the first LDAP object in the raw LDAP object list (python-ldap style) 641 self.ldap_cachetree_basedn = self._raw_ldap_data_on_construction[0][0] 642 643 # if the cachetree is more than one object, then look at the others 644 if len(self._raw_ldap_data_on_construction) > 1: 645 for i in self._raw_ldap_data_on_construction[1:]: 646 647 # ... and select any DN that is shorter as the new candidate for the cachetree base DN 648 for l in range(min(len(i[0].split(',')), len(self.ldap_cachetree_basedn.split(',')))): 649 if i[0].split(',')[-(l+1)] == self.ldap_cachetree_basedn.split(',')[-(l+1)]: 650 continue 651 652 self.ldap_cachetree_basedn = ",".join(self.ldap_cachetree_basedn.split(',')[-l:]) 653 break 654 655 # we remember... 656 return self.ldap_cachetree_basedn
657 658
659 - def set_cachetree_basedn(self, new_basedn):
660 print('Not implemented yet...') 661 easyLDAP_cache_history._push_cache_history(self)
662 663
664 - def is_childdn_of_dn(self, child_dn, parent_dn):
665 """ 666 """ 667 if is_dn_syntax(child_dn) and is_dn_syntax(parent_dn): 668 if child_dn.endswith(parent_dn): 669 return True 670 else: 671 raise easyLDAP_exceptions.INVALID_DN_SYNTAX 672 673 return False
674 675
676 - def is_childdn_of_cachetree_basedn(self, child_dn):
677 """ 678 """ 679 return self.is_childdn_of_dn(child_dn, self.get_cachetree_basedn())
680 681
682 - def is_childdn_of_ldapserver_basedn(self, child_dn):
683 """ 684 """ 685 return self.is_childdn_of_dn(child_dn, self._get_ldapserver_basedn())
686 687
688 - def strip_off_dn_from_dn(self, parent_dn, child_dn):
689 690 if self.is_childdn_of_dn(child_dn, parent_dn) or parent_dn.lower() == child_dn.lower(): 691 return child_dn.lower()[:-len(parent_dn)-1] 692 else: 693 raise easyLDAP_exceptions.DN_NOT_A_CHILD_OF_BASEDN
694 695
696 - def get_cachetree(self, linear=False, retrieve_data=False, hashed=False):
697 """ 698 retrieve_data works only on linear operations 699 """ 700 if not linear and not hashed: 701 return self.ldap_cachetree 702 else: 703 linear_res = self._get_linear_ldap_cachetree(self.get_cachetree(linear=False, retrieve_data=retrieve_data)) 704 if not hashed: 705 if not retrieve_data: 706 707 # format: list x = [ (<dn1>,<class_easyLDAP_object1>), (<dn2>,<class_easyLDAP_object2>), ...] 708 709 return linear_res 710 else: 711 712 # format: list x = [ (<dn1>,<pyldap_data_object1[0][1]>>), (<dn2>,<pyldap_data_object2[0][1]>), ...] 713 714 return [ tuple(obj_tuple[1].get_cacheobject()[0]) for obj_tuple in linear_res if obj_tuple[1] != None ] 715 else: 716 717 this_hash = {} 718 if not retrieve_data: 719 720 # format: dict x[<dn>] = <class_easyLDAP_object> 721 722 for obj_tuple in linear_res: 723 if obj_tuple: 724 this_hash[obj_tuple[0]] = obj_tuple[1] 725 else: 726 727 # format: dict x[<dn>] = <pyldap_data_object[0][1]> 728 729 for obj_tuple in linear_res: 730 if obj_tuple: 731 this_hash[obj_tuple[0]] = obj_tuple[1].get_cacheobject()[0][1] 732 return this_hash
733 734
735 - def get_cachetree_hash(self, retrieve_data=False):
736 737 return self.get_cachetree(linear=True, hashed=True, retrieve_data=retrieve_data)
738 739
740 - def get_cachetree_pyldap(self):
741 742 return self.get_cachetree(linear=True, retrieve_data=True)
743 744
745 - def get_cachetree_dnlist(self):
746 747 dn_list = self.get_cachetree_hash().keys() 748 dn_list.sort() 749 return dn_list
750 751
752 - def get_cachetree_depth(self):
753 """ 754 """ 755 dn_list = self.get_cachetree_dnlist() 756 depth = 0 757 for dn in dn_list: 758 depth = max(depth, len(split_dn(self.strip_off_dn_from_dn(self.ldap_server_basedn, dn), basedn=self.ldap_server_basedn))) 759 return depth
760 761
762 - def get_cachetree_subtree(self, dn, deepcopy=False):
763 """ 764 """ 765 dn = dn.lower() 766 767 if dn in self.get_cachetree_dnlist(): 768 if deepcopy: 769 tree_pyldap = self.get_cachetree_pyldap() 770 return easyLDAP_cachetree([ obj for obj in tree_pyldap if obj[0].endswith(dn) ], basedn=self.ldap_server_basedn, use_cache_history=self.use_cache_history, config_defaults=self.CONFIG) 771 else: 772 subtree = self.ldap_cachetree 773 774 if dn.lower() == self.ldap_cachetree_basedn: 775 return easyLDAP_cachetree(subtree, basedn=self.ldap_server_basedn, use_cache_history=self.use_cache_history, config_defaults=self.CONFIG) 776 777 rev_rdns = split_dn(dn, basedn=self.ldap_cachetree_basedn) 778 rev_rdns.reverse() 779 last_rdn = rev_rdns[0] 780 781 final_tree = { } 782 temp_tree = final_tree 783 for rdn in rev_rdns[1:]: 784 subtree = { rdn: subtree[last_rdn][1][rdn], } 785 temp_tree[last_rdn] = [ None, {'_ldap_parent_dn': last_rdn, rdn: [], } ] 786 787 temp_tree = temp_tree[last_rdn][1] 788 for k in temp_tree.keys(): 789 if k != rdn and k != '_ldap_parent_dn': 790 del temp_tree[k] 791 792 last_rdn = rdn 793 794 temp_tree[rdn].append(subtree[rdn][0]) 795 temp_tree[rdn].append(subtree[rdn][1]) 796 797 return easyLDAP_cachetree(final_tree, basedn=self.ldap_server_basedn, use_cache_history=self.use_cache_history, config_defaults=self.CONFIG) 798 else: 799 raise easyLDAP_exceptions.NO_SUCH_DN_IN_CACHE
800 801
802 - def get_cachetree_parenttree(self, dn, deepcopy=False):
803 """ 804 """ 805 dn = dn.lower() 806 807 if dn in self.get_cachetree_dnlist(): 808 parent_dn = get_parent_dn(dn) 809 return self.get_cachetree_subtree(parent_dn) 810 else: 811 raise easyLDAP_exceptions.NO_SUCH_DN_IN_CACHE
812 813
814 - def get_cachetree_subtree_data(self, dn):
815 """ 816 """ 817 return self.get_cachetree_subtree(dn).get_cachetree()
818 819
820 - def has_dn(self, dn):
821 822 return self.get_cachetree_hash().has_key(dn.lower())
823 824
825 - def has_children(self, dn):
826 827 dn_split = split_dn(dn, basedn=self.ldap_server_basedn) 828 dn_split.reverse() 829 subtree = self.ldap_cachetree[dn_split[0]][1] 830 if len(subtree.keys()) > 1: 831 if len(dn_split) > 1: 832 for rdn in dn_split[1:]: 833 subtree = subtree[rdn][1] 834 if len(subtree.keys()) > 1: 835 return True 836 else: 837 return True 838 839 return False
840 841
842 - def get_cacheobject_from_cachetree(self, object_dn):
843 """ 844 get_cacheobject_from_cachetree('DN') 845 846 returns the data of a single cache object from the 847 cached cachetree. 848 """ 849 for obj in self.get_cachetree(linear=True, retrieve_data=False): 850 if obj[0] == object_dn.lower(): 851 return obj[1] 852 else: 853 raise easyLDAP_exceptions.NO_SUCH_OBJECT_IN_CACHETREE
854 855 856 857
858 - def remove_cacheobject_from_cachetree(self, object_dn):
859 """ 860 """ 861 if self.has_dn(object_dn): 862 if not self.has_children(object_dn): 863 del self[object_dn] 864 else: 865 raise easyLDAP_exceptions.CACHEOBJECT_IS_SUBTREE 866 else: 867 raise easyLDAP_exceptions.NO_SUCH_OBJECT_IN_CACHETREE 868 869 easyLDAP_cache_history._push_cache_history(self)
870 871
872 - def has_parent_dn(self, dn):
873 """ 874 """ 875 return (','.join(split_dn(dn)[1:]) in self.get_cachetree_dnlist())
876 877
878 - def new_cachetree_object(self, object_data):
879 """ 880 """ 881 if not is_pyldapobject(object_data): 882 raise easyLDAP_exceptions.NOT_A_PYTHON_LDAPOBJECT 883 object_data[0][0] = object_data[0][0].lower() 884 object_dn = object_data[0][0] 885 if self.has_parent_dn(object_dn): 886 887 obj = easyLDAP_cacheobject(object_data) 888 889 object_dn_list = split_dn(object_dn, basedn=self.ldap_server_basedn) 890 object_dn_list.reverse() 891 dive = self.ldap_cachetree 892 for rdn in object_dn_list[:-1]: 893 dive = dive[rdn][1] 894 rdn = split_dn(object_dn) 895 dive[object_dn_list[-1]] = [ obj ] 896 dive[object_dn_list[-1]].append( { '_ldap_parent_dn': ','.join(split_dn(object_dn)[1:]) } ) 897 898 else: 899 raise easyLDAP_exception.NO_PARENTOBJECT_FOR_GIVEN_DN 900 901 #easyLDAP_cache_history._push_cache_history(self) 902 return self.get_cacheobject_from_cachetree(object_data[0][0])
903 904
905 - def del_cachesubtree_from_cachetree(self, subtree_basedn):
906 print('Not implemented yet...') 907 easyLDAP_cache_history._push_cache_history(self)
908 909
910 - def move_cachesubtree_in_cachetree(self, from_dn, to_dn):
911 print('Not implemented yet...') 912 easyLDAP_cache_history._push_cache_history(self)
913 914 if __name__=='__main__': 915 pass 916