60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
from authens.backends import ENSCASBackend
|
|
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.backends import ModelBackend
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class CASBackend(ENSCASBackend):
|
|
"""ENS CAS authentication backend, customized to get the full name at connection."""
|
|
|
|
def clean_cas_login(self, cas_login):
|
|
return f"cas__{cas_login.strip().lower()}"
|
|
|
|
def create_user(self, username, attributes):
|
|
email = attributes.get("email")
|
|
name = attributes.get("name")
|
|
|
|
return User.objects.create_user(username=username, email=email, full_name=name)
|
|
|
|
def _get_or_create(self, cas_login, attributes):
|
|
try:
|
|
return super()._get_or_create(cas_login, attributes)
|
|
except ValueError:
|
|
raise PermissionDenied
|
|
|
|
|
|
class PwdBackend(ModelBackend):
|
|
"""Password authentication"""
|
|
|
|
def authenticate(self, request, username=None, password=None):
|
|
if username is None or password is None:
|
|
return None
|
|
|
|
return super().authenticate(
|
|
request, username=f"pwd__{username}", password=password
|
|
)
|
|
|
|
|
|
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 = User.objects.get(
|
|
username=f"{election_id}__{login}", election=election_id
|
|
)
|
|
except User.DoesNotExist:
|
|
return None
|
|
|
|
if user.check_password(password):
|
|
return user
|