Code Monkey home page Code Monkey logo

django-allauth-2fa's Introduction

Welcome to django-allauth-2fa!

https://readthedocs.org/projects/django-allauth-2fa/badge/?version=latest

django-allauth-2fa adds two-factor authentication to django-allauth. django-allauth is a set of Django applications which help with authentication, registration, and other account management tasks.

Source code
http://github.com/percipient/django-allauth-2fa
Documentation
https://django-allauth-2fa.readthedocs.io/

Features

Compatibility

django-allauth-2fa attempts to maintain compatibility with supported versions of Django, django-allauth, and django-otp.

Current versions supported together is:

Django django-allauth django-otp Python
4.1 0.53.0 1.2 3.8, 3.9, 3.10, 3.11
4.2 0.53.0 1.2 3.8, 3.9, 3.10, 3.11

Contributing

django-allauth-2fa was initially created by Víðir Valberg Guðmundsson (@valberg), was maintained by Percipient Networks for many years, and is now maintained by Valohai. Please feel free to contribute if you find django-allauth-2fa useful!

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. If you feel uncomfortable or uncertain about an issue or your changes, feel free to email [email protected] and we will happily help you.
  3. Fork the repository on GitHub to start making your changes to the main branch (or branch off of it).
  4. Write a test which shows that the bug was fixed or that the feature works as expected.
  5. Send a pull request and bug the maintainer until it gets merged and published.

Start contributing

Start by cloning the project with:

git clone https://github.com/valohai/django-allauth-2fa.git

The project uses hatch for building and package management. If you don't have hatch installed, you can do so by running:

pip install hatch

Setup you virtual environment with hatch:

hatch env create

Running tests

Tests can be run using pytest

hatch run pytest

Running the test project

The test project can also be used as a minimal example using the following:

hatch run python manage.py migrate
hatch run python manage.py runserver

django-allauth-2fa's People

Contributors

9mido avatar akx avatar aqt01 avatar austintrose avatar beckedorf avatar chromakey avatar clokep avatar danielswain avatar dependabot[bot] avatar dicato avatar dmptrluke avatar erwinjunge avatar hailkomputer avatar humrochagf avatar illia-v avatar jduar avatar jeltef avatar jkaeske avatar mightyscollins avatar monosans avatar nicolaisoeborg avatar pennersr avatar pre-commit-ci[bot] avatar qvicksilver avatar ruksi avatar schrodingersgat avatar squio avatar stvnrlly avatar valberg avatar vgaicuks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-allauth-2fa's Issues

Exception when url has no name

When a URL has no name the following exception is thrown:
AttributeError: 'NoneType' object has no attribute 'startswith'
File "/usr/local/lib/python3.5/site-packages/allauth_2fa/middleware.py", line 18, in process_request

def process_request(self, request):
        if not resolve(request.path).url_name.startswith( # This does not always exist
                'two-factor-authenticate'):
            try:
                del request.session['allauth_2fa_user_id']
            except KeyError:
                pass

If I get time I'll make a PR. I could just add a name but an exception like this should not be thrown by a package.

Add license

Currently there is no license file in the repository.

Drop support for Django < 1.11

The newest version of django-allauth that was released (0.35) seems to drop support for Django < 1.11. We're using a couple of their compatibility tools that no longer exist.

Model class django_otp.plugins.otp_static.models.StaticDevice doesn't declare an explicit app_label

I'm trying to use this library. When i imported the views on my own urls.py using: from allauth_2fa import views i got the following error:

   File "C:\Users\User\Desktop\Heroku\github\backup\main\urls.py", line 20, in <module>
    from allauth_2fa import views
  File "C:\Users\User\lib\site-packages\allauth_2fa\views.py", line 23, in <module>
    from django_otp.plugins.otp_static.models import StaticToken
  File "C:\Users\User\lib\site-packages\django_otp\plugins\otp_static\models.py", line 11, in <module>
    class StaticDevice(Device):
  File "C:\Users\User\lib\site-packages\django\db\models\base.py", line 95, in __new__
    "INSTALLED_APPS." % (module, name)
RuntimeError: Model class django_otp.plugins.otp_static.models.StaticDevice doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

I don't understand if i'm doing something wrong, or the error is in the dependency module. Can anyone help me?

Release 0.6 missng 'two-factor-qr-code' reverse url

A quick test to add django-allauth-2fa to an existing project didn't work because the view two_factor/setup breaks on the reverse lookup of 'two-factor-qr-code'.

Our project uses pip3 with a requirements.txt file for deployment so there is no easy way to use a non-release version of the code.

Using Python 3.7.3

Relevant parts of requirements.txt:

Django~=2.2
django-allauth~=0.39
django-allauth-2fa~=0.6

The error message:

Request Method: | GET http://localhost/accounts/two_factor/setup
Django Version: 2.2.3
Exception: NoReverseMatch
Reverse for 'two-factor-qr-code' not found. 'two-factor-qr-code' is not a valid view function or pattern name.
/usr/local/lib/python3.7/site-packages/django/urls/resolvers.py in _reverse_with_prefix, line 668

It appears there are quite a few commits since the last 0.6 release which may fix thi issue already.

What is the timeline for a new release?

Clean-up URLs

The URLs we include are kind of a mess:

  • Some use dashes, others underscores
  • None of them have a trailing slash
  • Some are sub-directories, others are not

Theoretically we can just change these if people use names, but we would probably want to include redirects. It could also be nice to use a namespace.

Next query paramater is not used when enabling 2FA

Allauth uses a next GET parameter to get to redirect the user back to the page he tried to visit if it was auth only and the user was not logged in. After entering login credentials the next parameter is thrown away on the two-factor-authenticate page. This shouldn't happen, because now the user is redirected to the main login page instead of the page he tried to visit.

U2F support

Supporting U2F to be able to connect using a Yubikey would be a nice feature by integrating django-u2f or implementing it directly.

Accesing link "remove 2fa" when not strongly logged in

Hi,

When logging in (having 2FA enabled), we are automatically directed on the authenticate page. Which is normal, but then if I try to click on the link to disable the 2FA, I got a 500 error AttributeError: 'AnonymousUser' object has no attribute 'totpdevice_set'

Can you reproduce the bug ?

Thanks

two_factor/remove - StaticDevice matching query does not exist.

Maybe I am misunderstanding parts of django-allauth-2fa, but I encountered the bug above when trying to remove my two factor devices via the remove form.

The function seems to work fine if I have both, a TOTP device AND backup tokens. However, if no backup tokens were created ever "static_device = self.user.staticdevice_set.get(name='backup')" fails with a "DoesNotExist" exception and the tokens remain.

So the "Delete any backup tokens" section of TOTPDeviceRemoveForm has to be protected by a try/except clause that ignores backuptokens if none are present. Therefore I propose the following change:

class TOTPDeviceRemoveForm(forms.Form):
    def __init__(self, user, **kwargs):
        super(TOTPDeviceRemoveForm, self).__init__(**kwargs)
        self.user = user

    def save(self):
        # Delete any backup tokens.
        try:
            static_device = self.user.staticdevice_set.get(name='backup')
            static_device.token_set.all().delete()
            static_device.delete()
        except django_otp.plugins.otp_static.models.StaticDevice.DoesNotExist:
            pass

        # Delete TOTP device.
        device = TOTPDevice.objects.get(user=self.user)
        device.delete() 

Should backup codes be viewable more than once?

Currently backup codes are shown every time you go to the 2FA settings page. Most "big" websites will only show these to you once (but will let you completely regenerate them).

I'm unsure if there's a "best practice" here.

Require users to setup 2FA

It might be reasonable to have a mode where users are required to enable 2FA, i.e. they can only access the 2FA configuration page until it's enabled.

Using Email for Demo without TOTP

I am getting a crash when trying to use the otp_email by itself.

It appears the code calls allauth_2fa.utils.user_has_valid_totp_device() without checking to see which device(s) are installed. Since in our demo app we just have 'django_otp.plugins.otp_email', and none of the others devices installed we get the following error relation "django_otp_totpdevice" does not exist

Adding 'django_otp.plugins.otp_totp', to the INSTALLED_APP fixes this issue but then pushes the user through the TOTP flow instead of using email.

Given that there are other devices in the django_otp ecosystem (HOTP, Static, etc) it might be worthwhile to have user_has_valid_totp_device() replaced by something more generic user_has_valid_device with some logic to detect the install apps.

update README

To include:

  • initial credit to @valberg
  • being maintained by Percipient Networks
  • and a general once over of the file

How to get status

I wanna know about status: active it or not for user . How can I get it?

add unit tests

As the title suggest, this project could use some unit tests.

"staff_member_required"-solution in documentation (section installation at the end) leads to error for non_staff members

In the installation section of the documentation at the very end of the page, the following method is proposed to use the allauth authentication workflow (including two-factor authentication) for access the Django admin site:

admin.site.log = staff_member_required(admin.site.login, login_url = 'accounts/login')
admin.autodiscover()

However, if a registered user, who is not a staff member logs in, the result is an ERR_TOO_MANY_REDIRECTS error. I tried to come up with a solution by looking at the staff_member_required decorator in the django documentation but was not successful. I know it is not a django-allauth-2fa specific question, but since the above code snippet is from the documentation, I thought I give it a try.

unexpected behaviour of accounts/two_factor/setup/ -> page reload after pressing 'verify'

I am trying to use django-allauth & django-allauth-2fa in my Django app.

My django-allauth app is set uo correctly - everything is working as expected.

However, when trying to set up django-allauth-2fa I ran into some issues: Configuring a two-factor authentification at accounts/two_factor/setup/ when I scan the QR code, input the token generated and press verify the page simply reloads with a new QR code instead of leading me to the next step in the Two-Factor configuration workflow. I can't figure out what my mistake may be, as I set up everything as written in the django-allauth-2fa documentation

My Pipfile:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
django = "==3.0.0"
pylint = "==2.4.4"
django-crispy-forms = "==1.9"
django-allauth = "==0.42.0"
django-allauth-2fa = "==0.8"

[requires]
python_version = "3.7"

my settings.py file

...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',

    # Local
    'users.apps.UsersConfig',
    'pages.apps.PagesConfig',

    #Third-party
    'allauth',
    'allauth.account',
    'django_otp',
    'django_otp.plugins.otp_totp',
    'django_otp.plugins.otp_static',
    'allauth_2fa',
    'crispy_forms',
]



MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_otp.middleware.OTPMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'allauth_2fa.middleware.AllauthTwoFactorMiddleware',
]

SITE_ID = 1

ACCOUNT_ADAPTER = 'allauth_2fa.adapter.OTPAdapter'

...

my urls.py file

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth_2fa.urls')),
    path('accounts/', include('allauth.urls')),
    path('', include('pages.urls')),
]

And I also ran python manage.py migrate

Documentation error which can cause TFA bypass

The documentation, in the Installation section, has a warning at the end about the admin site, and then some sample code.

The sample code has an error which can result in TFA being bypassed for the admin site. The scenario is a site where some users do not have/need TFA, but all admin users do. Using the code provided, an attacker can login with a non-admin account without TFA. Then browse directly to the admin site, and are allowed to re-login there without TFA. The redirect provided in the documentation code:

admin.site.login = login_required(admin.site.login)

does not trigger the login_required wrapper because the user logged in already. They are instead taken directly to the admin site, which provides a login view that bypassess TFA.

FIX:

Instead of wrapping with login_required, wrap with staff_member_required:

`from django.contrib.admin.views.decorators import staff_member_required

admin.site.login = staff_member_required(admin.site.login, login_url='/accounts/login')`

This will the disallow showing the admin site to anyone not logged in as an admin, preventing the attack described.

Use of e.g. ServiceWorker makes login with 2FA impossible

When using a ServiceWorker, authentication with 2FA enabled is broken. Due to some limitations it is necessary to serve the workerscript from the root of the site. In case you run something like gunicorn behind a load balancer, you will most likely just save the worker script as a template file and serve it using a template view. However, combined with allauth_2fa this causes a problem that ultimately breaks authentication for all users that have 2FA enabled.

In the OTPAdapter (adapter.py line 22) user.id gets stored within the session:
request.session['allauth_2fa_user_id'] = str(user.id)

The presence of allauth_2fa_user_id in the session is then checked in the TwoFactorAuthenticate view, (views.py line 34) . In case it's not present, the user will be redirected to the login view. Otherwise the user with allauth_2fa_user_id will be put into kwargs and authentication will proceed.

allauth_2fa_user_id gets cleared from the session by means of AllauthTwoFactorMiddleware (middleware.py line 26).

When you happen to use a service worker, what will very frequently happen is:

  1. User with 2FA enabled wants to log in
  2. ServiceWorker checks if there is a new version available (requests e.g. /sw.js)
  3. User with 2FA enabled logs in via username and password
  4. allauth_2fa_user_id gets stored in the user's session
  5. User gets redirected to 2FA form
  6. ServiceWorker checks if there is a new version available (requests e.g. /sw.js)
  7. Because ServiceWorker has just requested "/sw.js", middleware removes allauth_2fa_user_id from the user's session, because the condition in middleware.py evaluates to true
  8. User enters his 2FA Token, but allauth_2fa_user_id is already gone and user is redirected to the login page

This szenario is not only limited to the usage ServiceWorkers, but is triggered everytime user makes (for whatever reason) a request between logging in and entering the 2FA token that causes the condition in the middleware to evaluate to true.

I am not sure what the best alternative solution is, or if there is any evil side effect, if we do not delete allauth_2fa_user_id at all. What do you guys suggest?

next url parameter is lost when going through 2fa

When I attempt to visit a page that requires authentication, I get redirected to the login form with a next parameter (e.g /login/?next/my/path). But when 2FA is enabled, this next redirect parameter is lost and I end up in the default account page.

The PR #44 seems to make sure that when I visit /two-factor-authenticate?next=/my/path then the query parameter is passed correctly.

But I think there is still a problem before: when submitting the first user/password form, the next parameter might be passed with a POST parameter, and when this happens the next path is lost. And the default template for allauth actually passes the next as a POST parameter, and not as a url query.

See attached screenshot, I end up in accounts/profile instead of my desired path

screenshot from 2017-06-27 16-33-30

I am running Django 1.11, allauth 0.32 and allauth-2fa 0.4.4

redirect_field_name is not passed to django-allauth-2fa

When using django-allauth and django-allauth-2fa the redirect_field_name is not passed to the 2fa login page. As you can see from the debug logs, first there is a POST to /accounts/login where the password of the user is checked and then, if required (based on BaseRequire2FAMiddleware) a GET to the two-factor-authenticate is executed - however the redirect_field_name value is gone.

Yes this is more of a problem with django-allauth but I was expecting a seamless integration. Any ideas what can be done? Right now I have my own adapter (inherited from allauth_2fa.adapter.OTPAdapter) where I can call get_login_redirect_url, however since the redirect_field value is gone, I have no way to build any logic as to where to redirect the user to.

[11/Oct/2020 12:14:35] INFO [django.server:154] "GET /admin/ HTTP/1.1" 302 0
[11/Oct/2020 12:14:35] INFO [django.server:154] "GET /admin/login/?next=/admin/ HTTP/1.1" 302 0
[11/Oct/2020 12:14:35] INFO [django.server:154] "GET /accounts/login?next=/admin/login/%3Fnext%3D/admin/ HTTP/1.1" 301 0
[11/Oct/2020 12:14:35] INFO [django.server:154] "GET /accounts/login/?next=/admin/login/%3Fnext%3D/admin/ HTTP/1.1" 200 23174
[11/Oct/2020 12:14:38] INFO [django.server:154] "POST /accounts/login/ HTTP/1.1" 302 0
[11/Oct/2020 12:14:38] INFO [django.server:154] "GET /two-factor-authenticate HTTP/1.1" 200 21569
[11/Oct/2020 12:14:43] INFO [django.server:154] "POST /two-factor-authenticate HTTP/1.1" 302 0
[11/Oct/2020 12:14:43] INFO [django.server:154] "GET / HTTP/1.1" 301 0

Redirect log out if not strongly authenticated

Hi,

While logged in but not yet input the 2FA code yet (so, on the authenticate page), when I try to access another URL, it directly logs me out. This is not a behavior that I want. I want to display the authenticate page again. Is there currently a way to do it ?

Thanks!

Loose strong dependencies

Currenty almost all dependencies in setup.py are exact. Is this really required?

"qrcode==5.1",
 "django-allauth==0.23.0",
"django-otp==0.3.1",

Python package version resolving not nearly as good as npm, unfortunately.

Make it easy to override base template

We should make it easy to override the base template (currently base.html). Upstream allauth uses account/base.html which by default is just a proxy for base.html, but using that structure makes it super easy to override the base template by creating a account/base.html file with different contents.

See https://github.com/pennersr/django-allauth/blob/master/allauth/templates/account/login.html#L1 and https://github.com/pennersr/django-allauth/blob/master/allauth/templates/account/base.html for context.

PR incoming.

Allow issuer for QR code to be customizable

Currently, the issuer for the qr code is hardcoded as part of the qr code generator view and always is the current django Site for the current request. https://github.com/percipient/django-allauth-2fa/blob/master/allauth_2fa/views.py#L206

If your site's 'name' is set some other way - for example if you're using Wagtail, which has its own site model - this is a problem, and there's not a good way to get around it without copying the entire qr generator view.

Proposed solution: add a get_issuer method to QRCodeGeneratorView that can be easily overridden to allow customization of the issuer name.

Fix up Codecov

  • Currently coverage reports are being generated somewhere within tox runs where the Codecov action can't find them.
    • Coverage should probably be merged from the various tox envs into a single file.
  • The readme still has a coveralls badge; should be a codecov badge.

Unable to login after setting up 2FA

After logging in and then navigating to /two_factor/setup/ and then successfully using Google Authenticator, and then navigating to /two_factor/backup_tokens/ and generating the backup tokens for an account, I logout of that account. When I try to login as that same account that was just setup to test the 2FA I am unable to login. After typing in my credentials and submitting the form then automatically navigating to /two-factor-authenticate, I get a page not found error.

Traceback:

[08/Feb/2020 23:51:25] "GET /accounts/login/?next=/memberships/profile/ HTTP/1.1" 200 11119
[08/Feb/2020 23:51:25] "GET /captcha/image/a0cfb5fe91bb6ee3caa7d92f053da85590d3bc12/ HTTP/1.1" 200 13165

(Type in the credentials then submit the form)

[08/Feb/2020 23:51:32] "POST /login/ HTTP/1.1" 302 0
Not Found: /two-factor-authenticate
[08/Feb/2020 23:51:32] "GET /two-factor-authenticate HTTP/1.1" 404 1767

New release?

I'm in need of a release with the redirect to next fix, can one be made soon?

Support Django 3.0 (/ drop support for Python 2.7)

Hi, I am currently evaluating upgrading a project to Django 3 and allauth-2fa is incompatible because dropped support of django.utils.six in version 3.

https://docs.djangoproject.com/en/3.0/releases/3.0/#removed-private-python-2-compatibility-apis

Here is a traceback of running allauth-2fa with Django 3.

|   File "/usr/local/lib/python3.7/site-packages/allauth_2fa/utils.py", line 8, in <module>
|     from django.utils.six import BytesIO
| ModuleNotFoundError: No module named 'django.utils.six'

Any plans to migrate to six and give support to Django 3?

Thank you

Change QR Code generation to enable displaying the secret

In some cases, a user may not be able to take a picture of the QR code. In those cases, some sites display the secret for the user to enter manually into their Authentication app.

Based on the way this package generates the QR code, I suspect it will take some refactoring to make this possible.

TypeError at /accounts/login/: Object of type 'UUID' is not JSON serializable

Howdy,
I have an existing project that's been using django-allauth successfully for several months now. I've setup django-allauth-2fa and I was able to successfully register a device. However, when I go to login, I get the following exception and traceback. I am using a UUIDField for my User model primary key. I am requiring that all users have 2FA enabled.

Thanks for all of your work on this project!

Environment:

Request Method: POST
Request URL: http://127.0.0.1:8000/accounts/login/

Django Version: 1.11.14
Python Version: 3.6.1

Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django_otp.middleware.OTPMiddleware',
 'allauth_2fa.middleware.AllauthTwoFactorMiddleware',
 'project.users.middleware.RequireSuperuser2FAMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'request_logging.middleware.LoggingMiddleware',
 'auditlog.middleware.AuditlogMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware']



Traceback:

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/utils/deprecation.py" in __call__
  142.             response = self.process_response(request, response)

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/middleware.py" in process_response
  58.                             request.session.save()

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py" in save
  81.             return self.create()

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py" in create
  54.                 self.save(must_create=True)

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py" in save
  83.         obj = self.create_model_instance(data)

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py" in create_model_instance
  69.             session_data=self.encode(data),

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py" in encode
  98.         serialized = self.serializer().dumps(session_dict)

File "/Users/chromakey/.virtualenvs/project/lib/python3.6/site-packages/django/core/signing.py" in dumps
  93.         return json.dumps(obj, separators=(',', ':')).encode('latin-1')

File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py" in dumps
  238.         **kw).encode(obj)

File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py" in encode
  199.         chunks = self.iterencode(o, _one_shot=True)

File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py" in iterencode
  257.         return _iterencode(o, 0)

File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py" in default
  180.                         o.__class__.__name__)

Exception Type: TypeError at /accounts/login/
Exception Value: Object of type 'UUID' is not JSON serializable

"two-factor-authenticate" remains accessible in the middle of a login flow

Hi,

Regarding the moment after clicking "Sign In" and before completing the 2FA form:

As addressed by issue #8, I know that going to any page other than "two-factor-authenticate" takes the user out of this intermediate state (by removing the "allauth_2fa_user_id" session key).

However, as long as I stay within the "two-factor-authenticate" page, it will remain in that state until the session expires. So, I can, for example, close the page, then reopen it several days later and the 2FA form will still be there waiting for the same user to type the token.

It seems like a behavior that could be potentially exploited. Should there be a mechanism against that? Maybe the session expiry time could be set to a small value, like 5 minutes, when reaching that state, then reset to a longer value only after the flow is completed?

Thank you in advance.

500 error on QRCodeGeneratorView with AnonymousUser

I don't know how a user can hit this since the setup page is protected from AnonymousUsers, but...I've seen some 500s on this page.

AttributeError: 'AnonymousUser' object has no attribute 'totpdevice_set'
  File "django/core/handlers/exception.py", line 39, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "allauth_2fa/views.py", line 158, in get
    device = request.user.totpdevice_set.filter(confirmed=False).first()
  File "django/utils/functional.py", line 235, in inner
    return func(self._wrapped, *args)
  File "django/utils/functional.py", line 235, in inner
    return func(self._wrapped, *args)

RequiredTwoFactor Middleware Setup Not Working

Hi,

I have a custom Middleware (source below) that should link whether two factor is required to a user model field. This is working and correctly determining when two factor should be required, and when not.

However, when a user for whom two factor is required logins, and is (correctly) redirected to the setup two factor page, the token is always coming back invalid. If a user doesn't have two factor required but setups up the two factor, the token works just fine.

Any ideas?

users.middleware.RequireTwoFactorRequiredMiddleware

from allauth_2fa.middleware import BaseRequire2FAMiddleware                                               
                                                                                                          
                                                                                                          
class RequireTwoFactorRequiredMiddleware(BaseRequire2FAMiddleware):                                       
    def require_2fa(self, request):                                                                       
        return request.user.two_factor_required

Middleware ordering:

'django_otp.middleware.OTPMiddleware',
'allauth_2fa.middleware.AllauthTwoFactorMiddleware',
'users.middleware.RequireTwoFactorRequiredMiddleware'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.