mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-13 08:52:01 -05:00
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
This commit is contained in:
1 parent
07059a5ef2
commit
bde9959091
8 files changed
+126
-16
No files matched your search
@@ -74,7 +74,7 @@ def main():
|
|||||||
|
|
||||||
for ent in groups:
|
for ent in groups:
|
||||||
try:
|
try:
|
||||||
members = client.group_members(ent.dn, ['dn','cn'])
|
members = client.group_members(ent.dn, ['dn','cn'], 0)
|
||||||
except ipa.ipaerror.IPAError, e:
|
except ipa.ipaerror.IPAError, e:
|
||||||
print "Error getting members for " + ent.dn
|
print "Error getting members for " + ent.dn
|
||||||
print str(e)
|
print str(e)
|
||||||
|
|||||||
@@ -326,11 +326,11 @@ class IPAClient:
|
|||||||
|
|
||||||
return self.transport.get_all_attrs()
|
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
|
"""Do a memberOf search of groupdn and return the attributes in
|
||||||
attr_list (an empty list returns everything)."""
|
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]
|
counter = results[0]
|
||||||
|
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ class RPCClient:
|
|||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
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
|
"""Do a memberOf search of groupdn and return the attributes in
|
||||||
attr_list (an empty list returns everything)."""
|
attr_list (an empty list returns everything)."""
|
||||||
|
|
||||||
@@ -620,7 +620,7 @@ class RPCClient:
|
|||||||
|
|
||||||
server = self.setup_server()
|
server = self.setup_server()
|
||||||
try:
|
try:
|
||||||
result = server.group_members(groupdn, attr_list)
|
result = server.group_members(groupdn, attr_list, memberstype)
|
||||||
except xmlrpclib.Fault, fault:
|
except xmlrpclib.Fault, fault:
|
||||||
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
||||||
except socket.error, (value, msg):
|
except socket.error, (value, msg):
|
||||||
|
|||||||
@@ -88,9 +88,22 @@ var dn_to_member_div_id = new Hash();
|
|||||||
*/
|
*/
|
||||||
function renderMemberInfo(newdiv, info) {
|
function renderMemberInfo(newdiv, info) {
|
||||||
if (info.type == "user") {
|
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(
|
newdiv.appendChild(document.createTextNode(
|
||||||
info.name + " " + info.descr + " "));
|
info.name + " " + info.descr + " "));
|
||||||
} else if (info.type == "group") {
|
} 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 = document.createElement('i');
|
||||||
ital.appendChild(document.createTextNode(
|
ital.appendChild(document.createTextNode(
|
||||||
info.name + " " +
|
info.name + " " +
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ class GroupController(IPAController):
|
|||||||
# convert members to users, for easier manipulation on the page
|
# 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 = members[1:]
|
||||||
members.sort(self.sort_group_member)
|
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)
|
# (so we don't have to do this on each round trip)
|
||||||
member_dicts = map(lambda member: member.toDict(), members)
|
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
|
# store a copy of the original group for the update later
|
||||||
group_data = b64encode(dumps(group_dict))
|
group_data = b64encode(dumps(group_dict))
|
||||||
member_data = b64encode(dumps(member_dicts))
|
member_data = b64encode(dumps(member_dicts))
|
||||||
@@ -411,11 +425,26 @@ class GroupController(IPAController):
|
|||||||
# convert members to users, for display on the page
|
# 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 = members[1:]
|
||||||
members.sort(self.sort_group_member)
|
members.sort(self.sort_group_member)
|
||||||
member_dicts = map(lambda member: member.toDict(), members)
|
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(),
|
return dict(group=group_dict, fields=ipagui.forms.group.GroupFields(),
|
||||||
members = member_dicts)
|
members = member_dicts)
|
||||||
except ipaerror.IPAError, e:
|
except ipaerror.IPAError, e:
|
||||||
|
|||||||
@@ -158,15 +158,22 @@ from ipagui.helpers import ipahelper
|
|||||||
member_dn_esc = ipahelper.javascript_string_escape(member_dn)
|
member_dn_esc = ipahelper.javascript_string_escape(member_dn)
|
||||||
|
|
||||||
member_uid = member.get('uid')
|
member_uid = member.get('uid')
|
||||||
|
member_inherited = member.get('inherited')
|
||||||
if member_uid:
|
if member_uid:
|
||||||
member_name = "%s %s" % (member.get('givenName', ''),
|
member_name = "%s %s" % (member.get('givenName', ''),
|
||||||
member.get('sn', ''))
|
member.get('sn', ''))
|
||||||
member_descr = "(%s)" % member.get('uid')
|
member_descr = "(%s)" % member.get('uid')
|
||||||
member_type = "user"
|
if member_inherited:
|
||||||
|
member_type = "iuser"
|
||||||
|
else:
|
||||||
|
member_type = "user"
|
||||||
else:
|
else:
|
||||||
member_name = member.get('cn')
|
member_name = member.get('cn')
|
||||||
member_descr = "[group]"
|
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_name_esc = ipahelper.javascript_string_escape(member_name)
|
||||||
member_descr_esc = ipahelper.javascript_string_escape(member_descr)
|
member_descr_esc = ipahelper.javascript_string_escape(member_descr)
|
||||||
member_type_esc = ipahelper.javascript_string_escape(member_type)
|
member_type_esc = ipahelper.javascript_string_escape(member_type)
|
||||||
@@ -178,7 +185,7 @@ from ipagui.helpers import ipahelper
|
|||||||
'${member_descr_esc}',
|
'${member_descr_esc}',
|
||||||
'${member_type_esc}'));
|
'${member_type_esc}'));
|
||||||
</script>
|
</script>
|
||||||
<a href="#"
|
<a py:if="member_inherited != True" href="#"
|
||||||
onclick="removememberHandler(this, '${member_dn_esc}',
|
onclick="removememberHandler(this, '${member_dn_esc}',
|
||||||
new MemberDisplayInfo('${member_name_esc}',
|
new MemberDisplayInfo('${member_name_esc}',
|
||||||
'${member_descr_esc}',
|
'${member_descr_esc}',
|
||||||
|
|||||||
@@ -73,10 +73,14 @@ from ipagui.helpers import userhelper
|
|||||||
<?python
|
<?python
|
||||||
|
|
||||||
member_uid = member.get('uid')
|
member_uid = member.get('uid')
|
||||||
|
member_inherited = member.get('inherited')
|
||||||
if member_uid:
|
if member_uid:
|
||||||
member_cn = "%s %s" % (member.get('givenName', ''), member.get('sn', ''))
|
member_cn = "%s %s" % (member.get('givenName', ''), member.get('sn', ''))
|
||||||
member_desc = "(%s)" % member_uid
|
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)
|
view_url = tg.url('/user/show', uid=member_uid)
|
||||||
else:
|
else:
|
||||||
mem = member.get('cn')
|
mem = member.get('cn')
|
||||||
@@ -84,14 +88,31 @@ from ipagui.helpers import userhelper
|
|||||||
mem = mem[0]
|
mem = mem[0]
|
||||||
member_cn = "%s" % mem
|
member_cn = "%s" % mem
|
||||||
member_desc = "[group]"
|
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)
|
view_url = tg.url('/group/show', cn=member_cn)
|
||||||
?>
|
?>
|
||||||
<span py:if='member_type == "user"'>
|
<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}"
|
<a href="${view_url}"
|
||||||
>${member_cn}</a> ${member_desc}
|
>${member_cn}</a> ${member_desc}
|
||||||
</span>
|
</span>
|
||||||
<span py:if='member_type == "group"'>
|
<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>
|
<i>
|
||||||
<a href="${view_url}"
|
<a href="${view_url}"
|
||||||
>${member_cn}</a> ${member_desc}
|
>${member_cn}</a> ${member_desc}
|
||||||
|
|||||||
@@ -1725,22 +1725,42 @@ class IPAServer:
|
|||||||
|
|
||||||
return attrs.attr_label_list
|
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
|
"""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:
|
if not isinstance(groupdn,basestring) or len(groupdn) == 0:
|
||||||
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
|
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
|
||||||
if attr_list is not None and not isinstance(attr_list,list):
|
if attr_list is not None and not isinstance(attr_list,list):
|
||||||
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
|
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)
|
config = self.get_ipa_config(opts)
|
||||||
timelimit = float(config.get('ipasearchtimelimit'))
|
timelimit = float(config.get('ipasearchtimelimit'))
|
||||||
|
|
||||||
|
logging.debug("IPA: group_members: %s %s %s" % (groupdn, attr_list, membertype))
|
||||||
|
|
||||||
searchlimit = float(config.get('ipasearchrecordslimit'))
|
searchlimit = float(config.get('ipasearchrecordslimit'))
|
||||||
|
|
||||||
groupdn = self.__safe_filter(groupdn)
|
groupdn = self.__safe_filter(groupdn)
|
||||||
searchfilter = "(memberOf=%s)" % groupdn
|
searchfilter = "(memberOf=%s)" % groupdn
|
||||||
|
|
||||||
|
if attr_list is None:
|
||||||
|
attr_list = []
|
||||||
|
attr_list.append("member")
|
||||||
|
|
||||||
conn = self.getConnection(opts)
|
conn = self.getConnection(opts)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@@ -1755,9 +1775,29 @@ class IPAServer:
|
|||||||
counter = results[0]
|
counter = results[0]
|
||||||
results = results[1:]
|
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:
|
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
|
return entries
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user