Reputation: 29863
In my website, I want to let the admins reset the password of any user.
With reset I mean exactly what the password_reset
view does (under contrib.auth): Send a confirmation link to that user email.
How would be the best way of doing that? Is there an already app/snippet that does that?
Edit:
Let's suppose user john is an admin. What I want is to let john reset any user's password through the admin interface. For example, to reset max password, he will just go to the max user, and click on any link to reset his password.
Upvotes: 7
Views: 10472
Reputation: 29863
What I finally did was to add a custom ModelAdmin
:
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
...
def reset_password(self, request, user_id):
if not self.has_change_permission(request):
raise PermissionDenied
user = get_object_or_404(self.model, pk=user_id)
form = PasswordResetForm(data={'email': user.email})
form.is_valid()
form.save(email_template_name='my_template.html')
return HttpResponseRedirect('..')
def get_urls(self):
urls = super(UserAdmin, self).get_urls()
my_urls = patterns('',
(r'^(\d+)/reset-password/$',
self.admin_site.admin_view(self.reset_password)
),
)
return my_urls + urls
and I also had to override the change_form.html
template, like this:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{# You can also give a name to that pattern and refer to it below using 'url' #}
<li><a href="reset-password/" class="historylink">Reset password</a></li>
<li><a href="history/" class="historylink">{% trans "History" %}</a></li>
{% if has_absolute_url %}
<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
{% trans "View on site" %}</a>
</li>
{% endif%}
</ul>
{% endif %}{% endif %}
{% endblock %}
The result looks like this:
If you want a more detailed explanation, I blogged about it.
Upvotes: 8
Reputation: 12978
The passreset app just exposes the django views via urls.py, and adjusts the login template to show a "Forgot my password" link.
The built-in django password reset views and templates are meant for self-reset. I guess the reset form could be prepopulated with a different user's email address (in the query string) but you'd still need to make adjustments such as changing the email template - "You're receiving this e-mail because you requested a password reset for your user account" is probably not what you want:
Therefore you should expose the views at different URLs if you want to include self-reset as well. Hook the django views into urls.py like so:
urlpatterns += patterns('django.contrib.auth.views',
url(r'^accounts/password/reset/$',
'password_reset',
name='password-reset'),
url(r'^accounts/password/reset/done/$',
'password_reset_done',
name='password-reset-done'),
url(r'^accounts/password/reset/confirm/(?P<uidb36>[-\w]+)/(?P<token>[-\w]+)/$',
'password_reset_confirm',
name='password-reset-confirm'),
url(r'^accounts/password/reset/complete/$',
'views.password_reset_complete',
name='password-reset-complete')
)
and where you want to make adjustments, pass in e.g. your own email template:
url(r'^/accounts/password/reset/$',
'password_reset',
{'email_template_name': 'my_templates/password_reset_email.html'}
name='password-reset'),
The "password_reset" view has more parameters you can tweak: https://docs.djangoproject.com/en/dev/topics/auth/#module-django.contrib.auth.views ("post_reset_redirect" comes to mind as another one for your purposes)
To show a corresponding link you'd either change the User admin (careful, already registered - unregister then register your own, subclassed plus additional link field) or the change_form template itself.
I'm unaware of an app that provides this out-of-the-box, so I upvoted the question :-).
Upvotes: 2
Reputation: 5391
Yep, there is an app for that. Check here:
https://github.com/bendavis78/django-passreset
Upvotes: 0