Skip to content
Snippets Groups Projects
auth_backends.py 1.52 KiB
Newer Older
  • Learn to ignore specific revisions
  • from django.contrib.auth import backends, get_user_model
    
    from allauth.account import auth_backends
    
    from funkwhale_api.common import authentication
    
    
    # ugly but allauth doesn't offer an easy way to override the querysets
    # used to retrieve users, so we monkey patch
    def decorate_for_auth(func):
        def inner(*args, **kwargs):
            qs = func(*args, **kwargs)
            try:
                return qs.for_auth()
            except AttributeError:
                return (
                    get_user_model()
                    .objects.all()
                    .for_auth()
                    .filter(pk__in=[u.pk for u in qs])
                )
    
        return inner
    
    
    auth_backends.filter_users_by_email = decorate_for_auth(
        auth_backends.filter_users_by_email
    )
    auth_backends.filter_users_by_username = decorate_for_auth(
        auth_backends.filter_users_by_username
    )
    
    
    
    class ModelBackend(backends.ModelBackend):
        def get_user(self, user_id):
            """
            Select related to avoid two additional queries
            """
            try:
    
                user = get_user_model().objects.all().for_auth().get(pk=user_id)
    
            except get_user_model().DoesNotExist:
                return None
    
            return user if self.user_can_authenticate(user) else None
    
    
        def user_can_authenticate(self, user):
    
            can_authenticate = super().user_can_authenticate(user)
            if authentication.should_verify_email(user):
                raise authentication.UnverifiedEmail(user)
    
            return can_authenticate
    
    
    
    class AllAuthBackend(auth_backends.AuthenticationBackend, ModelBackend):
        pass