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):
|
class CaseInsensitiveModelBackend(ModelBackend):
|
||||||
"""
|
"""
|
||||||
By default ModelBackend does case _sensitive_ username authentication, which isn't what is
|
By default ModelBackend does case _sensitive_ username
|
||||||
generally expected. This backend supports case insensitive username authentication.
|
authentication, which isn't what is generally expected. This
|
||||||
|
backend supports case insensitive username authentication.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def authenticate(self, username=None, password=None):
|
def authenticate(self, username=None, password=None, autologin=None):
|
||||||
User = get_user_model()
|
"""
|
||||||
|
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:
|
||||||
|
# In this case .backend will be assigned automatically
|
||||||
|
# somewhere along the # way.
|
||||||
|
Player = get_user_model()
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(username__iexact=username)
|
player = Player.objects.get(username__iexact=username)
|
||||||
if user.check_password(password):
|
if player.check_password(password):
|
||||||
return user
|
return player
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
except User.DoesNotExist:
|
except Player.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ page and serve it eventual static content.
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from django.shortcuts import render
|
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.players.models import PlayerDB
|
||||||
from evennia.utils import logger
|
from evennia.utils import logger
|
||||||
|
|
@ -33,6 +33,8 @@ def _shared_login(request):
|
||||||
# The webclient has previously registered a login to this browser_session
|
# The webclient has previously registered a login to this browser_session
|
||||||
player = PlayerDB.objects.get(id=sesslogin)
|
player = PlayerDB.objects.get(id=sesslogin)
|
||||||
try:
|
try:
|
||||||
|
# calls our custom authenticate in web/utils/backends.py
|
||||||
|
player = authenticate(autologin=player)
|
||||||
login(request, player)
|
login(request, player)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ templates on the fly.
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin.sites import site
|
from django.contrib.admin.sites import site
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import authenticate
|
||||||
from django.contrib.admin.views.decorators import staff_member_required
|
from django.contrib.admin.views.decorators import staff_member_required
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
@ -39,6 +40,8 @@ def _shared_login(request):
|
||||||
# The webclient has previously registered a login to this csession
|
# The webclient has previously registered a login to this csession
|
||||||
player = PlayerDB.objects.get(id=sesslogin)
|
player = PlayerDB.objects.get(id=sesslogin)
|
||||||
try:
|
try:
|
||||||
|
# calls our custom authenticate, in web/utils/backend.py
|
||||||
|
authenticate(autologin=player)
|
||||||
login(request, player)
|
login(request, player)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue