def save_or_update(self, *args, **kwargs): '''If the object exists, update its attributes from the new object. Otherwise create it.''' # Search for existing node. If found, update it. if self.dn: rdn_key = getattr(self.__class__, '_rdn_') rdn_val = getattr(self, self._rdn_) object_list = self.directory.search( self.__class__, basedn=self._parent, recursive=False, search_filter=eq(rdn_key, rdn_val), ) if object_list: self_old = object_list[0] for fname, field_object in self._fields.items(): if fname in ['object_class']: continue val_new = getattr(self, fname, None) if val_new: setattr(self_old, fname, val_new) return self_old.save() return self.save(*args, **kwargs)
def build_filters(self, filters=None, request=None): basedn = None filter = None parts = [] for arg_name, arg_value in filters.items(): if arg_name in ['limit', 'offset']: # XXX permit limit arg continue if arg_name not in self.fields or arg_name in ['limit']: raise InvalidFilterError( "Not a valid filter: {0}".format(arg_name)) if getattr(self.fields[arg_name], 'is_related', False): method = getattr(self, 'filter_on_{0}'.format(arg_name), None) if method: basedn = method(arg_value) continue else: raise InvalidFilterError( "Cannot filter on a relation field: {0}".format( arg_name)) model_field_name = self.get_model_field_name(arg_name) part = eq(model_field_name, arg_value) parts.append(part) if parts: filter = opand(*parts) search_params = SearchParams(basedn=basedn, filter=filter) return search_params
def get_object(cls, fieldname, value): directory = get_directory() object_list = directory.search( cls, search_filter=eq(getattr(cls, fieldname), value) ) if object_list: return object_list[0]
def search(self, model, basedn=None, recursive=True, search_filter=None, skip_basedn=False, lazy=False): """Search for all objects matching model and return list of model instances :argument model: model class to search for :parameter basedn: basedn for LDAP search operation, if None LDAP resource basedn will be used :parameter recursive: whenever to search with subtree scope, default is True :parameter search_filter: additional LDAP search filter to use :parameter lazy: whenever to fetch lazy attributes when doing LDAP search, default is False """ #HACK for base.get_children() - will be fixed in 0.2 if model is None: model = Model ocs = [] for oc in model.private_classes(): if self._resource.server_type == resource.ACTIVE_DIRECTORY_LDAP: if oc in ["securityPrincipal"]: continue #Active Directory doesn't treat these as actually set ocs.append(filters.eq('objectClass', oc)) model_filter = filters.opand(*ocs) if basedn is None: basedn = self._resource.basedn if recursive: scope = ldap.SCOPE_SUBTREE else: scope = ldap.SCOPE_ONELEVEL if search_filter: final_filter = filters.opand(model_filter, search_filter) else: final_filter = model_filter data = self._ldapconn.search_ext_s( self._encode(basedn), scope, final_filter, attrlist=model.ldap_attributes(lazy=lazy), timeout=self._resource.timeout, ) ret = ObjectList() for (dn, attrs) in data: if skip_basedn and self._encode(dn) == self._encode(basedn): continue ret.append(model(self, dn=dn, attrs=attrs)) return ret
def fget(self, instance): dns = instance._get_attr(self.name) if dns: if self.rdn_is_fk: pk = dns[0] else: pk = Dn(dns[0]).rdn_value to_model = get_model(self.to_model) models = instance.directory.search(to_model, search_filter=eq(to_model._rdn_, pk)) return models[0]
def obj_get(self, request=None, **kwargs): param_name = self.get_uri_pk_group_name() id = kwargs.get(param_name) model = self._meta.object_class try: object_list = self.directory.search(model, search_filter=eq( model.zarafaId, id)) return object_list[0] except IndexError: raise ResourceNotFound
def search(self, model, basedn=None, recursive=True, search_filter=None, skip_basedn=False, lazy=False): #HACK for base.get_children() - will be fixed in 0.2 if model is None: model = Model ocs = [] for oc in model.private_classes(): if self._resource.server_type == resource.ACTIVE_DIRECTORY_LDAP: if oc in ["securityPrincipal"]: continue # Active Directory doesn't treat these as actually set ocs.append(filters.eq('objectClass', oc)) model_filter = filters.opand(*ocs) if basedn is None: basedn = self._resource.basedn if recursive: scope = ldap.SCOPE_SUBTREE else: scope = ldap.SCOPE_ONELEVEL if search_filter: final_filter = filters.opand(model_filter, search_filter) else: final_filter = model_filter data = self._ldapconn.search_ext_s( self._encode(basedn), scope, final_filter, attrlist=model.ldap_attributes(lazy=lazy), timeout=self._resource.timeout, ) ret = ObjectList() for (dn, attrs) in data: if skip_basedn and self._encode(dn) == self._encode(basedn): continue # filter out results of the wrong shape (AD returns a mix of dicts and lists) if type(attrs) == dict: ret.append(model(self, dn=dn, attrs=attrs)) return ret
def _hook_post_save(self): """Post save hook needed to keep members gid in sync #TODO only added members are synced, we need to also take care of removed users """ log.debug("Running post save hook for gid '%s'" % self.gid) for uid in self.members: log.debug("Post save hook call for uid '%s'" % uid) member = self.directory.get( PosixUser, search_filter=eq(PosixUser.uid, uid) ) if not member is None: log.debug("Update gid to '%s' for uid '%s'" % (self.gid, uid)) member.gid = self.gid member.save()
def obj_update(self, bundle, request=None, **kwargs): # Fetch object, then hydrate and save object_list = self.directory.search( bundle.obj.__class__, search_filter=eq('zarafaId', bundle.data['id']), ) bundle.obj = object_list[0] try: bundle = self.full_hydrate(bundle) except ResourceNotFound as e: raise ValidationError(e.message) bundle.obj.save() return bundle
def get_by_userid(self, userid): uid, o = None, None try: [uid, o] = userid.rsplit('@', 1) except ValueError: pass if uid and o: users = [] try: users = get_directory().search( User, basedn=Tenant.get_dn(o), search_filter=eq(User.uid, uid), ) except ObjectNotFound: pass if users: user = users[0] return user
def __get__(self, instance, instance_type=None): pk = Dn(instance.dn).parent.parent.rdn_value # handle up/down tree to_model = get_model(self.to_model) models = instance.directory.search(to_model, search_filter=eq(to_model._rdn_, pk)) return models[0]