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