Implement a custom authenticate middleware to correctly handle already-authenticated players in auto-connect webclient mode. Resolves #1037.
This commit is contained in:
parent
86f963fa71
commit
07944918f7
3 changed files with 39 additions and 12 deletions
|
|
@ -3,16 +3,38 @@ from django.contrib.auth import get_user_model
|
|||
|
||||
class CaseInsensitiveModelBackend(ModelBackend):
|
||||
"""
|
||||
By default ModelBackend does case _sensitive_ username authentication, which isn't what is
|
||||
generally expected. This backend supports case insensitive username authentication.
|
||||
By default ModelBackend does case _sensitive_ username
|
||||
authentication, which isn't what is generally expected. This
|
||||
backend supports case insensitive username authentication.
|
||||
|
||||
"""
|
||||
def authenticate(self, username=None, password=None):
|
||||
User = get_user_model()
|
||||
try:
|
||||
user = User.objects.get(username__iexact=username)
|
||||
if user.check_password(password):
|
||||
return user
|
||||
def authenticate(self, username=None, password=None, autologin=None):
|
||||
"""
|
||||
Custom authenticate with bypass for auto-logins
|
||||
|
||||
Args:
|
||||
username (str, optional): Name of user to authenticate.
|
||||
password (str, optional): Password of user
|
||||
autologin (Player, optional): If given, assume this is
|
||||
an already authenticated player and bypass authentication.
|
||||
"""
|
||||
if autologin:
|
||||
# Note: Setting .backend on player is critical in order to
|
||||
# be allowed to call django.auth.login(player) later. This
|
||||
# is necessary for the auto-login feature of the webclient,
|
||||
# but it's important to make sure Django doesn't change this
|
||||
# requirement or the name of the property down the line. /Griatch
|
||||
autologin.backend = "evennia.web.utils.backends.CaseInsensitiveModelBackend"
|
||||
return autologin
|
||||
else:
|
||||
return None
|
||||
except User.DoesNotExist:
|
||||
return None
|
||||
# In this case .backend will be assigned automatically
|
||||
# somewhere along the # way.
|
||||
Player = get_user_model()
|
||||
try:
|
||||
player = Player.objects.get(username__iexact=username)
|
||||
if player.check_password(password):
|
||||
return player
|
||||
else:
|
||||
return None
|
||||
except Player.DoesNotExist:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ page and serve it eventual static content.
|
|||
"""
|
||||
from __future__ import print_function
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth import login
|
||||
from django.contrib.auth import login, authenticate
|
||||
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.utils import logger
|
||||
|
|
@ -33,6 +33,8 @@ def _shared_login(request):
|
|||
# The webclient has previously registered a login to this browser_session
|
||||
player = PlayerDB.objects.get(id=sesslogin)
|
||||
try:
|
||||
# calls our custom authenticate in web/utils/backends.py
|
||||
player = authenticate(autologin=player)
|
||||
login(request, player)
|
||||
except AttributeError:
|
||||
logger.log_trace()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ templates on the fly.
|
|||
"""
|
||||
from django.contrib.admin.sites import site
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.shortcuts import render
|
||||
|
||||
|
|
@ -39,6 +40,8 @@ def _shared_login(request):
|
|||
# The webclient has previously registered a login to this csession
|
||||
player = PlayerDB.objects.get(id=sesslogin)
|
||||
try:
|
||||
# calls our custom authenticate, in web/utils/backend.py
|
||||
authenticate(autologin=player)
|
||||
login(request, player)
|
||||
except AttributeError:
|
||||
logger.log_trace()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue