summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2008-03-27 09:54:41 -0400
committerRob Crittenden <rcritten@redhat.com>2008-03-27 09:54:41 -0400
commitbde9959091d263402c2016c183f8617dea488cc0 (patch)
tree581f055ebf18201d879487af3d58b5c7a4403387
parent07059a5ef25143b0f0a99f27d6039276a4f557f4 (diff)
downloadfreeipa-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-findgroup2
-rw-r--r--ipa-python/ipaclient.py4
-rw-r--r--ipa-python/rpcclient.py4
-rw-r--r--ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js13
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/group.py33
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupeditform.kid13
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupshow.kid25
-rw-r--r--ipa-server/xmlrpc-server/funcs.py48
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