Stormbase / django-otp-webauthn

Passkey support for Django. Currently in early stages of development and not ready for production use!
BSD 3-Clause "New" or "Revised" License
10 stars 2 forks source link

TypeError at /webauthn/authentication/begin/ unsupported operand type(s) for 'in': 'str' and 'EnumType' #5

Closed jmichalicek closed 2 months ago

jmichalicek commented 2 months ago

I have installed django-otp-webauthn 0.1.2. I was able so successfully register a passkey but when I try to log in I get an http 500 error back and the following stack trace (as much I firefox would give me in the network inspector tab).

Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/sentry_sdk/integrations/django/views.py", line 90, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django/utils/decorators.py", line 48, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/views.py", line 58, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
    ^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/views.py", line 134, in post
    data, state = helper.authenticate_begin(user=user, require_user_verification=require_user_verification)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/helpers.py", line 491, in authenticate_begin
    kwargs = self.get_generate_authentication_options_kwargs(

  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/helpers.py", line 473, in get_generate_authentication_options_kwargs
    kwargs["allow_credentials"] = WebAuthnCredential.get_credential_descriptors_for_user(user)
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/models.py", line 315, in get_credential_descriptors_for_user
    if t in AuthenticatorTransport:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 740, in __contains__
    raise TypeError(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The important bit is this:

  File "/app/.venv/lib/python3.11/site-packages/django_otp_webauthn/models.py", line 315, in get_credential_descriptors_for_user
    if t in AuthenticatorTransport:

And the actual exception message TypeError at /webauthn/authentication/begin/ unsupported operand type(s) for 'in': 'str' and 'EnumType'

On the main branch, where that code lives has moved a bit, but it still exists. I can submit a fix this evening or this weekend. It should only take a few minutes to fix up.

Stormheg commented 2 months ago

Hi @jmichalicek, thanks for trying out django-otp-webauthn! The package is pretty new and not well tested yet, so bugs like this are bound to happen. I'm still working on a comprehensive test suite that will expose bugs like this.

I'd be very happy if you make a pull request that fixes the issue 👍

If you encounter any other bugs let me know in an issue.