from django.conf import settings from django.contrib.auth.hashers import check_password, make_password from django.contrib.auth.models import User from django.contrib import messages from re import compile from django.http import HttpResponseRedirect from django.utils.http import is_safe_url class SettingsBackend: """ Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD. Use the login name and a hash of the password. For example: ADMIN_LOGIN = 'admin' ADMIN_PASSWORD = 'pbkdf2_sha256$30000$Vo0VlMnkR4Bk$qEvtdyZRWTcOsCnI/oQ7fVOu1XAURIZYoOZ3iq8Dr4M=' If ADMIN_PASSWORD is unhashed, then this returns a message warning you about that """ def authenticate(self, request, username=None, password=None): login_valid = (settings.ADMIN_LOGIN == username) if settings.ADMIN_PASSWORD.startswith("pbkdf2_sha256"): pwd_valid = check_password(password, settings.ADMIN_PASSWORD) else: pwd_valid = password == settings.ADMIN_PASSWORD if login_valid and pwd_valid: try: user = User.objects.get(username=username) except User.DoesNotExist: # Create a new user. There's no need to set a password # because only the password from settings.py is checked. user = User(username=username) user.is_staff = True user.is_superuser = True user.save() return user return None def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None # Based on https://gist.github.com/agusmakmun/b71ac536124e0535a8b076989f8cfcd3 EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))] if hasattr(settings, 'LOGIN_EXEMPT_URLS'): EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS] class LoginRequiredMiddleware: """ Middleware that requires a user to be authenticated to view any page other than LOGIN_URL. Exemptions to this requirement can optionally be specified in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which you can copy from your urls.py). Requires authentication middleware and template context processors to be loaded. You'll get an error if they aren't. Based on https://djangosnippets.org/snippets/1179/ My modification adds 'next' GET parameter to enable redirection after successful login. """ def __init__(self, get_response): self.get_response = get_response # One-time configuration and initialization def __call__(self, request): if not request.user.is_authenticated: path = request.path_info.lstrip('/') if not any(m.match(path) for m in EXEMPT_URLS): redirect_to = settings.LOGIN_URL # Add 'next' GET variable to support redirection after login if len(path) > 0 and is_safe_url(url=request.path_info, allowed_hosts=None): redirect_to = "%s?next=%s" %(settings.LOGIN_URL, request.path_info) return HttpResponseRedirect(redirect_to) elif not settings.ADMIN_PASSWORD.startswith("pbkdf2_sha256"): better_password = make_password(settings.ADMIN_PASSWORD) messages.warning(request, "ADMIN_PASSWORD is in plain text. Set it to %s instead" % better_password) return self.get_response(request)