diff options
author | Rob Crittenden <rcritten@redhat.com> | 2008-03-27 09:54:41 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2008-03-27 09:54:41 -0400 |
commit | bde9959091d263402c2016c183f8617dea488cc0 (patch) | |
tree | 581f055ebf18201d879487af3d58b5c7a4403387 | |
parent | 07059a5ef25143b0f0a99f27d6039276a4f557f4 (diff) | |
download | freeipa-bde9959091d263402c2016c183f8617dea488cc0.tar.gz freeipa-bde9959091d263402c2016c183f8617dea488cc0.tar.xz freeipa-bde9959091d263402c2016c183f8617dea488cc0.zip |
When getting members let user indicate what type of member they want.
The memberOf attribute includes members that are directly in the group
via the "member" attribute and those that are included as a result of
being in a group that is in the group.
The UI needs to be able to distinguish between the two.
438706
-rw-r--r-- | ipa-admintools/ipa-findgroup | 2 | ||||
-rw-r--r-- | ipa-python/ipaclient.py | 4 | ||||
-rw-r--r-- | ipa-python/rpcclient.py | 4 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js | 13 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/subcontrollers/group.py | 33 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/groupeditform.kid | 13 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/groupshow.kid | 25 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/funcs.py | 48 |
8 files changed, 126 insertions, 16 deletions
diff --git a/ipa-admintools/ipa-findgroup b/ipa-admintools/ipa-findgroup index 54a8ce525..706e77ae9 100644 --- a/ipa-admintools/ipa-findgroup +++ b/ipa-admintools/ipa-findgroup @@ -74,7 +74,7 @@ def main(): for ent in groups: try: - members = client.group_members(ent.dn, ['dn','cn']) + members = client.group_members(ent.dn, ['dn','cn'], 0) except ipa.ipaerror.IPAError, e: print "Error getting members for " + ent.dn print str(e) diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py index b685be38c..4fc836953 100644 --- a/ipa-python/ipaclient.py +++ b/ipa-python/ipaclient.py @@ -326,11 +326,11 @@ class IPAClient: return self.transport.get_all_attrs() - def group_members(self, groupdn, attr_list): + def group_members(self, groupdn, attr_list, membertype): """Do a memberOf search of groupdn and return the attributes in attr_list (an empty list returns everything).""" - results = self.transport.group_members(groupdn, attr_list) + results = self.transport.group_members(groupdn, attr_list, membertype) counter = results[0] diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py index 7fa075b1d..1c8e751b5 100644 --- a/ipa-python/rpcclient.py +++ b/ipa-python/rpcclient.py @@ -611,7 +611,7 @@ class RPCClient: return ipautil.unwrap_binary_data(result) - def group_members(self, groupdn, attr_list=None): + def group_members(self, groupdn, attr_list=None, memberstype=0): """Do a memberOf search of groupdn and return the attributes in attr_list (an empty list returns everything).""" @@ -620,7 +620,7 @@ class RPCClient: server = self.setup_server() try: - result = server.group_members(groupdn, attr_list) + result = server.group_members(groupdn, attr_list, memberstype) except xmlrpclib.Fault, fault: raise ipaerror.gen_exception(fault.faultCode, fault.faultString) except socket.error, (value, msg): diff --git a/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js index 4d73711e6..b670c457f 100644 --- a/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js +++ b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js @@ -88,10 +88,23 @@ var dn_to_member_div_id = new Hash(); */ function renderMemberInfo(newdiv, info) { if (info.type == "user") { + bold = document.createElement('b'); + bold.appendChild(document.createTextNode( + info.name + " " + info.descr + " ")); + newdiv.appendChild(bold); + } else if (info.type == "iuser") { newdiv.appendChild(document.createTextNode( info.name + " " + info.descr + " ")); } else if (info.type == "group") { ital = document.createElement('i'); + bold = document.createElement('b'); + ital.appendChild(bold); + bold.appendChild(document.createTextNode( + info.name + " " + + info.descr + " ")); + newdiv.appendChild(ital); + } else if (info.type == "igroup") { + ital = document.createElement('i'); ital.appendChild(document.createTextNode( info.name + " " + info.descr + " ")); diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py index 08ecf32ad..eac5cb0bd 100644 --- a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py @@ -208,7 +208,7 @@ class GroupController(IPAController): # convert members to users, for easier manipulation on the page # - members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn']) + members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 1) members = members[1:] members.sort(self.sort_group_member) @@ -216,6 +216,20 @@ class GroupController(IPAController): # (so we don't have to do this on each round trip) member_dicts = map(lambda member: member.toDict(), members) + indirect_members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 2) + indirect_members = indirect_members[1:] + indirect_members.sort(self.sort_group_member) + + # add our own flag + for i in range(len(indirect_members)): + indirect_members[i].setValue('inherited', True) + + # Map users into an array of dicts, which can be serialized + # (so we don't have to do this on each round trip) + indirect_members_dicts = map(lambda member: member.toDict(), indirect_members) + + member_dicts = member_dicts + indirect_members_dicts + # store a copy of the original group for the update later group_data = b64encode(dumps(group_dict)) member_data = b64encode(dumps(member_dicts)) @@ -411,11 +425,26 @@ class GroupController(IPAController): # convert members to users, for display on the page # - members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn']) + members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 1) members = members[1:] members.sort(self.sort_group_member) member_dicts = map(lambda member: member.toDict(), members) + indirect_members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 2) + indirect_members = indirect_members[1:] + indirect_members.sort(self.sort_group_member) + + # add our own flag + for i in range(len(indirect_members)): + indirect_members[i].setValue('inherited', True) + + # Map users into an array of dicts, which can be serialized + # (so we don't have to do this on each round trip) + indirect_members_dicts = map(lambda member: member.toDict(), indirect_members) + + member_dicts = member_dicts + indirect_members_dicts + logging.info("%s" % member_dicts) + return dict(group=group_dict, fields=ipagui.forms.group.GroupFields(), members = member_dicts) except ipaerror.IPAError, e: diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid index 7f446b036..78f76b0a1 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid @@ -158,15 +158,22 @@ from ipagui.helpers import ipahelper member_dn_esc = ipahelper.javascript_string_escape(member_dn) member_uid = member.get('uid') + member_inherited = member.get('inherited') if member_uid: member_name = "%s %s" % (member.get('givenName', ''), member.get('sn', '')) member_descr = "(%s)" % member.get('uid') - member_type = "user" + if member_inherited: + member_type = "iuser" + else: + member_type = "user" else: member_name = member.get('cn') member_descr = "[group]" - member_type = "group" + if member_inherited: + member_type = "igroup" + else: + member_type = "group" member_name_esc = ipahelper.javascript_string_escape(member_name) member_descr_esc = ipahelper.javascript_string_escape(member_descr) member_type_esc = ipahelper.javascript_string_escape(member_type) @@ -178,7 +185,7 @@ from ipagui.helpers import ipahelper '${member_descr_esc}', '${member_type_esc}')); </script> - <a href="#" + <a py:if="member_inherited != True" href="#" onclick="removememberHandler(this, '${member_dn_esc}', new MemberDisplayInfo('${member_name_esc}', '${member_descr_esc}', diff --git a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid index 0ddb93851..d0ca6982a 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid @@ -73,10 +73,14 @@ from ipagui.helpers import userhelper <?python member_uid = member.get('uid') + member_inherited = member.get('inherited') if member_uid: member_cn = "%s %s" % (member.get('givenName', ''), member.get('sn', '')) member_desc = "(%s)" % member_uid - member_type = "user" + if member_inherited: + member_type = "iuser" + else: + member_type = "user" view_url = tg.url('/user/show', uid=member_uid) else: mem = member.get('cn') @@ -84,14 +88,31 @@ from ipagui.helpers import userhelper mem = mem[0] member_cn = "%s" % mem member_desc = "[group]" - member_type = "group" + if member_inherited: + member_type = "igroup" + else: + member_type = "group" view_url = tg.url('/group/show', cn=member_cn) ?> <span py:if='member_type == "user"'> + <b> + <a href="${view_url}" + >${member_cn}</a> ${member_desc} + </b> + </span> + <span py:if='member_type == "iuser"'> <a href="${view_url}" >${member_cn}</a> ${member_desc} </span> <span py:if='member_type == "group"'> + <b> + <i> + <a href="${view_url}" + >${member_cn}</a> ${member_desc} + </i> + </b> + </span> + <span py:if='member_type == "igroup"'> <i> <a href="${view_url}" >${member_cn}</a> ${member_desc} diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index 43bcf9869..4c346698c 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -1725,22 +1725,42 @@ class IPAServer: return attrs.attr_label_list - def group_members(self, groupdn, attr_list, opts=None): + def group_members(self, groupdn, attr_list, membertype, opts=None): """Do a memberOf search of groupdn and return the attributes in - attr_list (an empty list returns everything).""" + attr_list (an empty list returns all attributes). + + membertype = 0 all members returned + membertype = 1 only direct members are returned + membertype = 2 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. + """ if not isinstance(groupdn,basestring) or len(groupdn) == 0: raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER) if attr_list is not None and not isinstance(attr_list,list): raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER) + if membertype is not None and not isinstance(membertype,int): + raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER) + if membertype is None: + membertype = 0 + if membertype < 0 or membertype > 3: + raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER) config = self.get_ipa_config(opts) timelimit = float(config.get('ipasearchtimelimit')) + logging.debug("IPA: group_members: %s %s %s" % (groupdn, attr_list, membertype)) + searchlimit = float(config.get('ipasearchrecordslimit')) groupdn = self.__safe_filter(groupdn) searchfilter = "(memberOf=%s)" % groupdn + if attr_list is None: + attr_list = [] + attr_list.append("member") + conn = self.getConnection(opts) try: try: @@ -1755,9 +1775,29 @@ class IPAServer: counter = results[0] results = results[1:] - entries = [counter] + if membertype == 0: + entries = [counter] + for e in results: + entries.append(self.convert_entry(e)) + + return entries + + group = self.get_entry_by_dn(groupdn, ['dn', 'member'], opts) + real_members = group.get('member') + if isinstance(real_members, basestring): + real_members = [real_members] + + entries = [0] for e in results: - entries.append(self.convert_entry(e)) + if e.dn not in real_members: + if membertype == 2: + entries.append(self.convert_entry(e)) + else: + if membertype == 1: + entries.append(self.convert_entry(e)) + + if len(entries) > 1: + entries[0] = len(entries) - 1 return entries |