summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorPavel Zuna <pzuna@redhat.com>2011-01-04 15:15:54 -0500
committerAdam Young <ayoung@redhat.com>2011-01-04 21:56:38 -0500
commitd6d579ead469e0b4690d6d1eec0f137dd3c40940 (patch)
treec8d6a027f5fe598b75687aa42dd193b2c51cf816 /ipalib
parent4f2a6e0a25cd5d92bdd436d23963f77b86f818ea (diff)
downloadfreeipa-d6d579ead469e0b4690d6d1eec0f137dd3c40940.tar.gz
freeipa-d6d579ead469e0b4690d6d1eec0f137dd3c40940.tar.xz
freeipa-d6d579ead469e0b4690d6d1eec0f137dd3c40940.zip
Improve filtering of enrollments search results.
This is required for effective filtering of enrollments search results in the webUI and also gives an edge to the CLI. After this patch, each LDAPObject can define its relationships to other LDAPObjects. For now, this is used only for filtering search results by enrollments, but there are probably more benefits to come. You can do this for example: # search for all users not enrolled in group admins ipa user-find --not-in-groups=admins # search for all groups not enrolled in group global with user Pavel ipa group-find --users=Pavel --not-in-groups=global # more examples: ipa group-find --users=Pavel,Jakub --no-users=Honza ipa hostgroup-find --hosts=webui.pzuna
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugins/baseldap.py57
-rw-r--r--ipalib/plugins/group.py2
-rw-r--r--ipalib/plugins/host.py7
-rw-r--r--ipalib/plugins/hostgroup.py2
-rw-r--r--ipalib/plugins/netgroup.py11
-rw-r--r--ipalib/plugins/user.py2
6 files changed, 68 insertions, 13 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 259d02b01..688f35bad 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -247,6 +247,15 @@ class LDAPObject(Object):
rdnattr = None
# Can bind as this entry (has userPassword or krbPrincipalKey)
bindable = False
+ relationships = {
+ # attribute: (label, inclusive param prefix, exclusive param prefix)
+ 'member': ('Member', '', 'no_'),
+ 'memberof': ('Parent', 'in_', 'not_in_'),
+ 'memberindirect': (
+ 'Indirect Member', None, 'no_indirect_'
+ ),
+ }
+ label = _('Entry')
container_not_found_msg = _('container entry (%(container)s) not found')
parent_not_found_msg = _('%(parent)s: %(oname)s not found')
@@ -343,7 +352,7 @@ class LDAPObject(Object):
'parent_object', 'container_dn', 'object_name', 'object_name_plural',
'object_class', 'object_class_config', 'default_attributes', 'label',
'hidden_attributes', 'uuid_attribute', 'attribute_members', 'name',
- 'takes_params', 'rdn_attribute', 'bindable',
+ 'takes_params', 'rdn_attribute', 'bindable', 'relationships',
)
def __json__(self):
@@ -1193,7 +1202,8 @@ class LDAPSearch(CallbackInterface, crud.Search):
Retrieve all LDAP entries matching the given criteria.
"""
member_attributes = []
- member_param_doc = 'exclude %s with member %s (comma-separated list)'
+ member_param_incl_doc = 'only %s with %s %s'
+ member_param_excl_doc = 'only %s with no %s %s'
takes_options = (
Int('timelimit?',
@@ -1225,21 +1235,50 @@ class LDAPSearch(CallbackInterface, crud.Search):
for attr in self.member_attributes:
for ldap_obj_name in self.obj.attribute_members[attr]:
ldap_obj = self.api.Object[ldap_obj_name]
- name = to_cli(ldap_obj_name)
- doc = self.member_param_doc % (
- self.obj.object_name_plural, ldap_obj.object_name_plural
+ relationship = self.obj.relationships.get(
+ attr, ['member', '', 'no_']
+ )
+ doc = self.member_param_incl_doc % (
+ self.obj.object_name_plural, relationship[0].lower(),
+ ldap_obj.object_name_plural
+ )
+ name = '%s%s' % (relationship[1], to_cli(ldap_obj_name))
+ yield List(
+ '%s?' % name, cli_name='%ss' % name, doc=doc,
+ label=ldap_obj.object_name
+ )
+ doc = self.member_param_excl_doc % (
+ self.obj.object_name_plural, relationship[0].lower(),
+ ldap_obj.object_name_plural
+ )
+ name = '%s%s' % (relationship[2], to_cli(ldap_obj_name))
+ yield List(
+ '%s?' % name, cli_name='%ss' % name, doc=doc,
+ label=ldap_obj.object_name
)
- yield List('no_%s?' % name, cli_name='no_%ss' % name, doc=doc,
- label=ldap_obj.object_name)
def get_member_filter(self, ldap, **options):
filter = ''
for attr in self.member_attributes:
for ldap_obj_name in self.obj.attribute_members[attr]:
- param_name = 'no_%s' % to_cli(ldap_obj_name)
+ ldap_obj = self.api.Object[ldap_obj_name]
+ relationship = self.obj.relationships.get(
+ attr, ['member', '', 'no_']
+ )
+ param_name = '%s%s' % (relationship[1], to_cli(ldap_obj_name))
+ if param_name in options:
+ dns = []
+ for pkey in options[param_name]:
+ dns.append(ldap_obj.get_dn(pkey))
+ flt = ldap.make_filter_from_attr(
+ attr, dns, ldap.MATCH_ALL
+ )
+ filter = ldap.combine_filters(
+ (filter, flt), ldap.MATCH_ALL
+ )
+ param_name = '%s%s' % (relationship[2], to_cli(ldap_obj_name))
if param_name in options:
dns = []
- ldap_obj = self.api.Object[ldap_obj_name]
for pkey in options[param_name]:
dns.append(ldap_obj.get_dn(pkey))
flt = ldap.make_filter_from_attr(
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 9fd24008c..ecf5453e4 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -213,7 +213,7 @@ class group_find(LDAPSearch):
"""
Search for groups.
"""
- member_attributes = ['member']
+ member_attributes = ['member', 'memberof']
msg_summary = ngettext(
'%(count)d group matched', '%(count)d groups matched', 0
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 283c2c165..e24da1bf3 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -170,6 +170,11 @@ class host(LDAPObject):
'managedby': ['host'],
}
bindable = True
+ relationships = {
+ 'memberof': ('Parent', 'in_', 'not_in_'),
+ 'enrolledby': ('Enrolled by', 'enroll_by_', 'not_enroll_by_'),
+ 'managedby': ('Managed by', 'man_by_', 'not_man_by_'),
+ }
label = _('Hosts')
@@ -568,7 +573,7 @@ class host_find(LDAPSearch):
msg_summary = ngettext(
'%(count)d host matched', '%(count)d hosts matched'
)
- member_attributes = ['managedby']
+ member_attributes = ['memberof', 'enrolledby', 'managedby']
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
if 'locality' in attrs_list:
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index db270aea0..082e4ef00 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -123,7 +123,7 @@ class hostgroup_find(LDAPSearch):
"""
Search for hostgroups.
"""
- member_attributes = ['member']
+ member_attributes = ['member', 'memberof']
msg_summary = ngettext(
'%(count)d hostgroup matched', '%(count)d hostgroups matched'
)
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 83e699908..ce9a51b6c 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -85,6 +85,15 @@ class netgroup(LDAPObject):
'memberuser': ['user', 'group'],
'memberhost': ['host', 'hostgroup'],
}
+ relationships = {
+ 'member': ('Member', '', 'no_'),
+ 'memberof': ('Parent', 'in_', 'not_in_'),
+ 'memberindirect': (
+ 'Indirect Member', None, 'no_indirect_'
+ ),
+ 'memberuser': ('Member', '', 'no_'),
+ 'memberhost': ('Member', '', 'no_'),
+ }
label = _('Net Groups')
@@ -171,7 +180,7 @@ class netgroup_find(LDAPSearch):
"""
Search for a netgroup.
"""
- member_attributes = ['member', 'memberuser', 'memberhost']
+ member_attributes = ['member', 'memberuser', 'memberhost', 'memberof']
has_output_params = LDAPSearch.has_output_params + output_params
msg_summary = ngettext(
'%(count)d netgroup matched', '%(count)d netgroups matched'
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 3d9b7e6d4..0afb8b5d2 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -316,6 +316,7 @@ class user_find(LDAPSearch):
"""
Search for users.
"""
+ member_attributes = ['memberof']
takes_options = LDAPSearch.takes_options + (
Flag('whoami',
@@ -323,6 +324,7 @@ class user_find(LDAPSearch):
doc=_('Display user record for current Kerberos principal'),
),
)
+
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options):
if options.get('whoami'):
return ("(&(objectclass=posixaccount)(krbprincipalname=%s))"%\