简体   繁体   中英

How do I 'monkey patch' or override User.is_authenticated()? Creates issues with using django-lazysignup

I installed django-lazysignup and am facing the challenge now of User.is_authenticated() returning True, for what are not actually authenticated users, but instead lazy-signup users. I can update any checks for User.is_authenticated() in my code with my own function. However, other packages like django-allauth, check this method to decide whether a user is already signed-in, and redirect from attempts to reach the login page.

class RedirectAuthenticatedUserMixin(object):
    def dispatch(self, request, *args, **kwargs):
        self.request = request
        if request.user.is_authenticated():
            redirect_to = self.get_authenticated_redirect_url()
            response = HttpResponseRedirect(redirect_to)
            return _ajax_response(request, response)
...

Are there any recommendations that don't require replacing is_authenticated() in every package that I include? Seems most of them expect it to function a particular way, and django-lazysignup turns that on its head. Could I monkey patch the User model with a new is_authenticated() method? If it's possible, where would I do this so that it's attached to the page request?

django-lazysignup , which you are using, allows you to deliver a custom LazyUser class ( here ). All you need to do is to write a subclass of lazysignup.models.LazyUser with defined is_authenticated method and set it as settings.LAZYSIGNUP_USER_MODEL .

But this is not the end of your troubles. Lots of django apps assume that authenticated user has some properties. Mainly, is_staff , is_superuser , permissions , groups . First and foremost, django.contrib.admin needs them to check if it can let the user in and what to show him. Look how django.contrib.auth.models.AnonymousUser mocks them and copy it. Remark: look how AnonymousUser is not subclassing any user class nor db.Model . Supplied user class only needs to quack.

Ended up just having to replace all calls to User.is_authenticated().

To prevent django-allauth from redirecting lazy-users from the login page, this ended up looking something like this:

from allauth.account.views import AjaxCapableProcessFormViewMixin

def _ajax_response(request, response, form=None):
    if request.is_ajax():
        if (isinstance(response, HttpResponseRedirect)
            or isinstance(response, HttpResponsePermanentRedirect)):
            redirect_to = response['Location']
        else:
            redirect_to = None
        response = get_adapter().ajax_response(request,
                                           response,
                                           form=form,
                                           redirect_to=redirect_to)
    return response


class RedirectUserWithAccountMixin(object):
    def dispatch(self, request, *args, **kwargs):
        self.request = request
        if user_has_account(request.user):
            redirect_to = self.get_authenticated_redirect_url()
            response = HttpResponseRedirect(redirect_to)
            return _ajax_response(request, response)
        else:
            response = super(RedirectUserWithAccountMixin,
                             self).dispatch(request,
                                            *args,
                                            **kwargs)
        return response

    def get_authenticated_redirect_url(self):
        redirect_field_name = self.redirect_field_name
        return get_login_redirect_url(self.request,
                                      url=self.get_success_url(),
                                      redirect_field_name=redirect_field_name)

class LoginView(RedirectUserWithAccountMixin,
            AjaxCapableProcessFormViewMixin,
            FormView):
...

Where user_has_account() was my own method for checking whether the user was actually signed in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM