diff options
-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 |