authenticates against settings authusermodel run the default password hasher once to reduce the timing difference between an existing and a nonexistent user 20760 reject users with isactivefalse custom user models that don t have that attribute are allowed return the permissions of userobj from fromname fromname can be either group or user to return permissions from getgrouppermissions or getuserpermissions respectively return a set of permission strings the user userobj has from their userpermissions return a set of permission strings the user userobj has from the groups they belong return true if userobj has any permissions in the given applabel return users that have permission perm by default filter out inactive users and include superusers this backend is to be used in conjunction with the remoteusermiddleware found in the middleware module of this package and is used when the server is handling authentication outside of django by default the authenticate method creates user objects for usernames that don t already exist in the database subclasses can disable this behavior by setting the createunknownuser attribute to false create a user object if not already in the database the username passed as remoteuser is considered trusted return the user object with the given username create a new user object if createunknownuser is true return none if createunknownuser is false and a user object with the given username is not found in the database note that this could be accomplished in one tryexcept clause but instead we use getorcreate when creating unknown users since it has builtin safeguards for multiple threads perform any cleaning on the username prior to using it to get or create the user object return the cleaned username by default return the username unchanged configure a user and return the updated user by default return the user unmodified authenticates against settings auth_user_model run the default password hasher once to reduce the timing difference between an existing and a nonexistent user 20760 reject users with is_active false custom user models that don t have that attribute are allowed return the permissions of user_obj from from_name from_name can be either group or user to return permissions from _get_group_permissions or _get_user_permissions respectively return a set of permission strings the user user_obj has from their user_permissions return a set of permission strings the user user_obj has from the groups they belong return true if user_obj has any permissions in the given app_label return users that have permission perm by default filter out inactive users and include superusers this backend is to be used in conjunction with the remoteusermiddleware found in the middleware module of this package and is used when the server is handling authentication outside of django by default the authenticate method creates user objects for usernames that don t already exist in the database subclasses can disable this behavior by setting the create_unknown_user attribute to false create a user object if not already in the database the username passed as remote_user is considered trusted return the user object with the given username create a new user object if create_unknown_user is true return none if create_unknown_user is false and a user object with the given username is not found in the database note that this could be accomplished in one try except clause but instead we use get_or_create when creating unknown users since it has built in safeguards for multiple threads perform any cleaning on the username prior to using it to get or create the user object return the cleaned username by default return the username unchanged configure a user and return the updated user by default return the user unmodified
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.db.models import Exists, OuterRef, Q

UserModel = get_user_model()


class BaseBackend:
    def authenticate(self, request, **kwargs):
        return None

    def get_user(self, user_id):
        return None

    def get_user_permissions(self, user_obj, obj=None):
        return set()

    def get_group_permissions(self, user_obj, obj=None):
        return set()

    def get_all_permissions(self, user_obj, obj=None):
        return {
            *self.get_user_permissions(user_obj, obj=obj),
            *self.get_group_permissions(user_obj, obj=obj),
        }

    def has_perm(self, user_obj, perm, obj=None):
        return perm in self.get_all_permissions(user_obj, obj=obj)


class ModelBackend(BaseBackend):
    

    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        if username is None or password is None:
            return
        try:
            user = UserModel._default_manager.get_by_natural_key(username)
        except UserModel.DoesNotExist:
            
            
            UserModel().set_password(password)
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

    def user_can_authenticate(self, user):
        
        return getattr(user, "is_active", True)

    def _get_user_permissions(self, user_obj):
        return user_obj.user_permissions.all()

    def _get_group_permissions(self, user_obj):
        user_groups_field = get_user_model()._meta.get_field("groups")
        user_groups_query = "group__%s" % user_groups_field.related_query_name()
        return Permission.objects.filter(**{user_groups_query: user_obj})

    def _get_permissions(self, user_obj, obj, from_name):
        
        if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
            return set()

        perm_cache_name = "_%s_perm_cache" % from_name
        if not hasattr(user_obj, perm_cache_name):
            if user_obj.is_superuser:
                perms = Permission.objects.all()
            else:
                perms = getattr(self, "_get_%s_permissions" % from_name)(user_obj)
            perms = perms.values_list("content_type__app_label", "codename").order_by()
            setattr(
                user_obj, perm_cache_name, {"%s.%s" % (ct, name) for ct, name in perms}
            )
        return getattr(user_obj, perm_cache_name)

    def get_user_permissions(self, user_obj, obj=None):
        
        return self._get_permissions(user_obj, obj, "user")

    def get_group_permissions(self, user_obj, obj=None):
        
        return self._get_permissions(user_obj, obj, "group")

    def get_all_permissions(self, user_obj, obj=None):
        if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
            return set()
        if not hasattr(user_obj, "_perm_cache"):
            user_obj._perm_cache = super().get_all_permissions(user_obj)
        return user_obj._perm_cache

    def has_perm(self, user_obj, perm, obj=None):
        return user_obj.is_active and super().has_perm(user_obj, perm, obj=obj)

    def has_module_perms(self, user_obj, app_label):
        
        return user_obj.is_active and any(
            perm[: perm.index(".")] == app_label
            for perm in self.get_all_permissions(user_obj)
        )

    def with_perm(self, perm, is_active=True, include_superusers=True, obj=None):
        
        if isinstance(perm, str):
            try:
                app_label, codename = perm.split(".")
            except ValueError:
                raise ValueError(
                    "Permission name should be in the form "
                    "app_label.permission_codename."
                )
        elif not isinstance(perm, Permission):
            raise TypeError(
                "The `perm` argument must be a string or a permission instance."
            )

        if obj is not None:
            return UserModel._default_manager.none()

        permission_q = Q(group__user=OuterRef("pk")) | Q(user=OuterRef("pk"))
        if isinstance(perm, Permission):
            permission_q &= Q(pk=perm.pk)
        else:
            permission_q &= Q(codename=codename, content_type__app_label=app_label)

        user_q = Exists(Permission.objects.filter(permission_q))
        if include_superusers:
            user_q |= Q(is_superuser=True)
        if is_active is not None:
            user_q &= Q(is_active=is_active)

        return UserModel._default_manager.filter(user_q)

    def get_user(self, user_id):
        try:
            user = UserModel._default_manager.get(pk=user_id)
        except UserModel.DoesNotExist:
            return None
        return user if self.user_can_authenticate(user) else None


class AllowAllUsersModelBackend(ModelBackend):
    def user_can_authenticate(self, user):
        return True


class RemoteUserBackend(ModelBackend):
    

    
    create_unknown_user = True

    def authenticate(self, request, remote_user):
        
        if not remote_user:
            return
        created = False
        user = None
        username = self.clean_username(remote_user)

        
        
        
        if self.create_unknown_user:
            user, created = UserModel._default_manager.get_or_create(
                **{UserModel.USERNAME_FIELD: username}
            )
        else:
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                pass
        user = self.configure_user(request, user, created=created)
        return user if self.user_can_authenticate(user) else None

    def clean_username(self, username):
        
        return username

    def configure_user(self, request, user, created=True):
        
        return user


class AllowAllUsersRemoteUserBackend(RemoteUserBackend):
    def user_can_authenticate(self, user):
        return True