Modified auth app so that login with alternate auth app is possible.
This commit is contained in:
parent
dabe362836
commit
507bb50a92
|
@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy, ugettext as _
|
||||||
ERROR_MESSAGE = ugettext_lazy("Please enter the correct username and password "
|
ERROR_MESSAGE = ugettext_lazy("Please enter the correct username and password "
|
||||||
"for a staff account. Note that both fields are case-sensitive.")
|
"for a staff account. Note that both fields are case-sensitive.")
|
||||||
|
|
||||||
|
|
||||||
class AdminAuthenticationForm(AuthenticationForm):
|
class AdminAuthenticationForm(AuthenticationForm):
|
||||||
"""
|
"""
|
||||||
A custom authentication form used in the admin app.
|
A custom authentication form used in the admin app.
|
||||||
|
|
|
@ -2,7 +2,7 @@ from functools import update_wrapper
|
||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.contrib.admin import ModelAdmin, actions
|
from django.contrib.admin import ModelAdmin, actions
|
||||||
from django.contrib.admin.forms import AdminAuthenticationForm
|
from django.contrib.admin.forms import AdminAuthenticationForm
|
||||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
|
||||||
from django.contrib.contenttypes import views as contenttype_views
|
from django.contrib.contenttypes import views as contenttype_views
|
||||||
from django.views.decorators.csrf import csrf_protect
|
from django.views.decorators.csrf import csrf_protect
|
||||||
from django.db.models.base import ModelBase
|
from django.db.models.base import ModelBase
|
||||||
|
@ -79,20 +79,23 @@ class AdminSite(object):
|
||||||
if model in self._registry:
|
if model in self._registry:
|
||||||
raise AlreadyRegistered('The model %s is already registered' % model.__name__)
|
raise AlreadyRegistered('The model %s is already registered' % model.__name__)
|
||||||
|
|
||||||
# If we got **options then dynamically construct a subclass of
|
# Ignore the registration if the model has been
|
||||||
# admin_class with those **options.
|
# swapped out.
|
||||||
if options:
|
if not model._meta.swapped:
|
||||||
# For reasons I don't quite understand, without a __module__
|
# If we got **options then dynamically construct a subclass of
|
||||||
# the created class appears to "live" in the wrong place,
|
# admin_class with those **options.
|
||||||
# which causes issues later on.
|
if options:
|
||||||
options['__module__'] = __name__
|
# For reasons I don't quite understand, without a __module__
|
||||||
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
|
# the created class appears to "live" in the wrong place,
|
||||||
|
# which causes issues later on.
|
||||||
|
options['__module__'] = __name__
|
||||||
|
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
|
||||||
|
|
||||||
# Validate (which might be a no-op)
|
# Validate (which might be a no-op)
|
||||||
validate(admin_class, model)
|
validate(admin_class, model)
|
||||||
|
|
||||||
# Instantiate the admin class to save in the registry
|
# Instantiate the admin class to save in the registry
|
||||||
self._registry[model] = admin_class(model, self)
|
self._registry[model] = admin_class(model, self)
|
||||||
|
|
||||||
def unregister(self, model_or_iterable):
|
def unregister(self, model_or_iterable):
|
||||||
"""
|
"""
|
||||||
|
@ -317,6 +320,7 @@ class AdminSite(object):
|
||||||
REDIRECT_FIELD_NAME: request.get_full_path(),
|
REDIRECT_FIELD_NAME: request.get_full_path(),
|
||||||
}
|
}
|
||||||
context.update(extra_context or {})
|
context.update(extra_context or {})
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'extra_context': context,
|
'extra_context': context,
|
||||||
'current_app': self.name,
|
'current_app': self.name,
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
{% if user.is_active and user.is_staff %}
|
{% if user.is_active and user.is_staff %}
|
||||||
<div id="user-tools">
|
<div id="user-tools">
|
||||||
{% trans 'Welcome,' %}
|
{% trans 'Welcome,' %}
|
||||||
<strong>{% filter force_escape %}{% firstof user.first_name user.username %}{% endfilter %}</strong>.
|
<strong>{% filter force_escape %}{% firstof user.get_short_name user.username %}{% endfilter %}</strong>.
|
||||||
{% block userlinks %}
|
{% block userlinks %}
|
||||||
{% url 'django-admindocs-docroot' as docsroot %}
|
{% url 'django-admindocs-docroot' as docsroot %}
|
||||||
{% if docsroot %}
|
{% if docsroot %}
|
||||||
|
|
|
@ -6,9 +6,10 @@ SESSION_KEY = '_auth_user_id'
|
||||||
BACKEND_SESSION_KEY = '_auth_user_backend'
|
BACKEND_SESSION_KEY = '_auth_user_backend'
|
||||||
REDIRECT_FIELD_NAME = 'next'
|
REDIRECT_FIELD_NAME = 'next'
|
||||||
|
|
||||||
|
|
||||||
def load_backend(path):
|
def load_backend(path):
|
||||||
i = path.rfind('.')
|
i = path.rfind('.')
|
||||||
module, attr = path[:i], path[i+1:]
|
module, attr = path[:i], path[i + 1:]
|
||||||
try:
|
try:
|
||||||
mod = import_module(module)
|
mod = import_module(module)
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
|
@ -21,6 +22,7 @@ def load_backend(path):
|
||||||
raise ImproperlyConfigured('Module "%s" does not define a "%s" authentication backend' % (module, attr))
|
raise ImproperlyConfigured('Module "%s" does not define a "%s" authentication backend' % (module, attr))
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
|
|
||||||
def get_backends():
|
def get_backends():
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
backends = []
|
backends = []
|
||||||
|
@ -30,6 +32,7 @@ def get_backends():
|
||||||
raise ImproperlyConfigured('No authentication backends have been defined. Does AUTHENTICATION_BACKENDS contain anything?')
|
raise ImproperlyConfigured('No authentication backends have been defined. Does AUTHENTICATION_BACKENDS contain anything?')
|
||||||
return backends
|
return backends
|
||||||
|
|
||||||
|
|
||||||
def authenticate(**credentials):
|
def authenticate(**credentials):
|
||||||
"""
|
"""
|
||||||
If the given credentials are valid, return a User object.
|
If the given credentials are valid, return a User object.
|
||||||
|
@ -46,6 +49,7 @@ def authenticate(**credentials):
|
||||||
user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
|
user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def login(request, user):
|
def login(request, user):
|
||||||
"""
|
"""
|
||||||
Persist a user id and a backend in the request. This way a user doesn't
|
Persist a user id and a backend in the request. This way a user doesn't
|
||||||
|
@ -69,6 +73,7 @@ def login(request, user):
|
||||||
request.user = user
|
request.user = user
|
||||||
user_logged_in.send(sender=user.__class__, request=request, user=user)
|
user_logged_in.send(sender=user.__class__, request=request, user=user)
|
||||||
|
|
||||||
|
|
||||||
def logout(request):
|
def logout(request):
|
||||||
"""
|
"""
|
||||||
Removes the authenticated user's ID from the request and flushes their
|
Removes the authenticated user's ID from the request and flushes their
|
||||||
|
@ -86,6 +91,16 @@ def logout(request):
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
request.user = AnonymousUser()
|
request.user = AnonymousUser()
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_model():
|
||||||
|
"Return the User model that is active in this project"
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db.models import get_model
|
||||||
|
|
||||||
|
app_label, model_name = settings.AUTH_USER_MODEL.split('.')
|
||||||
|
return get_model(app_label, model_name)
|
||||||
|
|
||||||
|
|
||||||
def get_user(request):
|
def get_user(request):
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.contrib.auth.models import User, Permission
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
|
|
||||||
class ModelBackend(object):
|
class ModelBackend(object):
|
||||||
|
@ -10,10 +11,13 @@ class ModelBackend(object):
|
||||||
# configurable.
|
# configurable.
|
||||||
def authenticate(self, username=None, password=None):
|
def authenticate(self, username=None, password=None):
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(username=username)
|
UserModel = get_user_model()
|
||||||
|
user = UserModel.objects.get(**{
|
||||||
|
getattr(UserModel, 'USERNAME_FIELD', 'username'): username
|
||||||
|
})
|
||||||
if user.check_password(password):
|
if user.check_password(password):
|
||||||
return user
|
return user
|
||||||
except User.DoesNotExist:
|
except UserModel.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_group_permissions(self, user_obj, obj=None):
|
def get_group_permissions(self, user_obj, obj=None):
|
||||||
|
@ -58,8 +62,9 @@ class ModelBackend(object):
|
||||||
|
|
||||||
def get_user(self, user_id):
|
def get_user(self, user_id):
|
||||||
try:
|
try:
|
||||||
return User.objects.get(pk=user_id)
|
UserModel = get_user_model()
|
||||||
except User.DoesNotExist:
|
return UserModel.objects.get(pk=user_id)
|
||||||
|
except UserModel.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,17 +97,23 @@ class RemoteUserBackend(ModelBackend):
|
||||||
user = None
|
user = None
|
||||||
username = self.clean_username(remote_user)
|
username = self.clean_username(remote_user)
|
||||||
|
|
||||||
|
UserModel = get_user_model()
|
||||||
|
|
||||||
# Note that this could be accomplished in one try-except clause, but
|
# Note that this could be accomplished in one try-except clause, but
|
||||||
# instead we use get_or_create when creating unknown users since it has
|
# instead we use get_or_create when creating unknown users since it has
|
||||||
# built-in safeguards for multiple threads.
|
# built-in safeguards for multiple threads.
|
||||||
if self.create_unknown_user:
|
if self.create_unknown_user:
|
||||||
user, created = User.objects.get_or_create(username=username)
|
user, created = UserModel.objects.get_or_create(**{
|
||||||
|
getattr(UserModel, 'USERNAME_FIELD', 'username'): username
|
||||||
|
})
|
||||||
if created:
|
if created:
|
||||||
user = self.configure_user(user)
|
user = self.configure_user(user)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(username=username)
|
user = UserModel.objects.get(**{
|
||||||
except User.DoesNotExist:
|
getattr(UserModel, 'USERNAME_FIELD', 'username'): username
|
||||||
|
})
|
||||||
|
except UserModel.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,9 @@ import getpass
|
||||||
import locale
|
import locale
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
from django.contrib.auth import models as auth_app
|
from django.contrib.auth import models as auth_app, get_user_model
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
from django.db.models import get_models, signals
|
from django.db.models import get_models, signals
|
||||||
from django.contrib.auth.models import User, get_user_model
|
|
||||||
|
|
||||||
|
|
||||||
def _get_permission_codename(action, opts):
|
def _get_permission_codename(action, opts):
|
||||||
|
@ -106,7 +105,7 @@ def get_default_username(check_db=True):
|
||||||
"""
|
"""
|
||||||
# If the User model has been swapped out, we can't make any assumptions
|
# If the User model has been swapped out, we can't make any assumptions
|
||||||
# about the default user name.
|
# about the default user name.
|
||||||
if User._meta.swapped:
|
if auth_app.User._meta.swapped:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
default_username = get_system_username()
|
default_username = get_system_username()
|
||||||
|
@ -118,15 +117,15 @@ def get_default_username(check_db=True):
|
||||||
|
|
||||||
# Run the username validator
|
# Run the username validator
|
||||||
try:
|
try:
|
||||||
User._meta.get_field('username').run_validators(default_username)
|
auth_app.User._meta.get_field('username').run_validators(default_username)
|
||||||
except exceptions.ValidationError:
|
except exceptions.ValidationError:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# Don't return the default username if it is already taken.
|
# Don't return the default username if it is already taken.
|
||||||
if check_db and default_username:
|
if check_db and default_username:
|
||||||
try:
|
try:
|
||||||
User.objects.get(username=default_username)
|
auth_app.User.objects.get(username=default_username)
|
||||||
except User.DoesNotExist:
|
except auth_app.User.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import getpass
|
import getpass
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.contrib.auth.models import get_user_model
|
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import getpass
|
||||||
import sys
|
import sys
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.management import get_default_username
|
from django.contrib.auth.management import get_default_username
|
||||||
from django.contrib.auth.models import get_user_model
|
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
|
@ -271,12 +270,6 @@ class AbstractBaseUser(models.Model):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
def get_user_model():
|
|
||||||
"Return the User model that is active in this project"
|
|
||||||
app_label, model_name = settings.AUTH_USER_MODEL.split('.')
|
|
||||||
return models.get_model(app_label, model_name)
|
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser):
|
class User(AbstractBaseUser):
|
||||||
"""
|
"""
|
||||||
Users within the Django authentication system are represented by this
|
Users within the Django authentication system are represented by this
|
||||||
|
|
|
@ -70,6 +70,7 @@ def login(request, template_name='registration/login.html',
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
def logout(request, next_page=None,
|
def logout(request, next_page=None,
|
||||||
template_name='registration/logged_out.html',
|
template_name='registration/logged_out.html',
|
||||||
redirect_field_name=REDIRECT_FIELD_NAME,
|
redirect_field_name=REDIRECT_FIELD_NAME,
|
||||||
|
@ -100,6 +101,7 @@ def logout(request, next_page=None,
|
||||||
# Redirect to this page until the session has been cleared.
|
# Redirect to this page until the session has been cleared.
|
||||||
return HttpResponseRedirect(next_page or request.path)
|
return HttpResponseRedirect(next_page or request.path)
|
||||||
|
|
||||||
|
|
||||||
def logout_then_login(request, login_url=None, current_app=None, extra_context=None):
|
def logout_then_login(request, login_url=None, current_app=None, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Logs out the user if he is logged in. Then redirects to the log-in page.
|
Logs out the user if he is logged in. Then redirects to the log-in page.
|
||||||
|
@ -108,6 +110,7 @@ def logout_then_login(request, login_url=None, current_app=None, extra_context=N
|
||||||
login_url = settings.LOGIN_URL
|
login_url = settings.LOGIN_URL
|
||||||
return logout(request, login_url, current_app=current_app, extra_context=extra_context)
|
return logout(request, login_url, current_app=current_app, extra_context=extra_context)
|
||||||
|
|
||||||
|
|
||||||
def redirect_to_login(next, login_url=None,
|
def redirect_to_login(next, login_url=None,
|
||||||
redirect_field_name=REDIRECT_FIELD_NAME):
|
redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
"""
|
"""
|
||||||
|
@ -124,6 +127,7 @@ def redirect_to_login(next, login_url=None,
|
||||||
|
|
||||||
return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
|
return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
|
||||||
|
|
||||||
|
|
||||||
# 4 views for password reset:
|
# 4 views for password reset:
|
||||||
# - password_reset sends the mail
|
# - password_reset sends the mail
|
||||||
# - password_reset_done shows a success message for the above
|
# - password_reset_done shows a success message for the above
|
||||||
|
@ -169,6 +173,7 @@ def password_reset(request, is_admin_site=False,
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
def password_reset_done(request,
|
def password_reset_done(request,
|
||||||
template_name='registration/password_reset_done.html',
|
template_name='registration/password_reset_done.html',
|
||||||
current_app=None, extra_context=None):
|
current_app=None, extra_context=None):
|
||||||
|
@ -178,6 +183,7 @@ def password_reset_done(request,
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
# Doesn't need csrf_protect since no-one can guess the URL
|
# Doesn't need csrf_protect since no-one can guess the URL
|
||||||
@sensitive_post_parameters()
|
@sensitive_post_parameters()
|
||||||
@never_cache
|
@never_cache
|
||||||
|
@ -191,7 +197,7 @@ def password_reset_confirm(request, uidb36=None, token=None,
|
||||||
View that checks the hash in a password reset link and presents a
|
View that checks the hash in a password reset link and presents a
|
||||||
form for entering a new password.
|
form for entering a new password.
|
||||||
"""
|
"""
|
||||||
assert uidb36 is not None and token is not None # checked by URLconf
|
assert uidb36 is not None and token is not None # checked by URLconf
|
||||||
if post_reset_redirect is None:
|
if post_reset_redirect is None:
|
||||||
post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
|
post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
|
||||||
try:
|
try:
|
||||||
|
@ -221,6 +227,7 @@ def password_reset_confirm(request, uidb36=None, token=None,
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
def password_reset_complete(request,
|
def password_reset_complete(request,
|
||||||
template_name='registration/password_reset_complete.html',
|
template_name='registration/password_reset_complete.html',
|
||||||
current_app=None, extra_context=None):
|
current_app=None, extra_context=None):
|
||||||
|
@ -232,6 +239,7 @@ def password_reset_complete(request,
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
@sensitive_post_parameters()
|
@sensitive_post_parameters()
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -257,6 +265,7 @@ def password_change(request,
|
||||||
return TemplateResponse(request, template_name, context,
|
return TemplateResponse(request, template_name, context,
|
||||||
current_app=current_app)
|
current_app=current_app)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def password_change_done(request,
|
def password_change_done(request,
|
||||||
template_name='registration/password_change_done.html',
|
template_name='registration/password_change_done.html',
|
||||||
|
|
Loading…
Reference in New Issue