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 54a8ce52..706e77ae 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 b685be38..4fc83695 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 7fa075b1..1c8e751b 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 4d73711e..b670c457 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 08ecf32a..eac5cb0b 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 7f446b03..78f76b0a 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 0ddb9385..d0ca6982 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 43bcf986..4c346698 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 |