def id_for_login(self, login): if not self._login_attr: return ensure_text(login) criteria = {self._login_attr: login} attrlist = [self._key_attr] res = self.context.search(criteria=criteria, attrlist=attrlist) if not res: return ensure_text(login) if len(res) > 1: # pragma: no cover msg = u'More than one principal with login "{0}" found.' logger.warning(msg.format(login)) return ensure_text(res[0][1][self._key_attr][0])
def __iter__(self): if self.name is None: return cookie = '' while True: try: res = self.ldap_session.search( scope=ONELEVEL, baseDN=self.DN, attrlist=[''], page_size=self._page_size, cookie=cookie ) except NO_SUCH_OBJECT: # happens if not persisted yet res = list() if isinstance(res, tuple): res, cookie = res for dn, _ in res: key = ensure_text(explode_dn(dn)[0]) # do not yield if node is supposed to be deleted if key not in self._deleted_children: yield key if not cookie: break # also yield keys of children not persisted yet. for key in self._added_children: yield key
def group_ids(self): groups = self.parent.parent.groups if self.parent.parent.ucfg.memberOfSupport: res = list() for dn in self.member_of_attr: dn = ensure_text(dn) if groups.context.DN not in dn: # Skip DN outside groups base DN continue try: res.append(groups.idbydn(dn)) except KeyError: # happens if DN is returned which does not fit the groups # base DN. pass else: member_format = groups._member_format attribute = groups._member_attribute if member_format == FORMAT_DN: criteria = {attribute: self.context.DN} elif member_format == FORMAT_UID: criteria = {attribute: self.context.attrs['uid']} attrlist = [groups._key_attr] # if roles configuration points to child of groups container, and # group configuration has search scope SUBTREE, and groups are # specified by the same criteria as roles, the search returns the # role id's as well. # XXX: such edge cases should be resolved at UGM init time matches_generator = groups.context.batched_search( criteria=criteria, attrlist=attrlist) res = [att[groups._key_attr][0] for _, att in matches_generator] return res
def __getitem__(self, key): key = ensure_text(key) try: return self.storage[key] except KeyError: criteria = {self._key_attr: key} attrlist = ['rdn', self._key_attr] res = self.context.search(criteria=criteria, attrlist=attrlist) if not res: raise KeyError(key) if len(res) > 1: # pragma: no cover msg = u'More than one principal with id "{0}" found.' logger.warning(msg.format(key)) prdn = res[0][1]['rdn'] if prdn in self.context._deleted_children: raise KeyError(key) dn = res[0][0] path = explode_dn(dn)[:len(self.context.DN.split(',')) * -1] context = self.context for rdn in reversed(path): context = context[rdn] principal = self.principal_factory( context, attraliaser=self.principal_attraliaser) principal.__name__ = key principal.__parent__ = self self.storage[key] = principal return principal
def __getitem__(self, key): key = ensure_text(key) if key not in self: raise KeyError(key) principals = self.related_principals(key) if key.startswith('group:'): key = key[6:] return principals[key]
def add(self, key): key = ensure_text(key) if key not in self.member_ids: val = self.translate_key(key) # self.context.attrs[self._member_attribute].append won't work here # issue in LDAPNodeAttributes, does not recognize changed this way. old = self.context.attrs.get(self._member_attribute, list()) self.context.attrs[self._member_attribute] = old + [val]
def __iter__(self): attrlist = ['rdn', self._key_attr] for principal in self.context.batched_search(attrlist=attrlist): prdn = principal[1]['rdn'] if prdn in self.context._deleted_children: continue yield ensure_text(principal[1][self._key_attr][0]) for principal in self.context._added_children: yield self.context[principal].attrs[self._key_attr]
def __setitem__(_next, self, key, val): if val in [u'', b'', UNSET]: if key in self: del self[key] return if not self.is_binary(key): val = decode(val) key = ensure_text(key) _next(self, key, val) self._set_attrs_modified()
def __delitem__(self, key): key = ensure_text(key) group = self[key] parent = self.parent if parent and parent.rcfg is not None: for role in group.roles: group.remove_role(role) context = group.context del context.parent[context.name] del self.storage[key]
def __delitem__(self, key): # do not delete immediately. Just mark LDAPNode to be deleted. key = ensure_text(key) # value not persistent yet, remove from storage and add list if key in self._added_children: del self.storage[key] self._added_children.remove(key) self.changed = False return val = self[key] val._action = ACTION_DELETE # this will also trigger the changed chain val.changed = True self._deleted_children.add(key)
def idbydn(self, dn, strict=False): """Return a principal's id for a given dn. Raise KeyError if not enlisted. """ # XXX: rename to id_by_dn # XXX: what was strict good for? remove # if strict: # raise KeyError(dn) try: search = self.context.ldap_session.search res = search(baseDN=dn)[0] return ensure_text(res[1][self._key_attr][0]) except ldap.NO_SUCH_OBJECT: raise KeyError(dn)
def __delitem__(self, key): key = ensure_text(key) if key not in self: raise KeyError(key) if self._member_format == FORMAT_DN: val = self.related_principals(key)[key].context.DN elif self._member_format == FORMAT_UID: val = key # self.context.attrs[self._member_attribute].remove won't work here # issue in LDAPNodeAttributes, does not recognize changed this way. members = self.context.attrs[self._member_attribute] members.remove(val) self.context.attrs[self._member_attribute] = members # XXX: call here immediately? self.context()
def __getitem__(self, key): # nodes are created for keys, if they do not already exist in memory key = ensure_text(key) try: return self.storage[key] except KeyError: val = self.child_factory() val.__name__ = key val.__parent__ = self try: res = self.ldap_session.search( scope=BASE, baseDN=val.DN, attrlist=[''] # no need for attrs ) # remember DN val._dn = res[0][0] val._ldap_session = self.ldap_session self.storage[key] = val return val except (NO_SUCH_OBJECT, INVALID_DN_SYNTAX): raise KeyError(key)
def __setitem__(self, key, val): key = ensure_text(key) if not isinstance(val, LDAPNode): # create one from whatever we got # XXX: raise KeyError instead of trying to create node val = self._create_suitable_node(val) val.__name__ = key val.__parent__ = self val._dn = self.child_dn(key) val._ldap_session = self.ldap_session try: self.ldap_session.search( scope=BASE, baseDN=val.DN, attrlist=[''] # no need for attrs ) except (NO_SUCH_OBJECT, INVALID_DN_SYNTAX): # the value is not yet in the directory val._action = ACTION_ADD val.changed = True self.changed = True self._added_children.add(key) rdn, rdn_val = key.split('=') if rdn not in val.attrs: val._notify_suppress = True val.attrs[rdn] = rdn_val val._notify_suppress = False self.storage[key] = val if self.child_defaults: for k, v in self.child_defaults.items(): if k in val.attrs: # skip default if attribute already exists continue if callable(v): v = v(self, key) val.attrs[k] = v
def __contains__(self, key): key = ensure_text(key) for uid in self: if uid == key: return True return False
def __getitem__(self, key): key = ensure_text(key) if key not in self: raise KeyError(key) return self.related_principals(key)[key]