Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/contrib/auth/backends.py: 34%
115 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from django.contrib.auth import get_user_model
2from django.contrib.auth.models import Permission
3from django.db.models import Exists, OuterRef, Q
5UserModel = get_user_model()
8class BaseBackend:
9 def authenticate(self, request, **kwargs):
10 return None
12 def get_user(self, user_id):
13 return None
15 def get_user_permissions(self, user_obj, obj=None):
16 return set()
18 def get_group_permissions(self, user_obj, obj=None):
19 return set()
21 def get_all_permissions(self, user_obj, obj=None):
22 return {
23 *self.get_user_permissions(user_obj, obj=obj),
24 *self.get_group_permissions(user_obj, obj=obj),
25 }
27 def has_perm(self, user_obj, perm, obj=None):
28 return perm in self.get_all_permissions(user_obj, obj=obj)
31class ModelBackend(BaseBackend):
32 """
33 Authenticates against settings.AUTH_USER_MODEL.
34 """
36 def authenticate(self, request, username=None, password=None, **kwargs):
37 if username is None: 37 ↛ 39line 37 didn't jump to line 39, because the condition on line 37 was never false
38 username = kwargs.get(UserModel.USERNAME_FIELD)
39 if username is None or password is None: 39 ↛ 40line 39 didn't jump to line 40, because the condition on line 39 was never true
40 return
41 try:
42 user = UserModel._default_manager.get_by_natural_key(username)
43 except UserModel.DoesNotExist:
44 # Run the default password hasher once to reduce the timing
45 # difference between an existing and a nonexistent user (#20760).
46 UserModel().set_password(password)
47 else:
48 if user.check_password(password) and self.user_can_authenticate(user): 48 ↛ exitline 48 didn't return from function 'authenticate', because the condition on line 48 was never false
49 return user
51 def user_can_authenticate(self, user):
52 """
53 Reject users with is_active=False. Custom user models that don't have
54 that attribute are allowed.
55 """
56 is_active = getattr(user, "is_active", None)
57 return is_active or is_active is None
59 def _get_user_permissions(self, user_obj):
60 return user_obj.user_permissions.all()
62 def _get_group_permissions(self, user_obj):
63 user_groups_field = get_user_model()._meta.get_field("groups")
64 user_groups_query = "group__%s" % user_groups_field.related_query_name()
65 return Permission.objects.filter(**{user_groups_query: user_obj})
67 def _get_permissions(self, user_obj, obj, from_name):
68 """
69 Return the permissions of `user_obj` from `from_name`. `from_name` can
70 be either "group" or "user" to return permissions from
71 `_get_group_permissions` or `_get_user_permissions` respectively.
72 """
73 if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
74 return set()
76 perm_cache_name = "_%s_perm_cache" % from_name
77 if not hasattr(user_obj, perm_cache_name):
78 if user_obj.is_superuser:
79 perms = Permission.objects.all()
80 else:
81 perms = getattr(self, "_get_%s_permissions" % from_name)(user_obj)
82 perms = perms.values_list("content_type__app_label", "codename").order_by()
83 setattr(
84 user_obj, perm_cache_name, {"%s.%s" % (ct, name) for ct, name in perms}
85 )
86 return getattr(user_obj, perm_cache_name)
88 def get_user_permissions(self, user_obj, obj=None):
89 """
90 Return a set of permission strings the user `user_obj` has from their
91 `user_permissions`.
92 """
93 return self._get_permissions(user_obj, obj, "user")
95 def get_group_permissions(self, user_obj, obj=None):
96 """
97 Return a set of permission strings the user `user_obj` has from the
98 groups they belong.
99 """
100 return self._get_permissions(user_obj, obj, "group")
102 def get_all_permissions(self, user_obj, obj=None):
103 if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
104 return set()
105 if not hasattr(user_obj, "_perm_cache"):
106 user_obj._perm_cache = super().get_all_permissions(user_obj)
107 return user_obj._perm_cache
109 def has_perm(self, user_obj, perm, obj=None):
110 return user_obj.is_active and super().has_perm(user_obj, perm, obj=obj)
112 def has_module_perms(self, user_obj, app_label):
113 """
114 Return True if user_obj has any permissions in the given app_label.
115 """
116 return user_obj.is_active and any(
117 perm[: perm.index(".")] == app_label
118 for perm in self.get_all_permissions(user_obj)
119 )
121 def with_perm(self, perm, is_active=True, include_superusers=True, obj=None):
122 """
123 Return users that have permission "perm". By default, filter out
124 inactive users and include superusers.
125 """
126 if isinstance(perm, str):
127 try:
128 app_label, codename = perm.split(".")
129 except ValueError:
130 raise ValueError(
131 "Permission name should be in the form "
132 "app_label.permission_codename."
133 )
134 elif not isinstance(perm, Permission):
135 raise TypeError(
136 "The `perm` argument must be a string or a permission instance."
137 )
139 if obj is not None:
140 return UserModel._default_manager.none()
142 permission_q = Q(group__user=OuterRef("pk")) | Q(user=OuterRef("pk"))
143 if isinstance(perm, Permission):
144 permission_q &= Q(pk=perm.pk)
145 else:
146 permission_q &= Q(codename=codename, content_type__app_label=app_label)
148 user_q = Exists(Permission.objects.filter(permission_q))
149 if include_superusers:
150 user_q |= Q(is_superuser=True)
151 if is_active is not None:
152 user_q &= Q(is_active=is_active)
154 return UserModel._default_manager.filter(user_q)
156 def get_user(self, user_id):
157 try:
158 user = UserModel._default_manager.get(pk=user_id)
159 except UserModel.DoesNotExist:
160 return None
161 return user if self.user_can_authenticate(user) else None
164class AllowAllUsersModelBackend(ModelBackend):
165 def user_can_authenticate(self, user):
166 return True
169class RemoteUserBackend(ModelBackend):
170 """
171 This backend is to be used in conjunction with the ``RemoteUserMiddleware``
172 found in the middleware module of this package, and is used when the server
173 is handling authentication outside of Django.
175 By default, the ``authenticate`` method creates ``User`` objects for
176 usernames that don't already exist in the database. Subclasses can disable
177 this behavior by setting the ``create_unknown_user`` attribute to
178 ``False``.
179 """
181 # Create a User object if not already in the database?
182 create_unknown_user = True
184 def authenticate(self, request, remote_user):
185 """
186 The username passed as ``remote_user`` is considered trusted. Return
187 the ``User`` object with the given username. Create a new ``User``
188 object if ``create_unknown_user`` is ``True``.
190 Return None if ``create_unknown_user`` is ``False`` and a ``User``
191 object with the given username is not found in the database.
192 """
193 if not remote_user:
194 return
195 user = None
196 username = self.clean_username(remote_user)
198 # Note that this could be accomplished in one try-except clause, but
199 # instead we use get_or_create when creating unknown users since it has
200 # built-in safeguards for multiple threads.
201 if self.create_unknown_user:
202 user, created = UserModel._default_manager.get_or_create(
203 **{UserModel.USERNAME_FIELD: username}
204 )
205 if created:
206 user = self.configure_user(request, user)
207 else:
208 try:
209 user = UserModel._default_manager.get_by_natural_key(username)
210 except UserModel.DoesNotExist:
211 pass
212 return user if self.user_can_authenticate(user) else None
214 def clean_username(self, username):
215 """
216 Perform any cleaning on the "username" prior to using it to get or
217 create the user object. Return the cleaned username.
219 By default, return the username unchanged.
220 """
221 return username
223 def configure_user(self, request, user):
224 """
225 Configure a user after creation and return the updated user.
227 By default, return the user unmodified.
228 """
229 return user
232class AllowAllUsersRemoteUserBackend(RemoteUserBackend):
233 def user_can_authenticate(self, user):
234 return True