From 1502efba76dbb7d4bc58bb640cc95c47921e0741 Mon Sep 17 00:00:00 2001 From: Adam Roach Date: Sat, 28 Jul 2012 21:51:00 +0000 Subject: [PATCH] Adding self-management page for user profile information - Legacy-Id: 4705 --- ietf/ietfauth/forms.py | 59 +++++++ ietf/ietfauth/urls.py | 1 + ietf/ietfauth/views.py | 89 +++++++++-- ietf/templates/base_leftmenu.html | 2 +- .../registration/add_email_email.txt | 20 +++ ietf/templates/registration/edit_profile.html | 147 ++++++++++++++++++ 6 files changed, 304 insertions(+), 14 deletions(-) create mode 100644 ietf/templates/registration/add_email_email.txt create mode 100644 ietf/templates/registration/edit_profile.html diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index 1f43e6b8d..4479888ce 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -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 + diff --git a/ietf/ietfauth/urls.py b/ietf/ietfauth/urls.py index 7e69f4c20..73eb8e4ef 100644 --- a/ietf/ietfauth/urls.py +++ b/ietf/ietfauth/urls.py @@ -17,5 +17,6 @@ urlpatterns += patterns('ietf.ietfauth.views', url(r'^confirm/(?P[\w.@+-]+)/(?P[\d]+)/(?P[\w]+)/(?P[a-f0-9]+)/$', 'confirm_account', name='confirm_account'), url(r'^reset/$', 'password_reset_view', name='password_reset'), url(r'^reset/confirm/(?P[\w.@+-]+)/(?P[\d]+)/(?P[\w]+)/(?P[a-f0-9]+)/$', 'confirm_password_reset', name='confirm_password_reset'), + url(r'^add_email/confirm/(?P[\w.@+-]+)/(?P[\d]+)/(?P[\w.@+-]+)/(?P[a-f0-9]+)/$', 'confirm_new_email', name='confirm_new_email'), url(r'^ajax/check_username/$', 'ajax_check_username', name='ajax_check_username'), ) diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index 5d6360fe5..eee1e85ab 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -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 diff --git a/ietf/templates/base_leftmenu.html b/ietf/templates/base_leftmenu.html index f7767efa7..f1d7919e6 100644 --- a/ietf/templates/base_leftmenu.html +++ b/ietf/templates/base_leftmenu.html @@ -37,7 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% load ietf_filters community_tags %}
  • Accounts
  • -
  • New Account
  • +
  • {% if request.user.is_authenticated %}Manage Account{% else %}New Account{% endif %}
  • {% if user|in_group:"Area_Director" %}
  • AD Dashboard
  • My Documents
  • diff --git a/ietf/templates/registration/add_email_email.txt b/ietf/templates/registration/add_email_email.txt new file mode 100644 index 000000000..538630e65 --- /dev/null +++ b/ietf/templates/registration/add_email_email.txt @@ -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 %} diff --git a/ietf/templates/registration/edit_profile.html b/ietf/templates/registration/edit_profile.html new file mode 100644 index 000000000..d28efb9eb --- /dev/null +++ b/ietf/templates/registration/edit_profile.html @@ -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 %} + +{% endblock %} + +{% block bodyAttrs %}onload='init_form();'{% endblock %} + +{% block title %}Profile for {{ user }}{% endblock %} + +{% block content %} +

    User information for {{ user.username }}

    + +
    {% csrf_token %} + + + + + + + {% for role in roles %} + + + + + + + {% endfor %} + {% for email in emails %} + + + + + + {% endfor %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    User name:{{ user.username }}
    {% if forloop.first %}Roles:{% endif %}{{ role.name }} in {{ role.group.acronym|upper }} ({{ role.group.type }}) +
    {% if forloop.first %}Email:{% endif %} + + {{email}}
    Note: Email addresses cannot be deleted, only deactivated.
    {{person_form.name.label}}:{{person_form.name}} - The preferred form of your name
    {{person_form.ascii.label}}:{{person_form.ascii}} - Your name as rendered in ASCII (Latin, unaccented) characters
    {{person_form.ascii_short.label}}:{{person_form.ascii_short}} - Short form, if any, of your name as renedered in ASCII (blank is okay)
    {{person_form.affiliation.label}}:{{person_form.affiliation}} - Employer, university, sponsor, etc.
    Mailing Address:{{person_form.address}}
    + + +
    +{% endblock %}