In the UI we don't want to display Edit links unless someone can actually

edit things. We use the 'editors' group for this. This group itself grants
no permission other than displaying certain things in the UI.

In order to be in the editors group a user must be a member of a group that
is the source group in a delegation. The memberof plugin will do all the
hard work to be sure that a user's memberof contains cn=editors if they
are in a delegated group.

432874
This commit is contained in:
Rob Crittenden 2008-02-27 15:14:52 -05:00
parent ad8096b51f
commit 999bd4fb1e
6 changed files with 121 additions and 16 deletions

View File

@ -139,6 +139,14 @@ def main():
client.update_entry(aci_entry) client.update_entry(aci_entry)
# Now add to the editors group so they can make changes in the UI
try:
group = client.get_entry_by_cn("editors")
client.add_group_to_group(new_aci.source_group, group.dn)
except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST):
# This is ok, ignore it
pass
print "Delegation %s successfully added" % args[1] print "Delegation %s successfully added" % args[1]
return 0 return 0

View File

@ -51,12 +51,15 @@ def main():
aci_str_list = [aci_str_list] aci_str_list = [aci_str_list]
acistr = None acistr = None
aci_list = []
for aci_str in aci_str_list: for aci_str in aci_str_list:
try: try:
aci = ipa.aci.ACI(aci_str) aci = ipa.aci.ACI(aci_str)
if aci.name == args[1]: if aci.name == args[1]:
acistr = aci_str acistr = aci_str
break source_group = aci.source_group
else:
aci_list.append(aci)
except SyntaxError: except SyntaxError:
# ignore aci_str's that ACI can't parse # ignore aci_str's that ACI can't parse
pass pass
@ -72,6 +75,18 @@ def main():
aci_entry.setValue('aci', new_aci_str_list) aci_entry.setValue('aci', new_aci_str_list)
client.update_entry(aci_entry) client.update_entry(aci_entry)
last = True
# If this is the last delegation for a group, remove it from editors
for a in aci_list:
if source_group == a.source_group:
last = False
break
if last:
group = client.get_entry_by_cn("editors")
client.remove_member_from_group(source_group, group.dn)
print "Delegation removed." print "Delegation removed."
return 0 return 0

View File

@ -49,9 +49,9 @@ def main():
if options.list: if options.list:
client = ipaclient.IPAClient() client = ipaclient.IPAClient()
list = client.get_all_attrs() l = client.get_all_attrs()
for x in list: for x in l:
print x print x
return 0 return 0
@ -124,12 +124,15 @@ def main():
old_aci = None old_aci = None
acistr = None acistr = None
aci_list = []
for aci_str in aci_str_list: for aci_str in aci_str_list:
try: try:
old_aci = ipa.aci.ACI(aci_str) old_aci = ipa.aci.ACI(aci_str)
if old_aci.name == args[1]: if old_aci.name == args[1]:
acistr = aci_str acistr = aci_str
break orig_group = old_aci.source_group
else:
aci_list.append(old_aci)
except SyntaxError: except SyntaxError:
# ignore aci_str's that ACI can't parse # ignore aci_str's that ACI can't parse
pass pass
@ -162,6 +165,26 @@ def main():
client.update_entry(aci_entry) client.update_entry(aci_entry)
if options.source:
last = True
# If this is the last delegation for a group, remove it from editors
for a in aci_list:
if orig_group == a.source_group:
last = False
break
if last:
group = client.get_entry_by_cn("editors")
client.remove_member_from_group(orig_group, group.dn)
# Now add to the editors group so they can make changes in the UI
try:
group = client.get_entry_by_cn("editors")
client.add_group_to_group(new_aci.source_group, group.dn)
except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST):
# This is ok, ignore it
pass
print "Delegation %s successfully updated" % args[1] print "Delegation %s successfully updated" % args[1]
return 0 return 0

View File

@ -24,6 +24,7 @@ from ipaserver import funcs
import ipa.config import ipa.config
import ipa.group import ipa.group
import ipa.user import ipa.user
import ldap
log = logging.getLogger("turbogears.identity") log = logging.getLogger("turbogears.identity")
@ -41,18 +42,18 @@ class IPA_User(object):
client = ipa.ipaclient.IPAClient(transport) client = ipa.ipaclient.IPAClient(transport)
client.set_krbccache(os.environ["KRB5CCNAME"]) client.set_krbccache(os.environ["KRB5CCNAME"])
try: try:
user = client.get_user_by_principal(user_name, ['dn']) # Use memberof so we can see recursive group memberships as well.
user = client.get_user_by_principal(user_name, ['dn', 'memberof'])
self.groups = [] self.groups = []
groups = client.get_groups_by_member(user.dn, ['dn', 'cn']) memberof = user.getValues('memberof')
if isinstance(groups, str): if isinstance(memberof, str):
groups = [groups] memberof = [memberof]
for ginfo in groups: for mo in memberof:
# cn may be multi-valued, add them all just in case rdn_list = ldap.explode_dn(mo, 0)
cn = ginfo.getValue('cn') first_rdn = rdn_list[0]
if isinstance(cn, str): (type,value) = first_rdn.split('=')
cn = [cn] if type == "cn":
for c in cn: self.groups.append(value)
self.groups.append(c)
except: except:
raise raise

View File

@ -134,6 +134,15 @@ class DelegationController(IPAController):
aci_entry.setValue('aci', new_aci.export_to_string()) aci_entry.setValue('aci', new_aci.export_to_string())
client.update_entry(aci_entry) client.update_entry(aci_entry)
# Now add to the editors group so they can make changes in the UI
try:
group = client.get_entry_by_cn("editors")
client.add_group_to_group(new_aci.source_group, group.dn)
except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST):
# This is ok, ignore it
pass
except ipaerror.IPAError, e: except ipaerror.IPAError, e:
turbogears.flash("Delgate add failed: " + str(e) + "<br/>" + e.detail[0]['desc']) turbogears.flash("Delgate add failed: " + str(e) + "<br/>" + e.detail[0]['desc'])
return dict(form=delegate_form, delegate=kw, return dict(form=delegate_form, delegate=kw,
@ -216,11 +225,37 @@ class DelegationController(IPAController):
new_aci_str = new_aci.export_to_string() new_aci_str = new_aci.export_to_string()
new_aci_str_list = copy.copy(aci_str_list) new_aci_str_list = copy.copy(aci_str_list)
old_aci = ipa.aci.ACI(new_aci_str_list[old_aci_index])
new_aci_str_list[old_aci_index] = new_aci_str new_aci_str_list[old_aci_index] = new_aci_str
aci_entry.setValue('aci', new_aci_str_list) aci_entry.setValue('aci', new_aci_str_list)
client.update_entry(aci_entry) client.update_entry(aci_entry)
if new_aci.source_group != old_aci.source_group:
aci_list = []
last = True
for aci_str in new_aci_str_list:
try:
aci = ipa.aci.ACI(aci_str)
if aci.source_group == old_aci.source_group:
last = False
break
except SyntaxError:
# ignore aci_str's that ACI can't parse
pass
if last:
group = client.get_entry_by_cn("editors")
client.remove_member_from_group(old_aci.source_group, group.dn)
# Now add to the editors group so they can make changes in the UI
try:
group = client.get_entry_by_cn("editors")
client.add_group_to_group(new_aci.source_group, group.dn)
except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST):
# This is ok, ignore it
pass
turbogears.flash("delegate updated") turbogears.flash("delegate updated")
raise turbogears.redirect('/delegate/list') raise turbogears.redirect('/delegate/list')
except (SyntaxError, ipaerror.IPAError), e: except (SyntaxError, ipaerror.IPAError), e:
@ -291,12 +326,28 @@ class DelegationController(IPAController):
"concurrently modified.") "concurrently modified.")
raise turbogears.redirect('/delegate/list') raise turbogears.redirect('/delegate/list')
old_aci = ipa.aci.ACI(aci_str_list[old_aci_index])
new_aci_str_list = copy.copy(aci_str_list) new_aci_str_list = copy.copy(aci_str_list)
del new_aci_str_list[old_aci_index] del new_aci_str_list[old_aci_index]
aci_entry.setValue('aci', new_aci_str_list) aci_entry.setValue('aci', new_aci_str_list)
client.update_entry(aci_entry) client.update_entry(aci_entry)
aci_list = []
last = True
for aci_str in new_aci_str_list:
try:
aci = ipa.aci.ACI(aci_str)
if aci.source_group == old_aci.source_group:
last = False
break
except SyntaxError:
# ignore aci_str's that ACI can't parse
pass
if last:
group = client.get_entry_by_cn("editors")
client.remove_member_from_group(old_aci.source_group, group.dn)
turbogears.flash("delegate deleted") turbogears.flash("delegate deleted")
raise turbogears.redirect('/delegate/list') raise turbogears.redirect('/delegate/list')
except (SyntaxError, ipaerror.IPAError), e: except (SyntaxError, ipaerror.IPAError), e:

View File

@ -1123,7 +1123,14 @@ class IPAServer:
return True return True
def get_groups_by_member (self, member_dn, sattrs, opts=None): def get_groups_by_member (self, member_dn, sattrs, opts=None):
"""Get a specific group's entry. Return as a dict of values. """Get all of the groups an object is explicitly a member of.
This does not include groups an entry may be a member of as a
result of recursion (being a group that is a member of another
group). In other words, this searches on 'member' and not
'memberof'.
Return as a dict of values.
Multi-valued fields are represented as lists. Multi-valued fields are represented as lists.
""" """
if not member_dn: if not member_dn: