#34565: Exception will be raised when settings.PASSWORD_HASHERS changes and the
check_password() method is called in an asynchronous context.
-------------------------------------+-------------------------------------
     Reporter:  Dingning             |                    Owner:  nobody
         Type:  Bug                  |                   Status:  assigned
    Component:  contrib.auth         |                  Version:  4.2
     Severity:  Normal               |               Resolution:
     Keywords:  async auth           |             Triage Stage:
  check_password                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Dingning:

Old description:

> When `settings.PASSWORD_HASHERS` is changed and `user.check_password()`
> is called in an async context, a `SynchronousOnlyOperation` exception may
> occur.
>
> The reason is that the check_password function will call the synchronous
> setter function to update the password field of the user table when the
> `settings.PASSWORD_HASHERS` is changed.
>

> == To reproduce the process:
> 1. Start Django and create a user. Suppose the user's password is 123456.
> 2. Close the server, modify `settings.PASSWORD_HASHERS`, for example,
> exchange the order of the first two Hashers. You can refer to
> `django.conf.global_settings.PASSWORD_HASHERS`.
> 3. Start the server and call `user.check_password('123456')` in the
> asynchronous view.
> 4. `SynchronousOnlyOperation` is raiesd.
>

> == Reference Code:
>
> {{{
> #!python
> from django.http import HttpResponse
> from django.contrib.auth import get_user_model
>

> async def test_check_password(request):
>     user = await get_user_model().objects.aget(id=1)
>     is_correct = user.check_password('123456')
>
>     return HttpResponse(is_correct)
> }}}
>

> == Significance:
> 1. When `settings.PASSWORD_HASHERS` changes, `check_password` and related
> functions can be called normally in an asynchronous environment.
> 2. Lay the foundation for the future `django.contrib.auth` module to
> support native asynchrony.
>

> == Solution:
> Add `acheck_password` method, this method will call the async setter
> function to update the password field of the user table when the
> `settings.PASSWORD_HASHERS` is changed.
>

> == Demo:
> I simply implemented the solution mentioned above and put it here for
> reference.
> https://github.com/HappyDingning/django/tree/acheck_password
>

> == Related discussions:
> https://forum.djangoproject.com/t/add-async-support-for-abstractbaseuser-
> check-password/20364
>
> Thanks to bigfootjon, carltongibson and UriahKingsley

New description:

 When `settings.PASSWORD_HASHERS` is changed and `user.check_password()` is
 called in an async context, a `SynchronousOnlyOperation` exception may
 occur.

 The reason is that the check_password function will call the synchronous
 setter function to update the password field of the user table when the
 `settings.PASSWORD_HASHERS` is changed.


 == To reproduce the process:
 1. Start Django and create a user. Suppose the user's password is 123456.
 2. Close the server, modify `settings.PASSWORD_HASHERS`, for example,
 exchange the order of the first two Hashers. You can refer to
 `django.conf.global_settings.PASSWORD_HASHERS`.
 3. Start the server and call `user.check_password('123456')` in the
 asynchronous view.
 4. `SynchronousOnlyOperation` is raiesd.


 == Reference Code:

 {{{
 #!python
 from django.http import HttpResponse
 from django.contrib.auth import get_user_model


 async def test_check_password(request):
     user = await get_user_model().objects.aget(id=1)
     is_correct = user.check_password('123456')

     return HttpResponse(is_correct)
 }}}


 == Significance:
 1. When `settings.PASSWORD_HASHERS` changes, `check_password` and related
 functions can be called normally in an asynchronous environment.
 2. Lay the foundation for the future `django.contrib.auth` module to
 support native async.


 == Solution:
 Add `acheck_password` method, this method will call the async setter
 function to update the password field of the user table when the
 `settings.PASSWORD_HASHERS` is changed.


 == Demo:
 I simply implemented the solution mentioned above and put it here for
 reference.
 https://github.com/HappyDingning/django/tree/acheck_password


 == Related discussions:
 https://forum.djangoproject.com/t/add-async-support-for-abstractbaseuser-
 check-password/20364

 Thanks to bigfootjon, carltongibson and UriahKingsley

--

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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701881bba352c-734af1fe-bc41-41ff-909e-f390187b9ed0-000000%40eu-central-1.amazonses.com.

Reply via email to