mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-26 00:41:25 -06:00
Add LDAPMultiQuery base class and make it the base of LDAPDelete.
In other words: make *-del commands accept 1 or more primary keys of entries to be deleted. Ticket #20
This commit is contained in:
parent
c53831037c
commit
838c1f2c94
@ -345,6 +345,19 @@ class LDAPQuery(CallbackInterface, crud.PKQuery):
|
|||||||
yield self.obj.primary_key.clone(attribute=True, query=True)
|
yield self.obj.primary_key.clone(attribute=True, query=True)
|
||||||
|
|
||||||
|
|
||||||
|
class LDAPMultiQuery(LDAPQuery):
|
||||||
|
"""
|
||||||
|
Base class for commands that need to retrieve one or more existing entries.
|
||||||
|
"""
|
||||||
|
def get_args(self):
|
||||||
|
for key in self.obj.get_ancestor_primary_keys():
|
||||||
|
yield key
|
||||||
|
if self.obj.primary_key:
|
||||||
|
yield self.obj.primary_key.clone(
|
||||||
|
attribute=True, query=True, multivalue=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LDAPRetrieve(LDAPQuery):
|
class LDAPRetrieve(LDAPQuery):
|
||||||
"""
|
"""
|
||||||
Retrieve an LDAP entry.
|
Retrieve an LDAP entry.
|
||||||
@ -512,7 +525,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
|||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
|
|
||||||
class LDAPDelete(LDAPQuery):
|
class LDAPDelete(LDAPMultiQuery):
|
||||||
"""
|
"""
|
||||||
Delete an LDAP entry and all of its direct subentries.
|
Delete an LDAP entry and all of its direct subentries.
|
||||||
"""
|
"""
|
||||||
@ -521,47 +534,66 @@ class LDAPDelete(LDAPQuery):
|
|||||||
def execute(self, *keys, **options):
|
def execute(self, *keys, **options):
|
||||||
ldap = self.obj.backend
|
ldap = self.obj.backend
|
||||||
|
|
||||||
dn = self.obj.get_dn(*keys, **options)
|
def delete_entry(pkey):
|
||||||
|
nkeys = keys[:-1] + (pkey, )
|
||||||
|
dn = self.obj.get_dn(*nkeys, **options)
|
||||||
|
|
||||||
for callback in self.PRE_CALLBACKS:
|
for callback in self.PRE_CALLBACKS:
|
||||||
if hasattr(callback, 'im_self'):
|
if hasattr(callback, 'im_self'):
|
||||||
dn = callback(ldap, dn, *keys, **options)
|
dn = callback(ldap, dn, *nkeys, **options)
|
||||||
else:
|
|
||||||
dn = callback(self, ldap, dn, *keys, **options)
|
|
||||||
|
|
||||||
def delete_subtree(base_dn):
|
|
||||||
truncated = True
|
|
||||||
while truncated:
|
|
||||||
try:
|
|
||||||
(subentries, truncated) = ldap.find_entries(
|
|
||||||
None, [''], base_dn, ldap.SCOPE_ONELEVEL
|
|
||||||
)
|
|
||||||
except errors.NotFound:
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
for (dn_, entry_attrs) in subentries:
|
dn = callback(self, ldap, dn, *nkeys, **options)
|
||||||
delete_subtree(dn_)
|
|
||||||
try:
|
def delete_subtree(base_dn):
|
||||||
ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn)
|
truncated = True
|
||||||
except errors.ExecutionError, e:
|
while truncated:
|
||||||
|
try:
|
||||||
|
(subentries, truncated) = ldap.find_entries(
|
||||||
|
None, [''], base_dn, ldap.SCOPE_ONELEVEL
|
||||||
|
)
|
||||||
|
except errors.NotFound:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
for (dn_, entry_attrs) in subentries:
|
||||||
|
delete_subtree(dn_)
|
||||||
try:
|
try:
|
||||||
self._call_exc_callbacks(
|
ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn)
|
||||||
keys, options, e, ldap.delete_entry, base_dn,
|
except errors.ExecutionError, e:
|
||||||
normalize=self.obj.normalize_dn
|
try:
|
||||||
)
|
self._call_exc_callbacks(
|
||||||
except errors.NotFound:
|
nkeys, options, e, ldap.delete_entry, base_dn,
|
||||||
self.obj.handle_not_found(*keys)
|
normalize=self.obj.normalize_dn
|
||||||
|
)
|
||||||
|
except errors.NotFound:
|
||||||
|
self.obj.handle_not_found(*nkeys)
|
||||||
|
|
||||||
delete_subtree(dn)
|
delete_subtree(dn)
|
||||||
|
|
||||||
for callback in self.POST_CALLBACKS:
|
for callback in self.POST_CALLBACKS:
|
||||||
if hasattr(callback, 'im_self'):
|
if hasattr(callback, 'im_self'):
|
||||||
result = callback(ldap, dn, *keys, **options)
|
result = callback(ldap, dn, *nkeys, **options)
|
||||||
|
else:
|
||||||
|
result = callback(self, ldap, dn, *nkeys, **options)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
if not self.obj.primary_key or not isinstance(keys[-1], (list, tuple)):
|
||||||
|
keys = keys[:-1] + (keys[-1], )
|
||||||
|
|
||||||
|
deleted = []
|
||||||
|
failed = []
|
||||||
|
result = True
|
||||||
|
for pkey in keys[-1]:
|
||||||
|
try:
|
||||||
|
if not delete_entry(pkey):
|
||||||
|
result = False
|
||||||
|
except errors.ExecutionError:
|
||||||
|
failed.append(pkey)
|
||||||
else:
|
else:
|
||||||
result = callback(self, ldap, dn, *keys, **options)
|
deleted.append(pkey)
|
||||||
|
|
||||||
if self.obj.primary_key and keys[-1] is not None:
|
if self.obj.primary_key and keys[-1] is not None:
|
||||||
return dict(result=result, value=keys[-1])
|
return dict(result=result, value=u','.join(deleted))
|
||||||
return dict(result=result, value=u'')
|
return dict(result=result, value=u'')
|
||||||
|
|
||||||
def pre_callback(self, ldap, dn, *keys, **options):
|
def pre_callback(self, ldap, dn, *keys, **options):
|
||||||
|
Loading…
Reference in New Issue
Block a user