diff options
author | Johan Lundberg <lundberg@nordu.net> | 2011-05-10 11:09:55 +0200 |
---|---|---|
committer | Johan Lundberg <lundberg@nordu.net> | 2011-05-10 11:09:55 +0200 |
commit | 01405d73d6839ae7e267482d483aecc628a67afd (patch) | |
tree | e49518ab3e6a4bde6622b449b5047978cd60fcbf | |
parent | 1c7bea1c752b7cb9b258230d16006a17b2ed1f8d (diff) |
Added reset password functionality.
-rw-r--r-- | templates/changepw/change_password.html | 8 | ||||
-rw-r--r-- | templates/changepw/index.html | 28 | ||||
-rw-r--r-- | templates/changepw/reset_password.html | 24 | ||||
-rw-r--r-- | urls.py | 5 | ||||
-rw-r--r-- | views.py | 61 |
5 files changed, 109 insertions, 17 deletions
diff --git a/templates/changepw/change_password.html b/templates/changepw/change_password.html index bb3f0c5..b0a919a 100644 --- a/templates/changepw/change_password.html +++ b/templates/changepw/change_password.html @@ -1,13 +1,15 @@ {% extends "base.html" %} {% block js %} -<script type="text/javascript" src="/nordunet/site_media/js/jquery/jquery-1.4.4.min.js"></script> -<script type="text/javascript" src="/nordunet/site_media/js/jquery/password_strength.js"></script> +<script type="text/javascript" src="/sso/site_media/js/jquery/jquery-1.4.4.min.js"></script> +<script type="text/javascript" src="/sso/site_media/js/jquery/password_strength.js"></script> {% endblock %} +{% block title %}Change password{% endblock %} {% block content %} <h2>Change password</h2> {% if form %} <p>When thinking of a new password you need to remember to use:</p> <ul> + <li>no fewer than eight characters</li> <li>at least one number</li> <li>at least one upper case and one lower case letter</li> <li>one or more special characters</li> @@ -19,7 +21,7 @@ <form action="{% url changepw %}" method="post" autocomplete="off">{% csrf_token %} <table> <tr> - <th class="formlabel">Username:</th><td>{{ user.username }}</td> + <th class="formlabel">Username:</th><td>{{ username }}</td> </tr> {% for field in form %} <tr> diff --git a/templates/changepw/index.html b/templates/changepw/index.html new file mode 100644 index 0000000..bd607ef --- /dev/null +++ b/templates/changepw/index.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}Password Manager{% endblock %} +{% block content %} +<h2>Password Manager</h2> +<p> + Hello {{ full_name }},<br /> + Welcome to the password management site. +</p> + +<table> + <tr> + <th>Your usernames</th> + </tr> + <tr> + <td>Username:</td><td>{{ username }}</td> + </tr> +</table> + +<p>Available actions:</p> +<ul> + <li><a href="{% url changepw %}">Change password.</a></li> + <li><a href="{% url resetpw %}">Reset password.</a></li> +</ul> + +<p><a href="{% url logout %}">Log out</a></p> +{% endblock %} diff --git a/templates/changepw/reset_password.html b/templates/changepw/reset_password.html new file mode 100644 index 0000000..a9e49e2 --- /dev/null +++ b/templates/changepw/reset_password.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% block js %} +{% endblock %} +{% block title %}Password reset{% endblock %} +{% block content %} +<h2>Password reset</h2> + +{% if return_value == 0 %} + <p>Here is your new password:</p> + <table> + <tr> + <td>Username:</td><td>{{ username }}</td> + </tr> + <tr> + <td>Password:</td><td>{{ username }}/ppp</td> + </tr> + </table> +{% else %} + <p>Something went wrong. Please contact an administrator.</p> + <p>Return code: {{ return_value }}</p> +{% endif %} + +<p><a href="{% url logout %}">Log out</a></p> +{% endblock %} @@ -1,6 +1,9 @@ # This also imports the include function from django.conf.urls.defaults import * +from nordunet_change_password import * urlpatterns = patterns('apps.changepw.views', - url(r'^/$', 'change_password', name='changepw'), + url(r'^/$', 'index', name='index'), + url(r'^/changepw$', change_password(request, change_nordunet_sso_pw), name='changepw'), + url(r'^/changeppp$', reset_password(request, reset_nordunet_ppp_pw), name='resetpw'), ) @@ -1,33 +1,68 @@ from django.contrib.auth.decorators import login_required from apps.changepw.models import ChangePasswordForm -from django import forms from django.shortcuts import render_to_response from django.template import RequestContext -from django.http import HttpResponseRedirect -import subprocess -@login_required(login_url='/nordunet/accounts/login/') -def change_password(request): +def _get_username(request): + ''' + Returns the actual username from the Shibboleth uid. + request.user.username == username@domain.com + ''' + return request.user.username.split('@')[0] + +def _generate_password(n): + ''' + Returns a psudo random string of lenght n. + http://code.activestate.com/recipes/576722-pseudo-random-string/ + ''' + import os, math + from base64 import b64encode + return b64encode(os.urandom(int(math.ceil(0.75*n))),'-_')[:n] + +@login_required(login_url='/sso/accounts/login/') +def index(request): + ''' + Greets the user and presents the choices available. + ''' + full_name = '%s %s' % (request.user.firstname, request.user.lastname) + username = _get_username(request) + return render_to_response('changepw/index.html', + {'full_name': full_name, 'username': username}, + context_instance=RequestContext(request)) + +@login_required(login_url='/sso/accounts/login/') +def change_password(request, func): ''' If the user is authenticated and the form is valid the password changing script will be run with the username and new password. + The function that changes the password has to be provided as func. ''' if request.method == 'POST': form = ChangePasswordForm(request.POST) if form.is_valid(): new_password = form.cleaned_data['new_password'] - - # Magic for actually changing the password happens here - return_value = subprocess.call(['echo', - request.user.username, - new_password]) - + return_value = func(request.user, new_password) return render_to_response('changepw/change_password.html', {'return_value': return_value}, context_instance=RequestContext(request)) else: form = ChangePasswordForm() - + username = _get_username(request) return render_to_response('changepw/change_password.html', - {'form': form, 'user': request.user}, + {'form': form, 'username': username}, context_instance=RequestContext(request)) + +@login_required(login_url='/sso/accounts/login/') +def reset_password(request, func): + ''' + Resets password for the authenticated user to a random string. + The function that actually sets the new password has to be provided as func. + ''' + password_length = 8 # chars + username = _get_username(request) + new_password = _generate_password(password_length) + return_value = func(request.user, new_password) + return render_to_response('changepw/reset_password.html', + {'username': username, 'new_password': new_password, + 'return_value': return_value}, + context_instance=RequestContext(request))
\ No newline at end of file |