0

I've already read this but the answer doesnt fit my needs.

I've made this very simple middleware:

class RedirectIfUserIsNotActiveMiddleware(object):
    """
    Middleware to redirect if account is disabled
    """
    @staticmethod
    def process_request(request):
        if not request.user.is_active:
            try:
                # test to see if not already on the right url:
                a = resolve(request.path)
                if a.url_name != settings.URL_REDIRECT_USER_NOT_ACTIVE:
                    return HttpResponseRedirect(
                        reverse_lazy(settings.URL_REDIRECT_USER_NOT_ACTIVE))

            # request.path do a 404 if URL unknown -> do nothing :
            except Resolver404:
                pass

And I've added this here:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'third_party.hqf_middleware.RedirectIfUserIsNotActiveMiddleware',
)

But when the account is disabled I get an infinite loop with the message on the webbrowser: "mywebsite.com redirected you too many times.".

In my settings I have this:

URL_REDIRECT_USER_NOT_ACTIVE = 'my_home_profile_account_desactivated'

And the URL I'm trying to get is always (even each time step by step) /en/my-home/profile/edit

What am I missing?

Community
  • 1
  • 1
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • Why do you want middleware, why can't you redirect when authenticating user? – Kishor Pawar Jun 01 '16 at 13:11
  • It's explained in my question here: http://stackoverflow.com/questions/35337120/is-there-a-way-to-add-custom-code-to-login-required and I'm trying to apply the suggested answer – Olivier Pons Jun 01 '16 at 13:14
  • Add some printing/logging to your middleware to find out what `a.url_name` and `settings.URL_REDIRECT_USER_NOT_ACTIVE` are. – Alasdair Jun 01 '16 at 13:21
  • As an aside, you don't need `reverse_lazy` inside a middleware method, `reverse` will do just fine. Or you could do `return redirect(URL_REDIRECT_USER_NOT_ACTIVE)` instead. – Alasdair Jun 01 '16 at 13:23
  • I've updated my question. Unfortunately I do need `reverse_lazy()` because if the user changes its language in the configuration, the URLs are properly translated, *except* those which use `reverse()` that's why I'm forced to use `reverse_lazy()` – Olivier Pons Jun 01 '16 at 13:26
  • I believe inactivity should be checked while authenticating only, otherwise this code will be running for each request even when user is active which will be overhead on your server. You can look for how to write custom decorator or overriding `login_required` decorator. – Kishor Pawar Jun 01 '16 at 13:26
  • I've not used i18n urls, but I'm surprised that `reverse_lazy` makes any difference - none of the examples in [the url internationalization docs](https://docs.djangoproject.com/en/1.9/topics/i18n/translation/#url-internationalization) docs use `reverse_lazy`. Anyway, that's probably off topic for this question. – Alasdair Jun 01 '16 at 13:36
  • What is the value of `a.url_name` inside the middleware, and what is the url pattern and view for `my_home_profile_account_desactivated`? – Alasdair Jun 01 '16 at 13:37
  • first redirect : `a.urlname = 'my_home_profile_account_desactivated'` then second redirect: `a.urlname = 'my_home_login'` and this does an infinite loop between those two values.... I guess this has something to do with the fact that the user is not active, so he has to login first then Django sees it's logged and goes to my middleware, which make a redirect... I'll try to used a boolean other than `is_active` in my models, just to see – Olivier Pons Jun 01 '16 at 14:16

1 Answers1

0

It looks as if the my_home_profile_account_desactivated view is redirecting to your login page, and then the middleware redirects back to my_home_profile_account_desactivated, creating a redirect loop.

You should be able to break the authentication loop by changing the middleware so that you only redirect users that are authenticated and inactive.

@staticmethod
def process_request(request):
    if request.user.is_authenticated() and not request.user.is_active:
        ...
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thank you this might be the right answer. I've solved my problem another way: I guessed that is_active was used somewhere by django core itself, so i've made my own "active" field and it works. – Olivier Pons Jun 02 '16 at 15:03