summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2010-10-04 17:45:40 -0400
committerSimo Sorce <ssorce@redhat.com>2010-10-28 15:15:52 -0400
commitc25d62965af9dffc655d659dfcd1f39e8d08e66c (patch)
tree7b939938c863b67fd65253f45d9d486b58b92627
parent47629a604d7f312ccb32e6b260782cb7c5c70954 (diff)
downloadfreeipa-c25d62965af9dffc655d659dfcd1f39e8d08e66c.tar.gz
freeipa-c25d62965af9dffc655d659dfcd1f39e8d08e66c.tar.xz
freeipa-c25d62965af9dffc655d659dfcd1f39e8d08e66c.zip
Populate indirect members when showing a group object.
This is done by creating a new attribute, memberindirect, to hold this indirect membership. The new function get_members() can return all members or just indirect or direct. We are only using it to retrieve indirect members currently. This also: * Moves all member display attributes into baseldap.py to reduce duplication * Adds netgroup nesting * Use a unique object name in hbacsvc and hbacsvcgroup ticket 296
-rw-r--r--ipalib/plugins/baseldap.py108
-rw-r--r--ipalib/plugins/group.py12
-rw-r--r--ipalib/plugins/hbacsvc.py6
-rw-r--r--ipalib/plugins/hbacsvcgroup.py21
-rw-r--r--ipalib/plugins/host.py12
-rw-r--r--ipalib/plugins/hostgroup.py17
-rw-r--r--ipalib/plugins/netgroup.py32
-rw-r--r--ipalib/plugins/rolegroup.py17
-rw-r--r--ipalib/plugins/sudocmdgroup.py3
-rw-r--r--ipalib/plugins/taskgroup.py18
-rw-r--r--ipalib/plugins/user.py16
-rw-r--r--ipaserver/plugins/ldap2.py71
-rw-r--r--tests/test_xmlrpc/test_hbac_plugin.py2
-rw-r--r--tests/test_xmlrpc/test_hbacsvcgroup_plugin.py10
-rw-r--r--tests/test_xmlrpc/test_nesting.py350
15 files changed, 557 insertions, 138 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 91aa39650..f764efbb7 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -32,6 +32,93 @@ from ipalib import output
from ipalib.text import _
from ipalib.util import json_serialize
+global_output_params = (
+ Str('member',
+ label=_('Failed members'),
+ ),
+ Str('member_user?',
+ label=_('Member users'),
+ ),
+ Str('member_group?',
+ label=_('Member groups'),
+ ),
+ Str('member_host?',
+ label=_('Member hosts'),
+ ),
+ Str('memberof_hostgroup?',
+ label=_('Member of host-groups'),
+ ),
+ Str('memberof_taskgroup?',
+ label=_('Member of task-groups'),
+ ),
+ Str('member_rolegroup?',
+ label=_('Member role-groups'),
+ ),
+ Str('member_netgroup?',
+ label=_('Member netgroups'),
+ ),
+ Str('memberof_netgroup?',
+ label=_('Member of netgroups'),
+ ),
+ Str('member_service?',
+ label=_('Member services'),
+ ),
+ Str('member_servicegroup?',
+ label=_('Member service groups'),
+ ),
+ Str('memberof_servicegroup?',
+ label='Member of service groups',
+ ),
+ Str('member_hbacsvcgroup?',
+ label=_('Member HBAC service groups'),
+ ),
+ Str('memberof_hbacsvcgroup?',
+ label='Member of HBAC service groups',
+ ),
+ Str('member_sudocmdgroup?',
+ label='Member SUDO command groups',
+ ),
+ Str('member_sudocmd?',
+ label='Member SUDO commands',
+ ),
+ Str('memberindirect_user?',
+ label=_('Indirect Member users'),
+ ),
+ Str('memberindirect_group?',
+ label=_('Indirect Member groups'),
+ ),
+ Str('memberindirect_host?',
+ label=_('Indirect Member hosts'),
+ ),
+ Str('memberindirect_hostgroup?',
+ label=_('Indirect Member host-groups'),
+ ),
+ Str('memberindirect_rolegroup?',
+ label=_('Indirect Member role-groups'),
+ ),
+ Str('memberindirect_taskgroup?',
+ label=_('Indirect Member role-groups'),
+ ),
+ Str('memberindirect_hbacsvc?',
+ label=_('Indirect Member HBAC service'),
+ ),
+ Str('memberindirect_hbacsvcgrp?',
+ label=_('Indirect Member HBAC service group'),
+ ),
+ Str('memberindirect_netgroup?',
+ label=_('Indirect Member netgroups'),
+ ),
+ Str('memberindirect_sudocmdgroup?',
+ label='Indirect Member SUDO command groups',
+ ),
+ Str('memberindirect_sudocmd?',
+ label='Indirect Member SUDO commands',
+ ),
+ Str('externalhost?',
+ label=_('External host'),
+ ),
+)
+
def validate_add_attribute(ugettext, attr):
validate_attribute(ugettext, 'addattr', attr)
@@ -273,6 +360,8 @@ class LDAPCreate(CallbackInterface, crud.Create):
for arg in super(crud.Create, self).get_args():
yield arg
+ has_output_params = global_output_params
+
def execute(self, *keys, **options):
ldap = self.obj.backend
@@ -425,6 +514,7 @@ class LDAPRetrieve(LDAPQuery):
Retrieve an LDAP entry.
"""
has_output = output.standard_entry
+ has_output_params = global_output_params
takes_options = (
Flag('rights',
@@ -502,6 +592,8 @@ class LDAPUpdate(LDAPQuery, crud.Update):
takes_options = _attr_options
+ has_output_params = global_output_params
+
def execute(self, *keys, **options):
ldap = self.obj.backend
@@ -630,6 +722,8 @@ class LDAPDelete(LDAPMultiQuery):
"""
has_output = output.standard_delete
+ has_output_params = global_output_params
+
def execute(self, *keys, **options):
ldap = self.obj.backend
@@ -765,11 +859,7 @@ class LDAPAddMember(LDAPModMember):
),
)
- has_output_params = (
- Str('member',
- label=_('Failed members'),
- ),
- )
+ has_output_params = global_output_params
def execute(self, *keys, **options):
ldap = self.obj.backend
@@ -870,11 +960,7 @@ class LDAPRemoveMember(LDAPModMember):
),
)
- has_output_params = (
- Str('member',
- label=_('Failed members'),
- ),
- )
+ has_output_params = global_output_params
def execute(self, *keys, **options):
ldap = self.obj.backend
@@ -989,6 +1075,8 @@ class LDAPSearch(CallbackInterface, crud.Search):
for option in super(LDAPSearch, self).get_options():
yield option
+ has_output_params = global_output_params
+
def execute(self, *args, **options):
ldap = self.obj.backend
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 975915b42..aec5ce057 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -83,12 +83,14 @@ class group(LDAPObject):
object_class_config = 'ipagroupobjectclasses'
search_attributes_config = 'ipagroupsearchfields'
default_attributes = [
- 'cn', 'description', 'gidnumber', 'member', 'memberof'
+ 'cn', 'description', 'gidnumber', 'member', 'memberof',
+ 'memberindirect',
]
uuid_attribute = 'ipauniqueid'
attribute_members = {
'member': ['user', 'group'],
'memberof': ['group', 'netgroup', 'rolegroup', 'taskgroup'],
+ 'memberindirect': ['user', 'group', 'netgroup', 'rolegroup', 'taskgroup'],
}
rdnattr = 'cn'
@@ -114,14 +116,6 @@ class group(LDAPObject):
label=_('GID'),
doc=_('GID (use this option to set it manually)'),
),
- Str('member_group?',
- label=_('Member groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_user?',
- label=_('Member users'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
api.register(group)
diff --git a/ipalib/plugins/hbacsvc.py b/ipalib/plugins/hbacsvc.py
index d5302cdee..4074eb33d 100644
--- a/ipalib/plugins/hbacsvc.py
+++ b/ipalib/plugins/hbacsvc.py
@@ -51,10 +51,10 @@ class hbacsvc(LDAPObject):
HBAC Service object.
"""
container_dn = api.env.container_hbacservice
- object_name = 'service'
- object_name_plural = 'services'
+ object_name = 'hbacsvc'
+ object_name_plural = 'hbacsvcs'
object_class = [ 'ipaobject', 'ipahbacservice' ]
- default_attributes = ['cn', 'description']
+ default_attributes = ['cn', 'description', 'memberindirect',]
uuid_attribute = 'ipauniqueid'
label = _('Services')
diff --git a/ipalib/plugins/hbacsvcgroup.py b/ipalib/plugins/hbacsvcgroup.py
index 70dd32b13..682a6c4e6 100644
--- a/ipalib/plugins/hbacsvcgroup.py
+++ b/ipalib/plugins/hbacsvcgroup.py
@@ -53,14 +53,17 @@ class hbacsvcgroup(LDAPObject):
HBAC service group object.
"""
container_dn = api.env.container_hbacservicegroup
- object_name = 'servicegroup'
- object_name_plural = 'servicegroups'
+ object_name = 'hbacsvcgroup'
+ object_name_plural = 'hbacsvcgroups'
object_class = ['ipaobject', 'ipahbacservicegroup']
- default_attributes = [ 'cn', 'description', 'member', 'memberof', ]
+ default_attributes = [ 'cn', 'description', 'member', 'memberof',
+ 'memberindirect',
+ ]
uuid_attribute = 'ipauniqueid'
attribute_members = {
'member': ['hbacsvc', 'hbacsvcgroup'],
'memberof': ['hbacsvcgroup'],
+ 'memberindirect': ['hbacsvc', 'hbacsvcgroup'],
}
label = _('HBAC Service Groups')
@@ -77,18 +80,6 @@ class hbacsvcgroup(LDAPObject):
label=_('Description'),
doc=_('HBAC service group description'),
),
- Str('member_service?',
- label=_('Member services'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_servicegroup?',
- label=_('Member service groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_servicegroup?',
- label='Member of service groups',
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
api.register(hbacsvcgroup)
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 3a63d212f..2c032f3e7 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -159,18 +159,6 @@ class host(LDAPObject):
label=_('Principal name'),
flags=['no_create', 'no_update', 'no_search'],
),
- Str('memberof_hostgroup?',
- label=_('Member of host-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_netgroup?',
- label=_('Member of net-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_rolegroup?',
- label=_('Member of role-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
def get_dn(self, *keys, **options):
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index 2f9cbab2c..51d058369 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -59,11 +59,14 @@ class hostgroup(LDAPObject):
object_name = 'hostgroup'
object_name_plural = 'hostgroups'
object_class = ['ipaobject', 'ipahostgroup']
- default_attributes = ['cn', 'description', 'member', 'memberof']
+ default_attributes = ['cn', 'description', 'member', 'memberof',
+ 'memberindirect'
+ ]
uuid_attribute = 'ipauniqueid'
attribute_members = {
'member': ['host', 'hostgroup'],
'memberof': ['hostgroup'],
+ 'memberindirect': ['host', 'hostgroup'],
}
label = _('Host Groups')
@@ -81,18 +84,6 @@ class hostgroup(LDAPObject):
label=_('Description'),
doc=_('A description of this host-group'),
),
- Str('member_host?',
- label=_('Member hosts'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_hostgroup?',
- label=_('Member host-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_hostgroup?',
- label=_('Member of host-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
api.register(hostgroup)
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 9edc45e55..3b714213a 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -46,23 +46,6 @@ from ipalib.plugins.baseldap import *
from ipalib import _, ngettext
-output_params = (
- Str('memberuser_user?',
- label='Member User',
- ),
- Str('memberuser_group?',
- label='Member Group',
- ),
- Str('memberhost_host?',
- label=_('Member Host'),
- ),
- Str('memberhost_hostgroup?',
- label='Member Hostgroup',
- ),
- Str('externalhost?',
- label=_('External host'),
- ),
- )
class netgroup(LDAPObject):
"""
Netgroup object.
@@ -72,13 +55,15 @@ class netgroup(LDAPObject):
object_name_plural = 'netgroups'
object_class = ['ipaobject', 'ipaassociation', 'ipanisnetgroup']
default_attributes = [
- 'cn', 'description', 'memberof', 'externalhost',
- 'nisdomainname', 'memberuser', 'memberhost',
+ 'cn', 'description', 'memberof', 'externalhost', 'nisdomainname',
+ 'memberuser', 'memberhost','member', 'memberindirect',
]
uuid_attribute = 'ipauniqueid'
rdn_attribute = 'ipauniqueid'
attribute_members = {
+ 'member': ['netgroup'],
'memberof': ['netgroup'],
+ 'memberindirect': ['netgroup'],
'memberuser': ['user', 'group'],
'memberhost': ['host', 'hostgroup'],
}
@@ -116,7 +101,6 @@ class netgroup_add(LDAPCreate):
"""
Add a new netgroup.
"""
- has_output_params = output_params
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
entry_attrs.setdefault('nisdomainname', self.api.env.domain)
return dn
@@ -128,6 +112,7 @@ class netgroup_del(LDAPDelete):
"""
Delete a netgroup.
"""
+ msg_summary = _('Deleted netgroup "%(value)s"')
api.register(netgroup_del)
@@ -136,7 +121,6 @@ class netgroup_mod(LDAPUpdate):
"""
Modify a netgroup.
"""
- has_output_params = output_params
api.register(netgroup_mod)
@@ -145,7 +129,6 @@ class netgroup_find(LDAPSearch):
"""
Search for a netgroup.
"""
- has_output_params = output_params
api.register(netgroup_find)
@@ -154,7 +137,6 @@ class netgroup_show(LDAPRetrieve):
"""
Display information about a netgroup.
"""
- has_output_params = output_params
api.register(netgroup_show)
@@ -163,8 +145,7 @@ class netgroup_add_member(LDAPAddMember):
"""
Add members to a netgroup.
"""
- has_output_params = LDAPAddMember.has_output_params + output_params
- member_attributes = ['memberuser', 'memberhost']
+ member_attributes = ['memberuser', 'memberhost', 'member']
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
completed_external = 0
# Sift through the host failures. We assume that these are all
@@ -199,7 +180,6 @@ class netgroup_remove_member(LDAPRemoveMember):
"""
Remove members from a netgroup.
"""
- has_output_params = LDAPRemoveMember.has_output_params + output_params
member_attributes = ['memberuser', 'memberhost']
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
# Run through the host failures and gracefully remove any defined as
diff --git a/ipalib/plugins/rolegroup.py b/ipalib/plugins/rolegroup.py
index feffa0d49..e0b6fbc4e 100644
--- a/ipalib/plugins/rolegroup.py
+++ b/ipalib/plugins/rolegroup.py
@@ -70,10 +70,13 @@ class rolegroup(LDAPObject):
object_name = 'rolegroup'
object_name_plural = 'rolegroups'
object_class = ['groupofnames', 'nestedgroup']
- default_attributes = ['cn', 'description', 'member', 'memberof']
+ default_attributes = ['cn', 'description', 'member', 'memberof',
+ 'memberindirect'
+ ]
attribute_members = {
'member': ['user', 'group', 'host', 'hostgroup'],
'memberof': ['taskgroup'],
+ 'memberindirect': ['user', 'group', 'host', 'hostgroup'],
}
rdnattr='cn'
@@ -91,18 +94,6 @@ class rolegroup(LDAPObject):
label=_('Description'),
doc=_('A description of this role-group'),
),
- Str('member_group?',
- label=_('Member groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_user?',
- label=_('Member users'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_taskgroup?',
- label=_('Member of task-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
api.register(rolegroup)
diff --git a/ipalib/plugins/sudocmdgroup.py b/ipalib/plugins/sudocmdgroup.py
index 75b3efbdb..5476f99cf 100644
--- a/ipalib/plugins/sudocmdgroup.py
+++ b/ipalib/plugins/sudocmdgroup.py
@@ -55,12 +55,13 @@ class sudocmdgroup(LDAPObject):
object_name_plural = 'sudocmdgroups'
object_class = ['ipaobject', 'ipasudocmdgrp']
default_attributes = [
- 'cn', 'description', 'member', 'memberof'
+ 'cn', 'description', 'member', 'memberof', 'memberindirect',
]
uuid_attribute = 'ipauniqueid'
attribute_members = {
'member': ['sudocmd', 'sudocmdgroup'],
'memberof': ['sudocmdgroup'],
+ 'memberindirect': ['sudocmd', 'sudocmdgroup'],
}
label = _('Sudo Command Groups')
diff --git a/ipalib/plugins/taskgroup.py b/ipalib/plugins/taskgroup.py
index 11bef4860..ba3f50738 100644
--- a/ipalib/plugins/taskgroup.py
+++ b/ipalib/plugins/taskgroup.py
@@ -33,7 +33,6 @@ from ipalib.plugins.baseldap import *
from ipalib import api, _, ngettext
-
class taskgroup(LDAPObject):
"""
Taskgroup object.
@@ -42,9 +41,12 @@ class taskgroup(LDAPObject):
object_name = 'taskgroup'
object_name_plural = 'taskgroups'
object_class = ['groupofnames']
- default_attributes = ['cn', 'description', 'member', 'memberof']
+ default_attributes = ['cn', 'description', 'member', 'memberof',
+ 'memberindirect'
+ ]
attribute_members = {
'member': ['user', 'group', 'rolegroup'],
+ 'memberindirect': ['user', 'group', 'rolegroup'],
# FIXME: taskgroup can be member of ???
}
rdnattr='cn'
@@ -63,18 +65,6 @@ class taskgroup(LDAPObject):
label=_('Description'),
doc=_('Task-group description'),
),
- Str('member_group?',
- label=_('Member groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_user?',
- label=_('Member users'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('member_rolegroup?',
- label=_('Member role-groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
)
api.register(taskgroup)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index fb0da4800..6bfb7b6fb 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -139,22 +139,6 @@ class user(LDAPObject):
cli_name='street',
label=_('Street address'),
),
- Str('memberof_group?',
- label=_('Groups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_netgroup?',
- label=_('Netgroups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_rolegroup?',
- label=_('Rolegroups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
- Str('memberof_taskgroup?',
- label=_('Taskgroups'),
- flags=['no_create', 'no_update', 'no_search'],
- ),
Str('telephonenumber*',
cli_name='phone',
label=_('Telephone Number') ),
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index 4117e47b7..b5efc428e 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -49,6 +49,11 @@ from ipalib.encoder import Encoder, encode_args, decode_retval
from ipalib.request import context
+# Group Member types
+MEMBERS_ALL = 0
+MEMBERS_DIRECT = 1
+MEMBERS_INDIRECT = 2
+
# SASL authentication mechanism
SASL_AUTH = _ldap_sasl.sasl({}, 'GSSAPI')
@@ -543,6 +548,13 @@ class ldap2(CrudBackend, Encoder):
if not res:
raise errors.NotFound(reason='no such entry')
+ if attrs_list and ('memberindirect' in attrs_list or '*' in attrs_list):
+ for r in res:
+ indirect = self.get_members(r[0], membertype=MEMBERS_INDIRECT,
+ time_limit=time_limit, size_limit=size_limit, normalize=normalize)
+ if len(indirect) > 0:
+ r[1]['memberindirect'] = indirect
+
return (res, truncated)
def find_entry_by_attr(self, attr, value, object_class, attrs_list=None,
@@ -814,6 +826,65 @@ class ldap2(CrudBackend, Encoder):
# update group entry
self.update_entry(group_dn, group_entry_attrs)
+ def get_members(self, group_dn, attr_list=[], membertype=MEMBERS_ALL, time_limit=None, size_limit=None, normalize=True):
+ """Do a memberOf search of groupdn and return the attributes in
+ attr_list (an empty list returns all attributes).
+
+ membertype = MEMBERS_ALL all members returned
+ membertype = MEMBERS_DIRECT only direct members are returned
+ membertype = MEMBERS_INDIRECT only inherited members are returned
+
+ Members may be included in a group as a result of being a member
+ of a group that is a member of the group being queried.
+
+ Returns a list of DNs.
+ """
+ if membertype not in [MEMBERS_ALL, MEMBERS_DIRECT, MEMBERS_INDIRECT]:
+ return None
+
+ searchfilter = "(memberof=%s)" % group_dn
+
+ attr_list.append("member")
+
+ # We have to do two searches because netgroups are not within the
+ # accounts container.
+ try:
+ (results, truncated) = self.find_entries(searchfilter, attr_list,
+ api.env.container_accounts, time_limit=time_limit, size_limit = size_limit, normalize=normalize)
+ except errors.NotFound:
+ results = []
+ try:
+ (netresults, truncated) = self.find_entries(searchfilter, attr_list,
+ api.env.container_netgroup, time_limit=time_limit, size_limit = size_limit, normalize=normalize)
+ except errors.NotFound:
+ netresults = []
+ results = results + netresults
+
+ if membertype == MEMBERS_ALL:
+ entries = []
+ for e in results:
+ entries.append(e[0])
+
+ return entries
+
+ (dn, group) = self.get_entry(group_dn, ['dn', 'member'])
+ real_members = group.get('member')
+ if isinstance(real_members, basestring):
+ real_members = [real_members]
+ if real_members is None:
+ real_members = []
+
+ entries = []
+ for e in results:
+ if unicode(e[0]) not in real_members:
+ if membertype == MEMBERS_INDIRECT:
+ entries.append(e[0])
+ else:
+ if membertype == MEMBERS_DIRECT:
+ entries.append(e[0])
+
+ return entries
+
def set_entry_active(self, dn, active):
"""Mark entry active/inactive."""
assert isinstance(active, bool)
diff --git a/tests/test_xmlrpc/test_hbac_plugin.py b/tests/test_xmlrpc/test_hbac_plugin.py
index 2405355c0..3c1cfaed5 100644
--- a/tests/test_xmlrpc/test_hbac_plugin.py
+++ b/tests/test_xmlrpc/test_hbac_plugin.py
@@ -267,7 +267,7 @@ class test_hbac(XMLRPC_test):
assert 'hbacsvc' in failed['memberservice']
assert not failed['memberservice']['hbacsvc']
entry = ret['result']
- assert_attr_equal(entry, 'memberservice_service', self.test_service)
+ assert_attr_equal(entry, 'memberservice_hbacsvc', self.test_service)
def test_a_hbac_remove_service(self):
"""
diff --git a/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py b/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py
index 8264ae903..da347f22d 100644
--- a/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py
+++ b/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py
@@ -130,7 +130,7 @@ class test_hbacsvcgroup(Declarative):
'dn': dn1,
'cn': [hbacsvcgroup1],
'description': [u'Test hbacsvcgroup 1'],
- 'member_service': [hbacsvc1],
+ 'member_hbacsvc': [hbacsvc1],
},
),
),
@@ -144,7 +144,7 @@ class test_hbacsvcgroup(Declarative):
summary=None,
result={
'dn': dn1,
- 'member_service': [hbacsvc1],
+ 'member_hbacsvc': [hbacsvc1],
'cn': [hbacsvcgroup1],
'description': [u'Test hbacsvcgroup 1'],
},
@@ -162,7 +162,7 @@ class test_hbacsvcgroup(Declarative):
result=[
{
'dn': dn1,
- 'member_service': [hbacsvc1],
+ 'member_hbacsvc': [hbacsvc1],
'cn': [hbacsvcgroup1],
'description': [u'Test hbacsvcgroup 1'],
},
@@ -182,7 +182,7 @@ class test_hbacsvcgroup(Declarative):
result=dict(
cn=[hbacsvcgroup1],
description=[u'Updated hbacsvcgroup 1'],
- member_service=[hbacsvc1],
+ member_hbacsvc=[hbacsvc1],
),
),
),
@@ -196,7 +196,7 @@ class test_hbacsvcgroup(Declarative):
summary=None,
result={
'dn': dn1,
- 'member_service': [hbacsvc1],
+ 'member_hbacsvc': [hbacsvc1],
'cn': [hbacsvcgroup1],
'description': [u'Updated hbacsvcgroup 1'],
},
diff --git a/tests/test_xmlrpc/test_nesting.py b/tests/test_xmlrpc/test_nesting.py
new file mode 100644
index 000000000..8c9e4b25f
--- /dev/null
+++ b/tests/test_xmlrpc/test_nesting.py
@@ -0,0 +1,350 @@
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2010 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; version 2 only
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+Test group nexting an indirect members
+"""
+
+from ipalib import api, errors
+from tests.test_xmlrpc import objectclasses
+from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
+
+group1 = u'testgroup1'
+group2 = u'testgroup2'
+group3 = u'testgroup3'
+user1 = u'tuser1'
+user2 = u'tuser2'
+
+
+class test_group(Declarative):
+ cleanup_commands = [
+ ('group_del', [group1], {}),
+ ('group_del', [group2], {}),
+ ('group_del', [group3], {}),
+ ('user_del', [user1], {}),
+ ('user_del', [user2], {}),
+ ]
+
+ tests = [
+
+ ################
+ # create group1:
+
+ dict(
+ desc='Create %r' % group1,
+ command=(
+ 'group_add', [group1], dict(description=u'Test desc 1')
+ ),
+ expected=dict(
+ value=group1,
+ summary=u'Added group "testgroup1"',
+ result=dict(
+ cn=[group1],
+ description=[u'Test desc 1'],
+ objectclass=objectclasses.group + [u'posixgroup'],
+ ipauniqueid=[fuzzy_uuid],
+ gidnumber=[fuzzy_digits],
+ dn=u'cn=testgroup1,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ ################
+ # create group2:
+ dict(
+ desc='Create %r' % group2,
+ command=(
+ 'group_add', [group2], dict(description=u'Test desc 2')
+ ),
+ expected=dict(
+ value=group2,
+ summary=u'Added group "testgroup2"',
+ result=dict(
+ cn=[group2],
+ description=[u'Test desc 2'],
+ gidnumber=[fuzzy_digits],
+ objectclass=objectclasses.group + [u'posixgroup'],
+ ipauniqueid=[fuzzy_uuid],
+ dn=u'cn=testgroup2,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Create %r' % group3,
+ command=(
+ 'group_add', [group3], dict(description=u'Test desc 3')
+ ),
+ expected=dict(
+ value=group3,
+ summary=u'Added group "testgroup3"',
+ result=dict(
+ cn=[group3],
+ description=[u'Test desc 3'],
+ gidnumber=[fuzzy_digits],
+ objectclass=objectclasses.group + [u'posixgroup'],
+ ipauniqueid=[fuzzy_uuid],
+ dn=u'cn=testgroup3,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Create %r' % user1,
+ command=(
+ 'user_add', [user1], dict(givenname=u'Test', sn=u'User1')
+ ),
+ expected=dict(
+ value=user1,
+ summary=u'Added user "%s"' % user1,
+ result=dict(
+ gecos=[user1],
+ givenname=[u'Test'],
+ homedirectory=[u'/home/tuser1'],
+ krbprincipalname=[u'tuser1@' + api.env.realm],
+ loginshell=[u'/bin/sh'],
+ objectclass=objectclasses.user,
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ ipauniqueid=[fuzzy_uuid],
+ dn=u'uid=%s,cn=users,cn=accounts,%s' % (user1, api.env.basedn)
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Create %r' % user2,
+ command=(
+ 'user_add', [user2], dict(givenname=u'Test', sn=u'User2')
+ ),
+ expected=dict(
+ value=user2,
+ summary=u'Added user "%s"' % user2,
+ result=dict(
+ gecos=[user2],
+ givenname=[u'Test'],
+ homedirectory=[u'/home/tuser2'],
+ krbprincipalname=[u'tuser2@' + api.env.realm],
+ loginshell=[u'/bin/sh'],
+ objectclass=objectclasses.user,
+ sn=[u'User2'],
+ uid=[user2],
+ uidnumber=[fuzzy_digits],
+ ipauniqueid=[fuzzy_uuid],
+ dn=u'uid=%s,cn=users,cn=accounts,%s' % (user2, api.env.basedn)
+ ),
+ ),
+ ),
+
+
+ ###############
+ # member stuff
+ #
+ # Create 3 groups and 2 users and set the following membership:
+ #
+ # g1:
+ # member: g2
+ #
+ # g2:
+ # member: g3
+ # member: user1
+ #
+ # g3:
+ # member: user2
+ #
+ # So when we do a show it looks like:
+ #
+ # g1:
+ # member: g2
+ # indirect group: g3
+ # indirect users: user1, user2
+ #
+ # g2:
+ # member group: g3
+ # member user: tuser1
+ # indirect users: user2
+ # memberof: g1
+ #
+ # g3:
+ # member: user2
+ # memberof: g1, g2
+
+
+ dict(
+ desc='Add a group member %r to %r' % (group2, group1),
+ command=(
+ 'group_add_member', [group1], dict(group=group2)
+ ),
+ expected=dict(
+ completed=1,
+ failed=dict(
+ member=dict(
+ group=tuple(),
+ user=tuple(),
+ ),
+ ),
+ result={
+ 'dn': u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn),
+ 'member_group': (group2,),
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [group1],
+ 'description': [u'Test desc 1'],
+ },
+ ),
+ ),
+
+
+ dict(
+ desc='Add a group member %r to %r' % (group3, group2),
+ command=(
+ 'group_add_member', [group2], dict(group=group3)
+ ),
+ expected=dict(
+ completed=1,
+ failed=dict(
+ member=dict(
+ group=tuple(),
+ user=tuple(),
+ ),
+ ),
+ result={
+ 'dn': u'cn=%s,cn=groups,cn=accounts,%s' % (group2, api.env.basedn),
+ 'member_group': (group3,),
+ 'memberof_group': (u'testgroup1',),
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [group2],
+ 'description': [u'Test desc 2'],
+ },
+ ),
+ ),
+
+
+ dict(
+ desc='Add a user member %r to %r' % (user1, group2),
+ command=(
+ 'group_add_member', [group2], dict(user=user1)
+ ),
+ expected=dict(
+ completed=1,
+ failed=dict(
+ member=dict(
+ group=tuple(),
+ user=tuple(),
+ ),
+ ),
+ result={
+ 'dn': u'cn=%s,cn=groups,cn=accounts,%s' % (group2, api.env.basedn),
+ 'member_user': (u'tuser1',),
+ 'member_group': (group3,),
+ 'memberof_group': (u'testgroup1',),
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [group2],
+ 'description': [u'Test desc 2'],
+ },
+ ),
+ ),
+
+
+ dict(
+ desc='Add a user member %r to %r' % (user2, group3),
+ command=(
+ 'group_add_member', [group3], dict(user=user2)
+ ),
+ expected=dict(
+ completed=1,
+ failed=dict(
+ member=dict(
+ group=tuple(),
+ user=tuple(),
+ ),
+ ),
+ result={
+ 'dn': u'cn=%s,cn=groups,cn=accounts,%s' % (group3, api.env.basedn),
+ 'member_user': (u'tuser2',),
+ 'memberof_group': (u'testgroup2', u'testgroup1'),
+ 'gidnumber': [fuzzy_digits],
+ 'cn': [group3],
+ 'description': [u'Test desc 3'],
+ },
+ ),
+ ),
+
+
+ dict(
+ desc='Retrieve group %r' % group1,
+ command=('group_show', [group1], {}),
+ expected=dict(
+ value=group1,
+ summary=None,
+ result=dict(
+ cn=[group1],
+ description=[u'Test desc 1'],
+ gidnumber= [fuzzy_digits],
+ memberindirect_group = (u'testgroup3',),
+ member_group = (u'testgroup2',),
+ memberindirect_user = (u'tuser1',u'tuser2',),
+ dn=u'cn=testgroup1,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Retrieve group %r' % group2,
+ command=('group_show', [group2], {}),
+ expected=dict(
+ value=group2,
+ summary=None,
+ result=dict(
+ cn=[group2],
+ description=[u'Test desc 2'],
+ gidnumber= [fuzzy_digits],
+ memberof_group = (u'testgroup1',),
+ member_group = (u'testgroup3',),
+ member_user = (u'tuser1',),
+ memberindirect_user = (u'tuser2',),
+ dn=u'cn=testgroup2,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Retrieve group %r' % group3,
+ command=('group_show', [group3], {}),
+ expected=dict(
+ value=group3,
+ summary=None,
+ result=dict(
+ cn=[group3],
+ description=[u'Test desc 3'],
+ gidnumber= [fuzzy_digits],
+ memberof_group = (u'testgroup2', u'testgroup1',),
+ member_user = (u'tuser2',),
+ dn=u'cn=testgroup3,cn=groups,cn=accounts,' + api.env.basedn,
+ ),
+ ),
+ ),
+
+
+ ]