Opened 7 years ago
Closed 7 years ago
#30471 closed Bug (duplicate)
"This account is inactive" error on login form will never display with ModelBackend
| Reported by: | Ben | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.auth | Version: | 2.2 |
| Severity: | Normal | Keywords: | login is_active inactive message form |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
In django/contrib/auth/forms.py the following code in clean tries to authenticate a username and password combination and show either an invalid login message (self.user_cache is None) or a message informing the user they are not allowed to login.
if username is not None and password:
self.user_cache = authenticate(self.request, username=username, password=password)
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
If the user has is_active set to false but provides the correct credentials I expect confirm_login_allowed to be called and eventually "This account is inactive" to be returned as an error.
However, this is not happening because in django/contrib/auth/backends.py we have:
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
The user_can_authenticate check checks for is_active so regardless of the success/failure of the login if is_active is false then user_can_authenticate will always return None.
I suspect the fix here is to remove the confirm_login_allowed check or use User.check_password after the failed authentication to drive the inactive logic. I am not sure which way the project would prefer to go and since this is important code I thought it best to ask. I'm happy to roll a patch once there's consensus on a good fix.
Change History (2)
comment:1 by , 7 years ago
| Component: | Uncategorized → contrib.auth |
|---|
comment:2 by , 7 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Duplicate of #28645.