From 71802073283847f5582df4eea1e4fdb5b37eca4f Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 30 Dec 2006 07:16:25 +0000 Subject: [PATCH] Fixed #3166 -- Added admin 'Change user password' view. Thanks for the patch, SmileyChris git-svn-id: http://code.djangoproject.com/svn/django/trunk@4266 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../admin/auth/user/change_password.html | 52 +++++++++++++++++++ django/contrib/admin/urls.py | 2 + django/contrib/admin/views/auth.py | 37 ++++++++++++- django/contrib/auth/forms.py | 15 ++++++ django/contrib/auth/models.py | 2 +- 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 django/contrib/admin/templates/admin/auth/user/change_password.html diff --git a/django/contrib/admin/templates/admin/auth/user/change_password.html b/django/contrib/admin/templates/admin/auth/user/change_password.html new file mode 100644 index 0000000000..80990faa24 --- /dev/null +++ b/django/contrib/admin/templates/admin/auth/user/change_password.html @@ -0,0 +1,52 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_modify adminmedia %} +{% block extrahead %}{{ block.super }} + +{% for js in javascript_imports %}{% include_admin_script js %}{% endfor %} +{% endblock %} +{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %} +{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %} +{% block userlinks %}{% trans 'Documentation' %} / {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} +{% block breadcrumbs %}{% if not is_popup %} + +{% endif %}{% endblock %} +{% block content %}
+
{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if form.error_dict %} +

+ {% blocktrans count form.error_dict.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} +

+{% endif %} + +

{% blocktrans with original.username|escape as username %}Enter a new username and password for the user {{ username }}.{% endblocktrans %}

+ +
+ +
+ {{ form.password1.html_error_list }} + {{ form.password1 }} +
+ +
+ {{ form.password2.html_error_list }} + {{ form.password2 }} +

{% trans 'Enter the same password as above, for verification.' %}

+
+ +
+ +
+ +
+ + +
+
+{% endblock %} diff --git a/django/contrib/admin/urls.py b/django/contrib/admin/urls.py index aaf9841e45..508bb3a1ca 100644 --- a/django/contrib/admin/urls.py +++ b/django/contrib/admin/urls.py @@ -29,6 +29,8 @@ urlpatterns = patterns('', # "Add user" -- a special-case view ('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'), + # "Change user password" -- another special-case view + ('^auth/user/(\d+)/password/$', 'django.contrib.admin.views.auth.user_change_password'), # Add/change/delete/history ('^([^/]+)/([^/]+)/$', 'django.contrib.admin.views.main.change_list'), diff --git a/django/contrib/admin/views/auth.py b/django/contrib/admin/views/auth.py index abc02e96c4..bea1f8533c 100644 --- a/django/contrib/admin/views/auth.py +++ b/django/contrib/admin/views/auth.py @@ -1,10 +1,11 @@ from django.contrib.admin.views.decorators import staff_member_required -from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.forms import UserCreationForm, AdminPasswordChangeForm from django.contrib.auth.models import User from django.core.exceptions import PermissionDenied from django import oldforms, template -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponseRedirect +from django.utils.html import escape def user_add_stage(request): if not request.user.has_perm('auth.change_user'): @@ -42,3 +43,35 @@ def user_add_stage(request): 'username_help_text': User._meta.get_field('username').help_text, }, context_instance=template.RequestContext(request)) user_add_stage = staff_member_required(user_add_stage) + +def user_change_password(request, id): + if not request.user.has_perm('auth.change_user'): + raise PermissionDenied + user = get_object_or_404(User, pk=id) + manipulator = AdminPasswordChangeForm(user) + if request.method == 'POST': + new_data = request.POST.copy() + errors = manipulator.get_validation_errors(new_data) + if not errors: + new_user = manipulator.save(new_data) + msg = _('Password changed successfully.') + request.user.message_set.create(message=msg) + return HttpResponseRedirect('..') + else: + errors = new_data = {} + form = oldforms.FormWrapper(manipulator, new_data, errors) + return render_to_response('admin/auth/user/change_password.html', { + 'title': _('Change password: %s') % escape(user.username), + 'form': form, + 'is_popup': request.REQUEST.has_key('_popup'), + 'add': True, + 'change': False, + 'has_delete_permission': False, + 'has_change_permission': True, + 'has_absolute_url': False, + 'first_form_field_id': 'id_password1', + 'opts': User._meta, + 'original': user, + 'show_save': True, + }, context_instance=template.RequestContext(request)) +user_change_password = staff_member_required(user_change_password) diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index aea52d1f2a..7700ec7d7a 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -126,3 +126,18 @@ class PasswordChangeForm(oldforms.Manipulator): "Saves the new password." self.user.set_password(new_data['new_password1']) self.user.save() + +class AdminPasswordChangeForm(oldforms.Manipulator): + "A form used to change the password of a user in the admin interface." + def __init__(self, user): + self.user = user + self.fields = ( + oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True), + oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True, + validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]), + ) + + def save(self, new_data): + "Saves the new password." + self.user.set_password(new_data['password1']) + self.user.save() diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 58cc07efa9..4f4f0b7538 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -91,7 +91,7 @@ class User(models.Model): first_name = models.CharField(_('first name'), maxlength=30, blank=True) last_name = models.CharField(_('last name'), maxlength=30, blank=True) email = models.EmailField(_('e-mail address'), blank=True) - password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]'")) + password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the change password form.")) is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site.")) is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts.")) is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))