patch queue: group_users_use_dns.patch

This commit is contained in:
Kevin McCarthy 2007-09-27 11:27:33 -07:00
parent 679343594d
commit d95b47232d
7 changed files with 139 additions and 71 deletions

View File

@ -17,6 +17,7 @@ from turbogears import identity
import ipa.config
import ipa.ipaclient
import ipa.user
from ipa.entity import utf8_encode_values
import xmlrpclib
import forms.user
import forms.group
@ -534,12 +535,13 @@ class Root(controllers.RootController):
#
failed_adds = []
try:
uidadds = kw.get('uidadd')
if uidadds != None:
if not(isinstance(uidadds,list) or isinstance(uidadds,tuple)):
uidadds = [uidadds]
failed_adds = client.add_users_to_group(uidadds, kw.get('cn'))
kw['uidadd'] = failed_adds
dnadds = kw.get('dnadd')
if dnadds != None:
if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)):
dnadds = [dnadds]
failed_adds = client.add_members_to_group(
utf8_encode_values(dnadds), kw.get('cn'))
kw['dnadd'] = failed_adds
except ipaerror.IPAError, e:
turbogears.flash("User update failed: " + str(e))
return dict(form=group_edit_form, group=kw, members=member_dicts,
@ -550,12 +552,13 @@ class Root(controllers.RootController):
#
failed_dels = []
try:
uiddels = kw.get('uiddel')
if uiddels != None:
if not(isinstance(uiddels,list) or isinstance(uiddels,tuple)):
uiddels = [uiddels]
failed_dels = client.remove_users_from_group(uiddels, kw.get('cn'))
kw['uiddel'] = failed_dels
dndels = kw.get('dndel')
if dndels != None:
if not(isinstance(dndels,list) or isinstance(dndels,tuple)):
dndels = [dndels]
failed_dels = client.remove_members_from_group(
utf8_encode_values(dndels), kw.get('cn'))
kw['dndel'] = failed_dels
except ipaerror.IPAError, e:
turbogears.flash("User update failed: " + str(e))
return dict(form=group_edit_form, group=kw, members=member_dicts,

View File

@ -11,7 +11,7 @@ class GroupFields():
group_orig = widgets.HiddenField(name="group_orig")
member_data = widgets.HiddenField(name="member_data")
uid_to_cn_json = widgets.HiddenField(name="uid_to_cn_json")
dn_to_cn_json = widgets.HiddenField(name="dn_to_cn_json")
class GroupNewValidator(validators.Schema):
cn = validators.String(not_empty=True)
@ -48,7 +48,7 @@ class GroupEditForm(widgets.Form):
fields = [GroupFields.gidnumber, GroupFields.description,
GroupFields.cn_hidden, GroupFields.editprotected_hidden,
GroupFields.group_orig, GroupFields.member_data,
GroupFields.uid_to_cn_json]
GroupFields.dn_to_cn_json]
validator = GroupEditValidator()

View File

@ -0,0 +1,9 @@
import re
def javascript_string_escape(input):
"""Escapes the ' " and \ characters in a string so
it can be embedded inside a dynamically generated string."""
return re.sub(r'[\'\"\\]',
lambda match: "\\%s" % match.group(),
input)

View File

@ -0,0 +1,8 @@
/*
* Escapes the ' " and \ characters in a string, so
* it can be embedded inside a dynamically generated string.
*/
function jsStringEscape(input) {
return input.gsub(/(['"\\])/, function(match){ return "\\" + match[0]} );
}

View File

@ -3,22 +3,31 @@
<form action="${action}" name="${name}" method="${method}" class="tableform"
onsubmit="preSubmit()" >
<?python
from ipagui.helpers import ipahelper
?>
<?python searchurl = tg.url('/userlist_ajax') ?>
<script type="text/javascript">
// this is used for round-trip recontruction of the names.
// the hidden fields only contain uids.
var uid_to_cn_hash = new Hash();
// the hidden fields only contain dns.
var dn_to_cn_hash = new Hash();
// used to filter search results.
// records uids already in the group
// records dns already in the group
var member_hash = new Hash();
// used to prevent double adding
// records uid to be added
// records dns to be added
var added_hash = new Hash();
// Tracks the div ids that each member belongs to.
// Since dn's will contain illegal characters for div ids, this is used
// to map them to the correct div
var dn_to_member_div_id = new Hash();
function toggleProtectedFields(checkbox) {
var gidnumberField = $('form_gidnumber');
@ -38,32 +47,32 @@
Element.remove(effect.element);
}
function adduser(uid, cn) {
uid_to_cn_hash[uid] = cn;
function adduser(dn, cn) {
dn_to_cn_hash[dn] = cn;
if ((added_hash[uid] == 1) || (member_hash[uid] == 1)) {
if ((added_hash[dn] == 1) || (member_hash[dn] == 1)) {
return null;
}
added_hash[uid] = 1;
added_hash[dn] = 1;
var newdiv = document.createElement('div');
newdiv.appendChild(document.createTextNode(
cn.escapeHTML() + " (" + uid.escapeHTML() + ") "));
cn.escapeHTML() + " "));
var undolink = document.createElement('a');
undolink.setAttribute('href', '');
undolink.setAttribute('onclick',
'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' +
'added_hash.remove("' + uid + '");' +
'added_hash.remove("' + jsStringEscape(dn) + '");' +
'return false;');
undolink.appendChild(document.createTextNode("undo"));
newdiv.appendChild(undolink);
var uidInfo = document.createElement('input');
uidInfo.setAttribute('type', 'hidden');
uidInfo.setAttribute('name', 'uidadd');
uidInfo.setAttribute('value', uid);
newdiv.appendChild(uidInfo);
var dnInfo = document.createElement('input');
dnInfo.setAttribute('type', 'hidden');
dnInfo.setAttribute('name', 'dnadd');
dnInfo.setAttribute('value', dn);
newdiv.appendChild(dnInfo);
newdiv.style.display = 'none';
$('newmembers').appendChild(newdiv);
@ -71,8 +80,8 @@
return newdiv
}
function adduserHandler(element, uid, cn) {
var newdiv = adduser(uid, cn)
function adduserHandler(element, dn, cn) {
var newdiv = adduser(dn, cn)
if (newdiv != null) {
new Effect.Fade(Element.up(element));
new Effect.Appear(newdiv);
@ -80,27 +89,28 @@
}
}
function removeuser(uid, cn) {
uid_to_cn_hash[uid] = cn;
function removeuser(dn, cn) {
dn_to_cn_hash[dn] = cn;
var newdiv = document.createElement('div');
newdiv.appendChild(document.createTextNode(
cn.escapeHTML() + " (" + uid.escapeHTML() + ") "));
cn.escapeHTML() + " "));
orig_div_id = dn_to_member_div_id[dn];
var undolink = document.createElement('a');
undolink.setAttribute('href', '');
undolink.setAttribute('onclick',
'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' +
"new Effect.Appear($('member-" + uid + "'));" +
"new Effect.Appear($('" + orig_div_id + "'));" +
'return false;');
undolink.appendChild(document.createTextNode("undo"));
newdiv.appendChild(undolink);
var uidInfo = document.createElement('input');
uidInfo.setAttribute('type', 'hidden');
uidInfo.setAttribute('name', 'uiddel');
uidInfo.setAttribute('value', uid);
newdiv.appendChild(uidInfo);
var dnInfo = document.createElement('input');
dnInfo.setAttribute('type', 'hidden');
dnInfo.setAttribute('name', 'dndel');
dnInfo.setAttribute('value', dn);
newdiv.appendChild(dnInfo);
newdiv.style.display = 'none';
$('delmembers').appendChild(newdiv);
@ -108,8 +118,8 @@
return newdiv
}
function removeuserHandler(element, uid, cn) {
var newdiv = removeuser(uid, cn);
function removeuserHandler(element, dn, cn) {
var newdiv = removeuser(dn, cn);
new Effect.Fade(Element.up(element));
new Effect.Appear(newdiv);
/* Element.up(element).remove(); */
@ -141,8 +151,8 @@
}
function preSubmit() {
var json = uid_to_cn_hash.toJSON();
$('form_uid_to_cn_json').value = json;
var json = dn_to_cn_hash.toJSON();
$('form_dn_to_cn_json').value = json;
return true;
}
</script>
@ -207,20 +217,32 @@
</div>
<div>
<div py:for="member in members" id="member-${member.get('uid')}">
<?python div_counter = 1 ?>
<div py:for="member in members" id="member-${div_counter}">
<?python
member_dn = member.get('dn')
member_dn_esc = ipahelper.javascript_string_escape(member_dn)
member_uid = member.get('uid')
member_uid_esc = ipahelper.javascript_string_escape(member_uid)
member_name = "%s %s" % (member.get('givenname', ''),
member.get('sn', ''))
member_name_esc = ipahelper.javascript_string_escape(member_name)
?>
${member_name} (${member_uid})
<a href="#"
onclick="removeuserHandler(this, '${member_uid}', '${member_name}');
onclick="removeuserHandler(this, '${member_dn_esc}',
'${member_name_esc} (${member_uid_esc})');
return false;"
>remove</a>
<script type="text/javascript">
member_hash["${member_uid}"] = 1;
dn_to_member_div_id['${member_dn_esc}'] = "member-${div_counter}";
member_hash["${member_dn_esc}"] = 1;
</script>
<?python
div_counter = div_counter + 1
?>
</div>
</div>
@ -272,8 +294,8 @@
* This section restores the contents of the add and remove lists
* dynamically if we have to refresh the page
*/
if ($('form_uid_to_cn_json').value != "") {
uid_to_cn_hash = new Hash($('form_uid_to_cn_json').value.evalJSON());
if ($('form_dn_to_cn_json').value != "") {
dn_to_cn_hash = new Hash($('form_dn_to_cn_json').value.evalJSON());
}
if ($('form_editprotected').value != "") {
@ -283,30 +305,37 @@
</script>
<?python
uidadds = value.get('uidadd', [])
if not(isinstance(uidadds,list) or isinstance(uidadds,tuple)):
uidadds = [uidadds]
dnadds = value.get('dnadd', [])
if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)):
dnadds = [dnadds]
uiddels = value.get('uiddel', [])
if not(isinstance(uiddels,list) or isinstance(uiddels,tuple)):
uiddels = [uiddels]
dndels = value.get('dndel', [])
if not(isinstance(dndels,list) or isinstance(dndels,tuple)):
dndels = [dndels]
?>
<script py:for="uidadd in uidadds">
var uid = "${uidadd}";
var cn = uid_to_cn_hash[uid];
var newdiv = adduser(uid, cn);
<script py:for="dnadd in dnadds">
<?python
dnadd_esc = ipahelper.javascript_string_escape(dnadd)
?>
var dn = "${dnadd_esc}";
var cn = dn_to_cn_hash[dn];
var newdiv = adduser(dn, cn);
if (newdiv != null) {
newdiv.style.display = 'block';
}
</script>
<script py:for="uiddel in uiddels">
var uid = "${uiddel}";
var cn = uid_to_cn_hash[uid];
var newdiv = removeuser(uid, cn);
<script py:for="dndel in dndels">
<?python
dndel_esc = ipahelper.javascript_string_escape(dndel)
?>
var dn = "${dndel_esc}";
var cn = dn_to_cn_hash[dn];
var newdiv = removeuser(dn, cn);
newdiv.style.display = 'block';
$('member-' + uid).style.display = 'none';
orig_div_id = dn_to_member_div_id[dn]
$(orig_div_id).style.display = 'none';
</script>
</div>

View File

@ -11,6 +11,7 @@
</style>
<script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/prototype.js')}"></script>
<script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/scriptaculous.js?load=effects')}"></script>
<script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/ipautil.js')}"></script>
</head>
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">

View File

@ -1,24 +1,42 @@
<div xmlns:py="http://purl.org/kid/ns#">
<?python
from ipagui.helpers import ipahelper
?>
<div id="search-results-count">
</div>
<?python
criteria_esc = ipahelper.javascript_string_escape(uid)
?>
<script type="text/javascript">
search_string = "${uid}";
search_string = "${criteria_esc}";
results_counter = 0;
</script>
<?python search_div_counter = 1 ?>
<div py:if='(users != None) and (len(users) > 0)'>
<div py:for="user in users" id="search-${user.uid}">
<div py:for="user in users" id="search-${search_div_counter}">
<?python
user_dn_esc = ipahelper.javascript_string_escape(user.dn)
user_uid_esc = ipahelper.javascript_string_escape(user.uid)
user_cn_esc = ipahelper.javascript_string_escape(user.cn)
?>
<script type="text/javascript">
if ((added_hash["${user.uid}"] == 1) ||
(member_hash["${user.uid}"] == 1)) {
$("search-${user.uid}").style.display = 'none';
if ((added_hash["${user_dn_esc}"] == 1) ||
(member_hash["${user_dn_esc}"] == 1)) {
$("search-${search_div_counter}").style.display = 'none';
} else {
results_counter = results_counter + 1;
}
</script>
${user.givenName} ${user.sn} (${user.uid})
<a href=""
onclick="adduserHandler(this, '${user.uid}', '${user.cn}'); return false;"
<a href=""
onclick="adduserHandler(this, '${user_dn_esc}',
'${user_cn_esc} (${user_uid_esc})');
return false;"
>add</a>
<?python
search_div_counter = search_div_counter + 1
?>
</div>
</div>
<script type="text/javascript">