2

I followed a Django tutorial and wrote a Middleware class, to be precise its a "Login-Required"-Middleware so Users are just allowed to do some things on the website when they are logged in.

The problem is that the middleware works as it should be but I can not visit the Django-Admin website anymore. Even after adding the admin-url to the exception list. He keeps redirecting me to the "normal login site".

This is my middleware

import re

from django.conf import settings
from django.shortcuts import redirect
from django.contrib.auth import logout
from django.urls import reverse


EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [re.compile(url) for url in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        assert hasattr(request, 'user')
        path = request.path_info.lstrip('/')
        print (path)

        # if not request.user.is_authenticated():
        #     if not any(url.match(path) for url in EXEMPT_URLS):
        #         return redirect(settings.LOGIN_URL)

        url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)

        if path == reverse('logout').lstrip('/'):
            logout(request)

        if request.user.is_authenticated() and url_is_exempt:
            return redirect(settings.LOGIN_REDIRECT_URL)

        elif request.user.is_authenticated() or url_is_exempt:
            return None

        else:
                return redirect(settings.LOGIN_URL)

This is the Login_EXEMPT_URLS in settings.py

LOGIN_EXEMPT_URLS = (
r'^admin/',
r'^kalender/login/$',
r'^kalender/logout/$',
r'^kalender/reset-password/$',
r'^kalender/reset-password/done/$',
r'^kalender/reset-password/complete/$',
r'^kalender/reset-password/$',
r'^kalender/reset-password/confirm/',
r'^kalender/returnjson/'
)

LOGIN_URL = '/kalender/login/'
LOGIN_REDIRECT_URL = '/kalender/'
LOGOUT_REDIRECT_URL = '/kalender/'
ADMIN_REDIRECT_URL = '/admin/'

This is my urls.py

urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^login/$', login, {'template_name': 'kalender/login.html'}, name='login'),
    #url(r'^logout/$', logout, {'template_name': 'kalender/login.html'}, name='logout'),
    url(r'^logout/$', logout, name='logout'),
    url(r'^delete/$', views.delete, name='delete'),
    url(r'^delete2/$', views.delete2, name='delete2'),
    url(r'^addTimestamp/$', views.addTimestamp, name='addTimestamp'),
    url(r'^delete_many/$', views.delete_many, name='delete_many'),
    url(r'^add_many/$', views.add_many, name='add_many'),
    url(r'^addPT/$', views.addPT, name='addPT'),
    url(r'^deletePT/$', views.deletePT, name='deletePT'),
    url(r'^settings/$', views.edit_settings, name='edit_settings'),
    url(r'^nextMonth/$', views.nextMonth, name='nextMonth'),
    url(r'^previousMonth/$', views.previousMonth, name='previousMonth'),
    url(r'^view_profile/$', views.view_profile, name='view_profile'),
    url(r'^edit_profile/$', views.edit_profile, name='edit_profile'),
    url(r'^change_postbox/$', views.change_postbox, name='change_postbox'),
    url(r'^getNextTimestamp/$', views.getNextTimestamp, name='getNextTimestamp'),
    url(r'^returnjson/$', views.returnjson, name='returnjson'),
    url(r'^change-password$', views.change_password, name='change_password'),
    url(r'^reset-password/$', password_reset, {'template_name': 'kalender/reset_password.html'}, name='reset_password'),
    url(r'^reset-password/done/$', password_reset_done, {'template_name': 'kalender/reset_password_done.html'}, name='password_reset_done'),
    url(r'^reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, {'template_name': 'kalender/reset_password_formular.html'}, name='password_reset_confirm'),
    url(r'^reset-password/complete/$', password_reset_complete, {'template_name': 'kalender/reset_password_complete.html'}, name='password_reset_complete'),
    #url(r'sendEmail/^$', views.sendEmail, name='sendEmail'),
]

EDIT: Thanks to the help i got here, i now can login to the admin page, but as soon as i login, i get redirected to my home view via the LOGIN_REDIRECT_URL. But I want to keep proceeding to the admin page after login. How do i do that? You can see the redirects here: (the output of the console in Pycharm)

admin/
[21/May/2018 13:11:38] "GET /admin/ HTTP/1.1" 302 0
admin/login/
[21/May/2018 13:11:38] "GET /admin/login/?next=/admin/ HTTP/1.1" 200 1668
admin/login/
[21/May/2018 13:11:44] "POST /admin/login/?next=/admin/ HTTP/1.1" 302 0
admin/
[21/May/2018 13:11:44] "GET /admin/ HTTP/1.1" 302 0
kalender/
stofuser91
  • 43
  • 3
  • Since you are already removing the leading slash in your middleware, you could remove `r'^/admin/$'` and `r'^/admin/login/?next=/admin/$'` since they are never going to match. – Alasdair Apr 12 '18 at 10:27

1 Answers1

0

The password reset confirm url is something like kalender/reset-password/confirm/abc-123/. None of your regexes match that. You need to add something like r'^kalender/reset-password/confirm/'

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thanks your advice helped. Now i just need to get this done for the django admin site. As you see I already added the URLs but he still redirects me to the login page when I try to open the admin site. – stofuser91 Apr 12 '18 at 10:19
  • `r'^admin/$'` will only match `admin/` (because of the dollar). If you use `r'^admin/'` instead, it will match `admin/` and other urls like `admin/something/else/`. – Alasdair Apr 12 '18 at 10:22
  • Damn, I tried so many things for hours and it didnt work because of that single dollar symbol. Thank you very much. I would like to mark your answer as useful but i cant since my account is new. – stofuser91 Apr 12 '18 at 14:18
  • Glad it helped. Don't worry about it - you'll be able to upvote other questions/answers once you've got a bit more reputation. – Alasdair Apr 12 '18 at 14:24
  • Hello @Alasdair, I think i rushed the things a little. Didnt work on the project for more than a month. There is still one problem left. I can now visit the admin site, but i after I login with admin credentials, i am still getting redirected to my home view. I editted the post. Can you please help me out again? Thanks in advance – stofuser91 May 21 '18 at 11:15
  • That sounds like a different issue, so you would be better to ask a new question -- this question is marked as accepted so it isn't going to get any attention. Looking briefly at your question, I don't understand why you are doing `if request.user.is_authenticated() and url_is_exempt:`. Also, when you do `redirect(settings.LOGIN_URL)`, you aren't including any information about where you are redirecting from (e.g. `?next=/current-url/`, so the user won't be redirected back to the original page after logging in. – Alasdair May 21 '18 at 12:11