Code

Ticket #12103: 12103_method_on_form.diff

File 12103_method_on_form.diff, 3.0 KB (added by ejucovy, 4 years ago)

Control login policy with an overridable method on the form

Line 
1Index: django/contrib/auth/forms.py
2===================================================================
3--- django/contrib/auth/forms.py        (revision 12678)
4+++ django/contrib/auth/forms.py        (working copy)
5@@ -79,9 +79,9 @@
6             self.user_cache = authenticate(username=username, password=password)
7             if self.user_cache is None:
8                 raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive."))
9-            elif not self.user_cache.is_active:
10-                raise forms.ValidationError(_("This account is inactive."))
11-
12+            else:
13+                self.confirm_login_allowed(user_cache)
14+       
15         # TODO: determine whether this should move to its own method.
16         if self.request:
17             if not self.request.session.test_cookie_worked():
18@@ -89,6 +89,19 @@
19 
20         return self.cleaned_data
21 
22+    def confirm_login_allowed(self, user):
23+        """
24+        Controls whether the given ``auth.User`` object may log in. This is a policy setting,
25+        independent of end-user authentication. This default behavior is to allow login by
26+        active users, and reject login by inactive users.
27+
28+        If the given user cannot log in, this method should raise a ``forms.ValidationError``.
29+
30+        If the given user may log in, this method should return None.
31+        """
32+        if not user.is_active:
33+            raise forms.ValidationError(_("This account is inactive."))
34+
35     def get_user_id(self):
36         if self.user_cache:
37             return self.user_cache.id
38Index: docs/topics/auth.txt
39===================================================================
40--- docs/topics/auth.txt        (revision 12678)
41+++ docs/topics/auth.txt        (working copy)
42@@ -1000,6 +1000,31 @@
43 
44     A form for logging a user in.
45 
46+    The ``AuthenticationForm`` rejects users whose ``is_active`` flag is set to ``False``.
47+    You may override this behavior with a custom policy to determine which users can log in.
48+    Do this with a custom form that subclasses ``AuthenticationForm`` and overrides the
49+    ``confirm_login_allowed(self, user)`` method.  This method will raise a ``forms.ValidationError``
50+    if the given user may not log in.
51+
52+    For example, to allow all users to log in, regardless of activation status::
53+
54+    .. code-block:: python
55+
56+        class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
57+            def confirm_login_allowed(self, user):
58+               return None
59+
60+    Or to allow only some active users to log in:
61+
62+    .. code-block:: python
63+
64+        class PickyAuthenticationForm(AuthenticationForm):
65+            def confirm_login_allowed(self, user):
66+               if not user.is_active:
67+                   raise forms.ValidationError(_("This account is inactive."))
68+               if user.username.startswith('b'):
69+                   raise forms.ValidationError(_("Sorry, accounts starting with 'b' aren't welcome here."))
70+
71 .. class:: PasswordChangeForm
72 
73     A form for allowing a user to change their password.