84 lines
2.3 KiB
Python
84 lines
2.3 KiB
Python
|
from django.contrib.auth import get_user_model
|
||
|
from django.contrib.auth.backends import ModelBackend
|
||
|
|
||
|
from .utils import get_cas_client
|
||
|
|
||
|
UserModel = get_user_model()
|
||
|
|
||
|
|
||
|
class ENSCASBackend:
|
||
|
"""ENS CAS authentication backend.
|
||
|
|
||
|
Implement standard CAS v3 authentication
|
||
|
"""
|
||
|
|
||
|
def authenticate(self, request, ticket=None):
|
||
|
cas_client = get_cas_client(request)
|
||
|
cas_login, attributes, _ = cas_client.verify_ticket(ticket)
|
||
|
|
||
|
if cas_login is None:
|
||
|
# Authentication failed
|
||
|
return None
|
||
|
cas_login = self.clean_cas_login(cas_login)
|
||
|
|
||
|
if request:
|
||
|
request.session["CASCONNECTED"] = True
|
||
|
|
||
|
return self._get_or_create(cas_login, attributes)
|
||
|
|
||
|
def clean_cas_login(self, cas_login):
|
||
|
return cas_login.strip().lower()
|
||
|
|
||
|
def _get_or_create(self, cas_login, attributes):
|
||
|
"""Handles account retrieval and creation for CAS authentication.
|
||
|
|
||
|
- If no CAS account exists, create one;
|
||
|
- If a matching CAS account exists, retrieve it.
|
||
|
"""
|
||
|
|
||
|
email = attributes.get("email")
|
||
|
|
||
|
try:
|
||
|
user = UserModel.objects.get(username=cas_login)
|
||
|
except UserModel.DoesNotExist:
|
||
|
user = None
|
||
|
|
||
|
if user is None:
|
||
|
user = UserModel.objects.create_user(username=cas_login, email=email)
|
||
|
return user
|
||
|
|
||
|
# Django boilerplate.
|
||
|
def get_user(self, user_id):
|
||
|
try:
|
||
|
return UserModel.objects.get(pk=user_id)
|
||
|
except UserModel.DoesNotExist:
|
||
|
return None
|
||
|
|
||
|
|
||
|
class ElectionBackend(ModelBackend):
|
||
|
"""Authentication for a specific election.
|
||
|
|
||
|
Given a login and an election, we check if the user `{election.id}__{login}`
|
||
|
exists, and then if the password matches.
|
||
|
"""
|
||
|
|
||
|
def authenticate(self, request, login=None, password=None, election_id=None):
|
||
|
if login is None or password is None or election_id is None:
|
||
|
return None
|
||
|
|
||
|
try:
|
||
|
user = UserModel.objects.get(username=f"{election_id}__{login}")
|
||
|
except UserModel.DoesNotExist:
|
||
|
return None
|
||
|
|
||
|
if user.check_password(password):
|
||
|
return user
|
||
|
return None
|
||
|
|
||
|
# Django boilerplate.
|
||
|
def get_user(self, user_id):
|
||
|
try:
|
||
|
return UserModel.objects.get(pk=user_id)
|
||
|
except UserModel.DoesNotExist:
|
||
|
return None
|