[Django] #32181: ModelBackend used hardcoded global variable UserModel, it can not be overrided.

8 views
Skip to first unread message

Django

unread,
Nov 9, 2020, 5:27:05 AM11/9/20
to django-...@googlegroups.com
#32181: ModelBackend used hardcoded global variable UserModel, it can not be
overrided.
-------------------------------------+-------------------------------------
Reporter: danilovmy | Owner: nobody
Type: | Status: new
Uncategorized |
Component: | Version: 3.1
contrib.auth | Keywords: custombackend,
Severity: Normal | ModelBackend
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
It is not possible override Usermodel for custombackend which depends on
ModelBackend.

if i want to change something un Usermodel class i should override whole
authenticate method. it is not difficult but stupid and brakes SOLID rule

it's easy to change:
1. add **usermodel=UserModel** in ModelBackend class definitions
2. Change global variable UserModel to local **self.usermodel**

{{{

class ModelBackend(BaseBackend):
"""
Authenticates against settings.AUTH_USER_MODEL.
"""
usermodel=UserModel

def authenticate(self, request, username=None, password=None,
**kwargs):
if username is None:
username = kwargs.get(self.usermodel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user =
self.usersermodel._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).
self.usermodel().set_password(password)
else:
if user.check_password(password) and
self.user_can_authenticate(user):
return user

}}}

after that it can be possible to do something like that:


{{{
class LoginBackend(ModelBackend):
"""docstring for LoginBackend."""

def authenticate(self, *args, **kwargs):
self.usermodel = change_something_in(self.usermodel, *args,
**kwargs)
return super().authenticate(self, *args, **kwargs).
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32181>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 9, 2020, 6:18:24 AM11/9/20
to django-...@googlegroups.com
#32181: ModelBackend used hardcoded global variable UserModel that cannot be

overrided.
-------------------------------------+-------------------------------------
Reporter: danilovmy | Owner: nobody
Type: New feature | Status: closed
Component: contrib.auth | Version: 3.1
Severity: Normal | Resolution: wontfix
Keywords: custombackend, | Triage Stage:
ModelBackend | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => wontfix
* easy: 1 => 0
* has_patch: 1 => 0
* type: Uncategorized => New feature


Comment:

I'm not really sure if I understand your use case. Do you have different
user models for different authorization backends? (because `ModelBackend`
supports a custom model for users). If so, it's fair that you need to
override `authenticate()` in such an advanced usage, IMO. We cannot
maintain hooks for all niche scenarios. You can start a discussion on
DevelopersMailingList if you don't agree.

--
Ticket URL: <https://code.djangoproject.com/ticket/32181#comment:1>

Reply all
Reply to author
Forward
0 new messages