robos85
robos85

Reputation: 2554

password_reset only for users who are not logged in

is it possible, to deny access to django.contrib.auth.views.password_reset for users who are authenticated? I want to use it, and make it only for not logged in.

I can't figure out how to do that. I have done all things with reset, but all users can enter it:/

UPDATE: I made it that way:

views.py

def password_remind(request):
    from django.contrib.auth.views import password_reset
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    return password_reset(request, template_name='remind_password.html', post_reset_redirect=reverse('password_remind_sent'))

def password_remind_sent(request):
    from django.contrib.auth.views import password_reset_done
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    return password_reset_done(request, template_name='remind_password.html')

def password_remind_set_new(request, uidb36, token):
    from django.contrib.auth.views import password_reset_confirm
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    return password_reset_confirm(request, template_name='set_new_password.html', post_reset_redirect=reverse('password_remind_changed'), token=token, uidb36=uidb36)

def password_remind_changed(request):
    from django.contrib.auth.views import password_reset_complete
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    return password_reset_complete(request, template_name='set_new_password.html')

urls.py:

url(r'^remind_password/$', 'password_remind', name='password_remind'),
    url(r'^remind_password/sent/$', 'password_remind_sent', name='password_remind_sent'),
    url(r'^remind_password/set_new/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'password_remind_set_new', name='password_remind_set_new'),
    url(r'^remind_password/changed/$', 'password_remind_changed', name='password_remind_changed'),

Upvotes: 0

Views: 378

Answers (2)

Steve Jalim
Steve Jalim

Reputation: 12195

I'd make a decorator function that ensures that request.user is not authenticated and if they are, redirects to an 'access denied' page with a 403 code.

Then, in my urls.py, I'd include url patterns for the view(s) I want to lock down (there are about four, I recall) and wrap the method call in that decorator function.

That way, you don't have to hack contrib.auth's views at all - you just wrap your code around it.

But do you really need to stop users accessing the reset password view?

UPDATE:

Example decorator function (untested code!)

from django.http import HttpResponseForbidden

def unauthenticated_users_only(func):
    """
    Decorator that checks whether a user 
    is logged in. 403s if not. 
    """
    def dec(request, *args, **kwargs):
        if not request.user.is_authenticated():  
            return HttpResponseForbidden()                
        return func(request, *args, **kwargs)

    dec.__doc__ = func.__doc__
    return dec

and then in your main urls.py, import all of the auth urls related to the reset flow and import and apply that function for each of them:

url(r'^password/reset/$', unauthenticated_users_only(auth_views.password_reset), name='auth_password_reset'),

Upvotes: 1

Sure, you can always wrap the function in your own function with some conditions and point your url to your wrapper function instead. (note to pass in whatever arguments you were passing in before...)

from django.contrib.auth.views import password_reset as real_password_reset

def password_reset(request, *args, **kwargs):
    if request.user.is_authenticated():
       # separate logic, redirect, whatever you wish.
       return direct_to_template(request, "my_password_change.html", {}) 
    return real_password_reset(request, *args, **kwargs)


(r'^password_reset/$', password_reset),

Upvotes: 2

Related Questions