- Add password generator method to controller.

This uses the random.SystemRandom() method to generate an 8-digit
  alphanumeric password.
- Add ajax call to usernew and useredit forms to generate a new password
- Add the prototype javascript library: http://www.prototypejs.org/
  prototype is distributed with the MIT license.
- Add a checkbox to toggle editing (and displaying) the password.
- Change usershow template to use same field labels as the edit and new forms.
This commit is contained in:
Kevin McCarthy 2007-08-14 09:40:13 -07:00
parent 10cbfe8787
commit 2ef4792fd1
7 changed files with 3370 additions and 14 deletions

View File

@ -1,3 +1,4 @@
import random
import cherrypy
import turbogears
from turbogears import controllers, expose, flash
@ -17,6 +18,8 @@ ipa.config.init_config()
user_new_form = forms.user.UserNewForm()
user_edit_form = forms.user.UserEditForm()
password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
client = ipa.ipaclient.IPAClient(True)
client.set_principal("test@FREEIPA.ORG")
@ -137,7 +140,7 @@ class Root(controllers.RootController):
"""Retrieve a single user for display"""
try:
user = client.get_user(uid)
return dict(user=user_to_hash(user))
return dict(user=user_to_hash(user), fields=forms.user.UserFields())
except xmlrpclib.Fault, f:
turbogears.flash("User show failed: " + str(f.faultString))
raise turbogears.redirect("/")
@ -154,6 +157,16 @@ class Root(controllers.RootController):
def userindex(self):
raise turbogears.redirect("/userlist")
@expose()
def generate_password(self):
password = ""
generator = random.SystemRandom()
for char in range(8):
index = generator.randint(0, len(password_chars) - 1)
password += password_chars[index]
return password
#########
# Group #

View File

@ -122,6 +122,10 @@ body {
text-align: right;
}
.small {
font-size: x-small;
}
#status_block {
margin: 0 auto 0.5em auto;
padding: 15px 10px 15px 55px;

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
<style type="text/css" media="screen">
@import "${tg.url('/static/css/style.css')}";
</style>
<script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/prototype.js')}"></script>
</head>
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">

View File

@ -19,17 +19,50 @@
</td>
</tr>
<!-- <tr>
<th>
<tr>
<th valign="top">
<label class="fieldlabel" for="${user.userPassword.field_id}"
py:content="user.userPassword.label" />
</th>
<td>
<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 id="password_text">********</span>
<input id="genpassword_button" type="button" value="Generate Password"
disabled="true"
onclick="new Ajax.Request('${tg.url('/generate_password')}',
{
method: 'get',
onSuccess: function(transport) {
document.getElementById('form_userPassword').value =
transport.responseText;
}
});" />
<br />
<input type="checkbox"
onclick="togglePassword(this);"><span class="small">edit</span></input>
<script type="text/javascript">
document.getElementById('form_userPassword').style.display='none';
function togglePassword(checkbox) {
passwordField = document.getElementById('form_userPassword');
passwordText = document.getElementById('password_text');
passwordButton = document.getElementById('genpassword_button');
if (checkbox.checked) {
passwordField.style.display='inline';
passwordText.style.display='none';
passwordButton.disabled=false;
} else {
passwordField.style.display='none';
passwordText.style.display='inline';
passwordButton.disabled=true;
}
}
</script>
</td>
</tr> -->
</tr>
<tr>
<th>

View File

@ -16,7 +16,7 @@
</td>
</tr>
<!-- <tr>
<tr>
<th>
<label class="fieldlabel" for="${user.userPassword.field_id}"
py:content="user.userPassword.label" />
@ -25,8 +25,18 @@
<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 =
transport.responseText;
}
});" />
</td>
</tr> -->
</tr>
<tr>
<th>

View File

@ -11,15 +11,21 @@
<div class="formsection">Account Details</div>
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
<tr>
<th>User ID:</th>
<th>
<label class="fieldlabel" py:content="fields.uid.label" />
</th>
<td>${user.get("uid")}</td>
</tr>
<tr>
<th>UID:</th>
<th>
<label class="fieldlabel" py:content="fields.uidNumber.label" />
</th>
<td>${user.get("uidNumber")}</td>
</tr>
<tr>
<th>GID:</th>
<th>
<label class="fieldlabel" py:content="fields.gidNumber.label" />
</th>
<td>${user.get("gidNumber")}</td>
</tr>
</table>
@ -27,19 +33,31 @@
<div class="formsection">Identity Details</div>
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
<tr>
<th>Full Name:</th>
<td>${user.get("givenName")} ${user.get("sn")}</td>
<th>
<label class="fieldlabel" py:content="fields.givenName.label" />
</th>
<td>${user.get("givenName")}</td>
</tr>
<tr>
<th>
<label class="fieldlabel" py:content="fields.sn.label" />
</th>
<td>${user.get("sn")}</td>
</tr>
</table>
<div class="formsection">Contact Details</div>
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
<tr>
<th>Email:</th>
<th>
<label class="fieldlabel" py:content="fields.mail.label" />
</th>
<td>${user.get("mail")}</td>
</tr>
<tr>
<th>Telephone:</th>
<th>
<label class="fieldlabel" py:content="fields.telephoneNumber.label" />
</th>
<td>${user.get("telephoneNumber")}</td>
</tr>
</table>