Merged [4705] from adam@nostrum.com:

Adding self-management page for user profile information
 - Legacy-Id: 4714
Note: SVN reference [4705] has been migrated to Git commit 1502efba76
This commit is contained in:
Henrik Levkowetz 2012-07-29 00:04:08 +00:00
parent 4730c1514f
commit 0b1158491f
6 changed files with 304 additions and 14 deletions

View file

@ -3,6 +3,7 @@ import hashlib
import subprocess
from django import forms
from django.forms import ModelForm
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
@ -155,3 +156,61 @@ class PasswordForm(forms.Form):
class TestEmailForm(forms.Form):
email = forms.EmailField(required=False)
class PersonForm(ModelForm):
request = None
new_emails = []
class Meta:
from ietf.person.models import Person
model = Person
exclude = ('time','user')
def confirm_address(self,email):
person = self.instance
domain = Site.objects.get_current().domain
user = person.user
if len(email) == 0:
return
subject = 'Confirm email address for %s' % person.name
from_email = settings.DEFAULT_FROM_EMAIL
to_email = email
today = datetime.date.today().strftime('%Y%m%d')
auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, user)).hexdigest()
context = {
'today': today,
'domain': domain,
'user': user,
'email': email,
'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK,
'auth': auth,
}
send_mail(self.request, to_email, from_email, subject, 'registration/add_email_email.txt', context)
def save(self, force_insert=False, force_update=False, commit=True):
from ietf.group.models import Role
m = super(PersonForm, self).save(commit=False)
self.new_emails = [v for k,v in self.data.items() if k[:10] == u'new_email_' and u'@' in v]
for email in self.new_emails:
self.confirm_address(email)
# Process email active flags
emails = Email.objects.filter(person=self.instance)
for email in emails:
email.active = self.data.__contains__(email.address)
if commit:
email.save()
# Process email for roles
for k,v in self.data.items():
if k[:11] == u'role_email_':
role = Role.objects.get(id=k[11:])
email = Email.objects.get(address = v)
role.email = email
if commit:
role.save()
if commit:
m.save()
return m

View file

@ -17,5 +17,6 @@ urlpatterns += patterns('ietf.ietfauth.views',
url(r'^confirm/(?P<username>[\w.@+-]+)/(?P<date>[\d]+)/(?P<realm>[\w]+)/(?P<registration_hash>[a-f0-9]+)/$', 'confirm_account', name='confirm_account'),
url(r'^reset/$', 'password_reset_view', name='password_reset'),
url(r'^reset/confirm/(?P<username>[\w.@+-]+)/(?P<date>[\d]+)/(?P<realm>[\w]+)/(?P<reset_hash>[a-f0-9]+)/$', 'confirm_password_reset', name='confirm_password_reset'),
url(r'^add_email/confirm/(?P<username>[\w.@+-]+)/(?P<date>[\d]+)/(?P<email>[\w.@+-]+)/(?P<hash>[a-f0-9]+)/$', 'confirm_new_email', name='confirm_new_email'),
url(r'^ajax/check_username/$', 'ajax_check_username', name='ajax_check_username'),
)

View file

@ -79,24 +79,87 @@ def ietf_loggedin(request):
@login_required
def profile(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.person.models import Person
from ietf.group.models import Role
from ietf.person.models import Person, Email, Alias
from ietf.group.models import Role
from ietf.ietfauth.forms import PersonForm
roles = []
person = None
roles = []
person = None
try:
person = request.user.get_profile()
except Person.DoesNotExist:
pass
if request.method == 'POST':
form = PersonForm(request.POST, instance=person)
success = False
new_emails = None
error = None
if form.is_valid():
try:
form.save()
success = True
new_emails = form.new_emails
except Exception as e:
error = e
return render_to_response('registration/confirm_profile_update.html',
{ 'success': success, 'new_emails': new_emails, 'error': error} ,
context_instance=RequestContext(request))
else:
roles = Role.objects.filter(person=person).order_by('name__name','group__name')
emails = Email.objects.filter(person=person).order_by('-active','-time')
aliases = Alias.objects.filter(person=person)
person_form = PersonForm(instance=person)
return render_to_response('registration/edit_profile.html',
{ 'user': request.user, 'emails': emails, 'person': person,
'roles': roles, 'person_form': person_form } ,
context_instance=RequestContext(request))
def confirm_new_email(request, username, date, email, hash):
from ietf.person.models import Person, Email, Alias
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
valid = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, date, email, username)).hexdigest() == hash
if not valid:
raise Http404
request_date = datetime.date(int(date[:4]), int(date[4:6]), int(date[6:]))
if datetime.date.today() > (request_date + datetime.timedelta(days=settings.DAYS_TO_EXPIRE_REGISTRATION_LINK)):
raise Http404
success = False
person = None
error = None
new_email = None
try:
# First, check whether this address exists (to give a more sensible
# error when a duplicate is created).
existing_email = Email.objects.get(address=email)
print existing_email
existing_person = existing_email.person
print existing_person
error = {'address': ["Email address '%s' is already assigned to user '%s' (%s)" %
(email, existing_person.user, existing_person.name)]}
except Exception:
try:
person = request.user.get_profile()
roles = Role.objects.filter(person=person)
person = Person.objects.get(user__username=username)
new_email = Email(address=email, person=person, active=True, time=datetime.datetime.now())
new_email.full_clean()
new_email.save()
success = True
except Person.DoesNotExist:
pass
error = {'person': ["No such user: %s" % (username)]}
except ValidationError as e:
error = e.message_dict
return render_to_response('registration/profileREDESIGN.html',
dict(roles=roles,
person=person),
context_instance=RequestContext(request))
return render_to_response('registration/confirm_new_email.html',
{ 'username': username, 'email': email,
'success': success, 'error': error,
'record': new_email},
context_instance=RequestContext(request))
return render_to_response('registration/profile.html', context_instance=RequestContext(request))
def create_account(request):
success = False

View file

@ -37,7 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% load ietf_filters community_tags %}
<ul>
<li class="sect first">Accounts</li>
<li><a href="{% url account_index %}">New Account</a></li>
<li><a href="{% url account_index %}">{% if request.user.is_authenticated %}Manage Account{% else %}New Account{% endif %}</a></li>
{% if user|in_group:"Area_Director" %}
<li class="sect first">AD Dashboard</li>
<li><a href="{% url doc_search_by_ad name=user.get_profile.person.full_name_as_key %}">My Documents</a></li>

View file

@ -0,0 +1,20 @@
{% autoescape off %}
Hello,
We have received a request to add the email address '{{ email }}'
to the user account '{{ user }}' at '{{ domain }}'.
If you requested this change, please confirm that this is your email
address by clicking on following link:
http://{{ domain }}{% url confirm_new_email user today email auth %}
This link will expire in {{ expire }} days.
If you did not request this change, you may safely ignore this email,
as no actions have been taken.
Best regards,
The datatracker login manager service
(for the IETF Secretariat)
{% endautoescape %}

View file

@ -0,0 +1,147 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "base.html" %}
{% block morecss %}
table.userProfile {
text-align: left;
}
th {
vertical-align: top;
text-align: right !important;
font-weight: bold !important;
}
.active {
color: #008000;
color: #008000;
}
.inactive {
color: #800000;
text-decoration: line-through;
}
.even {
background-color: #e0e0ff;
}
.odd {
background-color: #ffffff;
}
{% endblock %}
{% block pagehead %}
<script type="text/javascript">
function init_form()
{
// Make sure emails are styled correctly
var inputs = document.getElementsByTagName("input");
for (var input in inputs)
{
if (inputs[input].type=="checkbox")
{
style_email(inputs[input]);
}
}
}
function style_email(e)
{
var span = document.getElementById(e.id.replace("controller_","span_"));
if (!span) { return; }
if (e.checked)
{
span.className = 'active';
}
else
{
span.className = 'inactive';
}
}
function add_email()
{
var button_row = document.getElementById("add_email_row");
var tr = document.createElement("tr");
tr.appendChild(document.createElement("th"));
tr.appendChild(document.createElement("td"));
var td = document.createElement("td");
var input = document.createElement("input");
input.style.width="100%";
var date = new Date;
input.name = "new_email_"+date.getTime();
td.appendChild(input);
tr.appendChild(td);
button_row.parentNode.insertBefore(tr,button_row);
}
</script>
{% endblock %}
{% block bodyAttrs %}onload='init_form();'{% endblock %}
{% block title %}Profile for {{ user }}{% endblock %}
{% block content %}
<h1>User information for {{ user.username }}</h1>
<form method="post"> {% csrf_token %}
<table class="userProfile">
<tr>
<th>User name:</th>
<td></td>
<td>{{ user.username }}</td>
</tr>
{% for role in roles %}
<tr>
<th>{% if forloop.first %}Roles:{% endif %}</th>
<td></td>
<td class='{% cycle 'even' 'odd'%}'>{{ role.name }} in {{ role.group.acronym|upper }} ({{ role.group.type }})</td>
<td class='{% cycle 'even' 'odd'%}'>
<select name="role_email_{{role.id}}">
{% for email in emails %}<option value="{{email.address}}"{% ifequal email.address role.email.address %} selected="selected"{% endifequal %} class='{% if email.active %}active{% else %}inactive{% endif %}'>{{email}}</option>
{% endfor %}</select></td>
</tr>
{% endfor %}
{% for email in emails %}
<tr>
<th>{% if forloop.first %}Email:{% endif %}</th>
<td></td>
<td colspan="2">
<input type="checkbox" id="controller_{{email.address}}" name="{{email.address}}" {% if email.active %}checked="checked"{% else %}{% endif %} onchange="style_email(this)"/>
<span id="span_{{email.address}}">{{email}}</span></td>
</tr>
{% endfor %}
<tr id="add_email_row">
<th></th>
<td></td>
<td colspan='2'><input type="button" value="Add Email Address" onclick="add_email()"/></td>
</tr>
<tr><td colspan="2"></td><td colspan="2"><i>Note: Email addresses cannot be deleted, only deactivated.</i></td></tr>
<tr>
<th>{{person_form.name.label}}:</th>
<td></td>
<td colspan='2'>{{person_form.name}} - The preferred form of your name</td>
</tr>
<tr>
<th>{{person_form.ascii.label}}:</th>
<td></td>
<td colspan='2'>{{person_form.ascii}} - Your name as rendered in ASCII (Latin, unaccented) characters</td>
</tr>
<tr>
<th>{{person_form.ascii_short.label}}:</th>
<td></td>
<td colspan='2'>{{person_form.ascii_short}} - Short form, if any, of your name as renedered in ASCII (blank is okay)</td>
</tr>
<tr>
<th>{{person_form.affiliation.label}}:</th>
<td></td>
<td colspan='2'>{{person_form.affiliation}} - Employer, university, sponsor, etc.</td>
</tr>
<tr>
<th>Mailing Address:</th>
<td></td>
<td colspan='2'>{{person_form.address}}</td>
</tr>
<td colspan="4"><div width='100%' align='right'><input type="submit" value="Commit Changes" /></div></td></tr>
</table>
</form>
{% endblock %}