mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add group management to the user edit page.
Added a couple more API calls to make the inverse operations easier.
This commit is contained in:
parent
0cfccd0f8c
commit
dbf8c1aeb9
@ -266,6 +266,21 @@ class IPAClient:
|
|||||||
|
|
||||||
return self.transport.remove_users_from_group(user_uids, group_cn)
|
return self.transport.remove_users_from_group(user_uids, group_cn)
|
||||||
|
|
||||||
|
def add_groups_to_user(self, group_dns, user_dn):
|
||||||
|
"""Given a list of group dn's add them to the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not added.
|
||||||
|
"""
|
||||||
|
return self.transport.add_groups_to_user(group_dns, user_dn)
|
||||||
|
|
||||||
|
def remove_groups_from_user(self, group_dns, user_dn):
|
||||||
|
"""Given a list of group dn's remove them from the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not removed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.transport.remove_groups_from_user(group_dns, user_dn)
|
||||||
|
|
||||||
def update_group(self,group):
|
def update_group(self,group):
|
||||||
"""Update a group entry."""
|
"""Update a group entry."""
|
||||||
|
|
||||||
|
@ -441,6 +441,36 @@ class RPCClient:
|
|||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
|
def add_groups_to_user(self, group_dns, user_dn):
|
||||||
|
"""Given a list of group dn's add them to the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not added.
|
||||||
|
"""
|
||||||
|
server = self.setup_server()
|
||||||
|
try:
|
||||||
|
result = server.add_groups_to_user(group_dns, user_dn)
|
||||||
|
except xmlrpclib.Fault, fault:
|
||||||
|
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
||||||
|
except socket.error, (value, msg):
|
||||||
|
raise xmlrpclib.Fault(value, msg)
|
||||||
|
|
||||||
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
|
def remove_groups_from_user(self, group_dns, user_dn):
|
||||||
|
"""Given a list of group dn's remove them from the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not removed.
|
||||||
|
"""
|
||||||
|
server = self.setup_server()
|
||||||
|
try:
|
||||||
|
result = server.remove_groups_from_user(group_dns, user_dn)
|
||||||
|
except xmlrpclib.Fault, fault:
|
||||||
|
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
||||||
|
except socket.error, (value, msg):
|
||||||
|
raise xmlrpclib.Fault(value, msg)
|
||||||
|
|
||||||
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
def update_group(self,oldgroup,newgroup):
|
def update_group(self,oldgroup,newgroup):
|
||||||
"""Update an existing group. oldgroup and newgroup are dicts of attributes"""
|
"""Update an existing group. oldgroup and newgroup are dicts of attributes"""
|
||||||
server = self.setup_server()
|
server = self.setup_server()
|
||||||
|
@ -79,6 +79,15 @@ def sort_group_member(a, b):
|
|||||||
else:
|
else:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def sort_by_cn(a, b):
|
||||||
|
"""Comparator function used for sorting groups."""
|
||||||
|
if a.get('cn', '') == b.get('cn', ''):
|
||||||
|
return 0
|
||||||
|
elif a.get('cn', '') < b.get('cn', ''):
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
class Root(controllers.RootController):
|
class Root(controllers.RootController):
|
||||||
|
|
||||||
@expose(template="ipagui.templates.welcome")
|
@expose(template="ipagui.templates.welcome")
|
||||||
@ -144,6 +153,28 @@ class Root(controllers.RootController):
|
|||||||
turbogears.flash("User add failed: " + str(e))
|
turbogears.flash("User add failed: " + str(e))
|
||||||
return dict(form=user_new_form, tg_template='ipagui.templates.usernew')
|
return dict(form=user_new_form, tg_template='ipagui.templates.usernew')
|
||||||
|
|
||||||
|
@expose("ipagui.templates.dynamiceditsearch")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
|
def useredit_search(self, **kw):
|
||||||
|
"""Searches for groups and displays list of results in a table.
|
||||||
|
This method is used for the ajax search on the user edit page."""
|
||||||
|
client.set_krbccache(os.environ["KRB5CCNAME"])
|
||||||
|
groups = []
|
||||||
|
counter = 0
|
||||||
|
searchlimit = 100
|
||||||
|
criteria = kw.get('criteria')
|
||||||
|
if criteria != None and len(criteria) > 0:
|
||||||
|
try:
|
||||||
|
groups = client.find_groups(criteria.encode('utf-8'), None,
|
||||||
|
searchlimit)
|
||||||
|
groups_counter = groups[0]
|
||||||
|
groups = groups[1:]
|
||||||
|
except ipaerror.IPAError, e:
|
||||||
|
turbogears.flash("search failed: " + str(e))
|
||||||
|
|
||||||
|
return dict(users=None, groups=groups, criteria=criteria,
|
||||||
|
counter=groups_counter)
|
||||||
|
|
||||||
|
|
||||||
@expose("ipagui.templates.useredit")
|
@expose("ipagui.templates.useredit")
|
||||||
@identity.require(identity.not_anonymous())
|
@identity.require(identity.not_anonymous())
|
||||||
@ -152,18 +183,26 @@ class Root(controllers.RootController):
|
|||||||
if tg_errors:
|
if tg_errors:
|
||||||
turbogears.flash("There was a problem with the form!")
|
turbogears.flash("There was a problem with the form!")
|
||||||
|
|
||||||
try:
|
|
||||||
client.set_krbccache(os.environ["KRB5CCNAME"])
|
client.set_krbccache(os.environ["KRB5CCNAME"])
|
||||||
|
try:
|
||||||
user = client.get_user_by_uid(uid, user_fields)
|
user = client.get_user_by_uid(uid, user_fields)
|
||||||
user_dict = user.toDict()
|
user_dict = user.toDict()
|
||||||
# Edit shouldn't fill in the password field.
|
# Edit shouldn't fill in the password field.
|
||||||
if user_dict.has_key('userpassword'):
|
if user_dict.has_key('userpassword'):
|
||||||
del(user_dict['userpassword'])
|
del(user_dict['userpassword'])
|
||||||
|
|
||||||
|
user_groups = client.get_groups_by_member(user.dn, ['dn', 'cn'])
|
||||||
|
user_groups_dicts = map(lambda group: group.toDict(), user_groups)
|
||||||
|
user_groups_dicts.sort(sort_by_cn)
|
||||||
|
user_groups_data = b64encode(dumps(user_groups_dicts))
|
||||||
|
|
||||||
# store a copy of the original user for the update later
|
# store a copy of the original user for the update later
|
||||||
user_data = b64encode(dumps(user_dict))
|
user_data = b64encode(dumps(user_dict))
|
||||||
user_dict['user_orig'] = user_data
|
user_dict['user_orig'] = user_data
|
||||||
return dict(form=user_edit_form, user=user_dict)
|
user_dict['user_groups_data'] = user_groups_data
|
||||||
|
|
||||||
|
return dict(form=user_edit_form, user=user_dict,
|
||||||
|
user_groups=user_groups_dicts)
|
||||||
except ipaerror.IPAError, e:
|
except ipaerror.IPAError, e:
|
||||||
turbogears.flash("User edit failed: " + str(e))
|
turbogears.flash("User edit failed: " + str(e))
|
||||||
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
||||||
@ -178,12 +217,20 @@ class Root(controllers.RootController):
|
|||||||
turbogears.flash("Edit user cancelled")
|
turbogears.flash("Edit user cancelled")
|
||||||
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
||||||
|
|
||||||
|
# Decode the group data, in case we need to round trip
|
||||||
|
user_groups_dicts = loads(b64decode(kw.get('user_groups_data')))
|
||||||
|
|
||||||
tg_errors, kw = self.userupdatevalidate(**kw)
|
tg_errors, kw = self.userupdatevalidate(**kw)
|
||||||
if tg_errors:
|
if tg_errors:
|
||||||
return dict(form=user_edit_form, user=kw,
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
tg_template='ipagui.templates.useredit')
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
password_change = False
|
password_change = False
|
||||||
|
|
||||||
|
#
|
||||||
|
# Update the user itself
|
||||||
|
#
|
||||||
try:
|
try:
|
||||||
orig_user_dict = loads(b64decode(kw.get('user_orig')))
|
orig_user_dict = loads(b64decode(kw.get('user_orig')))
|
||||||
|
|
||||||
@ -210,22 +257,77 @@ class Root(controllers.RootController):
|
|||||||
new_user.getValue('sn')))
|
new_user.getValue('sn')))
|
||||||
|
|
||||||
rv = client.update_user(new_user)
|
rv = client.update_user(new_user)
|
||||||
|
#
|
||||||
|
# If the user update succeeds, but below operations fail, we
|
||||||
|
# need to make sure a subsequent submit doesn't try to update
|
||||||
|
# the user again.
|
||||||
|
#
|
||||||
|
kw['user_orig'] = b64encode(dumps(new_user.toDict()))
|
||||||
except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST), e:
|
except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST), e:
|
||||||
if not password_change:
|
# could be a password change
|
||||||
turbogears.flash("User update failed: " + str(e))
|
# could be groups change
|
||||||
return dict(form=user_edit_form, user=kw,
|
# too much work to figure out unless someone really screams
|
||||||
tg_template='ipagui.templates.useredit')
|
pass
|
||||||
except ipaerror.IPAError, e:
|
except ipaerror.IPAError, e:
|
||||||
turbogears.flash("User update failed: " + str(e))
|
turbogears.flash("User update failed: " + str(e))
|
||||||
return dict(form=user_edit_form, user=kw,
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
tg_template='ipagui.templates.useredit')
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Password change
|
||||||
|
#
|
||||||
try:
|
try:
|
||||||
if password_change:
|
if password_change:
|
||||||
rv = client.modifyPassword(kw['uid'], "", kw.get('userpassword'))
|
rv = client.modifyPassword(kw['uid'], "", kw.get('userpassword'))
|
||||||
except ipaerror.IPAError, e:
|
except ipaerror.IPAError, e:
|
||||||
turbogears.flash("User password change failed: " + str(e))
|
turbogears.flash("User password change failed: " + str(e))
|
||||||
return dict(form=user_edit_form, user=kw,
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add groups
|
||||||
|
#
|
||||||
|
failed_adds = []
|
||||||
|
try:
|
||||||
|
dnadds = kw.get('dnadd')
|
||||||
|
if dnadds != None:
|
||||||
|
if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)):
|
||||||
|
dnadds = [dnadds]
|
||||||
|
failed_adds = client.add_groups_to_user(
|
||||||
|
utf8_encode_values(dnadds), new_user.dn)
|
||||||
|
kw['dnadd'] = failed_adds
|
||||||
|
except ipaerror.IPAError, e:
|
||||||
|
turbogears.flash("Group update failed: " + str(e))
|
||||||
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove groups
|
||||||
|
#
|
||||||
|
failed_dels = []
|
||||||
|
try:
|
||||||
|
dndels = kw.get('dndel')
|
||||||
|
if dndels != None:
|
||||||
|
if not(isinstance(dndels,list) or isinstance(dndels,tuple)):
|
||||||
|
dndels = [dndels]
|
||||||
|
failed_dels = client.remove_groups_from_user(
|
||||||
|
utf8_encode_values(dndels), new_user.dn)
|
||||||
|
kw['dndel'] = failed_dels
|
||||||
|
except ipaerror.IPAError, e:
|
||||||
|
turbogears.flash("Group update failed: " + str(e))
|
||||||
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
|
if (len(failed_adds) > 0) or (len(failed_dels) > 0):
|
||||||
|
message = "There was an error updating groups.<br />"
|
||||||
|
message += "Failures have been preserved in the add/remove lists."
|
||||||
|
turbogears.flash(message)
|
||||||
|
return dict(form=user_edit_form, user=kw,
|
||||||
|
user_groups=user_groups_dicts,
|
||||||
tg_template='ipagui.templates.useredit')
|
tg_template='ipagui.templates.useredit')
|
||||||
|
|
||||||
turbogears.flash("%s updated!" % kw['uid'])
|
turbogears.flash("%s updated!" % kw['uid'])
|
||||||
|
@ -24,6 +24,8 @@ class UserFields():
|
|||||||
editprotected_hidden = widgets.HiddenField(name="editprotected")
|
editprotected_hidden = widgets.HiddenField(name="editprotected")
|
||||||
|
|
||||||
user_orig = widgets.HiddenField(name="user_orig")
|
user_orig = widgets.HiddenField(name="user_orig")
|
||||||
|
user_groups_data = widgets.HiddenField(name="user_groups_data")
|
||||||
|
dn_to_info_json = widgets.HiddenField(name="dn_to_info_json")
|
||||||
|
|
||||||
class UserNewValidator(validators.Schema):
|
class UserNewValidator(validators.Schema):
|
||||||
uid = validators.PlainText(not_empty=True)
|
uid = validators.PlainText(not_empty=True)
|
||||||
@ -88,6 +90,8 @@ class UserEditForm(widgets.Form):
|
|||||||
UserFields.uidnumber, UserFields.gidnumber,
|
UserFields.uidnumber, UserFields.gidnumber,
|
||||||
UserFields.krbPasswordExpiration_hidden,
|
UserFields.krbPasswordExpiration_hidden,
|
||||||
UserFields.editprotected_hidden,
|
UserFields.editprotected_hidden,
|
||||||
|
UserFields.user_groups_data,
|
||||||
|
UserFields.dn_to_info_json,
|
||||||
]
|
]
|
||||||
|
|
||||||
validator = UserEditValidator()
|
validator = UserEditValidator()
|
||||||
|
@ -35,6 +35,6 @@ else:
|
|||||||
Password has expired
|
Password has expired
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${form.display(action="userupdate", value=user)}
|
${form.display(action="userupdate", value=user, user_groups=user_groups)}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
<div xmlns:py="http://purl.org/kid/ns#"
|
<div xmlns:py="http://purl.org/kid/ns#"
|
||||||
class="simpleroster">
|
class="simpleroster">
|
||||||
<form action="${action}" name="${name}" method="${method}" class="tableform">
|
<form action="${action}" name="${name}" method="${method}" class="tableform"
|
||||||
|
onsubmit="preSubmit()">
|
||||||
|
|
||||||
|
<?python
|
||||||
|
from ipagui.helpers import ipahelper
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript" charset="utf-8"
|
||||||
|
src="${tg.url('/static/javascript/dynamicedit.js')}"></script>
|
||||||
|
|
||||||
|
<?python searchurl = tg.url('/useredit_search') ?>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function toggleProtectedFields(checkbox) {
|
function toggleProtectedFields(checkbox) {
|
||||||
@ -22,6 +32,40 @@
|
|||||||
$('form_editprotected').value = '';
|
$('form_editprotected').value = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function enterDoSearch(e) {
|
||||||
|
var keyPressed;
|
||||||
|
if (window.event) {
|
||||||
|
keyPressed = window.event.keyCode;
|
||||||
|
} else {
|
||||||
|
keyPressed = e.which;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyPressed == 13) {
|
||||||
|
return doSearch();
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSearch() {
|
||||||
|
$('searchresults').update("Searching...");
|
||||||
|
new Ajax.Updater('searchresults',
|
||||||
|
'${searchurl}',
|
||||||
|
{ asynchronous:true,
|
||||||
|
parameters: { criteria: $('criteria').value },
|
||||||
|
evalScripts: true });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// override dynamicedit.js version
|
||||||
|
// we don't need to show [group] nor italize groups
|
||||||
|
function renderMemberInfo(newdiv, info) {
|
||||||
|
if (info.type == "group") {
|
||||||
|
newdiv.appendChild(document.createTextNode(
|
||||||
|
info.name.escapeHTML() + " "));
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@ -213,6 +257,81 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="formsection">Groups</div>
|
||||||
|
|
||||||
|
<div class="floatlist">
|
||||||
|
<div class="floatheader">To Remove:</div>
|
||||||
|
<div id="delmembers">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<?python div_counter = 1 ?>
|
||||||
|
<div py:for="group in user_groups" id="member-${div_counter}">
|
||||||
|
<?python
|
||||||
|
group_dn = group.get('dn')
|
||||||
|
group_dn_esc = ipahelper.javascript_string_escape(group_dn)
|
||||||
|
|
||||||
|
group_name = group.get('cn')
|
||||||
|
group_descr = "[group]"
|
||||||
|
group_type = "group"
|
||||||
|
|
||||||
|
group_name_esc = ipahelper.javascript_string_escape(group_name)
|
||||||
|
group_descr_esc = ipahelper.javascript_string_escape(group_descr)
|
||||||
|
group_type_esc = ipahelper.javascript_string_escape(group_type)
|
||||||
|
?>
|
||||||
|
<span id="member-info-${div_counter}"></span>
|
||||||
|
<script type="text/javascript">
|
||||||
|
renderMemberInfo($('member-info-${div_counter}'),
|
||||||
|
new MemberDisplayInfo('${group_name_esc}',
|
||||||
|
'${group_descr_esc}',
|
||||||
|
'${group_type_esc}'));
|
||||||
|
</script>
|
||||||
|
<a href="#"
|
||||||
|
onclick="removememberHandler(this, '${group_dn_esc}',
|
||||||
|
new MemberDisplayInfo('${group_name_esc}',
|
||||||
|
'${group_descr_esc}',
|
||||||
|
'${group_type_esc}'));
|
||||||
|
return false;"
|
||||||
|
>remove</a>
|
||||||
|
<script type="text/javascript">
|
||||||
|
dn_to_member_div_id['${group_dn_esc}'] = "member-${div_counter}";
|
||||||
|
member_hash["${group_dn_esc}"] = 1;
|
||||||
|
</script>
|
||||||
|
<?python
|
||||||
|
div_counter = div_counter + 1
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="clear:both">
|
||||||
|
<div class="formsection">Add Groups</div>
|
||||||
|
|
||||||
|
<div class="floatlist">
|
||||||
|
<div class="floatheader">To Add:</div>
|
||||||
|
<div id="newmembers">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div id="search">
|
||||||
|
<input id="criteria" type="text" name="criteria"
|
||||||
|
onkeypress="return enterDoSearch(event);" />
|
||||||
|
<input type="button" value="Find"
|
||||||
|
onclick="return doSearch();"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div id="searchresults">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
|
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
@ -232,9 +351,52 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
/*
|
||||||
|
* This section restores the contents of the add and remove lists
|
||||||
|
* dynamically if we have to refresh the page
|
||||||
|
*/
|
||||||
|
if ($('form_dn_to_info_json').value != "") {
|
||||||
|
dn_to_info_hash = new Hash($('form_dn_to_info_json').value.evalJSON());
|
||||||
|
}
|
||||||
|
|
||||||
if ($('form_editprotected').value != "") {
|
if ($('form_editprotected').value != "") {
|
||||||
$('toggleprotected_checkbox').checked = true;
|
$('toggleprotected_checkbox').checked = true;
|
||||||
toggleProtectedFields($('toggleprotected_checkbox'));
|
toggleProtectedFields($('toggleprotected_checkbox'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<?python
|
||||||
|
dnadds = value.get('dnadd', [])
|
||||||
|
if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)):
|
||||||
|
dnadds = [dnadds]
|
||||||
|
|
||||||
|
dndels = value.get('dndel', [])
|
||||||
|
if not(isinstance(dndels,list) or isinstance(dndels,tuple)):
|
||||||
|
dndels = [dndels]
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script py:for="dnadd in dnadds">
|
||||||
|
<?python
|
||||||
|
dnadd_esc = ipahelper.javascript_string_escape(dnadd)
|
||||||
|
?>
|
||||||
|
var dn = "${dnadd_esc}";
|
||||||
|
var info = dn_to_info_hash[dn];
|
||||||
|
var newdiv = addmember(dn, info);
|
||||||
|
if (newdiv != null) {
|
||||||
|
newdiv.style.display = 'block';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script py:for="dndel in dndels">
|
||||||
|
<?python
|
||||||
|
dndel_esc = ipahelper.javascript_string_escape(dndel)
|
||||||
|
?>
|
||||||
|
var dn = "${dndel_esc}";
|
||||||
|
var info = dn_to_info_hash[dn];
|
||||||
|
var newdiv = removemember(dn, info);
|
||||||
|
newdiv.style.display = 'block';
|
||||||
|
orig_div_id = dn_to_member_div_id[dn]
|
||||||
|
$(orig_div_id).style.display = 'none';
|
||||||
|
</script>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -899,6 +899,56 @@ class IPAServer:
|
|||||||
|
|
||||||
return failed
|
return failed
|
||||||
|
|
||||||
|
def add_groups_to_user(self, group_dns, user_dn, opts=None):
|
||||||
|
"""Given a list of group dn's add them to the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not added.
|
||||||
|
"""
|
||||||
|
|
||||||
|
failed = []
|
||||||
|
|
||||||
|
if (isinstance(group_dns, str)):
|
||||||
|
group_dns = [group_dns]
|
||||||
|
|
||||||
|
for group_dn in group_dns:
|
||||||
|
# TODO - change add_member_to_group to take a group_dn
|
||||||
|
try:
|
||||||
|
group = self.get_group_by_dn(group_dn, ['cn'], opts)
|
||||||
|
self.add_member_to_group(user_dn, group.get('cn'), opts)
|
||||||
|
except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
|
||||||
|
# User is already in the group
|
||||||
|
failed.append(group_dn)
|
||||||
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
|
# User or the group does not exist
|
||||||
|
failed.append(group_dn)
|
||||||
|
|
||||||
|
return failed
|
||||||
|
|
||||||
|
def remove_groups_from_user(self, group_dns, user_dn, opts=None):
|
||||||
|
"""Given a list of group dn's remove them from the user.
|
||||||
|
|
||||||
|
Returns a list of the group dns that were not removed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
failed = []
|
||||||
|
|
||||||
|
if (isinstance(group_dns, str)):
|
||||||
|
group_dns = [group_dns]
|
||||||
|
|
||||||
|
for group_dn in group_dns:
|
||||||
|
# TODO - change remove_member_from_group to take a group_dn
|
||||||
|
try:
|
||||||
|
group = self.get_group_by_dn(group_dn, ['cn'], opts)
|
||||||
|
self.remove_member_from_group(user_dn, group.get('cn'), opts)
|
||||||
|
except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
|
||||||
|
# User is not in the group
|
||||||
|
failed.append(group_dn)
|
||||||
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
|
# User or the group does not exist
|
||||||
|
failed.append(group_dn)
|
||||||
|
|
||||||
|
return failed
|
||||||
|
|
||||||
def update_group (self, oldgroup, newgroup, opts=None):
|
def update_group (self, oldgroup, newgroup, opts=None):
|
||||||
"""Update a group in LDAP"""
|
"""Update a group in LDAP"""
|
||||||
return self.__update_entry(oldgroup, newgroup, opts)
|
return self.__update_entry(oldgroup, newgroup, opts)
|
||||||
|
@ -342,6 +342,8 @@ def handler(req, profiling=False):
|
|||||||
h.register_function(f.add_group_to_group)
|
h.register_function(f.add_group_to_group)
|
||||||
h.register_function(f.remove_user_from_group)
|
h.register_function(f.remove_user_from_group)
|
||||||
h.register_function(f.remove_users_from_group)
|
h.register_function(f.remove_users_from_group)
|
||||||
|
h.register_function(f.add_groups_to_user)
|
||||||
|
h.register_function(f.remove_groups_from_user)
|
||||||
h.register_function(f.update_group)
|
h.register_function(f.update_group)
|
||||||
h.register_function(f.delete_group)
|
h.register_function(f.delete_group)
|
||||||
h.handle_request(req)
|
h.handle_request(req)
|
||||||
|
Loading…
Reference in New Issue
Block a user