mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add update user to gui.
Fix fields to be lowercase in web gui (server now returns them lowercase). Fix ipaclient.py to refer to lowercase fields when adding a user. Fix user.getValue() to check isinstance(value,list) instead of value[0].
This commit is contained in:
@@ -59,18 +59,18 @@ class IPAClient:
|
||||
|
||||
# FIXME: This should be dynamic and can include just about anything
|
||||
# Let us add in some missing attributes
|
||||
if user.get('homeDirectory') is None:
|
||||
user['homeDirectory'] ='/home/%s' % user['uid']
|
||||
if user.get('homedirectory') is None:
|
||||
user['homedirectory'] ='/home/%s' % user['uid']
|
||||
if user.get('gecos') is None:
|
||||
user['gecos'] = user['uid']
|
||||
|
||||
# FIXME: This can be removed once the DS plugin is installed
|
||||
user['uidNumber'] ='501'
|
||||
user['uidnumber'] ='501'
|
||||
|
||||
# FIXME: What is the default group for users?
|
||||
user['gidNumber'] ='501'
|
||||
user['krbPrincipalName'] = "%s@%s" % (user['uid'], realm)
|
||||
user['cn'] = "%s %s" % (user['givenName'], user['sn'])
|
||||
user['gidnumber'] ='501'
|
||||
user['krbprincipalname'] = "%s@%s" % (user['uid'], realm)
|
||||
user['cn'] = "%s %s" % (user['givenname'], user['sn'])
|
||||
if user.get('gn'):
|
||||
del user['gn']
|
||||
|
||||
|
||||
@@ -58,9 +58,7 @@ class User:
|
||||
def getValue(self,name):
|
||||
"""Get the first value for the attribute named name"""
|
||||
value = self.data.get(name,[None])
|
||||
if (len(value) < 1):
|
||||
return value
|
||||
if isinstance(value[0],list) or isinstance(value[0],tuple):
|
||||
if isinstance(value,list) or isinstance(value,tuple):
|
||||
return value[0]
|
||||
else:
|
||||
return value
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import random
|
||||
from pickle import dumps, loads
|
||||
from base64 import b64encode, b64decode
|
||||
|
||||
import cherrypy
|
||||
import turbogears
|
||||
from turbogears import controllers, expose, flash
|
||||
@@ -8,6 +11,7 @@ from turbogears import error_handler
|
||||
# from model import *
|
||||
# import logging
|
||||
# log = logging.getLogger("ipagui.controllers")
|
||||
|
||||
import ipa.config
|
||||
import ipa.ipaclient
|
||||
import ipa.user
|
||||
@@ -28,20 +32,26 @@ def restrict_post():
|
||||
turbogears.flash("This method only accepts posts")
|
||||
raise turbogears.redirect("/")
|
||||
|
||||
def user_to_hash(user):
|
||||
return {
|
||||
'uid' : user.getValue('uid'),
|
||||
'givenName' : user.getValue('givenName'),
|
||||
'sn' : user.getValue('sn'),
|
||||
'mail' : user.getValue('mail'),
|
||||
'telephoneNumber': user.getValue('telephoneNumber'),
|
||||
'uidNumber' : user.getValue('uidNumber'),
|
||||
'gidNumber' : user.getValue('gidNumber'),
|
||||
'givenName_orig' : user.getValue('givenName'),
|
||||
'sn_orig' : user.getValue('sn'),
|
||||
'mail_orig' : user.getValue('mail'),
|
||||
'telephoneNumber_orig': user.getValue('telephoneNumber'),
|
||||
}
|
||||
def to_ldap_hash(orig):
|
||||
"""LDAP hashes expect all values to be a list. This method converts single
|
||||
entries to a list."""
|
||||
new={}
|
||||
for (k,v) in orig.iteritems():
|
||||
if v == None:
|
||||
continue
|
||||
if not isinstance(v, list) and k != 'dn':
|
||||
v = [v]
|
||||
new[k] = v
|
||||
|
||||
return new
|
||||
|
||||
def set_ldap_value(hash, key, value):
|
||||
"""Converts unicode strings to normal strings
|
||||
(because LDAP is choking on unicode strings"""
|
||||
if value != None:
|
||||
value = str(value)
|
||||
hash[key] = value
|
||||
|
||||
|
||||
class Root(controllers.RootController):
|
||||
|
||||
@@ -75,20 +85,14 @@ class Root(controllers.RootController):
|
||||
return dict(form=user_new_form, tg_template='ipagui.templates.usernew')
|
||||
|
||||
try:
|
||||
newuser = ipa.user.User(None)
|
||||
newuser.setValue('uid', kw['uid'])
|
||||
newuser.setValue('givenName', kw['givenName'])
|
||||
newuser.setValue('sn', kw['sn'])
|
||||
newuser.setValue('mail', kw['mail'])
|
||||
newuser.setValue('telephoneNumber', kw['telephoneNumber'])
|
||||
newuser2 = {
|
||||
'uid' : kw['uid'],
|
||||
'givenName' : kw['givenName'],
|
||||
'sn' : kw['sn'],
|
||||
'mail' : kw['mail'],
|
||||
'telephoneNumber': kw['telephoneNumber']
|
||||
}
|
||||
rv = client.add_user(newuser2)
|
||||
new_user = {}
|
||||
set_ldap_value(new_user, 'uid', kw.get('uid'))
|
||||
set_ldap_value(new_user, 'givenname', kw.get('givenname'))
|
||||
set_ldap_value(new_user, 'sn', kw.get('sn'))
|
||||
set_ldap_value(new_user, 'mail', kw.get('mail'))
|
||||
set_ldap_value(new_user, 'telephonenumber', kw.get('telephonenumber'))
|
||||
|
||||
rv = client.add_user(new_user)
|
||||
turbogears.flash("%s added!" % kw['uid'])
|
||||
raise turbogears.redirect('/usershow', uid=kw['uid'])
|
||||
except xmlrpclib.Fault, f:
|
||||
@@ -103,7 +107,11 @@ class Root(controllers.RootController):
|
||||
turbogears.flash("There was a problem with the form!")
|
||||
|
||||
user = client.get_user(uid)
|
||||
return dict(form=user_edit_form, user=user_to_hash(user))
|
||||
user_hash = user.toDict()
|
||||
# store a copy of the original user for the update later
|
||||
user_data = b64encode(dumps(user_hash))
|
||||
user_hash['user_orig'] = user_data
|
||||
return dict(form=user_edit_form, user=user_hash)
|
||||
|
||||
@expose()
|
||||
def userupdate(self, **kw):
|
||||
@@ -119,10 +127,22 @@ class Root(controllers.RootController):
|
||||
tg_template='ipagui.templates.useredit')
|
||||
|
||||
try:
|
||||
orig_user = loads(b64decode(kw.get('user_orig')))
|
||||
|
||||
new_user = dict(orig_user)
|
||||
set_ldap_value(new_user, 'givenname', kw.get('givenname'))
|
||||
set_ldap_value(new_user, 'sn', kw.get('sn'))
|
||||
set_ldap_value(new_user, 'mail', kw.get('mail'))
|
||||
set_ldap_value(new_user, 'telephonenumber', kw.get('telephonenumber'))
|
||||
|
||||
orig_user = to_ldap_hash(orig_user)
|
||||
new_user = to_ldap_hash(new_user)
|
||||
|
||||
rv = client.update_user(orig_user, new_user)
|
||||
turbogears.flash("%s updated!" % kw['uid'])
|
||||
raise turbogears.redirect('/usershow', uid=kw['uid'])
|
||||
except xmlrpclib.Fault, f:
|
||||
turbogears.flash("User add failed: " + str(f.faultString))
|
||||
turbogears.flash("User update failed: " + str(f.faultString))
|
||||
return dict(form=user_edit_form, user=kw,
|
||||
tg_template='ipagui.templates.useredit')
|
||||
|
||||
@@ -140,7 +160,7 @@ class Root(controllers.RootController):
|
||||
"""Retrieve a single user for display"""
|
||||
try:
|
||||
user = client.get_user(uid)
|
||||
return dict(user=user_to_hash(user), fields=forms.user.UserFields())
|
||||
return dict(user=user.toDict(), fields=forms.user.UserFields())
|
||||
except xmlrpclib.Fault, f:
|
||||
turbogears.flash("User show failed: " + str(f.faultString))
|
||||
raise turbogears.redirect("/")
|
||||
|
||||
@@ -3,36 +3,34 @@ from turbogears import validators, widgets
|
||||
|
||||
class UserFields():
|
||||
uid = widgets.TextField(name="uid", label="Login:")
|
||||
userPassword = widgets.TextField(name="userPassword", label="Password:")
|
||||
uidNumber = widgets.TextField(name="uidNumber", label="UID:")
|
||||
gidNumber = widgets.TextField(name="gidNumber", label="GID:")
|
||||
givenName = widgets.TextField(name="givenName", label="First name:")
|
||||
userpassword = widgets.TextField(name="userpassword", label="Password:")
|
||||
uidnumber = widgets.TextField(name="uidnumber", label="UID:")
|
||||
gidnumber = widgets.TextField(name="gidnumber", label="GID:")
|
||||
givenname = widgets.TextField(name="givenname", label="First name:")
|
||||
sn = widgets.TextField(name="sn", label="Last name:")
|
||||
mail = widgets.TextField(name="mail", label="E-mail address:")
|
||||
telephoneNumber = widgets.TextField(name="telephoneNumber", label="Phone:")
|
||||
telephonenumber = widgets.TextField(name="telephonenumber", label="Phone:")
|
||||
|
||||
uid.validator = validators.PlainText(not_empty=True)
|
||||
userPassword.validator = validators.String(not_empty=True)
|
||||
givenName.validator = validators.String(not_empty=True)
|
||||
userpassword.validator = validators.String(not_empty=True)
|
||||
givenname.validator = validators.String(not_empty=True)
|
||||
sn.validator = validators.String(not_empty=True)
|
||||
mail.validator = validators.Email(not_empty=True)
|
||||
# validators.PhoneNumber may be a bit too picky, requiring an area code
|
||||
telephoneNumber.validator = validators.PlainText(not_empty=True)
|
||||
telephonenumber.validator = validators.PlainText(not_empty=True)
|
||||
|
||||
uid_hidden = widgets.HiddenField(name="uid")
|
||||
uidNumber_hidden = widgets.HiddenField(name="uidNumber")
|
||||
gidNumber_hidden = widgets.HiddenField(name="gidNumber")
|
||||
givenName_orig = widgets.HiddenField(name="givenName_orig")
|
||||
sn_orig = widgets.HiddenField(name="sn_orig")
|
||||
mail_orig = widgets.HiddenField(name="mail_orig")
|
||||
telephoneNumber_orig = widgets.HiddenField(name="telephoneNumber_orig")
|
||||
uidnumber_hidden = widgets.HiddenField(name="uidnumber")
|
||||
gidnumber_hidden = widgets.HiddenField(name="gidnumber")
|
||||
|
||||
user_orig = widgets.HiddenField(name="user_orig")
|
||||
|
||||
|
||||
class UserNewForm(widgets.Form):
|
||||
params = ['user']
|
||||
|
||||
fields = [UserFields.uid, UserFields.givenName,
|
||||
UserFields.uidNumber, UserFields.gidNumber,
|
||||
fields = [UserFields.uid, UserFields.givenname,
|
||||
UserFields.uidnumber, UserFields.gidnumber,
|
||||
UserFields.sn, UserFields.mail]
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
@@ -51,10 +49,10 @@ class UserNewForm(widgets.Form):
|
||||
class UserEditForm(widgets.Form):
|
||||
params = ['user']
|
||||
|
||||
fields = [UserFields.givenName, UserFields.sn, UserFields.mail,
|
||||
UserFields.givenName_orig, UserFields.sn_orig, UserFields.mail_orig,
|
||||
UserFields.uid_hidden,
|
||||
UserFields.uidNumber_hidden, UserFields.gidNumber_hidden]
|
||||
fields = [UserFields.givenname, UserFields.sn, UserFields.mail,
|
||||
UserFields.uid_hidden, UserFields.user_orig,
|
||||
UserFields.uidnumber_hidden, UserFields.gidnumber_hidden,
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(UserEditForm,self).__init__(*args, **kw)
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
|
||||
<tr>
|
||||
<th valign="top">
|
||||
<label class="fieldlabel" for="${user.userPassword.field_id}"
|
||||
py:content="user.userPassword.label" />
|
||||
<label class="fieldlabel" for="${user.userpassword.field_id}"
|
||||
py:content="user.userpassword.label" />
|
||||
</th>
|
||||
<td valign="top">
|
||||
<span py:replace="user.userPassword.display(value_for(user.userPassword))" />
|
||||
<span py:if="tg.errors.get('userPassword')" class="fielderror"
|
||||
py:content="tg.errors.get('userPassword')" />
|
||||
<span py:replace="user.userpassword.display(value_for(user.userpassword))" />
|
||||
<span py:if="tg.errors.get('userpassword')" class="fielderror"
|
||||
py:content="tg.errors.get('userpassword')" />
|
||||
<span id="password_text">********</span>
|
||||
|
||||
<input id="genpassword_button" type="button" value="Generate Password"
|
||||
@@ -36,7 +36,7 @@
|
||||
{
|
||||
method: 'get',
|
||||
onSuccess: function(transport) {
|
||||
document.getElementById('form_userPassword').value =
|
||||
document.getElementById('form_userpassword').value =
|
||||
transport.responseText;
|
||||
}
|
||||
});" />
|
||||
@@ -44,10 +44,10 @@
|
||||
<input type="checkbox"
|
||||
onclick="togglePassword(this);"><span class="small">edit</span></input>
|
||||
<script type="text/javascript">
|
||||
document.getElementById('form_userPassword').style.display='none';
|
||||
document.getElementById('form_userpassword').style.display='none';
|
||||
|
||||
function togglePassword(checkbox) {
|
||||
passwordField = document.getElementById('form_userPassword');
|
||||
passwordField = document.getElementById('form_userpassword');
|
||||
passwordText = document.getElementById('password_text');
|
||||
passwordButton = document.getElementById('genpassword_button');
|
||||
if (checkbox.checked) {
|
||||
@@ -66,21 +66,21 @@
|
||||
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.uidNumber.field_id}"
|
||||
py:content="user.uidNumber.label" />
|
||||
<label class="fieldlabel" for="${user.uidnumber.field_id}"
|
||||
py:content="user.uidnumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
${value_for(user.uidNumber)}
|
||||
${value_for(user.uidnumber)}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.gidNumber.field_id}"
|
||||
py:content="user.gidNumber.label" />
|
||||
<label class="fieldlabel" for="${user.gidnumber.field_id}"
|
||||
py:content="user.gidnumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
${value_for(user.gidNumber)}
|
||||
${value_for(user.gidnumber)}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -89,13 +89,13 @@
|
||||
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.givenName.field_id}"
|
||||
py:content="user.givenName.label" />
|
||||
<label class="fieldlabel" for="${user.givenname.field_id}"
|
||||
py:content="user.givenname.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.givenName.display(value_for(user.givenName))" />
|
||||
<span py:if="tg.errors.get('givenName')" class="fielderror"
|
||||
py:content="tg.errors.get('givenName')" />
|
||||
<span py:replace="user.givenname.display(value_for(user.givenname))" />
|
||||
<span py:if="tg.errors.get('givenname')" class="fielderror"
|
||||
py:content="tg.errors.get('givenname')" />
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -128,13 +128,13 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.telephoneNumber.field_id}"
|
||||
py:content="user.telephoneNumber.label" />
|
||||
<label class="fieldlabel" for="${user.telephonenumber.field_id}"
|
||||
py:content="user.telephonenumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.telephoneNumber.display(value_for(user.telephoneNumber))" />
|
||||
<span py:if="tg.errors.get('telephoneNumber')" class="fielderror"
|
||||
py:content="tg.errors.get('telephoneNumber')" />
|
||||
<span py:replace="user.telephonenumber.display(value_for(user.telephonenumber))" />
|
||||
<span py:if="tg.errors.get('telephonenumber')" class="fielderror"
|
||||
py:content="tg.errors.get('telephonenumber')" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -18,20 +18,20 @@
|
||||
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.userPassword.field_id}"
|
||||
py:content="user.userPassword.label" />
|
||||
<label class="fieldlabel" for="${user.userpassword.field_id}"
|
||||
py:content="user.userpassword.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.userPassword.display(value_for(user.userPassword))" />
|
||||
<span py:if="tg.errors.get('userPassword')" class="fielderror"
|
||||
py:content="tg.errors.get('userPassword')" />
|
||||
<span py:replace="user.userpassword.display(value_for(user.userpassword))" />
|
||||
<span py:if="tg.errors.get('userpassword')" class="fielderror"
|
||||
py:content="tg.errors.get('userpassword')" />
|
||||
|
||||
<input type="button" value="Generate Password"
|
||||
onclick="new Ajax.Request('${tg.url('/generate_password')}',
|
||||
{
|
||||
method: 'get',
|
||||
onSuccess: function(transport) {
|
||||
document.getElementById('form_userPassword').value =
|
||||
document.getElementById('form_userpassword').value =
|
||||
transport.responseText;
|
||||
}
|
||||
});" />
|
||||
@@ -40,25 +40,25 @@
|
||||
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.uidNumber.field_id}"
|
||||
py:content="user.uidNumber.label" />
|
||||
<label class="fieldlabel" for="${user.uidnumber.field_id}"
|
||||
py:content="user.uidnumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.uidNumber.display(value_for(user.uidNumber))" />
|
||||
<span py:if="tg.errors.get('uidNumber')" class="fielderror"
|
||||
py:content="tg.errors.get('uidNumber')" />
|
||||
<span py:replace="user.uidnumber.display(value_for(user.uidnumber))" />
|
||||
<span py:if="tg.errors.get('uidnumber')" class="fielderror"
|
||||
py:content="tg.errors.get('uidnumber')" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.gidNumber.field_id}"
|
||||
py:content="user.gidNumber.label" />
|
||||
<label class="fieldlabel" for="${user.gidnumber.field_id}"
|
||||
py:content="user.gidnumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.gidNumber.display(value_for(user.gidNumber))" />
|
||||
<span py:if="tg.errors.get('gidNumber')" class="fielderror"
|
||||
py:content="tg.errors.get('gidNumber')" />
|
||||
<span py:replace="user.gidnumber.display(value_for(user.gidnumber))" />
|
||||
<span py:if="tg.errors.get('gidnumber')" class="fielderror"
|
||||
py:content="tg.errors.get('gidnumber')" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -67,13 +67,13 @@
|
||||
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.givenName.field_id}"
|
||||
py:content="user.givenName.label" />
|
||||
<label class="fieldlabel" for="${user.givenname.field_id}"
|
||||
py:content="user.givenname.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.givenName.display(value_for(user.givenName))" />
|
||||
<span py:if="tg.errors.get('givenName')" class="fielderror"
|
||||
py:content="tg.errors.get('givenName')" />
|
||||
<span py:replace="user.givenname.display(value_for(user.givenname))" />
|
||||
<span py:if="tg.errors.get('givenname')" class="fielderror"
|
||||
py:content="tg.errors.get('givenname')" />
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -106,13 +106,13 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" for="${user.telephoneNumber.field_id}"
|
||||
py:content="user.telephoneNumber.label" />
|
||||
<label class="fieldlabel" for="${user.telephonenumber.field_id}"
|
||||
py:content="user.telephonenumber.label" />
|
||||
</th>
|
||||
<td>
|
||||
<span py:replace="user.telephoneNumber.display(value_for(user.telephoneNumber))" />
|
||||
<span py:if="tg.errors.get('telephoneNumber')" class="fielderror"
|
||||
py:content="tg.errors.get('telephoneNumber')" />
|
||||
<span py:replace="user.telephonenumber.display(value_for(user.telephonenumber))" />
|
||||
<span py:if="tg.errors.get('telephonenumber')" class="fielderror"
|
||||
py:content="tg.errors.get('telephonenumber')" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -18,15 +18,15 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" py:content="fields.uidNumber.label" />
|
||||
<label class="fieldlabel" py:content="fields.uidnumber.label" />
|
||||
</th>
|
||||
<td>${user.get("uidNumber")}</td>
|
||||
<td>${user.get("uidnumber")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" py:content="fields.gidNumber.label" />
|
||||
<label class="fieldlabel" py:content="fields.gidnumber.label" />
|
||||
</th>
|
||||
<td>${user.get("gidNumber")}</td>
|
||||
<td>${user.get("gidnumber")}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" py:content="fields.givenName.label" />
|
||||
<label class="fieldlabel" py:content="fields.givenname.label" />
|
||||
</th>
|
||||
<td>${user.get("givenName")}</td>
|
||||
<td>${user.get("givenname")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
@@ -56,9 +56,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="fieldlabel" py:content="fields.telephoneNumber.label" />
|
||||
<label class="fieldlabel" py:content="fields.telephonenumber.label" />
|
||||
</th>
|
||||
<td>${user.get("telephoneNumber")}</td>
|
||||
<td>${user.get("telephonenumber")}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user