summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2013-03-11 12:37:29 +0100
committerMartin Kosek <mkosek@redhat.com>2013-04-09 19:00:30 +0200
commite64db8cbc2e9571200cd14e7d2313102022c2813 (patch)
tree2ebed4dd0c34b22003abe98a61a9831894f424b5
parent3f053437c979e13b22e3e5cac194d24dc9afcddf (diff)
downloadfreeipa.git-e64db8cbc2e9571200cd14e7d2313102022c2813.tar.gz
freeipa.git-e64db8cbc2e9571200cd14e7d2313102022c2813.tar.xz
freeipa.git-e64db8cbc2e9571200cd14e7d2313102022c2813.zip
Filter groups by type (POSIX, non-POSIX, external)
Added flag for each groups type: --posix, --nonposix, --external to group-find command. Group types: * non-POSIX: not posix, not external * POSIX: with objectclass posixgroup * external: with objectclass ipaexternalgroup https://fedorahosted.org/freeipa/ticket/3483
-rw-r--r--API.txt5
-rw-r--r--ipalib/plugins/group.py28
-rw-r--r--tests/test_xmlrpc/objectclasses.py1
-rw-r--r--tests/test_xmlrpc/test_group_plugin.py116
-rw-r--r--tests/test_xmlrpc/xmlrpc_test.py4
5 files changed, 151 insertions, 3 deletions
diff --git a/API.txt b/API.txt
index 81a1f618..87db8d67 100644
--- a/API.txt
+++ b/API.txt
@@ -1307,11 +1307,12 @@ output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: group_find
-args: 1,24,4
+args: 1,27,4
arg: Str('criteria?', noextrawhitespace=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Str('cn', attribute=True, autofill=False, cli_name='group_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=False)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Flag('external', autofill=True, cli_name='external', default=False)
option: Int('gidnumber', attribute=True, autofill=False, cli_name='gid', minvalue=1, multivalue=False, query=True, required=False)
option: Str('group*', cli_name='groups', csv=True)
option: Str('in_group*', cli_name='in_groups', csv=True)
@@ -1321,12 +1322,14 @@ option: Str('in_role*', cli_name='in_roles', csv=True)
option: Str('in_sudorule*', cli_name='in_sudorules', csv=True)
option: Str('no_group*', cli_name='no_groups', csv=True)
option: Str('no_user*', cli_name='no_users', csv=True)
+option: Flag('nonposix', autofill=True, cli_name='nonposix', default=False)
option: Str('not_in_group*', cli_name='not_in_groups', csv=True)
option: Str('not_in_hbacrule*', cli_name='not_in_hbacrules', csv=True)
option: Str('not_in_netgroup*', cli_name='not_in_netgroups', csv=True)
option: Str('not_in_role*', cli_name='not_in_roles', csv=True)
option: Str('not_in_sudorule*', cli_name='not_in_sudorules', csv=True)
option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('posix', autofill=True, cli_name='posix', default=False)
option: Flag('private', autofill=True, cli_name='private', default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Int('sizelimit?', autofill=False, minvalue=0)
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 21ee0049..02eeb10c 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -328,10 +328,35 @@ class group_find(LDAPSearch):
cli_name='private',
doc=_('search for private groups'),
),
+ Flag('posix',
+ cli_name='posix',
+ doc=_('search for POSIX groups'),
+ ),
+ Flag('external',
+ cli_name='external',
+ doc=_('search for groups with support of external non-IPA members from trusted domains'),
+ ),
+ Flag('nonposix',
+ cli_name='nonposix',
+ doc=_('search for non-POSIX groups'),
+ ),
)
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
assert isinstance(base_dn, DN)
+
+ # filter groups by pseudo type
+ filters = []
+ if options['posix']:
+ search_kw = {'objectclass': ['posixGroup']}
+ filters.append(ldap.make_filter(search_kw, rules=ldap.MATCH_ALL))
+ if options['external']:
+ search_kw = {'objectclass': ['ipaExternalGroup']}
+ filters.append(ldap.make_filter(search_kw, rules=ldap.MATCH_ALL))
+ if options['nonposix']:
+ search_kw = {'objectclass': ['posixGroup' , 'ipaExternalGroup']}
+ filters.append(ldap.make_filter(search_kw, rules=ldap.MATCH_NONE))
+
# if looking for private groups, we need to create a new search filter,
# because private groups have different object classes
if options['private']:
@@ -351,6 +376,9 @@ class group_find(LDAPSearch):
cflt = ldap.make_filter(search_kw, exact=False)
filter = ldap.combine_filters((oflt, cflt), rules=ldap.MATCH_ALL)
+ elif filters:
+ filters.append(filter)
+ filter = ldap.combine_filters(filters, rules=ldap.MATCH_ALL)
return (filter, base_dn, scope)
api.register(group_find)
diff --git a/tests/test_xmlrpc/objectclasses.py b/tests/test_xmlrpc/objectclasses.py
index d98a7ee6..75ac3eb1 100644
--- a/tests/test_xmlrpc/objectclasses.py
+++ b/tests/test_xmlrpc/objectclasses.py
@@ -46,6 +46,7 @@ group = [
]
externalgroup = group + [u'ipaexternalgroup']
+posixgroup = group + [u'posixgroup']
host = [
u'ipasshhost',
diff --git a/tests/test_xmlrpc/test_group_plugin.py b/tests/test_xmlrpc/test_group_plugin.py
index 2d6d2014..7a9b8b6d 100644
--- a/tests/test_xmlrpc/test_group_plugin.py
+++ b/tests/test_xmlrpc/test_group_plugin.py
@@ -23,7 +23,8 @@ Test the `ipalib/plugins/group.py` module.
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
-from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
+from tests.util import Fuzzy
+from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, fuzzy_set_ci
from ipapython.dn import DN
group1 = u'testgroup1'
@@ -248,7 +249,7 @@ class test_group(Declarative):
cn=[group2],
description=[u'Test desc 2'],
gidnumber=[fuzzy_digits],
- objectclass=objectclasses.group + [u'posixgroup'],
+ objectclass=objectclasses.posixgroup,
ipauniqueid=[fuzzy_uuid],
dn=get_group_dn('testgroup2'),
),
@@ -382,6 +383,98 @@ class test_group(Declarative):
),
),
+ dict(
+ desc='Search for non-POSIX groups',
+ command=('group_find', [], dict(nonposix=True, all=True)),
+ expected=dict(
+ summary=u'2 groups matched',
+ count=2,
+ truncated=False,
+ result=[
+ {
+ 'dn': get_group_dn('ipausers'),
+ 'cn': [u'ipausers'],
+ 'description': [u'Default group for all users'],
+ 'objectclass': fuzzy_set_ci(objectclasses.group),
+ 'ipauniqueid': [fuzzy_uuid],
+ },
+ {
+ 'dn': get_group_dn('trust admins'),
+ 'member_user': [u'admin'],
+ 'cn': [u'trust admins'],
+ 'description': [u'Trusts administrators group'],
+ 'objectclass': fuzzy_set_ci(objectclasses.group),
+ 'ipauniqueid': [fuzzy_uuid],
+ },
+ ],
+ ),
+ ),
+
+ dict(
+ desc='Search for non-POSIX groups with criteria filter',
+ command=('group_find', [u'users'], dict(nonposix=True, all=True)),
+ expected=dict(
+ summary=u'1 group matched',
+ count=1,
+ truncated=False,
+ result=[
+ {
+ 'dn': get_group_dn('ipausers'),
+ 'cn': [u'ipausers'],
+ 'description': [u'Default group for all users'],
+ 'objectclass': fuzzy_set_ci(objectclasses.group),
+ 'ipauniqueid': [fuzzy_uuid],
+ },
+ ],
+ ),
+ ),
+
+ dict(
+ desc='Search for POSIX groups',
+ command=('group_find', [], dict(posix=True, all=True)),
+ expected=dict(
+ summary=u'4 groups matched',
+ count=4,
+ truncated=False,
+ result=[
+ {
+ 'dn': get_group_dn('admins'),
+ 'member_user': [u'admin'],
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [u'admins'],
+ 'description': [u'Account administrators group'],
+ 'objectclass': fuzzy_set_ci(objectclasses.posixgroup),
+ 'ipauniqueid': [fuzzy_uuid],
+ },
+ {
+ 'dn': get_group_dn('editors'),
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [u'editors'],
+ 'description': [u'Limited admins who can edit other users'],
+ 'objectclass': fuzzy_set_ci(objectclasses.posixgroup),
+ 'ipauniqueid': [fuzzy_uuid],
+ },
+ dict(
+ dn=get_group_dn(group1),
+ cn=[group1],
+ description=[u'New desc 1'],
+ gidnumber=[fuzzy_digits],
+ objectclass=fuzzy_set_ci(objectclasses.posixgroup),
+ ipauniqueid=[fuzzy_uuid],
+ ),
+ dict(
+ dn=get_group_dn(group2),
+ cn=[group2],
+ description=[u'New desc 2'],
+ gidnumber=[fuzzy_digits],
+ objectclass=fuzzy_set_ci(objectclasses.posixgroup),
+ ipauniqueid=[fuzzy_uuid],
+ ),
+ ],
+ ),
+ ),
+
+
###############
# test external SID members for group3:
dict(
@@ -402,6 +495,25 @@ class test_group(Declarative):
),
),
+ dict(
+ desc='Search for external groups',
+ command=('group_find', [], dict(external=True, all=True)),
+ expected=dict(
+ summary=u'1 group matched',
+ count=1,
+ truncated=False,
+ result=[
+ dict(
+ cn=[group3],
+ description=[u'Test desc 3'],
+ objectclass=fuzzy_set_ci(objectclasses.externalgroup),
+ ipauniqueid=[fuzzy_uuid],
+ dn=get_group_dn(group3),
+ ),
+ ],
+ ),
+ ),
+
dict(
desc='Convert posix group %r to support external membership' % (group2),
diff --git a/tests/test_xmlrpc/xmlrpc_test.py b/tests/test_xmlrpc/xmlrpc_test.py
index cfd7bd33..89f1adc3 100644
--- a/tests/test_xmlrpc/xmlrpc_test.py
+++ b/tests/test_xmlrpc/xmlrpc_test.py
@@ -83,6 +83,10 @@ fuzzy_dergeneralizedtime = Fuzzy('^[0-9]{14}Z$')
# match any string
fuzzy_string = Fuzzy(type=basestring)
+# case insensitive match of sets
+def fuzzy_set_ci(s):
+ return Fuzzy(test=lambda other: set(x.lower() for x in other) == set(y.lower() for y in s))
+
try:
if not api.Backend.xmlclient.isconnected():
api.Backend.xmlclient.connect(fallback=False)