Showing preview only (6,017K chars total). Download the full file or copy to clipboard to get everything.
Repository: pennersr/django-allauth
Branch: main
Commit: cf7f55d79e42
Files: 1853
Total size: 5.4 MB
Directory structure:
gitextract_12fbmuov/
├── .dir-locals.el
├── .djlintrc
├── .editorconfig
├── .envrc
├── .gitea/
│ ├── ISSUE_TEMPLATE/
│ │ ├── discussion.md
│ │ └── issue.md
│ └── pull_request_template.md
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ └── issue.md
│ ├── SECURITY.md
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .readthedocs.yaml
├── .woodpecker.yaml
├── AUTHORS
├── CONTRIBUTING.rst
├── ChangeLog.rst
├── LICENSE
├── Makefile
├── README.rst
├── allauth/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── auth_backends.py
│ │ ├── authentication.py
│ │ ├── checks.py
│ │ ├── decorators.py
│ │ ├── fields.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── decorators.py
│ │ │ ├── emailkit.py
│ │ │ ├── flows/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── code_verification.py
│ │ │ │ ├── email_verification.py
│ │ │ │ ├── email_verification_by_code.py
│ │ │ │ ├── login.py
│ │ │ │ ├── login_by_code.py
│ │ │ │ ├── logout.py
│ │ │ │ ├── manage_email.py
│ │ │ │ ├── password_change.py
│ │ │ │ ├── password_reset.py
│ │ │ │ ├── password_reset_by_code.py
│ │ │ │ ├── phone_verification.py
│ │ │ │ ├── reauthentication.py
│ │ │ │ └── signup.py
│ │ │ ├── stagekit.py
│ │ │ └── userkit.py
│ │ ├── management/
│ │ │ ├── __init__.py
│ │ │ └── commands/
│ │ │ ├── __init__.py
│ │ │ └── account_unsetmultipleprimaryemails.py
│ │ ├── managers.py
│ │ ├── middleware.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_email_max_length.py
│ │ │ ├── 0003_alter_emailaddress_create_unique_verified_email.py
│ │ │ ├── 0004_alter_emailaddress_drop_unique_email.py
│ │ │ ├── 0005_emailaddress_idx_upper_email.py
│ │ │ ├── 0006_emailaddress_lower.py
│ │ │ ├── 0007_emailaddress_idx_email.py
│ │ │ ├── 0008_emailaddress_unique_primary_email_fixup.py
│ │ │ ├── 0009_emailaddress_unique_primary_email.py
│ │ │ └── __init__.py
│ │ ├── mixins.py
│ │ ├── models.py
│ │ ├── reauthentication.py
│ │ ├── signals.py
│ │ ├── stages.py
│ │ ├── static/
│ │ │ └── account/
│ │ │ └── js/
│ │ │ ├── account.js
│ │ │ └── onload.js
│ │ ├── templatetags/
│ │ │ ├── __init__.py
│ │ │ └── account.py
│ │ ├── urls.py
│ │ ├── utils.py
│ │ └── views.py
│ ├── app_settings.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── context.py
│ │ ├── exceptions.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── adapter.py
│ │ │ ├── cryptokit.py
│ │ │ ├── httpkit.py
│ │ │ ├── jwkkit.py
│ │ │ ├── modelkit.py
│ │ │ ├── ratelimit.py
│ │ │ ├── sessionkit.py
│ │ │ └── urlkit.py
│ │ └── ratelimit.py
│ ├── decorators.py
│ ├── exceptions.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── account/
│ │ │ ├── __init__.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── adapter.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── checks.py
│ │ ├── constants.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── security.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── authentication.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── authkit.py
│ │ │ ├── decorators.py
│ │ │ ├── restkit/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── inputs.py
│ │ │ │ ├── response.py
│ │ │ │ └── views.py
│ │ │ └── sessionkit.py
│ │ ├── mfa/
│ │ │ ├── __init__.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── socialaccount/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── inputs.py
│ │ │ ├── internal.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── spec/
│ │ │ ├── __init__.py
│ │ │ ├── doc/
│ │ │ │ ├── description.md
│ │ │ │ └── openapi.yaml
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── openapikit.py
│ │ │ │ └── schema.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── templates/
│ │ │ └── headless/
│ │ │ └── spec/
│ │ │ ├── redoc_cdn.html
│ │ │ └── swagger_cdn.html
│ │ ├── tokens/
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── sessions.py
│ │ │ ├── strategies/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── jwt/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── internal.py
│ │ │ │ │ └── strategy.py
│ │ │ │ └── sessions.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── urls.py
│ │ └── usersessions/
│ │ ├── __init__.py
│ │ ├── inputs.py
│ │ ├── response.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── idp/
│ │ ├── __init__.py
│ │ ├── oidc/
│ │ │ ├── __init__.py
│ │ │ ├── adapter.py
│ │ │ ├── admin.py
│ │ │ ├── app_settings.py
│ │ │ ├── apps.py
│ │ │ ├── contrib/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── ninja/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── security.py
│ │ │ │ └── rest_framework/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── authentication.py
│ │ │ │ └── permissions.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clientkit.py
│ │ │ │ ├── flows.py
│ │ │ │ ├── oauthlib/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── authorization_codes.py
│ │ │ │ │ ├── device_codes.py
│ │ │ │ │ ├── request_validator.py
│ │ │ │ │ ├── server.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── scope.py
│ │ │ │ └── tokens.py
│ │ │ ├── migrations/
│ │ │ │ ├── 0001_initial.py
│ │ │ │ ├── 0002_client_default_scopes.py
│ │ │ │ ├── 0003_client_allow_uri_wildcards.py
│ │ │ │ └── __init__.py
│ │ │ ├── models.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── locale/
│ │ ├── ar/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── az/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── bg/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ca/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── cs/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── da/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── de/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── el/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── en/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── es/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── et/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── eu/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fa/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fi/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── he/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── hr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ht/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── hu/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── id/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── it/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ja/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ka/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ko/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ky/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── lt/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── lv/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── mn/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── nb/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── nl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pt_BR/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pt_PT/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ro/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ru/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sk/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sr_Latn/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sv/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── th/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── tr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── uk/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── uz/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── zh_Hans/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ └── zh_Hant/
│ │ └── LC_MESSAGES/
│ │ └── django.po
│ ├── mfa/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── checks.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ └── flows/
│ │ │ ├── __init__.py
│ │ │ ├── add.py
│ │ │ └── trust.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_authenticator_timestamps.py
│ │ │ ├── 0003_authenticator_type_uniq.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── recovery_codes/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── signals.py
│ │ ├── stages.py
│ │ ├── static/
│ │ │ └── mfa/
│ │ │ └── js/
│ │ │ ├── webauthn-json.js
│ │ │ └── webauthn.js
│ │ ├── totp/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── urls.py
│ │ ├── utils.py
│ │ └── webauthn/
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── auth.py
│ │ │ └── flows.py
│ │ ├── stages.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── models.py
│ ├── ratelimit.py
│ ├── socialaccount/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── checks.py
│ │ ├── forms.py
│ │ ├── helpers.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── flows/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── email_authentication.py
│ │ │ │ ├── login.py
│ │ │ │ └── signup.py
│ │ │ ├── jwtkit.py
│ │ │ └── statekit.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_token_max_lengths.py
│ │ │ ├── 0003_extra_data_default_dict.py
│ │ │ ├── 0004_app_provider_id_settings.py
│ │ │ ├── 0005_socialtoken_nullable_app.py
│ │ │ ├── 0006_alter_socialaccount_extra_data.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── providers/
│ │ │ ├── __init__.py
│ │ │ ├── agave/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── amazon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── amazon_cognito/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── angellist/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── apple/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── apple_session.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── asana/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── atlassian/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── auth0/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── authentiq/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── baidu/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── base/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── basecamp/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── battlenet/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── validators.py
│ │ │ │ └── views.py
│ │ │ ├── bitbucket_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── bitly/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── box/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── cilogon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── clever/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── coinbase/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dataporten/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── daum/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── digitalocean/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dingtalk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── discogs/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── discord/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── disqus/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── douban/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── doximity/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── draugiem/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── drip/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dropbox/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dummy/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── templates/
│ │ │ │ │ └── dummy/
│ │ │ │ │ └── authenticate_form.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dwolla/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── edmodo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── edx/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── eventbrite/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── eveonline/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── evernote/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── exist/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── facebook/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── data/
│ │ │ │ │ └── FacebookLocales.xml
│ │ │ │ ├── flows.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── locale.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── static/
│ │ │ │ │ └── facebook/
│ │ │ │ │ └── js/
│ │ │ │ │ └── fbconnect.js
│ │ │ │ ├── templates/
│ │ │ │ │ └── facebook/
│ │ │ │ │ └── fbconnect.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── feedly/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── feishu/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── figma/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── fivehundredpx/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── flickr/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── foursquare/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── frontier/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── fxa/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gitea/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── github/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gitlab/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── globus/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── google/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gumroad/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── hubic/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── hubspot/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── instagram/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── jupyterhub/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── kakao/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── lemonldap/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── lichess/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── line/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── linkedin_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailchimp/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailcow/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailru/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mediawiki/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── meetup/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── microsoft/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── miro/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── naver/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── netiq/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── nextcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── notion/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── oauth/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── oauth1_auth.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── odnoklassniki/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── okta/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── openid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── admin.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── migrations/
│ │ │ │ │ ├── 0001_initial.py
│ │ │ │ │ └── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── openid_connect/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── openstreetmap/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── orcid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── patreon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── paypal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── pinterest/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── pocket/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── questrade/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── quickbooks/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── reddit/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── robinhood/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── salesforce/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── saml/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── sharefile/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── shopify/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── slack/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── snapchat/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── soundcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── spotify/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stackexchange/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── steam/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stocktwits/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── strava/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stripe/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── telegram/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── static/
│ │ │ │ │ └── telegram/
│ │ │ │ │ └── js/
│ │ │ │ │ └── telegram.js
│ │ │ │ ├── templates/
│ │ │ │ │ └── telegram/
│ │ │ │ │ └── callback.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tiktok/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── scope.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── trainingpeaks/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── trello/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tumblr/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tumblr_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twentythreeandme/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitch/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitter/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitter_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── untappd/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vimeo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vimeo_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── wahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── weibo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── weixin/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── windowslive/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── xing/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── yahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── yandex/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── ynab/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── zoho/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ └── zoom/
│ │ │ ├── __init__.py
│ │ │ ├── provider.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── sessions.py
│ │ ├── signals.py
│ │ ├── templatetags/
│ │ │ ├── __init__.py
│ │ │ └── socialaccount.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── templates/
│ │ ├── account/
│ │ │ ├── account_inactive.html
│ │ │ ├── base_confirm_code.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── base_manage_email.html
│ │ │ ├── base_manage_password.html
│ │ │ ├── base_manage_phone.html
│ │ │ ├── base_reauthenticate.html
│ │ │ ├── confirm_email_verification_code.html
│ │ │ ├── confirm_login_code.html
│ │ │ ├── confirm_password_reset_code.html
│ │ │ ├── confirm_phone_verification_code.html
│ │ │ ├── email/
│ │ │ │ ├── account_already_exists_message.txt
│ │ │ │ ├── account_already_exists_subject.txt
│ │ │ │ ├── base_message.txt
│ │ │ │ ├── base_notification.txt
│ │ │ │ ├── email_changed_message.txt
│ │ │ │ ├── email_changed_subject.txt
│ │ │ │ ├── email_confirm_message.txt
│ │ │ │ ├── email_confirm_subject.txt
│ │ │ │ ├── email_confirmation_message.txt
│ │ │ │ ├── email_confirmation_signup_message.txt
│ │ │ │ ├── email_confirmation_signup_subject.txt
│ │ │ │ ├── email_confirmation_subject.txt
│ │ │ │ ├── email_deleted_message.txt
│ │ │ │ ├── email_deleted_subject.txt
│ │ │ │ ├── login_code_message.txt
│ │ │ │ ├── login_code_subject.txt
│ │ │ │ ├── password_changed_message.txt
│ │ │ │ ├── password_changed_subject.txt
│ │ │ │ ├── password_reset_code_message.txt
│ │ │ │ ├── password_reset_code_subject.txt
│ │ │ │ ├── password_reset_key_message.txt
│ │ │ │ ├── password_reset_key_subject.txt
│ │ │ │ ├── password_reset_message.txt
│ │ │ │ ├── password_reset_subject.txt
│ │ │ │ ├── password_set_message.txt
│ │ │ │ ├── password_set_subject.txt
│ │ │ │ ├── unknown_account_message.txt
│ │ │ │ └── unknown_account_subject.txt
│ │ │ ├── email.html
│ │ │ ├── email_change.html
│ │ │ ├── email_confirm.html
│ │ │ ├── login.html
│ │ │ ├── logout.html
│ │ │ ├── messages/
│ │ │ │ ├── cannot_delete_primary_email.txt
│ │ │ │ ├── email_confirmation_failed.txt
│ │ │ │ ├── email_confirmation_sent.txt
│ │ │ │ ├── email_confirmed.txt
│ │ │ │ ├── email_deleted.txt
│ │ │ │ ├── logged_in.txt
│ │ │ │ ├── logged_out.txt
│ │ │ │ ├── login_code_sent.txt
│ │ │ │ ├── password_changed.txt
│ │ │ │ ├── password_set.txt
│ │ │ │ ├── phone_verification_sent.txt
│ │ │ │ ├── phone_verified.txt
│ │ │ │ ├── primary_email_set.txt
│ │ │ │ └── unverified_primary_email.txt
│ │ │ ├── password_change.html
│ │ │ ├── password_reset.html
│ │ │ ├── password_reset_done.html
│ │ │ ├── password_reset_from_key.html
│ │ │ ├── password_reset_from_key_done.html
│ │ │ ├── password_set.html
│ │ │ ├── phone_change.html
│ │ │ ├── reauthenticate.html
│ │ │ ├── request_login_code.html
│ │ │ ├── signup.html
│ │ │ ├── signup_by_passkey.html
│ │ │ ├── signup_closed.html
│ │ │ ├── snippets/
│ │ │ │ ├── already_logged_in.html
│ │ │ │ └── warn_no_email.html
│ │ │ ├── verification_sent.html
│ │ │ └── verified_email_required.html
│ │ ├── allauth/
│ │ │ ├── elements/
│ │ │ │ ├── alert.html
│ │ │ │ ├── badge.html
│ │ │ │ ├── button.html
│ │ │ │ ├── button_group.html
│ │ │ │ ├── details.html
│ │ │ │ ├── field.html
│ │ │ │ ├── fields.html
│ │ │ │ ├── form.html
│ │ │ │ ├── h1.html
│ │ │ │ ├── h2.html
│ │ │ │ ├── hr.html
│ │ │ │ ├── img.html
│ │ │ │ ├── p.html
│ │ │ │ ├── panel.html
│ │ │ │ ├── provider.html
│ │ │ │ ├── provider_list.html
│ │ │ │ ├── table.html
│ │ │ │ ├── tbody.html
│ │ │ │ ├── td.html
│ │ │ │ ├── th.html
│ │ │ │ ├── thead.html
│ │ │ │ └── tr.html
│ │ │ └── layouts/
│ │ │ ├── base.html
│ │ │ ├── entrance.html
│ │ │ └── manage.html
│ │ ├── idp/
│ │ │ └── oidc/
│ │ │ ├── authorization_form.html
│ │ │ ├── base.html
│ │ │ ├── device_authorization_code_form.html
│ │ │ ├── device_authorization_confirm_form.html
│ │ │ ├── device_authorization_confirmed.html
│ │ │ ├── device_authorization_denied.html
│ │ │ ├── error.html
│ │ │ └── logout.html
│ │ ├── mfa/
│ │ │ ├── authenticate.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── email/
│ │ │ │ ├── recovery_codes_generated_message.txt
│ │ │ │ ├── recovery_codes_generated_subject.txt
│ │ │ │ ├── totp_activated_message.txt
│ │ │ │ ├── totp_activated_subject.txt
│ │ │ │ ├── totp_deactivated_message.txt
│ │ │ │ ├── totp_deactivated_subject.txt
│ │ │ │ ├── webauthn_added_message.txt
│ │ │ │ ├── webauthn_added_subject.txt
│ │ │ │ ├── webauthn_removed_message.txt
│ │ │ │ └── webauthn_removed_subject.txt
│ │ │ ├── index.html
│ │ │ ├── messages/
│ │ │ │ ├── recovery_codes_generated.txt
│ │ │ │ ├── totp_activated.txt
│ │ │ │ ├── totp_deactivated.txt
│ │ │ │ ├── webauthn_added.txt
│ │ │ │ └── webauthn_removed.txt
│ │ │ ├── reauthenticate.html
│ │ │ ├── recovery_codes/
│ │ │ │ ├── base.html
│ │ │ │ ├── download.txt
│ │ │ │ ├── generate.html
│ │ │ │ └── index.html
│ │ │ ├── totp/
│ │ │ │ ├── activate_form.html
│ │ │ │ ├── base.html
│ │ │ │ └── deactivate_form.html
│ │ │ ├── trust.html
│ │ │ └── webauthn/
│ │ │ ├── add_form.html
│ │ │ ├── authenticator_confirm_delete.html
│ │ │ ├── authenticator_list.html
│ │ │ ├── base.html
│ │ │ ├── edit_form.html
│ │ │ ├── reauthenticate.html
│ │ │ ├── signup_form.html
│ │ │ └── snippets/
│ │ │ ├── login_script.html
│ │ │ └── scripts.html
│ │ ├── openid/
│ │ │ ├── base.html
│ │ │ └── login.html
│ │ ├── socialaccount/
│ │ │ ├── authentication_error.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── connections.html
│ │ │ ├── email/
│ │ │ │ ├── account_connected_message.txt
│ │ │ │ ├── account_connected_subject.txt
│ │ │ │ ├── account_disconnected_message.txt
│ │ │ │ └── account_disconnected_subject.txt
│ │ │ ├── login.html
│ │ │ ├── login_cancelled.html
│ │ │ ├── login_redirect.html
│ │ │ ├── messages/
│ │ │ │ ├── account_connected.txt
│ │ │ │ ├── account_connected_other.txt
│ │ │ │ ├── account_connected_updated.txt
│ │ │ │ └── account_disconnected.txt
│ │ │ ├── signup.html
│ │ │ └── snippets/
│ │ │ ├── login.html
│ │ │ ├── login_extra.html
│ │ │ └── provider_list.html
│ │ └── usersessions/
│ │ ├── base_manage.html
│ │ ├── messages/
│ │ │ └── sessions_logged_out.txt
│ │ └── usersession_list.html
│ ├── templatetags/
│ │ ├── __init__.py
│ │ └── allauth.py
│ ├── urls.py
│ ├── usersessions/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── flows/
│ │ │ ├── __init__.py
│ │ │ └── sessions.py
│ │ ├── middleware.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── signals.py
│ │ ├── urls.py
│ │ └── views.py
│ └── utils.py
├── devenv.nix
├── devenv.yaml
├── docs/
│ ├── Makefile
│ ├── account/
│ │ ├── adapter.rst
│ │ ├── advanced.rst
│ │ ├── configuration.rst
│ │ ├── decorators.rst
│ │ ├── email.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── phone.rst
│ │ ├── rate_limits.rst
│ │ ├── signals.rst
│ │ ├── templates.rst
│ │ └── views.rst
│ ├── common/
│ │ ├── admin.rst
│ │ ├── configuration.rst
│ │ ├── email.rst
│ │ ├── index.rst
│ │ ├── messages.rst
│ │ ├── rate_limits.rst
│ │ └── templates.rst
│ ├── conf.py
│ ├── faq.rst
│ ├── headless/
│ │ ├── adapter.rst
│ │ ├── api.rst
│ │ ├── configuration.rst
│ │ ├── cors.rst
│ │ ├── faq.rst
│ │ ├── index.rst
│ │ ├── installation.rst
│ │ ├── introduction.rst
│ │ ├── openapi-specification/
│ │ │ └── index.html
│ │ └── token-strategies/
│ │ ├── abstract-strategy.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── jwt-tokens.rst
│ │ └── session-tokens.rst
│ ├── idp/
│ │ ├── index.rst
│ │ └── openid-connect/
│ │ ├── adapter.rst
│ │ ├── clients.rst
│ │ ├── configuration.rst
│ │ ├── index.rst
│ │ ├── installation.rst
│ │ ├── integrations.rst
│ │ ├── introduction.rst
│ │ └── views.rst
│ ├── index.rst
│ ├── installation/
│ │ ├── examples.rst
│ │ ├── index.rst
│ │ ├── quickstart.rst
│ │ └── requirements.rst
│ ├── introduction/
│ │ └── index.rst
│ ├── mfa/
│ │ ├── adapter.rst
│ │ ├── configuration.rst
│ │ ├── django-allauth-2fa.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ └── webauthn.rst
│ ├── project/
│ │ ├── contributing.rst
│ │ ├── funding.rst
│ │ ├── index.rst
│ │ └── support.rst
│ ├── release-notes/
│ │ ├── 2012.rst
│ │ ├── 2013.rst
│ │ ├── 2014.rst
│ │ ├── 2015.rst
│ │ ├── 2016.rst
│ │ ├── 2017.rst
│ │ ├── 2018.rst
│ │ ├── 2019.rst
│ │ ├── 2020.rst
│ │ ├── 2021.rst
│ │ ├── 2022.rst
│ │ ├── 2023.rst
│ │ ├── 2024.rst
│ │ ├── history.rst
│ │ ├── index.rst
│ │ └── recent.rst
│ ├── requirements.txt
│ ├── settings.py
│ ├── socialaccount/
│ │ ├── adapter.rst
│ │ ├── advanced.rst
│ │ ├── configuration.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── provider_configuration.rst
│ │ ├── providers/
│ │ │ ├── 23andme.rst
│ │ │ ├── 500px.rst
│ │ │ ├── agave.rst
│ │ │ ├── amazon.rst
│ │ │ ├── amazon_cognito.rst
│ │ │ ├── angellist.rst
│ │ │ ├── apple.rst
│ │ │ ├── atlassian.rst
│ │ │ ├── auth0.rst
│ │ │ ├── authelia.rst
│ │ │ ├── authentiq.rst
│ │ │ ├── baidu.rst
│ │ │ ├── basecamp.rst
│ │ │ ├── battlenet.rst
│ │ │ ├── bitbucket.rst
│ │ │ ├── box.rst
│ │ │ ├── cern.rst
│ │ │ ├── cilogon.rst
│ │ │ ├── clever.rst
│ │ │ ├── dataporten.rst
│ │ │ ├── daum.rst
│ │ │ ├── digitalocean.rst
│ │ │ ├── dingtalk.rst
│ │ │ ├── discogs.rst
│ │ │ ├── discord.rst
│ │ │ ├── doximity.rst
│ │ │ ├── draugiem.rst
│ │ │ ├── drip.rst
│ │ │ ├── dropbox.rst
│ │ │ ├── dwolla.rst
│ │ │ ├── edmodo.rst
│ │ │ ├── edx.rst
│ │ │ ├── eventbrite.rst
│ │ │ ├── eveonline.rst
│ │ │ ├── evernote.rst
│ │ │ ├── exist.rst
│ │ │ ├── facebook.rst
│ │ │ ├── feishu.rst
│ │ │ ├── figma.rst
│ │ │ ├── flickr.rst
│ │ │ ├── frontier.rst
│ │ │ ├── fxa.rst
│ │ │ ├── gitea.rst
│ │ │ ├── github.rst
│ │ │ ├── gitlab.rst
│ │ │ ├── globus.rst
│ │ │ ├── google.rst
│ │ │ ├── gumroad.rst
│ │ │ ├── hubspot.rst
│ │ │ ├── index.rst
│ │ │ ├── instagram.rst
│ │ │ ├── jupyterhub.rst
│ │ │ ├── kakao.rst
│ │ │ ├── keycloak.rst
│ │ │ ├── lemonldap.rst
│ │ │ ├── lichess.rst
│ │ │ ├── line.rst
│ │ │ ├── linkedin.rst
│ │ │ ├── mailchimp.rst
│ │ │ ├── mailcow.rst
│ │ │ ├── mediawiki.rst
│ │ │ ├── microsoft.rst
│ │ │ ├── miro.rst
│ │ │ ├── naver.rst
│ │ │ ├── netiq.rst
│ │ │ ├── nextcloud.rst
│ │ │ ├── notion.rst
│ │ │ ├── oauth2.rst
│ │ │ ├── odnoklassniki.rst
│ │ │ ├── okta.rst
│ │ │ ├── openid.rst
│ │ │ ├── openid_connect.rst
│ │ │ ├── openstreetmap.rst
│ │ │ ├── orcid.rst
│ │ │ ├── patreon.rst
│ │ │ ├── paypal.rst
│ │ │ ├── pinterest.rst
│ │ │ ├── pocket.rst
│ │ │ ├── questrade.rst
│ │ │ ├── quickbooks.rst
│ │ │ ├── reddit.rst
│ │ │ ├── salesforce.rst
│ │ │ ├── saml.rst
│ │ │ ├── sharefile.rst
│ │ │ ├── shopify.rst
│ │ │ ├── slack.rst
│ │ │ ├── snapchat.rst
│ │ │ ├── soundcloud.rst
│ │ │ ├── stackexchange.rst
│ │ │ ├── steam.rst
│ │ │ ├── stocktwits.rst
│ │ │ ├── strava.rst
│ │ │ ├── stripe.rst
│ │ │ ├── telegram.rst
│ │ │ ├── tiktok.rst
│ │ │ ├── trainingpeaks.rst
│ │ │ ├── trello.rst
│ │ │ ├── tumblr_oauth2.rst
│ │ │ ├── twitch.rst
│ │ │ ├── twitter.rst
│ │ │ ├── twitter_oauth2.rst
│ │ │ ├── untappd.rst
│ │ │ ├── vimeo.rst
│ │ │ ├── vimeo_oauth2.rst
│ │ │ ├── vk.rst
│ │ │ ├── wahoo.rst
│ │ │ ├── weibo.rst
│ │ │ ├── weixin.rst
│ │ │ ├── windowslive.rst
│ │ │ ├── xing.rst
│ │ │ ├── yahoo.rst
│ │ │ ├── yandex.rst
│ │ │ ├── ynab.rst
│ │ │ ├── zoho.rst
│ │ │ └── zoom.rst
│ │ ├── signals.rst
│ │ ├── templates.rst
│ │ └── views.rst
│ └── usersessions/
│ ├── adapter.rst
│ ├── configuration.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── introduction.rst
│ └── signals.rst
├── examples/
│ ├── react-spa/
│ │ ├── Makefile
│ │ ├── README.org
│ │ ├── backend/
│ │ │ ├── Dockerfile
│ │ │ ├── backend/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── asgi.py
│ │ │ │ ├── drf_demo/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── serializers.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ └── views.py
│ │ │ │ ├── ninja_demo/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ └── views.py
│ │ │ │ ├── settings.py
│ │ │ │ ├── urls.py
│ │ │ │ └── wsgi.py
│ │ │ ├── manage.py
│ │ │ └── requirements.txt
│ │ ├── docker-compose.dev.yml
│ │ ├── docker-compose.yml
│ │ ├── e2e.spec.js
│ │ ├── frontend/
│ │ │ ├── Dockerfile
│ │ │ ├── package.json
│ │ │ ├── public/
│ │ │ │ ├── css/
│ │ │ │ │ └── style.css
│ │ │ │ └── index.html
│ │ │ └── src/
│ │ │ ├── App.js
│ │ │ ├── Calculator.js
│ │ │ ├── Home.js
│ │ │ ├── NavBar.js
│ │ │ ├── Root.js
│ │ │ ├── Router.js
│ │ │ ├── account/
│ │ │ │ ├── AuthenticateFlow.js
│ │ │ │ ├── ChangeEmail.js
│ │ │ │ ├── ChangePassword.js
│ │ │ │ ├── ConfirmLoginCode.js
│ │ │ │ ├── ConfirmPasswordResetCode.js
│ │ │ │ ├── Login.js
│ │ │ │ ├── Logout.js
│ │ │ │ ├── Reauthenticate.js
│ │ │ │ ├── ReauthenticateFlow.js
│ │ │ │ ├── RequestLoginCode.js
│ │ │ │ ├── RequestPasswordReset.js
│ │ │ │ ├── ResetPassword.js
│ │ │ │ ├── Signup.js
│ │ │ │ ├── VerificationEmailSent.js
│ │ │ │ ├── VerifyEmail.js
│ │ │ │ └── VerifyEmailByCode.js
│ │ │ ├── auth/
│ │ │ │ ├── AuthContext.js
│ │ │ │ ├── hooks.js
│ │ │ │ ├── index.js
│ │ │ │ └── routing.js
│ │ │ ├── components/
│ │ │ │ ├── Button.js
│ │ │ │ └── FormErrors.js
│ │ │ ├── index.js
│ │ │ ├── init.js
│ │ │ ├── lib/
│ │ │ │ ├── allauth.js
│ │ │ │ └── django.js
│ │ │ ├── mfa/
│ │ │ │ ├── ActivateTOTP.js
│ │ │ │ ├── AddWebAuthn.js
│ │ │ │ ├── AuthenticateCode.js
│ │ │ │ ├── AuthenticateFlow.js
│ │ │ │ ├── AuthenticateRecoveryCodes.js
│ │ │ │ ├── AuthenticateTOTP.js
│ │ │ │ ├── AuthenticateWebAuthn.js
│ │ │ │ ├── CreateSignupPasskey.js
│ │ │ │ ├── DeactivateTOTP.js
│ │ │ │ ├── GenerateRecoveryCodes.js
│ │ │ │ ├── ListWebAuthn.js
│ │ │ │ ├── MFAOverview.js
│ │ │ │ ├── ReauthenticateCode.js
│ │ │ │ ├── ReauthenticateRecoveryCodes.js
│ │ │ │ ├── ReauthenticateTOTP.js
│ │ │ │ ├── ReauthenticateWebAuthn.js
│ │ │ │ ├── RecoveryCodes.js
│ │ │ │ ├── SignupByPasskey.js
│ │ │ │ ├── Trust.js
│ │ │ │ └── WebAuthnLoginButton.js
│ │ │ ├── socialaccount/
│ │ │ │ ├── GoogleOneTap.js
│ │ │ │ ├── ManageProviders.js
│ │ │ │ ├── ProviderCallback.js
│ │ │ │ ├── ProviderList.js
│ │ │ │ └── ProviderSignup.js
│ │ │ └── usersessions/
│ │ │ └── Sessions.js
│ │ └── traefik.toml
│ └── regular-django/
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── Makefile
│ ├── README.org
│ ├── db/
│ │ └── .gitignore
│ ├── docker-compose.yml
│ ├── example/
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── templates/
│ │ │ ├── 429.html
│ │ │ ├── account/
│ │ │ │ ├── base_manage_email.html
│ │ │ │ ├── base_manage_password.html
│ │ │ │ └── base_manage_phone.html
│ │ │ ├── allauth/
│ │ │ │ ├── elements/
│ │ │ │ │ ├── alert.html
│ │ │ │ │ ├── badge.html
│ │ │ │ │ ├── button.html
│ │ │ │ │ ├── button__entrance.html
│ │ │ │ │ ├── button_group.html
│ │ │ │ │ ├── field.html
│ │ │ │ │ ├── fields.html
│ │ │ │ │ ├── form.html
│ │ │ │ │ ├── form__entrance.html
│ │ │ │ │ ├── h1.html
│ │ │ │ │ ├── h1__entrance.html
│ │ │ │ │ ├── h2__entrance.html
│ │ │ │ │ ├── img.html
│ │ │ │ │ ├── panel.html
│ │ │ │ │ ├── provider.html
│ │ │ │ │ ├── provider_list.html
│ │ │ │ │ └── table.html
│ │ │ │ └── layouts/
│ │ │ │ ├── base.html
│ │ │ │ ├── entrance.html
│ │ │ │ └── manage.html
│ │ │ ├── index.html
│ │ │ ├── mfa/
│ │ │ │ └── base_manage.html
│ │ │ ├── profile.html
│ │ │ ├── socialaccount/
│ │ │ │ └── base_manage.html
│ │ │ └── usersessions/
│ │ │ └── base_manage.html
│ │ ├── urls.py
│ │ ├── users/
│ │ │ ├── __init__.py
│ │ │ ├── allauth.py
│ │ │ ├── apps.py
│ │ │ ├── migrations/
│ │ │ │ ├── 0001_initial.py
│ │ │ │ └── __init__.py
│ │ │ └── models.py
│ │ └── wsgi.py
│ ├── manage.py
│ └── requirements.txt
├── manage.py
├── mise.toml
├── noxfile.py
├── package.json
├── pyproject.toml
├── pytest.ini
├── requirements-dev.txt
├── setup.cfg
└── tests/
├── __init__.py
├── apps/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── test_emailkit.py
│ │ ├── test_adapter.py
│ │ ├── test_ajax.py
│ │ ├── test_auth_backends.py
│ │ ├── test_change_email.py
│ │ ├── test_change_password.py
│ │ ├── test_commands.py
│ │ ├── test_decorators.py
│ │ ├── test_email_verification.py
│ │ ├── test_email_verification_by_code.py
│ │ ├── test_login.py
│ │ ├── test_login_by_code.py
│ │ ├── test_logout.py
│ │ ├── test_middleware.py
│ │ ├── test_models.py
│ │ ├── test_phone.py
│ │ ├── test_ratelimit.py
│ │ ├── test_reauthentication.py
│ │ ├── test_reset_password.py
│ │ ├── test_reset_password_by_code.py
│ │ ├── test_security.py
│ │ ├── test_signup.py
│ │ └── test_utils.py
│ ├── core/
│ │ ├── __init__.py
│ │ └── internal/
│ │ ├── __init__.py
│ │ ├── test_cryptokit.py
│ │ ├── test_httpkit.py
│ │ ├── test_modelkit.py
│ │ └── test_ratelimit.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── account/
│ │ │ ├── __init__.py
│ │ │ ├── test_change_email.py
│ │ │ ├── test_change_password.py
│ │ │ ├── test_email_verification.py
│ │ │ ├── test_email_verification_by_code.py
│ │ │ ├── test_login.py
│ │ │ ├── test_login_by_code.py
│ │ │ ├── test_phone.py
│ │ │ ├── test_reauthentication.py
│ │ │ ├── test_reset_password.py
│ │ │ ├── test_reset_password_by_code.py
│ │ │ ├── test_session.py
│ │ │ └── test_signup.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ └── test_views.py
│ │ ├── conftest.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_security.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── test_authentication.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── test_authkit.py
│ │ ├── mfa/
│ │ │ ├── __init__.py
│ │ │ ├── test_recovery_codes.py
│ │ │ ├── test_totp.py
│ │ │ ├── test_trust.py
│ │ │ ├── test_views.py
│ │ │ └── test_webauthn.py
│ │ ├── socialaccount/
│ │ │ ├── __init__.py
│ │ │ ├── test_inputs.py
│ │ │ └── test_views.py
│ │ ├── spec/
│ │ │ ├── __init__.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_openapikit.py
│ │ │ └── test_views.py
│ │ ├── tokens/
│ │ │ ├── test_jwttokenstrategy.py
│ │ │ └── test_tokens.py
│ │ └── usersessions/
│ │ ├── __init__.py
│ │ └── test_views.py
│ ├── idp/
│ │ ├── __init__.py
│ │ └── oidc/
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_views.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── test_views.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── oauthlib/
│ │ │ ├── __init__.py
│ │ │ ├── test_request_validator.py
│ │ │ └── test_utils.py
│ │ ├── test_authorization.py
│ │ ├── test_device.py
│ │ ├── test_rp_initiated_logout.py
│ │ ├── test_tokens.py
│ │ ├── test_views.py
│ │ └── test_wildcards.py
│ ├── mfa/
│ │ ├── __init__.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── test_adapter.py
│ │ │ ├── test_trust.py
│ │ │ ├── test_trust_fingerprint.py
│ │ │ └── test_views.py
│ │ ├── recovery_codes/
│ │ │ ├── __init__.py
│ │ │ ├── test_auth.py
│ │ │ └── test_views.py
│ │ ├── totp/
│ │ │ ├── __init__.py
│ │ │ ├── test_unit.py
│ │ │ └── test_views.py
│ │ └── webauthn/
│ │ ├── __init__.py
│ │ └── test_views.py
│ ├── socialaccount/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── conftest.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── test_jwtkit.py
│ │ │ └── test_statekit.py
│ │ ├── providers/
│ │ │ ├── __init__.py
│ │ │ ├── agave/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── amazon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── amazon_cognito/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── angellist/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── apple/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── asana/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── atlassian/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── auth0/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── authentiq/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── baidu/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── base/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_provider.py
│ │ │ ├── basecamp/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── battlenet/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── bitbucket_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── bitly/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── box/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── cilogon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── clever/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── coinbase/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dataporten/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── daum/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── digitalocean/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dingtalk/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── discogs/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── discord/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── disqus/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── douban/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── doximity/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── draugiem/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── drip/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dropbox/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dummy/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dwolla/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── edmodo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── edx/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── eventbrite/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── eveonline/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── evernote/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── exist/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── facebook/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── feedly/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── feishu/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── figma/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── fivehundredpx/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── flickr/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── foursquare/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── frontier/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── fxa/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gitea/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── github/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gitlab/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── globus/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── google/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gumroad/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── hubic/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── hubspot/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── instagram/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── jupyterhub/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── kakao/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── lemonldap/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── lichess/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── line/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── linkedin_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailchimp/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailcow/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailru/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mediawiki/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── meetup/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── microsoft/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── miro/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── naver/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── netiq/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── nextcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── notion/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests/
│ │ │ │ └── test_views.py
│ │ │ ├── odnoklassniki/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── okta/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openid/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openid_connect/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openstreetmap/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── orcid/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── patreon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── paypal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── pinterest/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── pocket/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── questrade/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── quickbooks/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── reddit/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── robinhood/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── salesforce/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── saml/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ └── tests.py
│ │ │ ├── sharefile/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── shopify/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── slack/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── snapchat/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── soundcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── spotify/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stackexchange/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── steam/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stocktwits/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── strava/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stripe/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── telegram/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tiktok/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── trainingpeaks/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── trello/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tumblr/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tumblr_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twentythreeandme/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitch/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitter/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitter_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── untappd/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vimeo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vimeo_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vk/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── wahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── weibo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── weixin/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── windowslive/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── xing/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── yahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── yandex/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── ynab/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── zoho/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ └── zoom/
│ │ │ ├── __init__.py
│ │ │ └── tests.py
│ │ ├── test_adapter.py
│ │ ├── test_connect.py
│ │ ├── test_login.py
│ │ ├── test_phone.py
│ │ ├── test_registry.py
│ │ ├── test_signup.py
│ │ └── test_utils.py
│ ├── test_utils.py
│ └── usersessions/
│ ├── __init__.py
│ ├── test_middleware.py
│ └── test_views.py
├── conftest.py
├── mocking.py
└── projects/
├── account_only/
│ ├── __init__.py
│ ├── settings.py
│ ├── templates/
│ │ └── 429.html
│ └── urls.py
├── common/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── adapters.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── ninja/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── rest_framework/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── idp/
│ │ ├── __init__.py
│ │ ├── ninja/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── rest_framework/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── phone_stub.py
│ ├── settings.py
│ ├── templates/
│ │ └── test_403_csrf.html
│ └── urls.py
├── headless_only/
│ ├── __init__.py
│ ├── settings.py
│ └── urls.py
├── login_required_mw/
│ ├── __init__.py
│ ├── middleware.py
│ ├── settings.py
│ ├── templates/
│ │ └── 429.html
│ └── urls.py
└── regular/
├── __init__.py
├── settings.py
└── urls.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .dir-locals.el
================================================
;;; This file contains project-specific emacs configuration
((python-mode . ((apheleia-formatter . (black isort)))))
================================================
FILE: .djlintrc
================================================
{
"custom_blocks": "element,slot,setvar"
}
================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.ini]
indent_size = 4
[*.py]
indent_size = 4
[*.html]
indent_size = 4
[Makefile]
indent_style = tab
indent_size = 8
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
================================================
FILE: .envrc
================================================
export DIRENV_WARN_TIMEOUT=20s
eval "$(devenv direnvrc)"
# The use_devenv function supports passing flags to the devenv command
# For example: use devenv --impure --option services.postgres.enable:bool true
use devenv
================================================
FILE: .gitea/ISSUE_TEMPLATE/discussion.md
================================================
---
name: "Discussion"
about: "Overall discussions and general questions"
title: ""
assignees: []
labels:
- "Discussion"
---
================================================
FILE: .gitea/ISSUE_TEMPLATE/issue.md
================================================
---
name: "Issue"
about: "For cases clearly pointing to an issue in django-allauth"
title: ""
labels: ""
assignees: []
---
================================================
FILE: .gitea/pull_request_template.md
================================================
# Submitting Pull Requests
## General
- [ ] Make sure you use [semantic commit messages](https://seesparkbox.com/foundry/semantic_commit_messages).
Examples: `"fix(google): Fixed foobar bug"`, `"feat(accounts): Added foobar feature"`.
- [ ] All Python code must formatted using Black, and clean from pep8 and isort issues.
- [ ] JavaScript code should adhere to [StandardJS](https://standardjs.com).
- [ ] If your changes are significant, please update `ChangeLog.rst`.
- [ ] If your change is substantial, feel free to add yourself to `AUTHORS`.
## Provider Specifics
In case you add a new provider:
- [ ] Make sure unit tests are available.
- [ ] Ensure your provider is tested by adding an entry over at `tests/projects/common/settings.py::INSTALLED_SOCIALACCOUNT_APPS`.
- [ ] Provide provider specific documentation at `docs/socialaccount/providers/<provider name>.rst`.
- [ ] Link to your provider specific documentation at `docs/insocialaccount/providers/index.rst`.
- [ ] Add an entry for your provider in the quickstart, over at `docs/installation/quickstart.rst::INSTALLED_APPS`.
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: pennersr
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/issue.md
================================================
---
name: "Issue (when not using Codeberg)"
about: "\U0001F6D1 Please use https://codeberg.org/allauth/django-allauth/issues"
title: ''
labels: ''
assignees: ''
---
# 🛑 Stop
The issue tracker has been moved to https://codeberg.org/allauth/django-allauth/issues.
Please submit your issue there.
================================================
FILE: .github/SECURITY.md
================================================
# Security Policy
Please report security issues only to security@allauth.org.
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
groups:
GitHub_Actions:
patterns:
- "*" # Group all Actions updates into a single larger pull request
schedule:
interval: weekly
================================================
FILE: .github/pull_request_template.md
================================================
# 🛑 Stop
The project has been moved to https://codeberg.org/allauth/django-allauth.
Please submit your pull request there.
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-24.04
strategy:
matrix:
include:
- python-version: "3.10"
debian-version: trixie
- python-version: "3.12"
debian-version: trixie
- python-version: "3.13"
debian-version: trixie
- python-version: "3.14"
debian-version: trixie
container:
image: python:${{ matrix.python-version }}-${{ matrix.debian-version }}
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
apt-get update
apt-get install -y --no-install-recommends gettext make
- name: Install nox
run: pip install nox
- name: Run tests
run: nox -x --session "test-${{ matrix.python-version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docs:
runs-on: ubuntu-22.04
needs: []
strategy:
matrix:
python-version: [3.14]
container:
image: python:3.14-trixie
steps:
- uses: actions/checkout@v6
- name: Install nox
run: pip install nox
- name: Build docs
run: nox -x --session "docs"
lint:
runs-on: ubuntu-22.04
needs: []
strategy:
matrix:
python-version: [3.14]
container:
image: python:3.14-trixie
steps:
- uses: actions/checkout@v6
- name: Install nox
run: pip install nox
- name: Run linter
run: nox -x -t lint
standardjs:
runs-on: ubuntu-24.04
needs: []
strategy:
matrix:
python-version: [3.14]
container:
image: node:22-trixie
steps:
- uses: actions/checkout@v6
- name: Install standardjs dependencies
run: make ci-install-standardjs
- name: Run standardjs
run: make standardjs
================================================
FILE: .gitignore
================================================
*.pyc
*~
.idea
.project
.pydevproject
*.geany
docs/_build
build
dist
*.egg*
examples/**/local_settings.py
node_modules/
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
coverage.xml
.mypy_cache/
.nox/
.ropeproject/*
pep8.txt
*.bak
.#*
\#*
*.db
*.tmp
virtualenv
.DS_Store
*.prefs
*.mo
/.stfolder
.direnv/
examples/react-spa/docker-compose.override.yml
# Devenv
.devenv*
devenv.local.nix
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml
================================================
FILE: .readthedocs.yaml
================================================
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt
================================================
FILE: .woodpecker.yaml
================================================
when:
- event: pull_request
- event: [push, tag, manual]
branch: main
steps:
test:
image: python:${PYTHON_VERSION}-${DEBIAN_VERSION}
commands:
- apt-get update
- apt-get install -y --no-install-recommends gettext make
- pip install nox
- nox -x --session "test-${PYTHON_VERSION}"
docs:
image: python:${PYTHON_VERSION}-${DEBIAN_VERSION}
commands:
- pip install nox
- nox -x --session "docs"
depends_on: []
when:
- matrix:
PYTHON_VERSION: 3.14
lint:
image: python:${PYTHON_VERSION}-${DEBIAN_VERSION}
commands:
- pip install nox
- nox -x -t lint
depends_on: []
when:
- matrix:
PYTHON_VERSION: 3.14
standardjs:
image: node:22-${DEBIAN_VERSION}
commands:
- make ci-install-standardjs
- make standardjs
depends_on: []
when:
- matrix:
PYTHON_VERSION: 3.14
matrix:
include:
# To cut down on CI pipeline duration, test oldest/latest Python only.
- PYTHON_VERSION: 3.10
DEBIAN_VERSION: trixie
- PYTHON_VERSION: 3.14
DEBIAN_VERSION: trixie
================================================
FILE: AUTHORS
================================================
django-allauth was started by Raymond Penners
(<raymond.penners@intenct.nl> or @pennersr) in October 2010, inspired
by and partly based on existing projects such as Pinax (account app),
Django-Socialauth, django-socialregistration.
# Contributors
Aarni Koskela
Aaron van Derlip
Abhinav Johri
Abhishek Kumar Jaiswal
Adam Johnson
Adam McKerlie
Agustin Perez Paladini
Ahmet Emre Aladağ
Aiden Lu
Aldiantoro Nugroho
Alexander Gaevsky
Alfredo Altamirano
Andrean Franc
Andrei Satsevich
Andrew Chen Wang
Andrey Akolpakov
Andrey Balandin
Andy Matthews
Ani Vera
Anna Sirota
Anton Goncharov
Antonin Delpeuch
Aron Griffis
Bas ten Berge
Basil Shubin
Ben Timby
Benjamin Howes
Benjamin Jorand
Bhavani Ravi
Biel Massot
Björn Andersson
Bojan Mihelac
Brandon Kong
Bruno Alla
Chris Beaven
Chris Davis
Christian Carter
Christopher Grebs
Dan LaManna
Dani Hodovic
Daniel Eriksson
Daniel Widerin
David Ascher
David Cain
David D. Lowe
David Evans
David Friedman
David Hummel
Dimitris Tsimpitas
Dmytro Litvinov
Egor Poderyagin
Eran Rundstein
Eric Amador
Eric Delord
Fabio Caritas Barrionuevo da Luz
Facundo Gaich
Felipe Faria
Filip Dobrovolný
Francis Brito
Frantisek Malina
Fred Palmer
Fábio Santos
George Whewell
Griffith Rees
Guignard Javier
Guilhem Saurel
Guillaume Schurck
Guillaume Vincent
Guoyu Hao
Haesung Park
Hatem Nassrat
Hyunwoo Shim
Ian R-P
Ignacio Ocampo
Illia Volochii
J. Erm
J. Fernando Sánchez
Jack Shedd
Jakob Gerhard Martinussen
James Rivett-Carnac
James Thompson
Jannis Leidel
Jannis Vajen
Jason Wallace
Jeff Bowen
Jeff Triplett
Jeremy Satterfield
Jerome Leclanche
Jesse Gerard Brands
Jihoon Park
Jiyoon Ha
Joe Vanderstelt
Joel Fernandes
John Bazik
John Whitlock
Jonas Aule
JoonHwan Kim
Josh Owen
Josh Wright
Joshua Butler
Joshua Sorenson
Julen Ruiz Aizpuru
Justin Michalicek
Justin Pogrob
Karthikeyan Singaravelan
Karun Shrestha
Kevin Dice
Kimsia Sim
Koichi Harakawa
Kun Liu
Kyle Harrison
Lee Semel
Lev Predan Kowarski
Luis Diego García
Luiz Guilherme Pais dos Santos
Luke Burden
Luke Crouch
Maksim Rukomoynikov
Marcin Skarbek
Marcin Spoczynski
Marco Fucci
Marjori Pomarole
Markus Kaiserswerth
Markus Thielen
Martin Bächtold
Matt Nishi-Broach
Mauro Stettler
Mikhail Mitiaev
Morgante Pell
Nariman Gharib
Nathan Strobbe
Nicolas Acosta
Niklas A Emanuelsson
Oleg Sergeev
Patrick Paul
Paul Juergen Fischer
Paulo Eduardo Neves
Pavel Oborin
Pavel Savchenko
Peter Bittner
Peter Rowlands
Peter Stein
Philip John James
Rabi Alam
Radek Czajka
Rense VanderHoek
Rick Westera
Robert Balfre
Roberto Novaes
Rod Xavier Bondoc
Roman Tomjak
Roumen Antonov
Ryan Jarvis
Ryan Verner
Safwan Rahman
Sam Solomon
Sanghyeok Lee
Seizan Shimazaki
Serafeim Papastefanos
Sergey Silaev
Shane Rice
Stephen Kent
Stuart Ross
Terry Jones
Tiago Loureiro
Tim Gates
Tom Hacohen
Tomas Babej
Tomas Marcik
Trey Corple
Tuk Bredsdorff
Udi Oron
Vadim Meshcheryakov
Veljko Jovanovic
Victor Semionov
Vlad Dmitrievich
Volodymyr Yatsyk
Vuong Nguyen
Wendy Edwards
Will Gordon
Will Ross
William Li
Yaroslav Muravsky
Youcef Mammar
Yuri Kriachko
Mohamed BEN MAKHLOUF
================================================
FILE: CONTRIBUTING.rst
================================================
Contributing to django-allauth
==============================
.. begin-contributing
Thank you for considering contributing to django-allauth! This document outlines the process for contributing to the project and sets up your development environment.
Code of Conduct
---------------
In the interest of fostering an open and welcoming community, we as contributors and maintainers pledge to make participation in our project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
Getting Started
---------------
Setting Up Your Development Environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two primary ways to set up your development environment:
Option 1: Standard Python Virtual Environment (Recommended for Beginners)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. **Install system dependencies**
Before creating a virtual environment, you'll need to install some system dependencies:
**On macOS:**
.. code-block:: bash
# Using Homebrew
brew install libxml2 libxmlsec1 pkg-config openssl
**On Ubuntu/Debian:**
.. code-block:: bash
sudo apt-get install libxml2-dev libxmlsec1-dev libxmlsec1-openssl pkg-config
**On RHEL/CentOS/Fedora:**
.. code-block:: bash
sudo dnf install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel
2. **Create and activate a virtual environment**
.. code-block:: bash
# Create a virtual environment
python -m venv virtualenv
# Activate it
# On Windows:
virtualenv\Scripts\activate
# On macOS/Linux:
source virtualenv/bin/activate
3. **Install django-allauth in development mode**
.. code-block:: bash
# Install development dependencies
pip install -r requirements-dev.txt
Option 2: Using devenv/Nix (Recommended for Advanced Users)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you prefer a more isolated and reproducible development environment, you can use Nix-based `devenv <https://devenv.sh>`_:
1. **Install devenv** (If you don't have it already)
Follow the `official installation instructions <https://devenv.sh/getting-started/>`_.
2. **Activate the developer environment**
.. code-block:: bash
# This will create an isolated environment with all required dependencies
devenv shell
Note: The first time you run this command, it may take a significant amount of time as it builds all dependencies. Subsequent launches will be much faster.
Running Tests
-------------
django-allauth uses a comprehensive test suite. You can run tests in several ways:
Using pytest directly
~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
# Run all tests for the default setup
pytest allauth/
# Run tests with a specific Django settings module
pytest --ds=tests.projects.regular.settings tests/
# Run a specific test file
pytest tests/apps/account/test_login.py
Note, if you are using MacOS, using pip and get this error when run tests:
.. code-block:: bash
import xmlsec
ImportError: dlopen( ... symbol not found in flat namespace '_xmlSecOpenSSLTransformHmacRipemd160GetKlass')
You can try:
.. code-block:: bash
pip uninstall xmlsec lxml
pip install --no-binary :all: xmlsec
# Ref: https://github.com/xmlsec/python-xmlsec/issues/320
Using nox (recommended)
~~~~~~~~~~~~~~~~~~~~~~~
Nox automates testing across different Python and Django versions:
.. code-block:: bash
# List all available sessions
nox --list
# Run tests for a specific Python version
nox -x --session "test-3.11"
# Run tests for specific environment
nox -x --session "test-3.11" --python 3.11 -- --ds=tests.projects.regular.settings tests/apps/account/test_login.py
Run Code Quality Checks
~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
# Run all linting checks
nox -t lint
# Run specific check
nox --session black
nox --session isort
nox --session flake8
nox --session bandit
nox --session djlint
Building Documentation
----------------------
Documentation is built using Sphinx:
.. code-block:: bash
# Build the documentation
nox --session docs
The built documentation will be available in the ``docs/_build/html`` directory.
Development Workflow
--------------------
1. **Create a new branch for your feature or bugfix**
.. code-block:: bash
git checkout -b feature/your-feature-name
2. **Make your changes and add tests**
All new features should include proper tests.
3. **Run tests locally to ensure everything passes**
.. code-block:: bash
nox -x --session "test-3.11"
4. **Run code quality checks**
.. code-block:: bash
nox -t lint
5. **Commit your changes with meaningful commit messages**
6. **Submit a pull request to the main repository**
Pull Request Guidelines
-----------------------
- Update documentation for significant changes
- Add tests for new functionality
- Ensure all tests pass
- Follow the project's code style
- Keep pull requests focused on a single topic
- Write clear, descriptive commit messages
Additional Resources
--------------------
- `Official Documentation <https://docs.allauth.org/en/latest/>`_
- `Issue Tracker <https://codeberg.org/allauth/django-allauth/issues>`_
- `Project Source <https://codeberg.org/allauth/django-allauth>`_
Thank you for your contributions!
.. end-contributing
================================================
FILE: ChangeLog.rst
================================================
65.15.0 (2025-03-09)
********************
.. note::
💙 **Is django-allauth's authentication the entrance to your business?**
Please consider supporting its continued development by becoming a sponsor at
https://allauth.org/sponsors/. Your support helps keep this project thriving!
Note worthy changes
-------------------
- All user facing codes (e.g. those that the user needs to manually input over
at password reset, email/phone verification, login code, OIDC device codes)
now follow the recommendations over at `RFC 8628, Section 6.1
<https://datatracker.ietf.org/doc/html/rfc8628#section-6.1>`_. It uses dashed
codes, such as "WDJB-MJHT", by default. You can control the format of all codes
via a new setting `ALLAUTH_USER_CODE_FORMAT``, or, adjust the format per use
case via one of ``ACCOUNT_LOGIN_BY_CODE_FORMAT``,
``ACCOUNT_PHONE_VERIFICATION_CODE_FORMAT``,
``ACCOUNT_PASSWORD_RESET_BY_CODE_FORMAT``,
``ACCOUNT_EMAIL_VERIFICATION_BY_CODE_FORMAT``, ``IDP_OIDC_USER_CODE_FORMAT``.
- Added optional support for requesting new login codes. See
``ACCOUNT_LOGIN_BY_CODE_SUPPORTS_RESEND``.
Backwards incompatible changes
------------------------------
- Dropped support for Python 3.8 and 3.9. Both these Python versions are
end-of-life.
65.14.3 (2026-02-13)
********************
Fixes
-----
- Version 65.14.2 was not compatible with Python 3.8/3.9 due to use of an
unsupported typing construct, fixed.
65.14.2 (2026-02-13)
********************
Security notice
---------------
- Rate limiting and IP address detection: as Django applications cannot reliably
determine client IP addresses out of the box, you must override
``get_client_ip()`` to match your deployment architecture. If you omitted to
do so, the default implementation trusted ``X-Forwarded-For``, which can be
spoofed to bypass rate limits. Now, ``X-Forwarded-For`` is distrusted by
default. You must either configure ``ALLAUTH_TRUSTED_PROXY_COUNT``, rely on
``ALLAUTH_TRUSTED_CLIENT_IP_HEADER``, or override ``get_client_ip()``. Thanks
to Ayato Shitomi for reporting.
65.14.1 (2026-02-07)
********************
Fixes
-----
- When using ``ACCOUNT_CHANGE_EMAIL = True``, if the user initiating the change
email process had no verified email address, ``user.email`` would still
reflect the old email address while the verification process was pending.
Security notice
---------------
- SAML: When IdP initiated SSO was enabled (it is by default disabled), any URL
found in the SAML ``RelayState`` parameter would be used to redirect to,
potentially redirecting the authenticated user to a wrong site. Thanks to
Ayato Shitomi and Funabiki Keisuke for reporting.
65.14.0 (2026-01-17)
********************
Note worthy changes
-------------------
- Steam: the provider now supports initiating headless logins per
redirect.
- Shopify: if ``email_verified`` is present in the user payload, it will be used
to mark the email address retrieved as verified accordingly.
- IdP: added support for JWT based access tokens (see
``IDP_OIDC_ACCESS_TOKEN_FORMAT``).
- IdP: added support for pointing to a custom userinfo endpoint (see
``IDP_OIDC_USERINFO_ENDPOINT``)
- For OpenID Connect providers, you can now configure the field to be used as
the account ID by setting ``"uid_field"`` in the relevant
``SocialApp.settings``.
- Headless: the JWT algorithm is now configurable, supporting HS256.
Fixes
-----
- IdP: Access tokens without a user attached (client credentials) were no longer
recognized in DRF/Ninja endpoints.
- ``requests`` sessions are now disposed of after use to avoid resource leaks.
65.13.1 (2025-11-20)
********************
Note worthy changes
-------------------
- Django 6.0 is now officially supported.
Fixes
-----
- Internal imports related to headless token strategies were causing (harmless)
deprecation warnings, fixed.
- Pending social signups stored in the session by allauth versions prior to
65.5.0 are not resumable by newer versions. This could cause 500s while
upgrading, fixed.
- Headless: the reauthentication-required response in the OpenAPI specification
was wrongly nested and did not match the actual implementation, fixed.
65.13.0 (2025-10-31)
********************
Note worthy changes
-------------------
- IdP: Added support for RP-Initiated Logout.
- Headless: added JWT token strategy.
- Added support for "Trust this browser?" functionality for logging in by code.
See ``ACCOUNT_LOGIN_BY_CODE_TRUST_ENABLED``.
- OpenID Connect: to avoid issues with client IDs containing colons,
``client_secret_post`` is now preferred above ``client_secret_basic``.
Security notice
---------------
- Both Okta and NetIQ were using ``preferred_username`` as the identifier for
third-party provider accounts. That value may be mutable and should therefore
be avoided for authorization decisions. The providers are now using ``sub``
instead.
- IdP: marking a user as ``is_active=False`` after having handed tokens for that
user while the account was still active had no effect. Fixed -- the
access/refresh tokens are now rejected. Thanks to Joshua Rogers for reporting
this and the previous issue.
Backwards incompatible changes
------------------------------
- Headless now requires the ``headless`` extra to be installed. For example:
``pip install django-allauth[headless]``.
- Okta and NetIQ: see the security notice on Okta and NetIQ. Already existing
``SocialAccount`` records will no longer be linked due to the switch to
``sub``. You will need to manually handle this situation either, by
populating ``SocialAccount.uid`` based on ``sub`` located in
``SocialAccount.extra_data``,or, if you are absolutely certain the security
notice is of no concern for your use case, by setting ``"uid_field":
"preferred_username"`` in the relevant ``SocialApp.settings``.
65.12.1 (2025-10-16)
********************
Security notice
---------------
- There was a flaw in the email verification process when using
``ACCOUNT_CHANGE_EMAIL = True``. If you are using this configuration, you are
advised to upgrade as soon as possible. Note that the default value is
``False``.
65.12.0 (2025-10-05)
********************
Note worthy changes
-------------------
- Updated VK urls from "vk.com" to "vk.ru".
- Added new socialaccount provider: Discogs.
- MediaWiki: you can now setup a custom user agent to avoid getting blocked,
see: https://phabricator.wikimedia.org/T400119
- IdP: Added optional support for wildcards in redirect URIs and CORS origins.
To support this, a new field was added to the ``Client`` model. Therefore, you
need to run migrations for the ``allauth.idp.oidc`` app.
- Headless: an email address that was in the process of being verified by code
was presented in the list of email address, but could not be deleted. Now, a
``DELETE`` will actually abort the process, effectively removing the pending
email address from the list.
65.11.2 (2025-09-09)
********************
Fixes
-----
- OpenID Connect: the OpenID Connect provider was using the wrong key lookup
mechanism, resulting in login failures.
65.11.1 (2025-08-27)
********************
Security notice
---------------
- If you configured password to be optional (e.g. using ``ACCOUNT_SIGNUP_FIELDS
= ["email*", "password1"]``), then accounts would be created having a blank
password instead of an unusable password. If you were using this configuration
then you may need to manually set an unusable password for accounts created.
65.11.0 (2025-08-15)
********************
Note worthy changes
-------------------
- OpenID Connect: using ``fetch_userinfo=False`` you can now skip the additional
call to the userinfo endpoint. Instead, the ID token will be used.
Fixes
-----
- Headless: passwordless signup was not supported, fixed.
- Headless: when serializing the user nested dataclasses, as well as optional
types ended up as ``string`` type, fixed.
- When signing up with a social account no authentication record was added to
the session, fixed.
Backwards incompatible changes
------------------------------
- OpenID Connect: the ID token and userinfo (when present) are now stored in
``SocialAccount.extra_data``, below the respective ``"id_token"`` and
``"userinfo"`` keys. Compatibility with ``extra_data`` from existing accounts
that do not have this new structure is retained. However, if your own project
expects ``extra_data`` to be in a certain format this change may impact you.
65.10.0 (2025-07-10)
********************
Note worthy changes
-------------------
- IdP: Added support for the device authorization grant.
- Headless: custom user payloads can now be properly reflected in the OpenAPI
specification by provider a user ``dataclass``. See the newly introduced
``get_user_dataclass()`` and ``user_as_dataclass()`` adapter methods.
- Added a new signal (``authentication_step_completed``) that is emitted when an
individual authentication step is completed.
- MFA: Added a setting (``MFA_ALLOW_UNVERIFIED_EMAIL``) to allow unverified
email addresses in combination with MFA.
Backwards incompatible changes
------------------------------
- Soundcloud: as per https://developers.soundcloud.com/blog/urn-num-to-string,
the provider now uses the user ``urn`` instead of the ``id`` as the ID for
social accounts. This change is backward incompatible. Instructions on
how to migrate existing social accounts can be found in the allauth provider
documentation for SoundCloud.
Fixes
-----
- Phone: The recently added support for phone (SMS) authentication did fully integrate
with third-party provider signups. For example, whether or not the phone
number is required was not respected during signup. Fixed.
- IdP: Token revocation failed when a single ``token_type_hint`` was passed,
fixed.
- The ``verified_email_required`` decorator did not support email verification
by code. Additionally, it did not rate limit verification emails
in case of GET requests. Both are fixed.
- The account adapter ``clean_email()`` method was not called when a social account
auto signup took place, fixed.
65.9.0 (2025-06-01)
*******************
Note worthy changes
-------------------
- Added ``allauth.idp`` to the project, offering out of the box OpenID Connect
provider support, as well as integration with Django REST framework and Django
Ninja.
- Headless: the OpenAPI specification now more accurately reflects single client
configurations set via ``HEADLESS_CLIENTS``. When a single client is active,
the redundant ``{client}`` path parameter and its global definition are
removed from the generated schema.
65.8.1 (2025-05-21)
*******************
Fixes
-----
- Fixed a compatibility issue with the newly released fido2 2.0.0 package.
Security notice
---------------
- After a successful login, the rate limits for that login were cleared,
allowing a succesful login on a specific IP address to be used as a means to
clear the login failed rate limit for that IP address. Fixed.
65.8.0 (2025-05-08)
*******************
Note worthy changes
-------------------
- Fixed VK (a.k.a VK ID) social account provider. Improved its documentation.
- Added optional support for requesting new email/phone verification codes during
signup. See ``ACCOUNT_EMAIL_VERIFICATION_SUPPORTS_RESEND`` and
``ACCOUNT_PHONE_VERIFICATION_SUPPORTS_RESEND``.
- Added optional support for changing your email or phone at the verification stage while signing up.
See ``ACCOUNT_EMAIL_VERIFICATION_SUPPORTS_CHANGE`` and
``ACCOUNT_PHONE_VERIFICATION_SUPPORTS_CHANGE``.
- Added support for Mailcow OAuth2.
65.7.0 (2025-04-03)
*******************
Note worthy changes
-------------------
- Officially support Django 5.2.
- Headless: the URL to the OpenID configuration of the provider is now exposed
in the provider configuration.
Fixes
-----
- Headless: when multiple login methods were enabled (e.g. both username and
email), the login endpoint would incorrectly return a 400
``invalid_login``. Fixed.
65.6.0 (2025-03-27)
*******************
Note worthy changes
-------------------
- MFA: Added support for "Trust this browser?" functionality, which presents users with MFA
enabled the choice to trust their browser allowing them to skip authenticating
per MFA on each login.
Fixes
-----
- A check is in place to verify that ``ACCOUNT_LOGIN_METHODS`` is aligned with
``ACCOUNT_SIGNUP_FIELDS``. The severity level of that check has now been
lowered from "critical" to "warning", as there may be valid use cases for
configuring a login method that you are not able to sign up with. This check
(``account.W001``) can be silenced using Django's ``SILENCED_SYSTEM_CHECKS``.
- The setting ``ACCOUNT_LOGIN_ON_PASSWORD_RESET = True`` was not respected when using
password reset by code.
65.5.0 (2025-03-14)
*******************
Note worthy changes
-------------------
- Added support for phone (SMS) authentication.
- Added support for resetting passwords by code, instead of a link
(``ACCOUNT_PASSWORD_RESET_BY_CODE_ENABLED``).
- Added support for Tumblr OAuth2.
- Simplified signup form configuration. The following settings all controlled
signup form: ``ACCOUNT_EMAIL_REQUIRED``, ``ACCOUNT_USERNAME_REQUIRED``,
``ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE``, ``ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE``.
This setup had its issues. For example, when email was not required it was
still available as an optional field, whereas the username field disappeared
when not required. Also, for phone/SMS support, additional settings
would have been required. The settings are now all deprecated, and replaced by one
new setting: ``ACCOUNT_SIGNUP_FIELDS``, which can be configured to
e.g. ``['username*', 'email', 'password1*', 'password2*']`` to indicate which
fields are present and required (``'*'``). This change is performed in a
backwards compatible manner.
- Headless: if, while signing up using a third-party provider account, there is
insufficient information received from the provider to automatically complete
the signup process, an additional step is needed to complete the missing data
before the user is fully signed up and authenticated. You can now perform a
``GET`` request to ``/_allauth/{client}/v1/auth/provider/signup`` to obtain
information on the pending signup.
- Headless: OpenID Connect providers now support token authentication.
- The "Forgot your password?" help text can now be more easily customized by
providing your own ``"account/password_reset_help_text.html"`` template.
- Removed inline scripts, so that it becomes possible to use a strong Content
Security Policy.
- Headless: The OpenAPI specification now dynamically reflects the
``ACCOUNT_SIGNUP_FIELDS`` configuration, as well as any custom fields you have
in ``ACCOUNT_SIGNUP_FORM_CLASS``.
- Added official support for Python 3.13.
Fixes
-----
- Headless: In case you had multiple apps of the same provider configured,
you could run into a ``MultipleObjectsReturned``. Fixed.
65.4.1 (2025-02-07)
*******************
Fixes
-----
- To make way for a future ``"phone"`` method, ``AUTHENTICATION_METHOD`` was
removed in favor of a new ``LOGIN_METHODS``. While this change was done in a
backwards compatible manner within allauth scope, other packages accessing
``allauth.account.app_settings.AUTHENTICATION_METHOD`` would break. Fixed.
65.4.0 (2025-02-06)
*******************
Note worthy changes
-------------------
- The setting ``ACCOUNT_AUTHENTICATION_METHOD: str`` (with values
``"username"``, ``"username_email"``, ``"email"``) has been replaced by
``ACCOUNT_LOGIN_METHODS: set[str]``. which is a set of values including
``"username"`` or ``"email"``. This change is performed in a backwards
compatible manner.
- Headless: when ``HEADLESS_SERVE_SPECIFICATION`` is set to ``True``, the API
specification will be served dynamically, over at
``/_allauth/openapi.(yaml|json|html)``. The
``HEADLESS_SPECIFICATION_TEMPLATE_NAME`` can be configured to choose between
Redoc (``"headless/spec/redoc_cdn.html"``) and Swagger (
(``"headless/spec/swagger_cdn.html"``).
- Headless: added a new setting, ``HEADLESS_CLIENTS`` which you can use to limit
the types of API clients (app/browser).
- Headless: expanded the React SPA example to showcase integration with
Django Ninja as well as Django REST framework.
- Headless: added out of the box support for being able to use the headless
session tokens with Django Ninja and Django REST framework.
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2010-2026 Raymond Penners and contributors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: Makefile
================================================
PYTHON = python
.PHONY: usage
usage:
@echo 'Usage: make [target]'
.PHONY: po
po:
( cd allauth ; $(PYTHON) ../manage.py makemessages -a -e html,txt,py )
.PHONY: mo
mo:
( cd allauth ; $(PYTHON) ../manage.py compilemessages )
.PHONY: isort
isort:
isort --check-only --diff allauth/ tests/
.PHONY: bandit
bandit:
bandit -q -c pyproject.toml -r allauth/
.PHONY: black
black:
black --check -q .
.PHONY: test
test:
pytest allauth/
.PHONY: djlint
djlint:
djlint --quiet --check allauth examples
.PHONY: flake8
flake8:
flake8 allauth
.PHONY: qa
qa: validate-api-spec mypy djlint bandit black isort flake8
.PHONY: mypy
mypy:
mypy allauth/
.PHONY: validate-api-spec
validate-api-spec:
@if command -v swagger-cli >/dev/null 2>&1; then \
swagger-cli validate allauth/headless/spec/doc/openapi.yaml; \
else \
echo "WARNING: swagger-cli not found in PATH."; \
fi
.PHONY: ci
ci:
woodpecker-cli exec .woodpecker.yaml
.PHONY: standardjs
standardjs:
find ./allauth -name '*.js' | xargs ./node_modules/.bin/standard --ignore allauth/mfa/static/mfa/js/webauthn-json.js
.PHONY: docs
docs:
$(MAKE) -C docs html
.PHONY: ci-install-standardjs
ci-install-standardjs:
npm install standard --no-lockfile --no-progress --non-interactive --silent
.PHONY: clean
clean:
-rm -rf build/ django_allauth.egg-info/
.PHONY: dist
dist: clean mo
python -m build --sdist
python -m build --wheel
================================================
FILE: README.rst
================================================
==========================
Welcome to django-allauth!
==========================
.. image:: https://codeberg.org/allauth/allauth.org/raw/commit/da3b56390e1b18eaec09b05cd89dfa7812212dfc/content/news/2024/04/website-redesign/logo-light.png
:target: https://allauth.org
:align: right
:alt: django-allauth logo
:width: 250px
.. |ci| image:: https://img.shields.io/github/actions/workflow/status/pennersr/django-allauth/ci.yml.svg
:target: https://github.com/pennersr/django-allauth/actions
.. |pypi| image:: https://img.shields.io/pypi/v/django-allauth
:target: https://pypi.python.org/pypi/django-allauth
.. |cov| image:: https://img.shields.io/coverallsCoverage/github/pennersr/django-allauth
:alt: Coverage Status
:target: https://coveralls.io/r/pennersr/django-allauth
.. |btc| image:: https://img.shields.io/badge/bitcoin-donate-yellow
:target: https://blockchain.info/address/1AJXuBMPHkaDCNX2rwAy34bGgs7hmrePEr
.. |liberapay| image:: https://img.shields.io/liberapay/receives/pennersr
:target: https://en.liberapay.com/pennersr
.. |pystyle| image:: https://img.shields.io/badge/code_style-pep8-green
:target: https://www.python.org/dev/peps/pep-0008/
.. |jsstyle| image:: https://img.shields.io/badge/code_style-standard-brightgreen
:target: http://standardjs.com
.. |editor| image:: https://img.shields.io/badge/editor-emacs-purple
:target: https://www.gnu.org/software/emacs/
.. |i18n| image:: https://img.shields.io/weblate/progress/allauth
:target: https://hosted.weblate.org/projects/allauth/django-allauth/
.. |pypidl| image:: https://img.shields.io/pypi/dm/django-allauth
:target: https://pypistats.org/packages/django-allauth
:alt: PyPI - Downloads
.. |djangodemo| image:: https://img.shields.io/badge/%E2%96%B6_demo-Django_project-red
:target: https://django.demo.allauth.org/
:alt: View Django Demo
.. |reactdemo| image:: https://img.shields.io/badge/%E2%96%B6_demo-React_SPA-red
:target: https://react.demo.allauth.org/
:alt: View React SPA Demo
|ci| |pypi| |cov| |btc| |liberapay| |pystyle| |jsstyle| |editor| |i18n| |pypidl| |djangodemo| |reactdemo|
Integrated set of Django applications addressing authentication,
registration, account management as well as 3rd party (social) account
authentication.
Home page
https://allauth.org/
Source code
https://codeberg.org/allauth/django-allauth
Issue Tracker
https://codeberg.org/allauth/django-allauth/issues
Documentation
https://docs.allauth.org/en/latest/
Stack Overflow
https://stackoverflow.com/questions/tagged/django-allauth
Demo
https://django.demo.allauth.org and https://react.demo.allauth.org
Translations
https://hosted.weblate.org/projects/allauth/django-allauth/
.. end-welcome
Rationale
=========
.. begin-rationale
Most existing Django apps that address the problem of social
authentication unfortunately focus only on one dimension - the social.
Most developers end up integrating another app in order to support authentication
flows that are locally generated.
This approach creates a development gap between local and social
authentication flows. It has remained an issue in spite of numerous common
scenarios that both require. For example, an email address passed along by an
OpenID provider may not be verified. Therefore, prior to hooking up
an OpenID account to a local account the email address must be
verified. This essentially is one of many use cases that mandate email
verification to be present in both worlds.
Integrating both is a humongous and tedious process. It is not as
simple as adding one social authentication app, and one
local account registration app to your ``INSTALLED_APPS`` list.
This inadequacy is the reason for this project's existence -- to offer a fully
integrated authentication app that allows for both local and social
authentication, with flows that just work, beautifully!
.. end-rationale
Features
========
.. begin-features
**🔑 Comprehensive account functionality**
Supports multiple authentication
schemes (e.g. login by user name, or by email), as well as multiple
strategies for account verification (ranging from none to mandatory email
verification).
**👥 Social Login**
Login using external identity providers, supporting any *Open ID Connect
compatible* provider, many *OAuth 1.0/2.0* providers, as well as
custom protocols such as, for example, *Telegram* authentication.
**💼 Enterprise ready**
Supports SAML 2.0, which is often used in a B2B context.
**🕵️ Battle-tested**
The package has been out in the open since 2010. It is in use by many
commercial companies whose business depends on it and has hence been
subjected to various penetration testing attempts.
**⏳Rate limiting**
When you expose an authentication-enabled web service to
the internet, it is important to be prepared for potential brute force
attempts. Therefore, rate limiting is enabled out of the box.
**🔒 Private**
Many sites leak information. For example, on many sites you can
check whether someone you know has an account by input their email address
into the password forgotten form, or trying to signup with it. We offer
account enumeration prevention, making it impossible to tell whether or not
somebody already has an account.
**🧩 Customizable**
As a developer, you have the flexibility to customize the core functionality
according to your specific requirements. By employing the adapter pattern, you
can effortlessly introduce interventions at the desired points to deviate from
the standard behavior. This level of customization empowers you to tailor the
software to meet your unique needs and preferences.
**⚙️ Configuration**
The required consumer keys and secrets for interacting with Facebook,
X (Twitter) and the likes can be configured using regular settings, or, can be
configured in the database via the Django admin. Here, optional support for
the Django sites framework is available, which is helpful for larger
multi-domain projects, but also allows for easy switching between a
development (localhost) and production setup without messing with your
settings and database.
.. end-features
Commercial Support
==================
.. begin-support
Commercial support is available. If you find certain functionality missing, or
require assistance on your project(s), please contact us: info@intenct.nl.
.. end-support
================================================
FILE: allauth/__init__.py
================================================
r"""
_ ___ __ __ .___________. __ __
/\| |/\ / \ | | | | | || | | |
\ ` ' / / ^ \ | | | | `---| |----`| |__| |
|_ _| / /_\ \ | | | | | | | __ |
/ , . \ / _____ \ | `--' | | | | | | |
\/|_|\//__/ \__\ \______/ |__| |__| |__|
"""
VERSION = (65, 15, 0, "final", 0)
__title__ = "django-allauth"
__version_info__ = VERSION
__version__ = ".".join(map(str, VERSION[:3])) + (
f"-{VERSION[3]}{VERSION[4] or ''}" if VERSION[3] != "final" else ""
)
__author__ = "Raymond Penners"
__license__ = "MIT"
__copyright__ = "Copyright 2010-2026 Raymond Penners and contributors"
================================================
FILE: allauth/account/__init__.py
================================================
================================================
FILE: allauth/account/adapter.py
================================================
import html
import inspect
import json
import warnings
from http import HTTPStatus
from urllib.parse import urlparse
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import (
authenticate,
get_backends,
get_user_model,
login as django_login,
logout as django_logout,
)
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.password_validation import (
MinimumLengthValidator,
validate_password,
)
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import FieldDoesNotExist, PermissionDenied
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
from django.http.request import validate_host
from django.shortcuts import resolve_url
from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
from allauth import app_settings as allauth_settings
from allauth.account import app_settings, signals
from allauth.core import context
from allauth.core.internal import ratelimit
from allauth.core.internal.adapter import BaseAdapter
from allauth.core.internal.cryptokit import generate_user_code
from allauth.core.internal.httpkit import (
HTTP_USER_AGENT_MAX_LENGTH,
get_client_ip,
headed_redirect_response,
is_headless_request,
)
from allauth.utils import generate_unique_username, import_attribute
class DefaultAccountAdapter(BaseAdapter):
"""The adapter class allows you to override various functionality of the
``allauth.account`` app. To do so, point ``settings.ACCOUNT_ADAPTER`` to
your own class that derives from ``DefaultAccountAdapter`` and override the
behavior by altering the implementation of the methods according to your own
needs.
"""
error_messages = {
"account_inactive": _("This account is currently inactive."),
"cannot_remove_primary_email": _(
"You cannot remove your primary email address."
),
"duplicate_email": _(
"This email address is already associated with this account."
),
"email_password_mismatch": _(
"The email address and/or password you specified are not correct."
),
"phone_password_mismatch": _(
"The phone number and/or password you specified are not correct."
),
"email_taken": _("A user is already registered with this email address."),
"enter_current_password": _("Please type your current password."),
"incorrect_code": _("Incorrect code."),
"incorrect_password": _("Incorrect password."),
"invalid_or_expired_key": _("Invalid or expired key."),
"invalid_login": _("Invalid login."),
"invalid_password_reset": _("The password reset token was invalid."),
"max_email_addresses": _("You cannot add more than %d email addresses."),
"phone_taken": _("A user is already registered with this phone number."),
"too_many_login_attempts": _(
"Too many failed login attempts. Try again later."
),
"unknown_email": _("The email address is not assigned to any user account."),
"unknown_phone": _("The phone number is not assigned to any user account."),
"unverified_primary_email": _("Your primary email address must be verified."),
"username_blacklisted": _(
"Username can not be used. Please use other username."
),
"username_password_mismatch": _(
"The username and/or password you specified are not correct."
),
"username_taken": AbstractUser._meta.get_field("username").error_messages[
"unique"
],
"select_only_one": _("Please select only one."),
"same_as_current": _("The new value must be different from the current one."),
"rate_limited": _("Be patient, you are sending too many requests."),
}
def stash_verified_email(self, request, email):
request.session["account_verified_email"] = email
def unstash_verified_email(self, request):
ret = request.session.get("account_verified_email")
request.session["account_verified_email"] = None
return ret
def is_email_verified(self, request, email):
"""
Checks whether or not the email address is already verified
beyond allauth scope, for example, by having accepted an
invitation before signing up.
"""
ret = False
verified_email = request.session.get("account_verified_email")
if verified_email:
ret = verified_email.lower() == email.lower()
return ret
def can_delete_email(self, email_address) -> bool:
"""
Returns whether or not the given email address can be deleted.
"""
from allauth.account.models import EmailAddress
if not email_address.pk:
return True
has_other = (
EmailAddress.objects.filter(user_id=email_address.user_id)
.exclude(pk=email_address.pk)
.exists()
)
login_by_email = app_settings.LOGIN_METHODS == {app_settings.LoginMethod.EMAIL}
if email_address.primary:
if has_other:
# Don't allow, let the user mark one of the others as primary
# first.
return False
elif login_by_email:
# Last email & login is by email, prevent dangling account.
return False
return True
elif has_other:
# Account won't be dangling.
return True
elif login_by_email:
# This is the last email.
return False
else:
return True
def format_email_subject(self, subject) -> str:
"""
Formats the given email subject.
"""
prefix = app_settings.EMAIL_SUBJECT_PREFIX
if prefix is None:
site = get_current_site(context.request)
prefix = f"[{site.name}] "
return prefix + force_str(subject)
def get_from_email(self):
"""
This is a hook that can be overridden to programmatically
set the 'from' email address for sending emails
"""
return settings.DEFAULT_FROM_EMAIL
def render_mail(self, template_prefix, email, context, headers=None):
"""
Renders an email to `email`. `template_prefix` identifies the
email that is to be sent, e.g. "account/email/email_confirmation"
"""
to = [email] if isinstance(email, str) else email
subject = render_to_string(f"{template_prefix}_subject.txt", context)
# remove superfluous line breaks
subject = " ".join(subject.splitlines()).strip()
subject = self.format_email_subject(subject)
from_email = self.get_from_email()
bodies = {}
html_ext = app_settings.TEMPLATE_EXTENSION
for ext in [html_ext, "txt"]:
try:
template_name = f"{template_prefix}_message.{ext}"
bodies[ext] = render_to_string(
template_name,
context,
globals()["context"].request,
).strip()
except TemplateDoesNotExist:
if ext == "txt" and not bodies:
# We need at least one body
raise
if "txt" in bodies:
msg = EmailMultiAlternatives(
subject, bodies["txt"], from_email, to, headers=headers
)
if html_ext in bodies:
msg.attach_alternative(bodies[html_ext], "text/html")
else:
msg = EmailMessage(
subject, bodies[html_ext], from_email, to, headers=headers
)
msg.content_subtype = "html" # Main content is now text/html
return msg
def send_mail(self, template_prefix: str, email: str, context: dict) -> None:
request = globals()["context"].request
ctx = {
"request": request,
"email": email,
"current_site": get_current_site(request),
}
ctx.update(context)
msg = self.render_mail(template_prefix, email, ctx)
msg.send()
def get_signup_redirect_url(self, request):
"""
Returns the default URL to redirect to directly after signing up.
"""
return resolve_url(app_settings.SIGNUP_REDIRECT_URL)
def get_login_redirect_url(self, request):
"""
Returns the default URL to redirect to after logging in. Note
that URLs passed explicitly (e.g. by passing along a `next`
GET parameter) take precedence over the value returned here.
"""
assert request.user.is_authenticated # nosec
url = getattr(settings, "LOGIN_REDIRECT_URLNAME", None)
if url:
warnings.warn(
"LOGIN_REDIRECT_URLNAME is deprecated, simply"
" use LOGIN_REDIRECT_URL with a URL name",
DeprecationWarning,
)
else:
url = settings.LOGIN_REDIRECT_URL
return resolve_url(url)
def get_logout_redirect_url(self, request):
"""
Returns the URL to redirect to after the user logs out. Note that
this method is also invoked if you attempt to log out while no users
is logged in. Therefore, request.user is not guaranteed to be an
authenticated user.
"""
return resolve_url(app_settings.LOGOUT_REDIRECT_URL)
def get_email_verification_redirect_url(self, email_address):
"""
The URL to return to after email verification.
"""
get_url = getattr(self, "get_email_confirmation_redirect_url", None)
if get_url:
# Deprecated.
return get_url(self.request)
if self.request.user.is_authenticated:
if app_settings.EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL:
return app_settings.EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL
else:
return self.get_login_redirect_url(self.request)
else:
return app_settings.EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL
def get_password_change_redirect_url(self, request):
"""
The URL to redirect to after a successful password change/set.
NOTE: Not called during the password reset flow.
"""
return reverse("account_change_password")
def is_open_for_signup(self, request):
"""
Checks whether or not the site is open for signups.
Next to simply returning True/False you can also intervene the
regular flow by raising an ImmediateHttpResponse
"""
return True
def new_user(self, request):
"""
Instantiates a new User instance.
"""
user = get_user_model()()
return user
def populate_username(self, request, user):
"""
Fills in a valid username, if required and missing. If the
username is already present it is assumed to be valid
(unique).
"""
from .utils import user_email, user_field, user_username
first_name = user_field(user, "first_name")
last_name = user_field(user, "last_name")
email = user_email(user)
username = user_username(user)
if app_settings.USER_MODEL_USERNAME_FIELD:
user_username(
user,
username
or self.generate_unique_username(
[first_name, last_name, email, username, "user"]
),
)
def generate_unique_username(self, txts, regex=None):
return generate_unique_username(txts, regex)
def save_user(self, request, user, form, commit=True):
"""
Saves a new `User` instance using information provided in the
signup form.
"""
from .utils import user_email, user_field, user_username
data = form.cleaned_data
first_name = data.get("first_name")
last_name = data.get("last_name")
email = data.get("email")
username = data.get("username")
user_email(user, email)
user_username(user, username)
if first_name:
user_field(user, "first_name", first_name)
if last_name:
user_field(user, "last_name", last_name)
if "password1" in data:
password = data["password1"]
elif "password" in data:
password = data["password"]
else:
password = None
if password:
user.set_password(password)
else:
user.set_unusable_password()
self.populate_username(request, user)
if commit:
user.save()
if getattr(form, "_has_phone_field", False):
phone = form.cleaned_data.get("phone")
if phone:
self.set_phone(user, phone, False)
return user
def clean_username(self, username, shallow=False):
"""
Validates the username. You can hook into this if you want to
(dynamically) restrict what usernames can be chosen.
"""
for validator in app_settings.USERNAME_VALIDATORS:
validator(username)
# TODO: Add regexp support to USERNAME_BLACKLIST
username_blacklist_lower = [
ub.lower() for ub in app_settings.USERNAME_BLACKLIST
]
if username.lower() in username_blacklist_lower:
raise self.validation_error("username_blacklisted")
# Skipping database lookups when shallow is True, needed for unique
# username generation.
if not shallow:
from .utils import filter_users_by_username
if filter_users_by_username(username).exists():
raise self.validation_error("username_taken")
return username
def clean_email(self, email: str) -> str:
"""
Validates an email value. You can hook into this if you want to
(dynamically) restrict what email addresses can be chosen.
"""
return email
def clean_password(self, password, user=None):
"""
Validates a password. You can hook into this if you want to
restric the allowed password choices.
"""
min_length = app_settings.PASSWORD_MIN_LENGTH
if min_length:
MinimumLengthValidator(min_length).validate(password)
validate_password(password, user)
return password
def clean_phone(self, phone: str) -> str:
"""
Validates a phone number. You can hook into this if you want to
(dynamically) restrict what phone numbers can be chosen.
"""
return phone
def validate_unique_email(self, email):
return email
def add_message(
self,
request,
level,
message_template=None,
message_context=None,
extra_tags="",
message=None,
):
"""
Wrapper of `django.contrib.messages.add_message`, that reads
the message text from a template.
"""
if is_headless_request(request):
return
if "django.contrib.messages" in settings.INSTALLED_APPS:
if message:
messages.add_message(request, level, message, extra_tags=extra_tags)
return
try:
if message_context is None:
message_context = {}
escaped_message = render_to_string(
message_template,
message_context,
context.request,
).strip()
if escaped_message:
message = html.unescape(escaped_message)
messages.add_message(request, level, message, extra_tags=extra_tags)
except TemplateDoesNotExist:
pass
def ajax_response(self, request, response, redirect_to=None, form=None, data=None):
resp = {}
status = response.status_code
if redirect_to:
status = HTTPStatus.OK
resp["location"] = redirect_to
if form:
if request.method == "POST":
if form.is_valid():
status = HTTPStatus.OK
else:
status = HTTPStatus.BAD_REQUEST
else:
status = HTTPStatus.OK
resp["form"] = self.ajax_response_form(form)
if hasattr(response, "render"):
response.render()
resp["html"] = response.content.decode("utf8")
if data is not None:
resp["data"] = data
return HttpResponse(
json.dumps(resp), status=status, content_type="application/json"
)
def ajax_response_form(self, form):
form_spec = {
"fields": {},
"field_order": [],
"errors": form.non_field_errors(),
}
for field in form:
field_spec = {
"label": force_str(field.label),
"value": field.value(),
"help_text": force_str(field.help_text),
"errors": [force_str(e) for e in field.errors],
"widget": {
"attrs": {
k: force_str(v) for k, v in field.field.widget.attrs.items()
}
},
}
form_spec["fields"][field.html_name] = field_spec
form_spec["field_order"].append(field.html_name)
return form_spec
def pre_login(
self,
request,
user,
*,
email_verification,
signal_kwargs,
email,
signup,
redirect_url,
):
if not user.is_active:
return self.respond_user_inactive(request, user)
def post_login(
self,
request,
user,
*,
email_verification,
signal_kwargs,
email,
signup,
redirect_url,
):
from .utils import get_login_redirect_url
if is_headless_request(request):
from allauth.headless.base.response import AuthenticationResponse
response = AuthenticationResponse(request)
else:
response = HttpResponseRedirect(
get_login_redirect_url(request, redirect_url, signup=signup)
)
if signal_kwargs is None:
signal_kwargs = {}
signals.user_logged_in.send(
sender=user.__class__,
request=request,
response=response,
user=user,
**signal_kwargs,
)
self.add_message(
request,
messages.SUCCESS,
"account/messages/logged_in.txt",
{"user": user},
)
return response
def login(self, request, user):
# HACK: This is not nice. The proper Django way is to use an
# authentication backend
if not hasattr(user, "backend"):
from .auth_backends import AuthenticationBackend
backends = get_backends()
backend = None
for b in backends:
if isinstance(b, AuthenticationBackend):
# prefer our own backend
backend = b
break
elif not backend and hasattr(b, "get_user"):
# Pick the first valid one
backend = b
backend_path = f"{backend.__module__}.{backend.__class__.__name__}"
user.backend = backend_path
django_login(request, user)
def logout(self, request):
django_logout(request)
def confirm_email(self, request, email_address):
"""
Marks the email address as confirmed on the db
"""
from allauth.account.internal.flows import email_verification
return email_verification.verify_email(request, email_address)
def set_password(self, user, password) -> None:
"""
Sets the password for the user.
"""
user.set_password(password)
user.save()
def get_user_search_fields(self):
ret = []
User = get_user_model()
candidates = [
app_settings.USER_MODEL_USERNAME_FIELD,
"first_name",
"last_name",
"email",
]
for candidate in candidates:
try:
User._meta.get_field(candidate)
ret.append(candidate)
except FieldDoesNotExist:
pass
return ret
def is_safe_url(self, url):
from django.utils.http import url_has_allowed_host_and_scheme
# get_host already validates the given host, so no need to check it again
allowed_hosts = {context.request.get_host()} | set(settings.ALLOWED_HOSTS)
# Include hosts derived from CSRF_TRUSTED_ORIGINS
trusted_hosts = {
urlparse(origin).netloc for origin in settings.CSRF_TRUSTED_ORIGINS
}
allowed_hosts.update(trusted_hosts)
# ALLOWED_HOSTS supports wildcards, and subdomains using a '.' prefix.
# But, `url_has_allowed_host_and_scheme()` doesn't support that. So,
# let's check the domain using the ALLOWED_HOSTS logic, and if valid,
# add it as allowed so that we can then call
# `url_has_allowed_host_and_scheme()`.
parsed_host = urlparse(url).netloc
if parsed_host:
if validate_host(parsed_host, allowed_hosts):
allowed_hosts.add(parsed_host)
return url_has_allowed_host_and_scheme(url, allowed_hosts=allowed_hosts)
def send_password_reset_mail(self, user, email, context):
"""
Method intended to be overridden in case you need to customize the logic
used to determine whether a user is permitted to request a password reset.
For example, if you are enforcing something like "social only" authentication
in your app, you may want to intervene here by checking `user.has_usable_password`
"""
return self.send_mail("account/email/password_reset_key", email, context)
def get_reset_password_from_key_url(self, key):
"""
Method intended to be overridden in case the password reset email
needs to be adjusted.
"""
from allauth.account.internal import flows
return flows.password_reset.get_reset_password_from_key_url(self.request, key)
def get_email_confirmation_url(self, request, emailconfirmation):
"""Constructs the email confirmation (activation) url.
Note that if you have architected your system such that email
confirmations are sent outside of the request context `request`
can be `None` here.
"""
from allauth.account.internal import flows
return flows.email_verification.get_email_verification_url(
request, emailconfirmation
)
def should_send_confirmation_mail(self, request, email_address, signup) -> bool:
return True
def send_account_already_exists_mail(self, email: str) -> None:
from allauth.account.internal import flows
signup_url = flows.signup.get_signup_url(context.request)
password_reset_url = flows.password_reset.get_reset_password_url(
context.request
)
ctx = {
"signup_url": signup_url,
"password_reset_url": password_reset_url,
}
self.send_mail("account/email/account_already_exists", email, ctx)
def send_confirmation_mail(self, request, emailconfirmation, signup):
ctx = {
"user": emailconfirmation.email_address.user,
}
if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
ctx.update({"code": emailconfirmation.key})
else:
ctx.update(
{
"key": emailconfirmation.key,
"activate_url": self.get_email_confirmation_url(
request, emailconfirmation
),
}
)
if signup:
email_template = "account/email/email_confirmation_signup"
else:
email_template = "account/email/email_confirmation"
self.send_mail(email_template, emailconfirmation.email_address.email, ctx)
def respond_user_inactive(self, request, user):
return headed_redirect_response("account_inactive")
def respond_email_verification_sent(self, request, user):
return headed_redirect_response("account_email_verification_sent")
def _get_login_attempts_cache_key(self, request, **credentials):
site = get_current_site(request)
login = credentials.get("email", credentials.get("username", "")).lower()
return f"{site.domain}:{login}"
def _delete_login_attempts_cached_email(self, request, **credentials):
cache_key = self._get_login_attempts_cache_key(request, **credentials)
# Here, we wipe the login failed rate limit, completely. This is safe,
# as we only do this on a succesful password reset, which is rate limited
# on itself (e.g. sending of email etc.).
ratelimit.clear(
request,
config=app_settings.RATE_LIMITS,
action="login_failed",
key=cache_key,
)
def _rollback_login_failed_rl_usage(self) -> None:
usage = getattr(self, "_login_failed_rl_usage", None)
if usage:
usage.rollback()
def pre_authenticate(self, request, **credentials):
cache_key = self._get_login_attempts_cache_key(request, **credentials)
self._login_failed_rl_usage = ratelimit.consume(
request,
config=app_settings.RATE_LIMITS,
action="login_failed",
key=cache_key,
)
if not self._login_failed_rl_usage:
raise self.validation_error("too_many_login_attempts")
def authenticate(self, request, **credentials):
"""Only authenticates, does not actually login. See `login`"""
from allauth.account.auth_backends import AuthenticationBackend
self.pre_authenticate(request, **credentials)
AuthenticationBackend.unstash_authenticated_user()
user = authenticate(request, **credentials)
alt_user = AuthenticationBackend.unstash_authenticated_user()
user = user or alt_user
if user:
# On a succesful login, we cannot just wipe the login failed rate
# limit. That consists of 2 parts, a per IP limit, and, a per
# key(email) limit. Wiping it completely would allow an attacker to
# insert periodic successful logins during a brute force
# process. So instead, we are rolling back our consumption.
self._rollback_login_failed_rl_usage()
else:
self.authentication_failed(request, **credentials)
return user
def authentication_failed(self, request, **credentials):
pass
def reauthenticate(self, user, password):
from allauth.account.models import EmailAddress
from allauth.account.utils import user_username
credentials = {"password": password}
username = user_username(user)
if username:
credentials["username"] = username
email = EmailAddress.objects.get_primary_email(user)
if email:
credentials["email"] = email
if app_settings.LoginMethod.PHONE in app_settings.LOGIN_METHODS:
phone_verified = self.get_phone(user)
if phone_verified:
credentials["phone"] = phone_verified[0]
reauth_user = self.authenticate(context.request, **credentials)
return reauth_user is not None and reauth_user.pk == user.pk
def is_ajax(self, request):
return any(
[
request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest",
request.content_type == "application/json",
request.META.get("HTTP_ACCEPT") == "application/json",
]
)
def get_client_ip(self, request) -> str:
"""
Returns the IP address of the client.
"""
ip = get_client_ip(request)
if not ip:
raise PermissionDenied("Unable to determine client IP address")
return ip
def get_http_user_agent(self, request: HttpRequest) -> str:
return request.META.get("HTTP_USER_AGENT", "Unspecified")
def generate_emailconfirmation_key(self, email):
key = get_random_string(64).lower()
return key
def get_login_stages(self):
ret = []
ret.append("allauth.account.stages.LoginByCodeStage")
ret.append("allauth.account.stages.PhoneVerificationStage")
ret.append("allauth.account.stages.EmailVerificationStage")
if allauth_settings.MFA_ENABLED:
from allauth.mfa import app_settings as mfa_settings
ret.append("allauth.mfa.stages.AuthenticateStage")
if mfa_settings._TRUST_STAGE_ENABLED:
ret.append("allauth.mfa.stages.TrustStage")
if mfa_settings.PASSKEY_SIGNUP_ENABLED:
ret.append("allauth.mfa.webauthn.stages.PasskeySignupStage")
return ret
def get_reauthentication_methods(self, user):
"""The order of the methods returned matters. The first method is the
default when using the `@reauthentication_required` decorator.
"""
from allauth.account.internal.flows.reauthentication import (
get_reauthentication_flows,
)
flow_by_id = {f["id"]: f for f in get_reauthentication_flows(user)}
ret = []
if "reauthenticate" in flow_by_id:
entry = {
"id": "reauthenticate",
"description": _("Use your password"),
"url": reverse("account_reauthenticate"),
}
ret.append(entry)
if "mfa_reauthenticate" in flow_by_id:
types = flow_by_id["mfa_reauthenticate"]["types"]
if "recovery_codes" in types or "totp" in types:
entry = {
"id": "mfa_reauthenticate",
"description": _("Use authenticator app or code"),
"url": reverse("mfa_reauthenticate"),
}
ret.append(entry)
if "webauthn" in types:
entry = {
"id": "mfa_reauthenticate:webauthn",
"description": _("Use a security key"),
"url": reverse("mfa_reauthenticate_webauthn"),
}
ret.append(entry)
return ret
def send_notification_mail(self, template_prefix, user, context=None, email=None):
from allauth.account.models import EmailAddress
if not app_settings.EMAIL_NOTIFICATIONS:
return
if not email:
email = EmailAddress.objects.get_primary_email(user)
if not email:
return
ctx = {
"timestamp": timezone.now(),
"ip": self.get_client_ip(self.request),
"user_agent": self.get_http_user_agent(self.request)[
:HTTP_USER_AGENT_MAX_LENGTH
],
}
if context:
ctx.update(context)
self.send_mail(template_prefix, email, ctx)
def generate_login_code(self) -> str:
"""
Generates a new login code.
"""
return generate_user_code(**app_settings.LOGIN_BY_CODE_FORMAT)
def generate_password_reset_code(self) -> str:
"""
Generates a new password reset code.
"""
return generate_user_code(**app_settings.PASSWORD_RESET_BY_CODE_FORMAT)
def generate_email_verification_code(self) -> str:
"""
Generates a new email verification code.
"""
return generate_user_code(**app_settings.EMAIL_VERIFICATION_BY_CODE_FORMAT)
def generate_phone_verification_code(self, *, user, phone: str) -> str:
"""
Generates a new phone verification code.
"""
return generate_user_code(**app_settings.PHONE_VERIFICATION_CODE_FORMAT)
def _generate_phone_verification_code_compat(self, *, user, phone: str) -> str:
sig = inspect.signature(self.generate_phone_verification_code)
if len(sig.parameters) == 0:
warnings.warn(
"generate_phone_verification_code(self) is deprecated, use generate_phone_verification_code(self, *, user, phone)",
DeprecationWarning,
)
return self.generate_phone_verification_code() # type: ignore[call-arg]
return self.generate_phone_verification_code(user=user, phone=phone)
def is_login_by_code_required(self, login) -> bool:
"""
Returns whether or not login-by-code is required for the given
login.
"""
from allauth.account import authentication
method = None
records = authentication.get_authentication_records(self.request)
if records:
method = records[-1]["method"]
if method == "code":
return False
value = app_settings.LOGIN_BY_CODE_REQUIRED
if isinstance(value, bool):
return value
if not value:
return False
return method is None or method in value
def phone_form_field(self, **kwargs):
"""
Returns a form field used to input phone numbers.
"""
from allauth.account.fields import PhoneField
return PhoneField(**kwargs)
def send_unknown_account_sms(self, phone: str, **kwargs) -> None:
"""
In case enumeration prevention is enabled, and, a verification code
is requested for an unlisted phone number, this method is invoked to
send a text explaining that no account is on file.
"""
pass
def send_account_already_exists_sms(self, phone: str) -> None:
pass
def send_verification_code_sms(self, user, phone: str, code: str, **kwargs):
"""
Sends a verification code.
"""
raise NotImplementedError
@property
def _has_phone_impl(self) -> bool:
"""
Checks whether the phone number adapter is fully implemented.
"""
methods = (
"send_verification_code_sms",
"set_phone",
"get_phone",
"set_phone_verified",
"get_user_by_phone",
)
return all(
getattr(self.__class__, method) != getattr(DefaultAccountAdapter, method)
for method in methods
)
def set_phone(self, user, phone: str, verified: bool):
"""
Sets the phone number (and verified status) for the given user.
"""
raise NotImplementedError
def get_phone(self, user) -> tuple[str, bool] | None:
"""
Returns the phone number stored for the given user. A tuple of the
phone number itself, and whether or not the phone number was verified is
returned.
"""
raise NotImplementedError
def set_phone_verified(self, user, phone: str):
"""
Marks the specified phone number for the given user as
verified. Note that the user is already expected to have
the phone number attached to the account.
"""
raise NotImplementedError
def get_user_by_phone(self, phone: str):
"""
Looks up a user given the specified phone number. Returns ``None`` if no user
was found.
"""
raise NotImplementedError
def get_adapter(request=None) -> DefaultAccountAdapter:
return import_attribute(app_settings.ADAPTER)(request)
================================================
FILE: allauth/account/admin.py
================================================
from django.contrib import admin, messages
from django.utils.translation import gettext_lazy as _
from allauth.account import app_settings, signals
from allauth.account.adapter import get_adapter
from allauth.account.models import EmailAddress, EmailConfirmation
class EmailAddressAdmin(admin.ModelAdmin):
list_display = ("email", "user", "primary", "verified")
list_filter = ("primary", "verified")
search_fields = []
raw_id_fields = ("user",)
actions = ["make_verified"]
def get_search_fields(self, request):
base_fields = get_adapter().get_user_search_fields()
return ["email"] + list(map(lambda a: f"user__{a}", base_fields))
def make_verified(self, request, queryset):
for email_address in queryset.filter(verified=False).iterator():
if email_address.set_verified():
signals.email_confirmed.send(
sender=EmailAddress,
request=request,
email_address=email_address,
)
self.message_user(
request,
_("Marked {email} as verified.").format(email=email_address.email),
level=messages.SUCCESS,
)
else:
self.message_user(
request,
_("Failed to mark {email} as verified.").format(
email=email_address.email
),
level=messages.ERROR,
)
make_verified.short_description = _("Mark selected email addresses as verified") # type: ignore[attr-defined]
class EmailConfirmationAdmin(admin.ModelAdmin):
list_display = ("email_address", "created", "sent", "key")
list_filter = ("sent",)
raw_id_fields = ("email_address",)
if not app_settings.EMAIL_CONFIRMATION_HMAC:
admin.site.register(EmailConfirmation, EmailConfirmationAdmin)
admin.site.register(EmailAddress, EmailAddressAdmin)
================================================
FILE: allauth/account/app_settings.py
================================================
import warnings
from enum import Enum
from allauth import app_settings as allauth_settings
from allauth.core.internal.cryptokit import UserCodeFormat
class AppSettings:
class AuthenticationMethod(str, Enum):
USERNAME = "username"
EMAIL = "email"
USERNAME_EMAIL = "username_email"
class LoginMethod(str, Enum):
USERNAME = "username"
EMAIL = "email"
PHONE = "phone"
class EmailVerificationMethod(str, Enum):
# After signing up, keep the user account inactive until the email
# address is verified
MANDATORY = "mandatory"
# Allow login with unverified email (email verification is
# still sent)
OPTIONAL = "optional"
# Don't send email verification mails during signup
NONE = "none"
def __init__(self, prefix):
self.prefix = prefix
def _setting(self, name, dflt):
from allauth.utils import get_setting
return get_setting(self.prefix + name, dflt)
@property
def PREVENT_ENUMERATION(self):
return self._setting("PREVENT_ENUMERATION", True)
@property
def DEFAULT_HTTP_PROTOCOL(self):
return self._setting("DEFAULT_HTTP_PROTOCOL", "http").lower()
@property
def EMAIL_CONFIRMATION_EXPIRE_DAYS(self):
"""
Determines the expiration date of email confirmation mails (#
of days)
"""
from django.conf import settings
return self._setting(
"EMAIL_CONFIRMATION_EXPIRE_DAYS",
getattr(settings, "EMAIL_CONFIRMATION_DAYS", 3),
)
@property
def EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL(self):
"""
The URL to redirect to after a successful email confirmation, in
case of an authenticated user
"""
return self._setting("EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL", None)
@property
def EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL(self):
"""
The URL to redirect to after a successful email confirmation, in
case no user is logged in
"""
from django.conf import settings
return self._setting(
"EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL", settings.LOGIN_URL
)
@property
def EMAIL_REQUIRED(self):
"""
The user is required to hand over an email address when signing up
"""
warnings.warn(
"app_settings.EMAIL_REQUIRED is deprecated, use: app_settings.SIGNUP_FIELDS['email']['required']",
stacklevel=3,
)
email = self.SIGNUP_FIELDS.get("email")
return email and email["required"]
@property
def EMAIL_VERIFICATION(self):
"""
See email verification method
"""
ret = self._setting("EMAIL_VERIFICATION", self.EmailVerificationMethod.OPTIONAL)
# Deal with legacy (boolean based) setting
if ret is True:
ret = self.EmailVerificationMethod.MANDATORY
elif ret is False:
ret = self.EmailVerificationMethod.OPTIONAL
return self.EmailVerificationMethod(ret)
@property
def EMAIL_VERIFICATION_BY_CODE_ENABLED(self):
return self._setting("EMAIL_VERIFICATION_BY_CODE_ENABLED", False)
@property
def EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS(self):
return self._setting("EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS", 3)
@property
def EMAIL_VERIFICATION_BY_CODE_TIMEOUT(self):
return self._setting("EMAIL_VERIFICATION_BY_CODE_TIMEOUT", 15 * 60)
@property
def EMAIL_VERIFICATION_MAX_CHANGE_COUNT(self) -> int:
"""
The maximum number of times the email can be changed after signup at
the email veriication stage.
"""
v = self._setting("EMAIL_VERIFICATION_SUPPORTS_CHANGE", False)
if isinstance(v, bool):
v = 2 if v else 0
return v
@property
def EMAIL_VERIFICATION_MAX_RESEND_COUNT(self) -> int:
"""
The maximum number of times the user can request a new email verification code.
"""
v = self._setting("EMAIL_VERIFICATION_SUPPORTS_RESEND", False)
if isinstance(v, bool):
v = 2 if v else 0
return v
@property
def MAX_EMAIL_ADDRESSES(self):
return self._setting("MAX_EMAIL_ADDRESSES", None)
@property
def CHANGE_EMAIL(self):
return self._setting("CHANGE_EMAIL", False)
@property
def AUTHENTICATION_METHOD(self):
warnings.warn(
"app_settings.AUTHENTICATION_METHOD is deprecated, use: app_settings.LOGIN_METHODS",
stacklevel=3,
)
methods = self.LOGIN_METHODS
if self.LoginMethod.EMAIL in methods and self.LoginMethod.USERNAME in methods:
return "username_email"
elif self.LoginMethod.EMAIL in methods:
return "email"
elif self.LoginMethod.USERNAME in methods:
return "username"
else:
raise NotADirectoryError
@property
def LOGIN_METHODS(self) -> frozenset[LoginMethod]:
methods = self._setting("LOGIN_METHODS", None)
if methods is None:
auth_method = self._setting(
"AUTHENTICATION_METHOD", self.AuthenticationMethod.USERNAME
)
if auth_method == self.AuthenticationMethod.USERNAME_EMAIL:
methods = {self.LoginMethod.EMAIL, self.LoginMethod.USERNAME}
else:
methods = {self.LoginMethod(auth_method)}
return frozenset([self.LoginMethod(m) for m in methods])
@property
def EMAIL_MAX_LENGTH(self):
"""
Adjust max_length of email addresses
"""
return self._setting("EMAIL_MAX_LENGTH", 254)
@property
def PHONE_VERIFICATION_ENABLED(self):
return self._setting("PHONE_VERIFICATION_ENABLED", True)
@property
def PHONE_VERIFICATION_MAX_ATTEMPTS(self):
return self._setting("PHONE_VERIFICATION_MAX_ATTEMPTS", 3)
@property
def PHONE_VERIFICATION_MAX_CHANGE_COUNT(self) -> int:
"""
The maximum number of times the phone number can be changed after
signup at the phone number verification stage.
"""
v = self._setting("PHONE_VERIFICATION_SUPPORTS_CHANGE", False)
if isinstance(v, bool):
v = 2 if v else 0
return v
@property
def PHONE_VERIFICATION_MAX_RESEND_COUNT(self) -> int:
"""
The maximum number of times the user can request a new phone number
verification code.
"""
v = self._setting("PHONE_VERIFICATION_SUPPORTS_RESEND", False)
if isinstance(v, bool):
v = 2 if v else 0
return v
@property
def PHONE_VERIFICATION_TIMEOUT(self):
return self._setting("PHONE_VERIFICATION_TIMEOUT", 15 * 60)
@property
def UNIQUE_EMAIL(self):
"""
Enforce uniqueness of email addresses
"""
return self._setting("UNIQUE_EMAIL", True)
@property
def SIGNUP_EMAIL_ENTER_TWICE(self):
"""
Signup email verification
"""
warnings.warn(
"app_settings.SIGNUP_EMAIL_ENTER_TWICE is deprecated, use: 'email2' in app_settings.SIGNUP_FIELDS",
stacklevel=3,
)
return "email2" in self.SIGNUP_FIELDS
@property
def SIGNUP_PASSWORD_ENTER_TWICE(self):
"""
Signup password verification
"""
warnings.warn(
"app_settings.SIGNUP_PASSWORD_ENTER_TWICE is deprecated, use: 'password2' in app_settings.SIGNUP_FIELDS",
stacklevel=3,
)
return "password2" in self.SIGNUP_FIELDS
@property
def SIGNUP_REDIRECT_URL(self):
from django.conf import settings
return self._setting("SIGNUP_REDIRECT_URL", settings.LOGIN_REDIRECT_URL)
@property
def PASSWORD_MIN_LENGTH(self):
"""
Minimum password Length
"""
from django.conf import settings
ret = None
if not settings.AUTH_PASSWORD_VALIDATORS:
ret = self._setting("PASSWORD_MIN_LENGTH", 6)
return ret
@property
def RATE_LIMITS(self):
rls = self._setting("RATE_LIMITS", {})
if rls is False:
return {}
attempts_amount = self._setting("LOGIN_ATTEMPTS_LIMIT", 5)
attempts_timeout = self._setting("LOGIN_ATTEMPTS_TIMEOUT", 60 * 5)
login_failed_rl = None
if attempts_amount and attempts_timeout:
login_failed_rl = f"10/m/ip,{attempts_amount}/{attempts_timeout}s/key"
if self.EMAIL_VERIFICATION_BY_CODE_ENABLED:
confirm_email_rl = "1/10s/key"
else:
cooldown = self._setting("EMAIL_CONFIRMATION_COOLDOWN", 3 * 60)
confirm_email_rl = None
if cooldown:
confirm_email_rl = f"1/{cooldown}s/key"
ret = {
# Change password view (for users already logged in)
"change_password": "5/m/user", # nosec
# Change phone number
"change_phone": "1/m/user",
# Email management (e.g. add, remove, change primary)
"manage_email": "10/m/user",
# Request a password reset, global rate limit per IP
"reset_password": "20/m/ip,5/m/key",
# Reauthentication for users already logged in
"reauthenticate": "10/m/user",
# Password reset (the view the password reset email links to).
"reset_password_from_key": "20/m/ip",
# Signups.
"signup": "20/m/ip",
# Logins.
"login": "30/m/ip",
# Request a login code: key is the email.
"request_login_code": "20/m/ip,3/m/key",
# Logins.
"login_failed": login_failed_rl,
# Verify email (to be renamed to verify_email)
"confirm_email": confirm_email_rl,
# Verify phone
"verify_phone": "1/30s/key,3/m/ip",
}
ret.update(rls)
return ret
@property
def EMAIL_SUBJECT_PREFIX(self):
"""
Subject-line prefix to use for email messages sent
"""
return self._setting("EMAIL_SUBJECT_PREFIX", None)
@property
def SIGNUP_FORM_CLASS(self):
"""
Signup form
"""
return self._setting("SIGNUP_FORM_CLASS", None)
@property
def SIGNUP_FORM_HONEYPOT_FIELD(self):
"""
Honeypot field name. Empty string or ``None`` will disable honeypot behavior.
"""
return self._setting("SIGNUP_FORM_HONEYPOT_FIELD", None)
@property
def SIGNUP_FIELDS(self) -> dict:
fields = self._setting("SIGNUP_FIELDS", None)
if not fields:
fields = []
username = self._setting("USERNAME_REQUIRED", True)
email = self._setting("EMAIL_REQUIRED", False)
email2 = self._setting("SIGNUP_EMAIL_ENTER_TWICE", False)
password2 = self._setting(
"SIGNUP_PASSWORD_ENTER_TWICE",
self._setting("SIGNUP_PASSWORD_VERIFICATION", True),
)
if email:
fields.append("email*")
else:
fields.append("email")
if email2:
fields.append("email2*" if email else "email2")
if username:
fields.append("username*")
fields.append("password1*")
if password2:
fields.append("password2*")
ret = {}
for field in fields:
f, req, _ = field.partition("*")
ret[f] = {"required": bool(req)}
return ret
@property
def USERNAME_REQUIRED(self):
"""
The user is required to enter a username when signing up
"""
warnings.warn(
"app_settings.USERNAME_REQUIRED is deprecated, use: app_settings.SIGNUP_FIELDS['username']['required']",
stacklevel=3,
)
username = self.SIGNUP_FIELDS.get("username")
return username and username["required"]
@property
def USERNAME_MIN_LENGTH(self):
"""
Minimum username Length
"""
return self._setting("USERNAME_MIN_LENGTH", 1)
@property
def USERNAME_BLACKLIST(self):
"""
List of usernames that are not allowed
"""
return self._setting("USERNAME_BLACKLIST", [])
@property
def PASSWORD_INPUT_RENDER_VALUE(self):
"""
render_value parameter as passed to PasswordInput fields
"""
return self._setting("PASSWORD_INPUT_RENDER_VALUE", False)
@property
def ADAPTER(self):
return self._setting("ADAPTER", "allauth.account.adapter.DefaultAccountAdapter")
@property
def CONFIRM_EMAIL_ON_GET(self):
return self._setting("CONFIRM_EMAIL_ON_GET", False)
@property
def AUTHENTICATED_LOGIN_REDIRECTS(self):
return self._setting("AUTHENTICATED_LOGIN_REDIRECTS", True)
@property
def LOGIN_ON_EMAIL_CONFIRMATION(self):
"""
Automatically log the user in once they confirmed their email address
"""
return self._setting("LOGIN_ON_EMAIL_CONFIRMATION", False)
@property
def LOGIN_ON_PASSWORD_RESET(self):
"""
Automatically log the user in immediately after resetting
their password.
"""
return self._setting("LOGIN_ON_PASSWORD_RESET", False)
@property
def LOGOUT_REDIRECT_URL(self):
from django.conf import settings
return self._setting("LOGOUT_REDIRECT_URL", settings.LOGOUT_REDIRECT_URL or "/")
@property
def LOGOUT_ON_GET(self):
return self._setting("LOGOUT_ON_GET", False)
@property
def LOGOUT_ON_PASSWORD_CHANGE(self):
return self._setting("LOGOUT_ON_PASSWORD_CHANGE", False)
@property
def USER_MODEL_USERNAME_FIELD(self):
return self._setting("USER_MODEL_USERNAME_FIELD", "username")
@property
def USER_MODEL_EMAIL_FIELD(self):
return self._setting("USER_MODEL_EMAIL_FIELD", "email")
@property
def SESSION_COOKIE_AGE(self):
"""
Deprecated -- use Django's settings.SESSION_COOKIE_AGE instead
"""
from django.conf import settings
return self._setting("SESSION_COOKIE_AGE", settings.SESSION_COOKIE_AGE)
@property
def SESSION_REMEMBER(self):
"""
Controls the life time of the session. Set to `None` to ask the user
("Remember me?"), `False` to not remember, and `True` to always
remember.
"""
return self._setting("SESSION_REMEMBER", None)
@property
def TEMPLATE_EXTENSION(self):
"""
A string defining the template extension to use, defaults to `html`.
"""
return self._setting("TEMPLATE_EXTENSION", "html")
@property
def FORMS(self):
return self._setting("FORMS", {})
@property
def EMAIL_CONFIRMATION_HMAC(self):
return self._setting("EMAIL_CONFIRMATION_HMAC", True)
@property
def SALT(self):
return self._setting("SALT", "account")
@property
def PRESERVE_USERNAME_CASING(self):
return self._setting("PRESERVE_USERNAME_CASING", True)
@property
def USERNAME_VALIDATORS(self):
from django.contrib.auth import get_user_model
from django.core.exceptions import ImproperlyConfigured
from allauth.utils import import_attribute
path = self._setting("USERNAME_VALIDATORS", None)
if path:
ret = import_attribute(path)
if not isinstance(ret, list):
raise ImproperlyConfigured(
"ACCOUNT_USERNAME_VALIDATORS is expected to be a list"
)
else:
if self.USER_MODEL_USERNAME_FIELD is not None:
ret = (
get_user_model()
._meta.get_field(self.USER_MODEL_USERNAME_FIELD)
.validators
)
else:
ret = []
return ret
@property
def PASSWORD_RESET_BY_CODE_ENABLED(self):
return self._setting("PASSWORD_RESET_BY_CODE_ENABLED", False)
@property
def PASSWORD_RESET_BY_CODE_MAX_ATTEMPTS(self):
return self._setting("PASSWORD_RESET_BY_CODE_MAX_ATTEMPTS", 3)
@property
def PASSWORD_RESET_BY_CODE_TIMEOUT(self):
return self._setting("PASSWORD_RESET_BY_CODE_TIMEOUT", 3 * 60)
@property
def PASSWORD_RESET_TOKEN_GENERATOR(self):
from allauth.account.forms import EmailAwarePasswordResetTokenGenerator
from allauth.utils import import_attribute
token_generator_path = self._setting("PASSWORD_RESET_TOKEN_GENERATOR", None)
if token_generator_path is not None:
token_generator = import_attribute(token_generator_path)
else:
token_generator = EmailAwarePasswordResetTokenGenerator
return token_generator
@property
def EMAIL_UNKNOWN_ACCOUNTS(self):
return self._setting("EMAIL_UNKNOWN_ACCOUNTS", True)
@property
def REAUTHENTICATION_TIMEOUT(self):
return self._setting("REAUTHENTICATION_TIMEOUT", 300)
@property
def EMAIL_NOTIFICATIONS(self):
return self._setting("EMAIL_NOTIFICATIONS", False)
@property
def REAUTHENTICATION_REQUIRED(self):
return self._setting("REAUTHENTICATION_REQUIRED", False)
@property
def LOGIN_BY_CODE_ENABLED(self):
return self._setting("LOGIN_BY_CODE_ENABLED", False)
@property
def LOGIN_BY_CODE_TRUST_ENABLED(self):
return self._setting("LOGIN_BY_CODE_TRUST_ENABLED", False)
@property
def LOGIN_BY_CODE_MAX_ATTEMPTS(self):
return self._setting("LOGIN_BY_CODE_MAX_ATTEMPTS", 3)
@property
def LOGIN_BY_CODE_MAX_RESEND_COUNT(self) -> int:
"""
The maximum number of times the user can request a new login code.
"""
v = self._setting("LOGIN_BY_CODE_SUPPORTS_RESEND", False)
if isinstance(v, bool):
v = 2 if v else 0
return v
@property
def LOGIN_BY_CODE_TIMEOUT(self):
return self._setting("LOGIN_BY_CODE_TIMEOUT", 3 * 60)
@property
def LOGIN_TIMEOUT(self):
"""
The maximum allowed time (in seconds) for a login to go through the
various login stages. This limits, for example, the time span that the
2FA stage remains available.
"""
return self._setting("LOGIN_TIMEOUT", 15 * 60)
@property
def LOGIN_BY_CODE_REQUIRED(self) -> bool | set[str]:
"""
When enabled (in case of ``True``), every user logging in is
required to input a login confirmation code sent by email.
Alternatively, you can specify a set of authentication methods
(``"password"``, ``"mfa"``, or ``"socialaccount"``) for which login
codes are required.
"""
value = self._setting("LOGIN_BY_CODE_REQUIRED", False)
if isinstance(value, bool):
return value
return set(value)
@property
def LOGIN_BY_CODE_FORMAT(self) -> UserCodeFormat:
"""
Controls the format of the login code.
"""
return self._setting("LOGIN_BY_CODE_FORMAT", allauth_settings.USER_CODE_FORMAT)
@property
def PHONE_VERIFICATION_CODE_FORMAT(self) -> UserCodeFormat:
"""
Controls the format of the phone verification code.
"""
return self._setting(
"PHONE_VERIFICATION_CODE_FORMAT", allauth_settings.USER_CODE_FORMAT
)
@property
def PASSWORD_RESET_BY_CODE_FORMAT(self) -> UserCodeFormat:
"""
Controls the format of the password reset code.
"""
return self._setting(
"PASSWORD_RESET_BY_CODE_CODE_FORMAT", allauth_settings.USER_CODE_FORMAT
)
@property
def EMAIL_VERIFICATION_BY_CODE_FORMAT(self) -> UserCodeFormat:
"""
Controls the format of the email verification code.
"""
return self._setting(
"EMAIL_VERIFICATION_BY_CODE_FORMAT", allauth_settings.USER_CODE_FORMAT
)
_app_settings = AppSettings("ACCOUNT_")
def __getattr__(name):
# See https://peps.python.org/pep-0562/
return getattr(_app_settings, name)
================================================
FILE: allauth/account/apps.py
================================================
from django.apps import AppConfig
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.translation import gettext_lazy as _
from allauth import app_settings
class AccountConfig(AppConfig):
name = "allauth.account"
verbose_name = _("Accounts")
default_auto_field = app_settings.DEFAULT_AUTO_FIELD or "django.db.models.AutoField"
def ready(self):
from allauth.account import checks # noqa
required_mw = "allauth.account.middleware.AccountMiddleware"
if required_mw not in settings.MIDDLEWARE:
raise ImproperlyConfigured(
f"{required_mw} must be added to settings.MIDDLEWARE"
)
================================================
FILE: allauth/account/auth_backends.py
================================================
from threading import local
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from allauth.account.adapter import get_adapter
from allauth.account.app_settings import LoginMethod
from . import app_settings
from .utils import filter_users_by_email, filter_users_by_username
_stash = local()
class AuthenticationBackend(ModelBackend):
def authenticate(self, request, **credentials):
password = credentials.get("password")
if not password:
return None
self._did_check_password = False
user = self._authenticate(request, **credentials)
if not self._did_check_password:
self._mitigate_timing_attack(password)
return user
def _authenticate(self, request, **credentials):
password = credentials.get("password")
username = credentials.get("username")
if username:
if LoginMethod.EMAIL in app_settings.LOGIN_METHODS:
# Username/email ambiguity: even though allauth will pass along
# `email` explicitly, other apps may not respect this. For example,
# when using django-tastypie basic authentication, the login is
# always passed as `username`. So let's play nice with other apps
# and use username as fallback.
user = self._authenticate_by_email(username, password)
if user:
return user
user = self._authenticate_by_username(username, password)
if user:
return user
email = credentials.get("email")
if email:
user = self._authenticate_by_email(email, password)
if user:
return user
phone = credentials.get("phone")
if phone:
user = self._authenticate_by_phone(phone, password)
if user:
return user
return None
def _authenticate_by_phone(self, phone: str, password: str):
if not phone or LoginMethod.PHONE not in app_settings.LOGIN_METHODS:
return None
adapter = get_adapter()
user = adapter.get_user_by_phone(phone)
return self._check_password(user, password)
def _authenticate_by_username(self, username: str, password: str):
if (
(LoginMethod.USERNAME not in app_settings.LOGIN_METHODS)
or (not app_settings.USER_MODEL_USERNAME_FIELD)
or not username
):
return None
user = filter_users_by_username(username).first()
return self._check_password(user, password)
def _authenticate_by_email(
self,
email: str,
password: str,
):
if not email or LoginMethod.EMAIL not in app_settings.LOGIN_METHODS:
return None
users = filter_users_by_email(email, prefer_verified=True)
for user in users:
if self._check_password(user, password):
return user
return None
def _mitigate_timing_attack(self, password):
get_user_model()().set_password(password)
def _check_password(self, user, password):
if not user:
return None
self._did_check_password = True
ok = user.check_password(password)
if ok:
ok = self.user_can_authenticate(user)
if not ok:
self._stash_user(user)
return user if ok else None
@classmethod
def _stash_user(cls, user):
"""Now, be aware, the following is quite ugly, let me explain:
Even if the user credentials match, the authentication can fail because
Django's default ModelBackend calls user_can_authenticate(), which
checks `is_active`. Now, earlier versions of allauth did not do this
and simply returned the user as authenticated, even in case of
`is_active=False`. For allauth scope, this does not pose a problem, as
these users are properly redirected to an account inactive page.
This does pose a problem when the allauth backend is used in a
different context where allauth is not responsible for the login. Then,
by not checking on `user_can_authenticate()` users will allow to become
authenticated whereas according to Django logic this should not be
allowed.
In order to preserve the allauth behavior while respecting Django's
logic, we stash a user for which the password check succeeded but
`user_can_authenticate()` failed. In the allauth authentication logic,
we can then unstash this user and proceed pointing the user to the
account inactive page.
"""
global _stash # noqa: F824
ret = getattr(_stash, "user", None)
_stash.user = user
return ret
@classmethod
def unstash_authenticated_user(cls):
return cls._stash_user(None)
================================================
FILE: allauth/account/authentication.py
================================================
from allauth.account.internal.flows.login import AUTHENTICATION_METHODS_SESSION_KEY
def get_authentication_records(request):
return request.session.get(AUTHENTICATION_METHODS_SESSION_KEY, [])
================================================
FILE: allauth/account/checks.py
================================================
from django.core.checks import Critical, Warning, register
@register()
def adapter_check(app_configs, **kwargs):
from allauth.account.adapter import get_adapter
ret = []
adapter = get_adapter()
if hasattr(adapter, "get_email_confirmation_redirect_url"):
ret.append(
Warning(
msg="adapter.get_email_confirmation_redirect_url(request) is deprecated, use adapter.get_email_verification_redirect_url(email_address)"
)
)
return ret
@register()
def settings_check(app_configs, **kwargs):
from django.conf import settings
from allauth import app_settings as allauth_app_settings
from allauth.account import app_settings
ret = []
if allauth_app_settings.SOCIALACCOUNT_ONLY:
if app_settings.LOGIN_BY_CODE_ENABLED:
ret.append(
Critical(
msg="SOCIALACCOUNT_ONLY does not work with ACCOUNT_LOGIN_BY_CODE_ENABLED"
)
)
if allauth_app_settings.MFA_ENABLED:
ret.append(
Critical(msg="SOCIALACCOUNT_ONLY does not work with 'allauth.mfa'")
)
if app_settings.EMAIL_VERIFICATION != app_settings.EmailVerificationMethod.NONE:
ret.append(
Critical(
msg="SOCIALACCOUNT_ONLY requires ACCOUNT_EMAIL_VERIFICATION = 'none'"
)
)
if (
app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED
and app_settings.EMAIL_VERIFICATION
!= app_settings.EmailVerificationMethod.MANDATORY
):
ret.append(
Critical(
msg="ACCOUNT_EMAIL_VERFICATION_BY_CODE requires ACCOUNT_EMAIL_VERIFICATION = 'mandatory'"
)
)
# Often made mistake: ACCOUNT_SIGNUP_FIELDS = [..., "password", ...]
signup_fields = getattr(settings, "ACCOUNT_SIGNUP_FIELDS", None)
for wrong_field, right_field in [
("password", "password1"),
("password*", "password1*"),
]:
if signup_fields and wrong_field in signup_fields:
ret.append(
Critical(
msg=f"'{wrong_field}' is not a valid field for ACCOUNT_SIGNUP_FIELDS, use '{right_field}'",
)
)
# Cross-check SIGNUP_FIELDS against LOGIN_METHODS. E.g. login is by email, email should be required
signup_fields = app_settings.SIGNUP_FIELDS
if not any(
lm in signup_fields and signup_fields[lm]["required"]
for lm in app_settings.LOGIN_METHODS
):
ret.append(
Warning(
msg="ACCOUNT_LOGIN_METHODS conflicts with ACCOUNT_SIGNUP_FIELDS",
id="account.W001",
)
)
# If login includes email, email must be unique
if (
app_settings.LoginMethod.EMAIL in app_settings.LOGIN_METHODS
and not app_settings.UNIQUE_EMAIL
):
ret.append(
Critical(msg="Using email as a login method requires ACCOUNT_UNIQUE_EMAIL")
)
# Mandatory email verification requires email
email_required = "email" in signup_fields and signup_fields["email"]["required"]
if (
app_settings.EMAIL_VERIFICATION
== app_settings.EmailVerificationMethod.MANDATORY
and not email_required
):
ret.append(
Critical(
msg="ACCOUNT_EMAIL_VERIFICATION = 'mandatory' requires 'email*' in ACCOUNT_SIGNUP_FIELDS"
)
)
if not app_settings.USER_MODEL_USERNAME_FIELD:
if "username" in signup_fields:
ret.append(
Critical(
msg="No ACCOUNT_USER_MODEL_USERNAME_FIELD, yet, ACCOUNT_SIGNUP_FIELDS contains 'username'"
)
)
if app_settings.LoginMethod.USERNAME in app_settings.LOGIN_METHODS:
ret.append(
Critical(
msg="No ACCOUNT_USER_MODEL_USERNAME_FIELD, yet, ACCOUNT_LOGIN_METHODS requires it"
)
)
if (
app_settings.MAX_EMAIL_ADDRESSES is not None
and app_settings.MAX_EMAIL_ADDRESSES <= 0
):
ret.append(Critical(msg="ACCOUNT_MAX_EMAIL_ADDRESSES must be None or > 0"))
if app_settings.CHANGE_EMAIL:
if (
app_settings.MAX_EMAIL_ADDRESSES is not None
and app_settings.MAX_EMAIL_ADDRESSES != 2
):
ret.append(
Critical(
msg="Invalid combination of ACCOUNT_CHANGE_EMAIL and ACCOUNT_MAX_EMAIL_ADDRESSES"
)
)
if hasattr(settings, "ACCOUNT_LOGIN_ATTEMPTS_LIMIT") or hasattr(
settings, "ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT"
):
ret.append(
Warning(
msg="settings.ACCOUNT_LOGIN_ATTEMPTS_LIMIT/TIMEOUT is deprecated, use: settings.ACCOUNT_RATE_LIMITS['login_failed']"
)
)
if hasattr(settings, "ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN"):
ret.append(
Warning(
msg="settings.ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN is deprecated, use: settings.ACCOUNT_RATE_LIMITS['confirm_email']"
)
)
if hasattr(settings, "ACCOUNT_AUTHENTICATION_METHOD"):
converted = set(settings.ACCOUNT_AUTHENTICATION_METHOD.split("_"))
ret.append(
Warning(
f"settings.ACCOUNT_AUTHENTICATION_METHOD is deprecated, use: settings.ACCOUNT_LOGIN_METHODS = {repr(converted)}"
)
)
for field in [
"ACCOUNT_USERNAME_REQUIRED",
"ACCOUNT_EMAIL_REQUIRED",
"ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE",
"ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE",
]:
if hasattr(settings, field):
signup_fields_converted = [
k + ("*" if v["required"] else "")
for k, v in app_settings.SIGNUP_FIELDS.items()
]
ret.append(
Warning(
f"settings.{field} is deprecated, use: settings.ACCOUNT_SIGNUP_FIELDS = {repr(signup_fields_converted)}"
)
)
if (
not allauth_app_settings.MFA_ENABLED
and app_settings.LOGIN_BY_CODE_TRUST_ENABLED
):
ret.append(
Critical(
msg="ACCOUNT_LOGIN_BY_CODE_TRUST_ENABLED requires MFA to be enabled"
)
)
return ret
================================================
FILE: allauth/account/decorators.py
================================================
from functools import wraps
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.http import HttpResponseRedirect
from django.shortcuts import render, resolve_url
from django.urls import reverse
from allauth.account import app_settings
from allauth.account.internal.flows import reauthentication
from allauth.account.internal.flows.email_verification import (
send_verification_email_for_user,
)
from allauth.account.models import EmailAddress
from allauth.account.utils import get_next_redirect_url
from allauth.core.exceptions import ReauthenticationRequired
from allauth.core.internal import httpkit
def verified_email_required(
function=None, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME
):
"""
Even when email verification is not mandatory during signup, there
may be circumstances during which you really want to prevent
unverified users to proceed. This decorator ensures the user is
authenticated and has a verified email address. If the former is
not the case then the behavior is identical to that of the
standard `login_required` decorator. If the latter does not hold,
email verification mails are automatically resend and the user is
presented with a page informing them they needs to verify their email
address.
"""
def decorator(view_func):
@login_required(redirect_field_name=redirect_field_name, login_url=login_url)
def _wrapped_view(request, *args, **kwargs):
if not EmailAddress.objects.filter(
user=request.user, verified=True
).exists():
send_verification_email_for_user(request, request.user)
if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
url = httpkit.add_query_params(
reverse("account_email_verification_sent"),
{REDIRECT_FIELD_NAME: request.get_full_path()},
)
return HttpResponseRedirect(url)
return render(request, "account/verified_email_required.html")
return view_func(request, *args, **kwargs)
return _wrapped_view
if function:
return decorator(function)
return decorator
def reauthentication_required(
function=None,
redirect_field_name=REDIRECT_FIELD_NAME,
allow_get=False,
enabled=None,
):
def decorator(view_func):
@wraps(view_func)
def _wrapper_view(request, *args, **kwargs):
pass_method = allow_get and request.method == "GET"
ena = (enabled is None) or (
enabled(request) if callable(enabled) else enabled
)
if ena and not pass_method:
if (
request.user.is_anonymous
or not reauthentication.did_recently_authenticate(request)
):
raise ReauthenticationRequired()
return view_func(request, *args, **kwargs)
return _wrapper_view
if function:
return decorator(function)
return decorator
def secure_admin_login(function=None):
def decorator(view_func):
@wraps(view_func)
def _wrapper_view(request, *args, **kwargs):
if request.user.is_authenticated:
if not request.user.is_staff or not request.user.is_active:
raise PermissionDenied()
return view_func(request, *args, **kwargs)
else:
next_url = get_next_redirect_url(request)
if not next_url:
next_url = request.get_full_path()
login_url = resolve_url(settings.LOGIN_URL)
login_url = httpkit.add_query_params(
login_url, {REDIRECT_FIELD_NAME: next_url}
)
return HttpResponseRedirect(login_url)
return _wrapper_view
if function:
return decorator(function)
return decorator
================================================
FILE: allauth/account/fields.py
================================================
from django import forms
from django.contrib.auth import password_validation
from django.core.validators import RegexValidator
from django.utils.translation import gettext_lazy as _
from allauth.account import app_settings
from allauth.account.adapter import get_adapter
class EmailField(forms.EmailField):
def __init__(self, *args, **kwargs) -> None:
kwargs.setdefault("label", _("Email"))
kwargs.setdefault(
"widget",
forms.TextInput(
attrs={
"type": "email",
"autocomplete": "email",
"placeholder": _("Email address"),
}
),
)
super().__init__(*args, **kwargs)
def clean(self, value):
return super().clean(value).lower()
class PasswordField(forms.CharField):
def __init__(self, *args, **kwargs):
render_value = kwargs.pop(
"render_value", app_settings.PASSWORD_INPUT_RENDER_VALUE
)
kwargs["widget"] = forms.PasswordInput(
render_value=render_value,
attrs={"placeholder": kwargs.get("label")},
)
autocomplete = kwargs.pop("autocomplete", None)
if autocomplete is not None:
kwargs["widget"].attrs["autocomplete"] = autocomplete
super().__init__(*args, **kwargs)
class SetPasswordField(PasswordField):
def __init__(self, *args, **kwargs):
kwargs["autocomplete"] = "new-password"
kwargs.setdefault(
"help_text", password_validation.password_validators_help_text_html()
)
super().__init__(*args, **kwargs)
self.user = None
def clean(self, value):
value = super().clean(value)
value = get_adapter().clean_password(value, user=self.user)
return value
class PhoneField(forms.CharField):
e164_validator = RegexValidator(
regex=r"^\+[1-9]\d{5,14}$",
message=_("Enter a phone number including country code (e.g. +1 for the US)."),
code="invalid_phone",
)
def __init__(self, *args, **kwargs):
widget = forms.TextInput(
attrs={"placeholder": _("Phone"), "autocomplete": "tel", "type": "tel"}
)
kwargs.setdefault("validators", [self.e164_validator])
kwargs.setdefault("widget", widget)
kwargs.setdefault("label", _("Phone"))
super().__init__(*args, **kwargs)
def clean(self, value):
value = super().clean(value)
if value:
value = value.replace(" ", "").replace("-", "")
value = get_adapter().clean_phone(value)
return value
================================================
FILE: allauth/account/forms.py
================================================
from django import forms
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model, password_validation
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core import exceptions, validators
from django.template.exceptions import TemplateDoesNotExist
from django.template.loader import render_to_string
from django.urls import NoReverseMatch, reverse
from django.utils.safestring import mark_safe
from django.utils.translation import gettext, gettext_lazy as _, pgettext
from allauth.account.app_settings import LoginMethod
from allauth.account.fields import EmailField, PasswordField, SetPasswordField
from allauth.account.internal import flows
from allauth.account.internal.flows.manage_email import (
email_already_exists,
sync_user_email_address,
)
from allauth.account.internal.flows.phone_verification import phone_already_exists
from allauth.account.internal.flows.signup import base_signup_form_class
from allauth.core import context, ratelimit
from allauth.core.internal.cryptokit import compare_user_code
from allauth.core.internal.httpkit import headed_redirect_response
from allauth.utils import get_username_max_length, set_form_field_order
from . import app_settings
from .adapter import get_adapter
from .models import EmailAddress, Login
from .utils import (
filter_users_by_email,
setup_user_email,
url_str_to_user_pk,
user_email,
user_username,
)
class EmailAwarePasswordResetTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
ret = super()._make_hash_value(user, timestamp)
sync_user_email_address(user)
email = user_email(user)
emails = set([email] if email else [])
emails.update(
EmailAddress.objects.filter(user=user).values_list("email", flat=True)
)
ret += "|".join(sorted(emails))
return ret
default_token_generator = app_settings.PASSWORD_RESET_TOKEN_GENERATOR()
class PasswordVerificationMixin:
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get("password1")
password2 = cleaned_data.get("password2")
if (password1 and password2) and password1 != password2:
self.add_error("password2", _("You must type the same password each time."))
return cleaned_data
class LoginForm(forms.Form):
password = PasswordField(label=_("Password"), autocomplete="current-password")
remember = forms.BooleanField(label=_("Remember Me"), required=False)
user = None
def __init__(self, *args, **kwargs) -> None:
self.request = kwargs.pop("request", None)
super().__init__(*args, **kwargs)
adapter = get_adapter()
login_field: forms.Field
if app_settings.LOGIN_METHODS == {LoginMethod.EMAIL}:
login_field = EmailField()
elif app_settings.LOGIN_METHODS == {LoginMethod.USERNAME}:
login_widget = forms.TextInput(
attrs={"placeholder": _("Username"), "autocomplete": "username"}
)
login_field = forms.CharField(
label=_("Username"),
widget=login_widget,
max_length=get_username_max_length(),
)
elif app_settings.LOGIN_METHODS == {LoginMethod.PHONE}:
login_field = adapter.phone_form_field(required=True)
else:
login_widget = forms.TextInput(
attrs={
"placeholder": self._get_login_field_placeholder(),
"autocomplete": "email",
}
)
login_field = forms.CharField(
label=pgettext("field label", "Login"), widget=login_widget
)
self.fields["login"] = login_field
set_form_field_order(self, ["login", "password", "remember"])
if app_settings.SESSION_REMEMBER is not None:
del self.fields["remember"]
self._setup_password_field()
def _get_login_field_placeholder(self):
methods = app_settings.LOGIN_METHODS
assert len(methods) > 1 # nosec
assert methods.issubset(
{
LoginMethod.USERNAME,
LoginMethod.EMAIL,
LoginMethod.PHONE,
}
) # nosec
if len(methods) == 3:
placeholder = _("Username, email or phone")
elif methods == {LoginMethod.USERNAME, LoginMethod.EMAIL}:
placeholder = _("Username or email")
elif methods == {LoginMethod.USERNAME, LoginMethod.PHONE}:
placeholder = _("Username or phone")
elif methods == {LoginMethod.EMAIL, LoginMethod.PHONE}:
placeholder = _("Email or phone")
else:
raise ValueError(methods)
return placeholder
def _setup_password_field(self):
password_field = app_settings.SIGNUP_FIELDS.get("password1")
if not password_field:
del self.fields["password"]
return
try:
self.fields["password"].help_text = render_to_string(
f"account/password_reset_help_text.{app_settings.TEMPLATE_EXTENSION}"
)
return
except TemplateDoesNotExist:
pass
try:
reset_url = reverse("account_reset_password")
except NoReverseMatch:
pass
else:
forgot_txt = _("Forgot your password?")
self.fields["password"].help_text = mark_safe(
f'<a href="{reset_url}">{forgot_txt}</a>'
) # nosec
def user_credentials(self) -> dict:
"""
Provides the credentials required to authenticate the user for
login.
"""
login = self.cleaned_data["login"]
method = flows.login.derive_login_method(login)
credentials = {}
credentials[method] = login
# There are projects using usernames that look like email addresses,
# yet, really are usernames. So, if username is a login method, always
# give that a shot.
if (
LoginMethod.USERNAME in app_settings.LOGIN_METHODS
and method != LoginMethod.USERNAME
):
credentials[LoginMethod.USERNAME] = login
password = self.cleaned_data.get("password")
if password:
credentials["password"] = password
return credentials
def clean_login(self) -> str:
login = self.cleaned_data["login"]
return login.strip()
def clean(self):
cleaned_data = super().clean()
if self._errors:
return cleaned_data
credentials = self.user_credentials()
if "password" in credentials:
return self._clean_with_password(credentials)
return self._clean_without_password(
credentials.get("email"), credentials.get("phone")
)
def _clean_without_password(self, email: str | None, phone: str | None):
"""
If we don't have a password field, we need to replicate the request-login-code
behavior.
"""
data = {}
if email:
data["email"] = email
if phone:
data["phone"] = phone
if not data:
self.add_error("login", get_adapter().validation_error("invalid_login"))
else:
form = RequestLoginCodeForm(data)
if not form.is_valid():
for field in ["phone", "email"]:
errors = form.errors.get(field) or [] # type: ignore
for error in errors:
self.add_error("login", error)
else:
self.user = form._user
return self.cleaned_data
def _clean_with_password(self, credentials: dict):
adapter = get_adapter(self.request)
user = adapter.authenticate(self.request, **credentials)
if user:
login = Login(user=user, email=credentials.get("email"))
if flows.login.is_login_rate_limited(context.request, login):
raise adapter.validation_error("too_many_login_attempts")
self._login = login
self.user = user
else:
login_method = flows.login.derive_login_method(
login=self.cleaned_data["login"]
)
raise adapter.validation_error(f"{login_method.value}_password_mismatch")
return self.cleaned_data
def login(self, request, redirect_url=None):
credentials = self.user_credentials()
if "password" in credentials:
return self._login_with_password(request, redirect_url, credentials)
return self._login_by_code(request, redirect_url, credentials)
def _login_by_code(self, request, redirect_url, credentials):
user = getattr(self, "user", None)
phone = credentials.get("phone")
email = credentials.get("email")
flows.login_by_code.LoginCodeVerificationProcess.initiate(
request=request,
user=user,
phone=phone,
email=email,
)
query = None
if redirect_url:
query = {}
query[REDIRECT_FIELD_NAME] = redirect_url
return headed_redirect_response("account_confirm_login_code", query=query)
def _login_with_password(self, request, redirect_url, credentials):
login = self._login
login.redirect_url = redirect_url
ret = flows.login.perform_password_login(request, credentials, login)
remember = app_settings.SESSION_REMEMBER
if remember is None:
remember = self.cleaned_data["remember"]
if remember:
request.session.set_expiry(app_settings.SESSION_COOKIE_AGE)
else:
request.session.set_expiry(0)
return ret
class BaseSignupForm(base_signup_form_class()): # type: ignore[misc]
username = forms.CharField(
label=_("Username"),
min_length=app_settings.USERNAME_MIN_LENGTH,
widget=forms.TextInput(
attrs={"placeholder": _("Username"), "autocomplete": "username"}
),
)
email = EmailField()
def __init__(self, *args, **kwargs) -> None:
self._signup_fields = self._get_signup_fields(kwargs)
self.account_already_exists = False
super().__init__(*args, **kwargs)
username_field = self.fields["username"]
username_field.max_length = get_username_max_length()
username_field.validators.append(
validators.MaxLengthValidator(username_field.max_length)
)
username_field.widget.attrs["maxlength"] = str(username_field.max_length)
email2 = self._signup_fields.get("email2")
if email2:
self.fields["email2"] = EmailField(
label=_("Email (again)"),
required=email2["required"],
widget=forms.TextInput(
attrs={
"type": "email",
"placeholder": _("Email address confirmation"),
}
),
)
email = self._signup_fields.get("email")
if email:
if email["required"]:
self.fields["email"].label = gettext("Email")
self.fields["email"].required = True
else:
self.fields["email"].label = gettext("Email (optional)")
self.fields["email"].required = False
self.fields["email"].widget.is_required = False
else:
del self.fields["email"]
username = self._signup_fields.get("username")
if username:
if username["required"]:
self.fields["username"].label = gettext("Username")
self.fields["username"].required = True
else:
self.fields["username"].label = gettext("Username (optional)")
self.fields["username"].required = False
self.fields["username"].widget.is_required = False
else:
del self.fields["username"]
phone = self._signup_fields.get("phone")
self._has_phone_field = bool(phone)
if phone:
adapter = get_adapter()
self.fields["phone"] = adapter.phone_form_field(
label=_("Phone"), required=phone["required"]
)
default_field_order = list(self._signup_fields.keys())
set_form_field_order(
self, getattr(self, "field_order", None) or default_field_order
)
def _get_signup_fields(self, kwargs):
signup_fields = app_settings.SIGNUP_FIELDS
if "email_required" in kwargs:
email = signup_fields.get("email")
if not email:
raise exceptions.ImproperlyConfigured(
"email required but not listed as a field"
)
email["required"] = kwargs.pop("email_required")
email2 = signup_fields.get("email2")
if email2:
email2["required"] = email["required"]
if "username_required" in kwargs:
username = signup_fields.get("username")
if not username:
raise exceptions.ImproperlyConfigured(
"username required but not listed as a field"
)
username["required"] = kwargs.pop("username_required")
return signup_fields
def clean_username(self) -> str:
value = self.cleaned_data["username"]
if not value and not self._signup_fields["username"]["required"]:
return value
value = get_adapter().clean_username(value)
# Note regarding preventing enumeration: if the username is already
# taken, but the email address is not, we would still leak information
# if we were to send an email to that email address stating that the
# username is already in use.
return value
def clean_email(self) -> str:
value = self.cleaned_data["email"].lower()
value = get_adapter().clean_email(value)
if value:
value = self.validate_unique_email(value)
return value
def clean_email2(self) -> str:
value = self.cleaned_data["email2"].lower()
return value
def validate_unique_email(self, value) -> str:
email, self.account_already_exists = flows.manage_email.email_already_exists(
value
)
return email
def clean(self) -> dict:
cleaned_data = super().clean()
if "email2" in self._signup_fields:
email = cleaned_data.get("email")
email2 = cleaned_data.get("email2")
if (email and email2) and email != email2:
self.add_error("email2", _("You must type the same email each time."))
if "phone" in self._signup_fields:
self._clean_phone()
return cleaned_data
def _clean_phone(self):
"""Intentionally NOT `clean_phone()`:
- phone field is optional (depending on ACCOUNT_SIGNUP_FIELDS)
- we don't want to have clean_phone() mistakenly called when a project
is using a custom signup form with their own `phone` field.
"""
adapter = get_adapter()
if phone := self.cleaned_data.get("phone"):
user = adapter.get_user_by_phone(phone)
if user:
if not app_settings.PREVENT_ENUMERATION:
self.add_error("phone", adapter.error_messages["phone_taken"])
else:
self.account_already_exists = True
def custom_signup(self, request, user) -> None:
self.signup(request, user)
def try_save(self, request):
"""Try and save the user. This can fail in case of a conflict on the
email address, in that case we will send an "account already exists"
email and return a standard "email verification sent" response.
"""
if self.account_already_exists:
# Don't create a new account, only send an email informing the user
# that (s)he already has one...
email = self.cleaned_data.get("email")
phone = None
if "phone" in self._signup_fields:
phone = self.cleaned_data.get("phone")
resp = flows.signup.prevent_enumeration(request, email=email, phone=phone)
user = None
else:
user = self.save(request)
resp = None
return user, resp
def save(self, request):
email = self.cleaned_data.get("email")
if self.account_already_exists:
raise ValueError(email)
adapter = get_adapter()
user = adapter.new_user(request)
adapter.save_user(request, user, self)
self.custom_signup(request, user)
# TODO: Move into adapter `save_user` ?
setup_user_email(request, user, [EmailAddress(email=email)] if email else [])
return user
class SignupForm(BaseSignupForm):
def __init__(self, *args, **kwargs) -> None:
self.by_passkey = kwargs.pop("by_passkey", False)
super().__init__(*args, **kwargs)
password1_field = self._signup_fields.get("password1")
if not self.by_passkey and password1_field:
self.fields["password1"] = PasswordField(
label=_("Password"),
autocomplete="new-password",
help_text=password_validation.password_validators_help_text_html(),
required=password1_field["required"],
)
if "password2" in self._signup_fields:
self.fields["password2"] = PasswordField(
label=_("Password (again)"),
autocomplete="new-password",
required=password1_field["required"],
)
if hasattr(self, "field_order"):
set_form_field_order(self, self.field_order)
honeypot_field_name = app_settings.SIGNUP_FORM_HONEYPOT_FIELD
if honeypot_field_name:
self.fields[honeypot_field_name] = forms.CharField(
required=False,
label="",
widget=forms.TextInput(
attrs={
"style": "position: absolute; right: -99999px;",
"tabindex": "-1",
"autocomplete": "nope",
}
),
)
def try_save(self, request):
"""
override of parent class method that adds additional catching
of a potential bot filling out the honeypot field and returns a
'fake' email verification response if honeypot was filled out
"""
honeypot_field_name = app_settings.SIGNUP_FORM_HONEYPOT_FIELD
if honeypot_field_name:
if self.cleaned_data[honeypot_field_name]:
user = None
adapter = get_adapter()
# honeypot fields work best when you do not report to the bot
# that anything went wrong. So we return a fake email verification
# sent response but without creating a user
resp = adapter.respond_email_verification_sent(request, None)
return user, resp
return super().try_save(request)
def clean(self) -> dict:
super().clean()
# `password` cannot be of type `SetPasswordField`, as we don't
# have a `User` yet. So, let's populate a dummy user to be used
# for password validation.
User = get_user_model()
dummy_user = User()
user_username(dummy_user, self.cleaned_data.get("username"))
user_email(dummy_user, self.cleaned_data.get("email"))
password = self.cleaned_data.get("password1")
if password:
try:
get_adapter().clean_password(password, user=dummy_user)
except forms.ValidationError as e:
self.add_error("password1", e)
if (
"password2" in self._signup_fields
and "password1" in self.cleaned_data
and "password2" in self.cleaned_data
):
if self.cleaned_data["password1"] != self.cleaned_data["password2"]:
self.add_error(
"password2",
_("You must type the same password each time."),
)
return self.cleaned_data
class UserForm(forms.Form):
def __init__(self, user=None, *args, **kwargs) -> None:
self.user = user
super().__init__(*args, **kwargs)
class AddEmailForm(UserForm):
email = EmailField(required=True)
def clean_email(self) -> str:
from allauth.account import signals
value = self.cleaned_data["email"].lower()
adapter = get_adapter()
value = adapter.clean_email(value)
users = filter_users_by_email(value)
on_this_account = [u for u in users if u.pk == self.user.pk]
on_diff_account = [u for u in users if u.pk != self.user.pk]
if on_this_account:
raise adapter.validation_error("duplicate_email")
if (
# Email is taken by a different account...
on_diff_account
# We care about not having duplicate emails
and app_settings.UNIQUE_EMAIL
# Enumeration prevention is turned off.
and (not app_settings.PREVENT_ENUMERATION)
):
raise adapter.validation_error("email_taken")
if not EmailAddress.objects.can_add_email(self.user):
raise adapter.validation_error(
"max_email_addresses", app_settings.MAX_EMAIL_ADDRESSES
)
signals._add_email.send(
sender=self.user.__class__,
email=value,
user=self.user,
)
return value
def save(self, request):
if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
email_address = EmailAddress(
user=self.user, email=self.cleaned_data["email"]
)
flows.email_verification.send_verification_email_to_address(
request, email_address
)
return email_address
elif app_settings.CHANGE_EMAIL:
return EmailAddress.objects.add_new_email(
request, self.user, self.cleaned_data["email"]
)
return EmailAddress.objects.add_email(
request, self.user, self.cleaned_data["email"], confirm=True
)
class ChangePasswordForm(PasswordVerificationMixin, UserForm):
oldpassword = PasswordField(
label=_("Current Password"), autocomplete="current-password"
)
password1 = SetPasswordField(label=_("New Password"))
password2 = PasswordField(label=_("New Password (again)"))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["password1"].user = self.user
def clean_oldpassword(self) -> str:
if not self.user.check_password(self.cleaned_data.get("oldpassword")):
raise get_adapter().validation_error("enter_current_password")
return self.cleaned_data["oldpassword"]
def save(self) -> None:
flows.password_change.change_password(self.user, self.cleaned_data["password1"])
class SetPasswordForm(PasswordVerificationMixin, UserForm):
password1 = SetPasswordField(label=_("Password"))
password2 = PasswordField(label=_("Password (again)"))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["password1"].user = self.user
def save(self) -> None:
flows.password_change.change_password(self.user, self.cleaned_data["password1"])
class ResetPasswordForm(forms.Form):
email = EmailField(required=True)
def clean_email(self) -> str:
email = self.cleaned_data["email"].lower()
email = get_adapter().clean_email(email)
self.users = filter_users_by_email(email, is_active=True, prefer_verified=True)
if not self.users and not app_settings.PREVENT_ENUMERATION:
raise get_adapter().validation_error("unknown_email")
return self.cleaned_data["email"]
def save(self, request, **kwargs) -> str:
email = self.cleaned_data["email"]
if app_settings.PASSWORD_RESET_BY_CODE_ENABLED:
flows.password_reset_by_code.PasswordResetVerificationProcess.initiate(
request=request,
user=(self.users[0] if self.users else None),
email=email,
)
else:
token_generator = kwargs.get("token_generator", default_token_generator)
flows.password_reset.request_password_reset(
request, email, self.users, token_generator
)
return email
class ResetPasswordKeyForm(PasswordVerificationMixin, forms.Form):
password1 = SetPasswordField(label=_("New Password"))
password2 = PasswordField(label=_("New Password (again)"))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
self.temp_key = kwargs.pop("temp_key", None)
super().__init__(*args, **kwargs)
self.fields["password1"].user = self.user
def save(self) -> None:
flows.password_reset.reset_password(self.user, self.cleaned_data["password1"])
class UserTokenForm(forms.Form):
uidb36 = forms.CharField()
key = forms.CharField()
reset_user = None
token_generator = default_token_generator
def _get_user(self, uidb36):
User = get_user_model()
try:
pk = url_str_to_user_pk(uidb36)
return User.objects.get(pk=pk)
except (ValueError, User.DoesNotExist):
return None
def clean(self):
cleaned_data = super().clean()
uidb36 = cleaned_data.get("uidb36", None)
key = cleaned_data.get("key", None)
adapter = get_adapter()
if not key:
raise adapter.validation_error("invalid_password_reset")
self.reset_user = self._get_user(uidb36)
if self.reset_user is None or not self.token_generator.check_token(
self.reset_user, key
):
raise adapter.validation_error("invalid_password_reset")
return cleaned_data
class ReauthenticateForm(forms.Form):
password = PasswordField(label=_("Password"), autocomplete="current-password")
def __init__(self, *args, **kwargs) -> None:
self.user = kwargs.pop("user")
super().__init__(*args, **kwargs)
def clean_password(self) -> str:
password = self.cleaned_data["password"]
if not get_adapter().reauthenticate(self.user, password):
raise get_adapter().validation_error("incorrect_password")
return password
class RequestLoginCodeForm(forms.Form):
email = EmailField()
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._has_email = LoginMethod.EMAIL in app_settings.LOGIN_METHODS
self._has_phone = LoginMethod.PHONE in app_settings.LOGIN_METHODS
if self._has_phone:
adapter = get_adapter()
self.fields["phone"] = adapter.phone_form_field(
required=not self._has_email
)
self.fields["email"].required = False
# Inconsistent, but kept for backwards compatibility: even if email is not a login
# method the email field is added. May be used when login is by username.
if self._has_phone and not self._has_email:
self.fields.pop("email")
def clean(self):
cleaned_data = super().clean()
adapter = get_adapter()
phone = cleaned_data.get("phone")
email = cleaned_data.get("email")
if email and phone:
raise adapter.validation_error("select_only_one")
return cleaned_data
def clean_phone(self) -> str:
adapter = get_adapter()
phone = self.cleaned_data["phone"]
if phone:
self._user = adapter.get_user_by_phone(phone)
if not self._user and not app_settings.PREVENT_ENUMERATION:
raise adapter.validation_error("unknown_phone")
if not ratelimit.consume(
context.request, action="request_login_code", key=phone.lower()
):
raise adapter.validation_error("too_many_login_attempts")
return phone
def clean_email(self) -> str:
adapter = get_adapter()
email = self.cleaned_data["email"]
if email:
users = filter_users_by_email(email, is_active=True, prefer_verified=True)
if not app_settings.PREVENT_ENUMERATION:
if not users:
raise adapter.validation_error("unknown_email")
if not ratelimit.consume(
context.request, action="request_login_code", key=email.lower()
):
raise adapter.validation_error("too_many_login_attempts")
self._user = users[0] if users else None
return email
class BaseConfirmCodeForm(forms.Form):
code = forms.CharField(
label=_("Code"),
widget=forms.TextInput(
attrs={"placeholder": _("Code"), "autocomplete": "one-time-code"},
),
)
def __init__(self, *args, **kwargs) -> None:
self.expected_code = kwargs.pop("code", None)
super().__init__(*args, **kwargs)
def clean_code(self) -> str:
code = self.cleaned_data["code"]
if not compare_user_code(actual=code, expected=self.expected_code):
raise get_adapter().validation_error("incorrect_code")
return code
class ConfirmLoginCodeForm(BaseConfirmCodeForm):
pass
class ConfirmEmailVerificationCodeForm(BaseConfirmCodeForm):
def __init__(self, *args, **kwargs) -> None:
self.user = kwargs.pop("user", None)
self.email = kwargs.pop("email", None)
super().__init__(*args, **kwargs)
def clean_code(self) -> str:
code = super().clean_code()
if code:
# We have a valid code. But, can we actually perform the change?
email_already_exists(user=self.user, email=self.email, always_raise=True)
return code
class ConfirmPasswordResetCodeForm(BaseConfirmCodeForm):
pass
class VerifyPhoneForm(BaseConfirmCodeForm):
def __init__(self, *args, **kwargs) -> None:
self.user = kwargs.pop("user", None)
self.phone = kwargs.pop("phone", None)
super().__init__(*args, **kwargs)
def clean_code(self) -> str:
code = super().clean_code()
if code:
# We have a valid code. But, can we actually perform the change?
phone_already_exists(self.user, self.phone, always_raise=True)
return code
class ChangePhoneForm(forms.Form):
def __init__(self, *args, **kwargs) -> None:
self.user = kwargs.pop("user", None)
self.phone = kwargs.pop("phone", None)
super().__init__(*args, **kwargs)
adapter = get_adapter()
self.fields["phone"] = adapter.phone_form_field(required=True)
def clean_phone(self) -> str:
phone = self.cleaned_data["phone"]
adapter = get_adapter()
if phone == self.phone:
raise adapter.validation_error("same_as_current")
self.account_already_exists = phone_already_exists(self.user, phone)
return phone
class ChangeEmailForm(forms.Form):
email = EmailField(required=True)
def __init__(self, *args, **kwargs) -> None:
self.email = kwargs.pop("email", None)
super().__init__(*args, **kwargs)
def clean_email(self) -> str:
email = self.cleaned_data["email"]
if email == self.email:
raise get_adapter().validation_error("same_as_current")
email, self.account_already_exists = email_already_exists(email)
return email
================================================
FILE: allauth/account/internal/__init__.py
================================================
from allauth.account.internal import flows
__all__ = ["flows"]
================================================
FILE: allauth/account/internal/constants.py
================================================
from enum import Enum
class LoginStageKey(str, Enum):
LOGIN_BY_CODE = "login_by_code"
VERIFY_EMAIL = "verify_email"
VERIFY_PHONE = "verify_phone"
================================================
FILE: allauth/account/internal/decorators.py
================================================
from functools import wraps
from django.contrib.auth import decorators
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views.decorators.cache import never_cache
from allauth.account.stages import LoginStageController
from allauth.account.utils import get_login_redirect_url
def _dummy_login_not_required(view_func):
return view_func
login_not_required = getattr(
decorators, "login_not_required", _dummy_login_not_required
)
def login_stage_required(stage: str, redirect_urlname: str):
def decorator(view_func):
@never_cache
@login_not_required
@wraps(view_func)
def _wrapper_view(request, *args, **kwargs):
if request.user.is_authenticated:
return HttpResponseRedirect(get_login_redirect_url(request))
login_stage = LoginStageController.enter(request, stage)
if not login_stage:
return HttpResponseRedirect(reverse(redirect_urlname))
request._login_stage = login_stage
return view_func(request, *args, **kwargs)
return _wrapper_view
return decorator
================================================
FILE: allauth/account/internal/emailkit.py
================================================
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.db.models.fields import EmailField
from allauth.account.adapter import get_adapter
def valid_email_or_none(email: str | None) -> str | None:
ret: str | None = None
try:
if email:
validate_email(email)
max_length = EmailField().max_length
if max_length is None or len(email) <= max_length:
ret = get_adapter().clean_email(email.lower())
except ValidationError:
pass
return ret
================================================
FILE: allauth/account/internal/flows/__init__.py
================================================
from allauth.account.internal.flows import (
email_verification,
email_verification_by_code,
login,
login_by_code,
logout,
manage_email,
password_change,
password_reset,
password_reset_by_code,
phone_verification,
reauthentication,
signup,
)
__all__ = [
"email_verification",
"email_verification_by_code",
"login",
"login_by_code",
"logout",
"manage_email",
"password_change",
"password_reset",
"password_reset_by_code",
"phone_verification",
"reauthentication",
"signup",
]
================================================
FILE: allauth/account/internal/flows/code_verification.py
================================================
import abc
import time
from typing import Any
from django.contrib.auth import get_user_model
from allauth.account.internal.userkit import str_to_user_id, user_id_to_str
class AbstractCodeVerificationProcess(abc.ABC):
def __init__(
self,
max_attempts: int,
timeout: int,
state: dict,
user=None,
) -> None:
self._user = user
self.max_attempts = max_attempts
self.timeout = timeout
self.state = state
@property
def user(self):
if self._user:
return self._user
user_id = self.state.get("user_id")
if not user_id:
return None
user_id = str_to_user_id(user_id)
self._user = get_user_model().objects.filter(pk=user_id).first()
return self._user
@property
def code(self):
return self.state.get("code", "")
@classmethod
def initial_state(cls, user, email: str | None = None, phone: str | None = None):
state: dict[str, Any] = {
"at": time.time(),
"failed_attempts": 0,
"resend_count": 0,
"change_count": 0,
}
if email:
state["email"] = email
if phone:
state["phone"] = phone
if user:
state["user_id"] = user_id_to_str(user)
return state
def record_invalid_attempt(self) -> bool:
self.state["failed_attempts"] += 1
if self.state["failed_attempts"] >= self.max_attempts:
self.abort()
return False
self.persist()
return True
def abort_if_invalid(self):
if not self.is_valid():
self.abort()
return None
return self
def is_valid(self) -> bool:
return time.time() - self.state["at"] <= self.timeout
@abc.abstractmethod
def persist(self): ... # noqa: E704
@abc.abstractmethod
def send(self): ... # noqa: E704
@abc.abstractmethod
def abort(self): ... # noqa: E704
def is_resend_quota_reached(self, quota: int) -> bool:
return self.state["resend_count"] >= quota
def is_change_quota_reached(self, quota: int) -> bool:
return self.state["change_count"] >= quota
def record_change(
self, *, email: str | None = None, phone: str | None = None
) -> None:
self.state["change_count"] += 1
if email:
self.state["email"] = email
if phone:
self.state["phone"] = phone
def record_resend(self):
self.state["resend_count"] += 1
@property
def can_resend(self) -> bool:
return False
@property
def can_change(self) -> bool:
return False
================================================
FILE: allauth/account/internal/flows/email_verification.py
================================================
from django.contrib import messages
from django.contrib.auth.base_user import AbstractBaseUser
from django.http import HttpRequest, HttpResponse
from django.urls import reverse
from allauth.account import app_settings, signals
from allauth.account.adapter import get_adapter
from allauth.account.internal.flows.manage_email import (
emit_email_changed,
sync_email_address,
sync_user_email_address,
)
from allauth.account.internal.flows.signup import send_unknown_account_mail
from allauth.account.models import EmailAddress, Login
from allauth.core.exceptions import ImmediateHttpResponse
from allauth.core.internal import ratelimit
from allauth.core.internal.httpkit import get_frontend_url
from allauth.core.ratelimit import respond_429
from allauth.utils import build_absolute_uri
def verify_email_indirectly(
request: HttpRequest, user: AbstractBaseUser, email: str
) -> bool:
try:
email_address = EmailAddress.objects.get_for_user(user, email)
except EmailAddress.DoesNotExist:
return False
else:
if not email_address.verified:
return verify_email(request, email_address)
return True
def verify_email_and_resume(
request: HttpRequest, verification
) -> tuple[EmailAddress | None, HttpResponse | None]:
email_address = verification.confirm(request)
if not email_address:
return None, None
response = login_on_verification(request, email_address)
return email_address, response
def verify_email(request: HttpRequest, email_address: EmailAddress) -> bool:
"""
Marks the email address as confirmed on the db
"""
added = not email_address.pk
from_email_address = (
EmailAddress.objects.filter(user_id=email_address.user_id)
.exclude(pk=email_address.pk)
.first()
)
if not email_address.set_verified(commit=False):
get_adapter(request).add_message(
request,
messages.ERROR,
"account/messages/email_confirmation_failed.txt",
{"email": email_address.email},
)
return False
email_address.set_as_primary(conditional=(not app_settings.CHANGE_EMAIL))
email_address.save()
if added:
signals.email_added.send(
sender=EmailAddress,
request=request,
user=request.user,
email_address=email_address,
)
signals.email_confirmed.send(
sender=EmailAddress,
request=request,
email_address=email_address,
)
if app_settings.CHANGE_EMAIL:
for instance in EmailAddress.objects.filter(
user_id=email_address.user_id
).exclude(pk=email_address.pk):
instance.remove()
emit_email_changed(request, from_email_address, email_address)
get_adapter(request).add_message(
request,
messages.SUCCESS,
"account/messages/email_confirmed.txt",
{"email": email_address.email},
)
return True
def get_email_verification_url(request: HttpRequest, emailconfirmation) -> str:
"""Constructs the email confirmation (activation) url.
Note that if you have architected your system such that email
confirmations are sent outside of the request context `request`
can be `None` here.
"""
url = get_frontend_url(request, "account_confirm_email", key=emailconfirmation.key)
if not url:
url = reverse("account_confirm_email", args=[emailconfirmation.key])
url = build_absolute_uri(request, url)
return url
def login_on_verification(request, email_address) -> HttpResponse | None:
"""Simply logging in the user may become a security issue. If you
do not take proper care (e.g. don't purge used email
confirmations), a malicious person that got hold of the link
will be able to login over and over again and the user is
unable to do anything about it. Even restoring their own mailbox
security will not help, as the links will still work. For
password reset this is different, this mechanism works only as
long as the attacker has access to the mailbox. If they no
longer has access they cannot issue a password request and
intercept it. Furthermore, all places where the links are
listed (log files, but even Google Analytics) all of a sudden
need to be secured. Purging the email confirmation once
confirmed changes the behavior -- users will not be able to
repeatedly confirm (in case they forgot that they already
clicked the mail).
All in all, we only login on verification when the user that is in the
process of signing up is present in the session to avoid all of the above.
This may not 100% work in case the user closes the browser (and the session
gets lost), but at least we're secure.
"""
from allauth.account.stages import EmailVerificationStage, LoginStageController
stage = LoginStageController.enter(request, EmailVerificationStage.key)
if (
(
# Logging in on email verification is disabled...
not app_settings.LOGIN_ON_EMAIL_CONFIRMATION
# (but, that is only relevant for verification-by-link)
and not app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED
)
or (request.user.is_authenticated)
or (not stage or not stage.login.user)
or (stage.login.user.pk != email_address.user_id)
):
if stage:
stage.abort()
return None
return stage.exit()
def consume_email_verification_rate_limit(
request: HttpRequest,
email: str,
dry_run: bool = False,
raise_exception: bool = False,
) -> bool:
return bool(
ratelimit.consume(
request,
config=app_settings.RATE_LIMITS,
action="confirm_email",
key=email.lower(),
dry_run=dry_run,
raise_exception=raise_exception,
limit_get=True,
)
)
def handle_verification_email_rate_limit(
request, email: str, raise_exception: bool = False
) -> bool:
"""
For email verification by link, it is not an issue if the user runs into rate
limits. The reason is that the link is session independent. Therefore, if the
user hits rate limits, we can just silently skip sending additional
verification emails, as the previous emails that were already sent still
contain valid links. This is different from email verification by code. Here,
the session contains a specific code, meaning, silently skipping new
verification emails is not an option, and we must hard fail (429) instead. The
latter was missing, fixed.
"""
rl_ok = consume_email_verification_rate_limit(
request, email, raise_exception=raise_exception
)
if not rl_ok and app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
raise ImmediateHttpResponse(respond_429(request))
return rl_ok
def get_address_for_user(user: AbstractBaseUser) -> EmailAddress | None:
address = (
EmailAddress.objects.filter(user_id=user.pk)
.order_by("-primary", "-verified")
.first()
)
if not address:
address = sync_user_email_address(user)
return address
def get_address_for_login(login: Login):
assert login.user # nosec
if login.email:
try:
return EmailAddress.objects.get_for_user(login.user, login.email)
except EmailAddress.DoesNotExist:
# We do have an email, it's not stored as an EmailAddress. Might be the
# case that a user was setup in the admin. So, let's sync
# EmailAddress'es on the fly here.
return sync_email_address(login.user, login.email)
else:
return get_address_for_user(login.user)
def send_verification_email_for_user(
request: HttpRequest, user: AbstractBaseUser
) -> bool:
"""
Used in the email-required-decorator.
"""
address = get_address_for_user(user)
if not address:
return False
return send_verification_email_to_address(request, address)
def send_verification_email_to_address(
request: HttpRequest,
address: EmailAddress,
signup: bool = False,
process=None,
skip_enumeration_mails: bool = False,
) -> bool:
"""
Resend email verification for an existing email address.
"""
if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
if not process:
from allauth.account.internal.flows.email_verification_by_code import (
EmailVerificationProcess,
)
process = EmailVerificationProcess.initiate(
request=request,
user=address.user if address.user_id else None,
email=address.email,
)
return process.did_send
send = handle_verification_email_rate_limit(
request,
address.email,
)
if not send:
return False
if not address.user_id:
if skip_enumeration_mails:
pass
elif signup:
get_adapter().send_account_already_exists_mail(address.email)
else:
send_unknown_account_mail(request, address.email)
confirmation = None
elif app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
get_adapter().send_confirmation_mail(request, process, signup=signup)
confirmation = process
else:
confirmation = address.send_confirmation(request, signup=signup)
add_email_verification_sent_message(request, address.email, signup=signup)
if confirmation:
signals.email_confirmation_sent.send(
sender=confirmation.__class__,
request=request,
confirmation=confirmation,
signup=signup,
)
return True
def send_verification_email_at_login(request: HttpRequest, login: Login) -> bool:
"""
At this point, it has already been confirmed that email verification
is needed.
Email verification mails are sent:
a) Explicitly: when a user signs up
b) Implicitly: when a user attempts to log in using an unverified
email while EMAIL_VERIFICATION is mandatory.
"""
if not login.user:
sent = send_verification_email_at_fake_login(request, login)
else:
sent = send_verification_email_at_real_login(request, login)
return sent
def send_verification_email_at_real_login(request: HttpRequest, login: Login) -> bool:
assert login.user # nosec
address = get_address_for_login(login)
if not address:
return False
if address.verified:
return False
send = get_adapter().should_send_confirmation_mail(request, address, login.signup)
if not send:
return False
return send_verification_email_to_address(request, address, signup=login.signup)
def send_verification_email_at_fake_login(request: HttpRequest, login: Login) -> bool:
"""
Enumeration prevention.
"""
assert not login.user # nosec
if not login.email:
# Odd, no user & no email implies email enumeration prevention is
# active, at signup, which implies we should have an email here?
return False
address = EmailAddress(user=None, email=login.email)
return send_verification_email_to_address(request, address, signup=True)
def add_email_verification_sent_message(request: HttpRequest, email: str, signup: bool):
get_adapter().add_message(
request,
messages.INFO,
"account/messages/email_confirmation_sent.txt",
{"email": email, "login": not signup, "signup": signup},
)
def is_verification_rate_limited(request: HttpRequest, login: Login) -> bool:
"""
Returns whether or not the email verification is *hard* rate limited.
Hard, meaning, it would be blocking login (verification by code, not link).
"""
if (
(not login.email)
or (not app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED)
or login.email_verification != app_settings.EmailVerificationMethod.MANDATORY
):
return False
try:
email_address = EmailAddress.objects.get_for_user(login.user, login.email)
if not email_address.verified:
if not consume_email_verification_rate_limit(
request, login.email, dry_run=True
):
return True
except EmailAddress.DoesNotExist:
pass
return False
def mark_email_address_as_verified(
request: HttpRequest, address: EmailAddress
) -> EmailAddress | None:
if not address.verified:
confirmed = get_adapter().confirm_email(request, address)
if confirmed:
return address
return None
================================================
FILE: allauth/account/internal/flows/email_verification_by_code.py
================================================
from typing import Optional
from django.utils.functional import cached_property
from allauth.account import app_settings
from allauth.account.adapter import get_adapter
from allauth.account.internal.flows.code_verification import (
AbstractCodeVerificationProcess,
)
from allauth.account.internal.stagekit import clear_login
from allauth.account.internal.userkit import did_user_login, user_email
from allauth.account.models import EmailAddress
from allauth.core import context
EMAIL_VERIFICATION_CODE_SESSION_KEY = "account_email_verification_code"
class EmailVerificationProcess(AbstractCodeVerificationProcess):
def __init__(self, request, state: dict, user=None) -> None:
self.request = request
super().__init__(
state=state,
user=user,
max_attempts=app_settings.EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS,
timeout=app_settings.EMAIL_VERIFICATION_BY_CODE_TIMEOUT,
)
@property
def email(self) -> str:
return self.state["email"]
def persist(self) -> None:
self.request.session[EMAIL_VERIFICATION_CODE_SESSION_KEY] = self.state
def abort(self) -> None:
self.request.session.pop(EMAIL_VERIFICATION_CODE_SESSION_KEY, None)
clear_login(self.request)
def send(self, skip_enumeration_mails: bool = False) -> None:
from allauth.account.internal.flows.email_verification import (
send_verification_email_to_address,
)
email_address = self.email_address
signup = (
(not did_user_login(email_address.user)) if email_address.user_id else True
)
self.did_send = send_verification_email_to_address(
self.request,
email_address,
signup=signup,
process=self,
skip_enumeration_mails=skip_enumeration_mails,
)
@cached_property
def email_address(self) -> EmailAddress:
email = self.state["email"]
if not self.user or self.state.get("account_already_exists"):
return EmailAddress(email=email)
try:
email_address = EmailAddress.objects.get_for_user(self.user, email)
except EmailAddress.DoesNotExist:
email_address = EmailAddress(user=self.user, email=email)
return email_address
def finish(self) -> EmailAddress | None:
from allauth.account.internal.flows.email_verification import (
mark_email_address_as_verified,
)
if not self.user or self.state.get("account_already_exists"):
raise ValueError
self.request.session.pop(EMAIL_VERIFICATION_CODE_SESSION_KEY, None)
return mark_email_address_as_verified(self.request, self.email_address)
def generate_code(self) -> None:
self.state["code"] = get_adapter().generate_email_verification_code()
@classmethod
def initiate(cls, *, request, user, email: str) -> "EmailVerificationProcess":
state = cls.initial_state(user, email)
process = EmailVerificationProcess(request=request, user=user, state=state)
process.generate_code()
process.send()
process.persist()
return process
@classmethod
def resume(cls, request) -> Optional["EmailVerificationProcess"]:
if not app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED:
return None
state = request.session.get(EMAIL_VERIFICATION_CODE_SESSION_KEY)
if not state:
return None
process = EmailVerificationProcess(request=request, state=state)
return process.abort_if_invalid()
@property
def can_change(self) -> bool:
# TODO: Prevent enumeration flaw: if we don't have a user, we cannot
# change the email. To fix this, we would need to serialize
# the user and perform an on-the-fly signup here.
return (
not self.is_change_quota_reached(
app_settings.EMAIL_VERIFICATION_MAX_CHANGE_COUNT
)
and bool(self.user)
and not did_user_login(self.user)
)
def change_to(self, email: str, account_already_exists: bool) -> None:
self.state["account_already_exists"] = account_already_exists
self.generate_code()
if account_already_exists:
pass
else:
EmailAddress.objects.add_new_email(
context.request, self.user, email, send_verification=False
)
user_email(self.user, email, commit=True)
self.record_change(email=email)
self.send()
self.persist()
@property
def can_resend(self) -> bool:
return not self.is_resend_quota_reached(
app_settings.EMAIL_VERIFICATION_MAX_RESEND_COUNT
)
def resend(self) -> None:
self.generate_code()
self.send(skip_enumeration_mails=True)
self.record_resend()
self.persist()
@property
def key(self):
return self.code
================================================
FILE: allauth/account/internal/flows/login.py
================================================
import time
from typing import Any
from django.core import exceptions, validators
from django.http import HttpRequest, HttpResponse
from allauth import app_settings as allauth_settings
from allauth.account import app_settings
from allauth.account.adapter import get_adapter
from allauth.account.app_settings import LoginMethod
from allauth.account.models import Login
from allauth.account.signals import authentication_step_completed
from allauth.core.exceptions import ImmediateHttpResponse
AUTHENTICATION_METHODS_SESSION_KEY = "account_authentication_methods"
def record_authentication(request, user, method: str, **extra_data) -> None:
"""Here we keep a log of all authentication methods used within the current
session. Important to note is that having entries here does not imply that
a user is fully signed in. For example, consider a case where a user
authenticates using a password, but fails to complete the 2FA challenge.
Or, a user successfully signs in into an inactive account or one that still
needs verification. In such cases, ``request.user`` is still anonymous, yet,
we do have an entry here.
Example data::
{'method': 'password',
'at': 1701423602.7184925,
'username': 'john.doe'}
{'method': 'socialaccount',
'at': 1701423567.6368647,
'provider': 'amazon',
'uid': 'amzn1.account.K2LI23KL2LK2'}
{'method': 'mfa',
'at': 1701423602.6392953,
'id': 1,
'type': 'totp'}
"""
methods = request.session.get(AUTHENTICATION_METHODS_SESSION_KEY, [])
data = {
"method": method,
"at": time.time(),
}
for k, v in extra_data.items():
if v is not None:
data[k] = v
methods.append(data)
request.session[AUTHENTICATION_METHODS_SESSION_KEY] = methods
authentication_step_completed.send(
sender=user.__class__, request=request, method=method, user=user, **extra_data
)
def _get_login_hook_kwargs(login: Login) -> dict[str, Any]:
"""
TODO: Just break backwards compatibility and pass only `login` to
`pre/post_login()`.
"""
return dict(
email_verification=login.email_verification,
redirect_url=login.redirect_url,
signal_kwargs=login.signal_kwargs,
signup=login.signup,
email=login.email,
)
def perform_password_login(
request: HttpRequest, credentials: dict[str, Any], login: Login
) -> HttpResponse:
extra_data = {
field: credentials.get(field)
for field in ["email", "username"]
if credentials.get(field)
}
record_authentication(request, login.user, method="password", **extra_data)
return perform_login(request, login)
def perform_login(request: HttpRequest, login: Login) -> HttpResponse:
adapter = get_adapter()
hook_kwargs = _get_login_hook_kwargs(login)
if login.user:
response = adapter.pre_login(request, login.user, **hook_kwargs)
if response:
return response
return resume_login(request, login)
def resume_login(request: HttpRequest, login: Login) -> HttpResponse:
from allauth.account.stages import LoginStageController
adapter = get_adapter()
ctrl = LoginStageController(request, login)
try:
response = ctrl.handle()
if response:
return response
adapter.login(request, login.user)
hook_kwargs = _get_login_hook_kwargs(login)
response = adapter.post_login(request, login.user, **hook_kwargs)
if response:
return response
except ImmediateHttpResponse as e:
if allauth_settings.HEADLESS_ENABLED:
from allauth.headless.internal.restkit.response import APIResponse
if isinstance(e.response, APIResponse):
raise e
response = e.response
return response
def is_login_rate_limited(request, login: Login) -> bool:
from allauth.account.internal.flows.email_verification import (
is_verification_rate_limited,
)
if is_verification_rate_limited(request, login):
return True
return False
def derive_login_method(login: str) -> LoginMethod:
if len(app_settings.LOGIN_METHODS) == 1:
return next(iter(app_settings.LOGIN_METHODS))
if LoginMethod.EMAIL in app_settings.LOGIN_METHODS:
try:
validators.validate_email(login)
return LoginMethod.EMAIL
except exceptions.ValidationError:
pass
if LoginMethod.PHONE in app_settings.LOGIN_METHODS:
try:
get_adapter().phone_form_field(required=True).clean(login)
return LoginMethod.PHONE
except exceptions.ValidationError:
pass
return LoginMethod.USERNAME
================================================
FILE: allauth/account/internal/flows/login_by_code.py
================================================
from django.contrib import messages
from allauth.account import app_settings
from allauth.account.adapter import get_adapter
from allauth.account.internal.flows.code_verification import (
AbstractCodeVerificationProcess,
)
from allauth.account.internal.flows.email_verification import verify_email_indirectly
from allauth.account.internal.flows.login import perform_login, record_authentication
from allauth.account.internal.flows.phone_verification import verify_phone_indirectly
from allauth.account.internal.flows.signup import send_unknown_account_mail
from allauth.account.internal.stagekit import clear_login, stash_login
from allauth.account.models import Login
from allauth.account.stages import LoginByCodeStage, LoginStageController
LOGIN_CODE_STATE_KEY = "login_code"
class LoginCodeVerificationProcess(AbstractCodeVerificationProcess):
def __init__(self, stage):
self.stage = stage
self.request = stage.request
super().__init__(
state=stage.state,
timeout=app_settings.LOGIN_BY_CODE_TIMEOUT,
max_attempts=app_settings.LOGIN_BY_CODE_MAX_ATTEMPTS,
user=stage.login.user,
)
def finish(self, redirect_url: str | None):
email = self.state.get("email")
phone = self.state.get("phone")
user = self.user
record_authentication(
self.request, user, method="code", email=email, phone=phone
)
if email:
verify_email_indirectly(self.request, user, email)
if phone:
verify_phone_indirectly(self.request, user, phone)
if self.state["initiated_by_user"]:
# Just requesting a login code does is not considered to be a real login,
# yet, is needed in order to make the stage machinery work. Now that we've
# completed the code, let's start a real login.
login = Login(
user=user,
redirect_url=redirect_url,
email=email,
)
return perform_login(self.request, login)
else:
return self.stage.exit()
def abort(self) -> None:
clear_login(self.request)
def persist(self) -> None:
stash_login(self.request, self.stage.login)
def send(self, skip_enumeration_mails: bool = False) -> None:
email = self.state.get("email")
phone = self.state.get("phone")
if email:
self.send_by_email(email, skip_enumeration_mails=skip_enumeration_mails)
elif phone:
self.send_by_phone(phone, skip_enumeration_mails=skip_enumeration_mails)
else:
raise ValueError()
def generate_code(self) -> str:
email = self.state.get("email")
phone = self.state.get("phone")
adapter = get_adapter()
if email:
code = adapter.generate_login_code()
elif phone:
code = adapter._generate_phone_verification_code_compat(
user=self.user, phone=phone
)
else:
raise ValueError()
self.state["code"] = code
return code
def send_by_phone(self, phone: str, skip_enumeration_mails: bool = False) -> None:
adapter = get_adapter()
if self.user:
code = self.generate_code()
adapter.send_verification_code_sms(user=self.user, phone=phone, code=code)
elif not skip_enumeration_mails:
if self.stage.login.signup:
adapter.send_account_already_exists_sms(phone)
else:
adapter.send_unknown_account_sms(phone)
self.add_sent_message({"recipient": phone, "phone": phone})
def send_by_email(self, email: str, skip_enumeration_mails: bool = False) -> None:
adapter = get_adapter()
if self.user:
code = self.generate_code()
context = {
"request": self.request,
"code": code,
}
adapter.send_mail("account/email/login_code", email, context)
elif not skip_enumeration_mails:
if self.stage.login.signup:
adapter.send_account_already_exists_mail(email)
else:
send_unknown_account_mail(self.request, email)
self.add_sent_message({"email": email, "recipient": email})
def add_sent_message(self, context) -> None:
get_adapter().add_message(
self.request,
messages.SUCCESS,
"account/messages/login_code_sent.txt",
context,
)
@classmethod
def initiate(
cls,
*,
request,
user,
email: str | None = None,
phone: str | None = None,
stage=None,
):
initial_state = cls.initial_state(user=user, email=email, phone=phone)
initial_state["initiated_by_user"] = stage is None
if not stage:
login = Login(user=user, email=email)
login.state["stages"] = {"current": "login_by_code"}
stage = LoginByCodeStage(
LoginStageController(request, login), request, login
)
stage.state.update(initial_state)
process = LoginCodeVerificationProcess(stage=stage)
process.send()
process.persist()
return process
@classmethod
def resume(cls, stage):
process = LoginCodeVerificationProcess(stage=stage)
return process.abort_if_invalid()
@property
def can_resend(self) -> bool:
return not self.is_resend_quota_reached(
app_settings.LOGIN_BY_CODE_MAX_RESEND_COUNT
)
def resend(self) -> None:
self.generate_code()
self.send(skip_enumeration_mails=True)
self.record_resend()
self.persist()
================================================
FILE: allauth/account/internal/flows/logout.py
================================================
from django.contrib import messages
from django.http import HttpRequest
from allauth.account.internal.flows.password_reset_by_code import (
PASSWORD_RESET_VERIFICATION_SESSION_KEY,
)
from allauth.account.internal.stagekit import clear_login
def logout(request: HttpRequest, *, show_message: bool = True) -> None:
from allauth.account.adapter import get_adapter
from allauth.account.views import INTERNAL_RESET_SESSION_KEY
if request.user.is_authenticated:
adapter = get_adapter()
if show_message:
adapter.add_message(
request, messages.SUCCESS, "account/messages/logged_out.txt"
)
adapter.logout(request)
clear_login(request)
request.session.pop(PASSWORD_RESET_VERIFICATION_SESSION_KEY, None)
request.session.pop(INTERNAL_RESET_SESSION_KEY, None)
================================================
FILE: allauth/account/internal/flows/manage_email.py
================================================
from django.contrib import messages
from django.contrib.auth.base_user import AbstractBaseUser
from django.http import HttpRequest
from allauth.account import app_settings, signals
from allauth.account.adapter import get_adapter
from allauth.account.internal.flows.reauthentication import (
raise_if_reauthentication_required,
)
from allauth.account.internal.userkit import user_email
from allauth.account.models import EmailAddress
def can_delete_email(email_address: EmailAddress) -> bool:
adapter = get_adapter()
return adapter.can_delete_email(email_address)
def delete_email(request: HttpRequest, email_address: EmailAddress) -> bool:
if app_settings.REAUTHENTICATION_REQUIRED:
raise_if_reauthentication_required(request)
success = False
adapter = get_adapter()
if not can_delete_email(email_address):
adapter.add_message(
request,
messages.ERROR,
"account/messages/cannot_delete_primary_email.txt",
{"email": email_address.email},
)
else:
email_address.remove()
signals.email_removed.send(
sender=EmailAddress,
request=request,
user=request.user,
email_address=email_address,
)
adapter.add_message(
request,
messages.SUCCESS,
"account/messages/email_deleted.txt",
{"email": email_address.email},
)
adapter.send_notification_mail(
"account/email/email_deleted",
request.user,
{"deleted_email": email_address.email},
)
success = True
return success
def add_email(request: HttpRequest, form) -> None:
if app_settings.REAUTHENTICATION_REQUIRED:
raise_if_reauthentication_required(request)
email_address = form.save(request)
if email_address.pk:
signals.email_added.send(
sender=EmailAddress,
request=request,
user=request.user,
email_address=email_address,
)
def can_mark_as_primary(email_address: EmailAddress) -> bool:
if not email_address.pk:
return False
return (
email_address.verified
or not EmailAddress.objects.filter(
user=email_address.user, verified=True
).exists()
)
def mark_as_primary(request: HttpRequest, email_address: EmailAddress) -> bool:
if app_settings.REAUTHENTICATION_REQUIRED:
raise_if_reauthentication_required(request)
# Not primary=True -- Slightly different variation, don't
# require verified unless moving from a verified
# address. Ignore constraint if previous primary email
# address is not verified.
success = False
if not can_mark_as_primary(email_address):
get_adapter().add_message(
request,
messages.ERROR,
"account/messages/unverified_primary_email.txt",
)
else:
assert request.user.is_authenticated # nosec
from_email_address = EmailAddress.objects.filter(
user=request.user, primary=True
).first()
email_address.set_as_primary()
adapter = get_adapter()
adapter.add_message(
request,
messages.SUCCESS,
"account/messages/primary_email_set.txt",
)
emit_email_changed(request, from_email_address, email_address)
success = True
return success
def emit_email_changed(
request: HttpRequest,
from_email_address: EmailAddress | None,
to_email_address: EmailAddress,
) -> None:
user = to_email_address.user
signals.email_changed.send(
sender=EmailAddress,
request=request,
user=user,
from_email_address=from_email_address,
to_email_address=to_email_address,
)
if from_email_address:
get_adapter().send_notification_mail(
"account/email/email_changed",
user,
context={
"from_email": from_email_address.email,
"to_email": to_email_address.email,
},
email=from_email_address.email,
)
def assess_unique_email(
email: str, user: AbstractBaseUser | None = None
) -> bool | None:
"""
True -- email is unique
False -- email is already in use
None -- email is in use, but we should hide that using email verification.
"""
from allauth.account.utils import filter_users_by_email
if not app_settings.UNIQUE_EMAIL:
return True
users_with_email = filter_users_by_email(email)
if user:
users_with_email = [u for u in users_with_email if u.pk != user.pk]
conflict = len(users_with_email) > 0
if not conflict:
# All good.
return True
elif not app_settings.PREVENT_ENUMERATION:
# Fail right away.
return False
elif (
app_settings.EMAIL_VERIFICATION
== app_settings.EmailVerificationMethod.MANDATORY
):
# In case of mandatory verification and enumeration prevention,
# we can avoid creating a new account with the same (unverified)
# email address, because we are going to send an email anyway.
assert app_settings.PREVENT_ENUMERATION # nosec
return None
elif app_settings.PREVENT_ENUMERATION == "strict":
# We're going to be strict on enumeration prevention, and allow for
# this email address to pass even though it already exists. In this
# scenario, you can signup multiple times using the same email
# address resulting in multiple accounts with an unverified email.
return True
else:
assert app_settings.PREVENT_ENUMERATION is True # nosec
# Conflict. We're supposed to prevent enumeration, but we can't
# because that means letting the user in, while emails are required
# to be unique. In this case, uniqueness takes precedence over
# enumeration prevention.
return False
def list_email_addresses(
request: HttpRequest, user: AbstractBaseUser
) -> list[EmailAddress]:
addresses = list(EmailAddress.objects.filter(user_id=user.pk))
if (
app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED
and request.user.is_authenticated
):
from allauth.account.internal.flows.email_verification_by_code import (
EmailVerificationProcess,
)
process = EmailVerificationProcess.resume(request)
if process:
email_address = process.email_address
if email_address.user_id == user.pk:
addresses.append(email_address)
return addresses
def email_already_exists(
email: str, user: AbstractBaseUser | None = None, always_raise: bool = False
) -> tuple[str, bool]:
"""
Throws a validation error (if allowed by enumeration prevention rules).
Returns a tuple of [email, already_exists].
"""
adapter = get_adapter()
assessment = assess_unique_email(email, user=user)
if assessment is True:
# No conflict
already_exists = False
el
gitextract_12fbmuov/
├── .dir-locals.el
├── .djlintrc
├── .editorconfig
├── .envrc
├── .gitea/
│ ├── ISSUE_TEMPLATE/
│ │ ├── discussion.md
│ │ └── issue.md
│ └── pull_request_template.md
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ └── issue.md
│ ├── SECURITY.md
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .readthedocs.yaml
├── .woodpecker.yaml
├── AUTHORS
├── CONTRIBUTING.rst
├── ChangeLog.rst
├── LICENSE
├── Makefile
├── README.rst
├── allauth/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── auth_backends.py
│ │ ├── authentication.py
│ │ ├── checks.py
│ │ ├── decorators.py
│ │ ├── fields.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── decorators.py
│ │ │ ├── emailkit.py
│ │ │ ├── flows/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── code_verification.py
│ │ │ │ ├── email_verification.py
│ │ │ │ ├── email_verification_by_code.py
│ │ │ │ ├── login.py
│ │ │ │ ├── login_by_code.py
│ │ │ │ ├── logout.py
│ │ │ │ ├── manage_email.py
│ │ │ │ ├── password_change.py
│ │ │ │ ├── password_reset.py
│ │ │ │ ├── password_reset_by_code.py
│ │ │ │ ├── phone_verification.py
│ │ │ │ ├── reauthentication.py
│ │ │ │ └── signup.py
│ │ │ ├── stagekit.py
│ │ │ └── userkit.py
│ │ ├── management/
│ │ │ ├── __init__.py
│ │ │ └── commands/
│ │ │ ├── __init__.py
│ │ │ └── account_unsetmultipleprimaryemails.py
│ │ ├── managers.py
│ │ ├── middleware.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_email_max_length.py
│ │ │ ├── 0003_alter_emailaddress_create_unique_verified_email.py
│ │ │ ├── 0004_alter_emailaddress_drop_unique_email.py
│ │ │ ├── 0005_emailaddress_idx_upper_email.py
│ │ │ ├── 0006_emailaddress_lower.py
│ │ │ ├── 0007_emailaddress_idx_email.py
│ │ │ ├── 0008_emailaddress_unique_primary_email_fixup.py
│ │ │ ├── 0009_emailaddress_unique_primary_email.py
│ │ │ └── __init__.py
│ │ ├── mixins.py
│ │ ├── models.py
│ │ ├── reauthentication.py
│ │ ├── signals.py
│ │ ├── stages.py
│ │ ├── static/
│ │ │ └── account/
│ │ │ └── js/
│ │ │ ├── account.js
│ │ │ └── onload.js
│ │ ├── templatetags/
│ │ │ ├── __init__.py
│ │ │ └── account.py
│ │ ├── urls.py
│ │ ├── utils.py
│ │ └── views.py
│ ├── app_settings.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── context.py
│ │ ├── exceptions.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── adapter.py
│ │ │ ├── cryptokit.py
│ │ │ ├── httpkit.py
│ │ │ ├── jwkkit.py
│ │ │ ├── modelkit.py
│ │ │ ├── ratelimit.py
│ │ │ ├── sessionkit.py
│ │ │ └── urlkit.py
│ │ └── ratelimit.py
│ ├── decorators.py
│ ├── exceptions.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── account/
│ │ │ ├── __init__.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── adapter.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── checks.py
│ │ ├── constants.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── security.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── authentication.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── authkit.py
│ │ │ ├── decorators.py
│ │ │ ├── restkit/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── inputs.py
│ │ │ │ ├── response.py
│ │ │ │ └── views.py
│ │ │ └── sessionkit.py
│ │ ├── mfa/
│ │ │ ├── __init__.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── socialaccount/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── inputs.py
│ │ │ ├── internal.py
│ │ │ ├── response.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── spec/
│ │ │ ├── __init__.py
│ │ │ ├── doc/
│ │ │ │ ├── description.md
│ │ │ │ └── openapi.yaml
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── openapikit.py
│ │ │ │ └── schema.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── templates/
│ │ │ └── headless/
│ │ │ └── spec/
│ │ │ ├── redoc_cdn.html
│ │ │ └── swagger_cdn.html
│ │ ├── tokens/
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── inputs.py
│ │ │ ├── response.py
│ │ │ ├── sessions.py
│ │ │ ├── strategies/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── jwt/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── internal.py
│ │ │ │ │ └── strategy.py
│ │ │ │ └── sessions.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── urls.py
│ │ └── usersessions/
│ │ ├── __init__.py
│ │ ├── inputs.py
│ │ ├── response.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── idp/
│ │ ├── __init__.py
│ │ ├── oidc/
│ │ │ ├── __init__.py
│ │ │ ├── adapter.py
│ │ │ ├── admin.py
│ │ │ ├── app_settings.py
│ │ │ ├── apps.py
│ │ │ ├── contrib/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── ninja/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── security.py
│ │ │ │ └── rest_framework/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── authentication.py
│ │ │ │ └── permissions.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clientkit.py
│ │ │ │ ├── flows.py
│ │ │ │ ├── oauthlib/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── authorization_codes.py
│ │ │ │ │ ├── device_codes.py
│ │ │ │ │ ├── request_validator.py
│ │ │ │ │ ├── server.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── scope.py
│ │ │ │ └── tokens.py
│ │ │ ├── migrations/
│ │ │ │ ├── 0001_initial.py
│ │ │ │ ├── 0002_client_default_scopes.py
│ │ │ │ ├── 0003_client_allow_uri_wildcards.py
│ │ │ │ └── __init__.py
│ │ │ ├── models.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── locale/
│ │ ├── ar/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── az/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── bg/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ca/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── cs/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── da/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── de/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── el/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── en/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── es/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── et/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── eu/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fa/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fi/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── fr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── he/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── hr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ht/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── hu/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── id/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── it/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ja/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ka/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ko/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ky/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── lt/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── lv/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── mn/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── nb/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── nl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pt_BR/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── pt_PT/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ro/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── ru/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sk/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sl/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sr_Latn/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── sv/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── th/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── tr/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── uk/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── uz/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ ├── zh_Hans/
│ │ │ └── LC_MESSAGES/
│ │ │ └── django.po
│ │ └── zh_Hant/
│ │ └── LC_MESSAGES/
│ │ └── django.po
│ ├── mfa/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── checks.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ └── flows/
│ │ │ ├── __init__.py
│ │ │ ├── add.py
│ │ │ └── trust.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_authenticator_timestamps.py
│ │ │ ├── 0003_authenticator_type_uniq.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── recovery_codes/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── signals.py
│ │ ├── stages.py
│ │ ├── static/
│ │ │ └── mfa/
│ │ │ └── js/
│ │ │ ├── webauthn-json.js
│ │ │ └── webauthn.js
│ │ ├── totp/
│ │ │ ├── __init__.py
│ │ │ ├── forms.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ └── flows.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── urls.py
│ │ ├── utils.py
│ │ └── webauthn/
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── auth.py
│ │ │ └── flows.py
│ │ ├── stages.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── models.py
│ ├── ratelimit.py
│ ├── socialaccount/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── checks.py
│ │ ├── forms.py
│ │ ├── helpers.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── flows/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── email_authentication.py
│ │ │ │ ├── login.py
│ │ │ │ └── signup.py
│ │ │ ├── jwtkit.py
│ │ │ └── statekit.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_token_max_lengths.py
│ │ │ ├── 0003_extra_data_default_dict.py
│ │ │ ├── 0004_app_provider_id_settings.py
│ │ │ ├── 0005_socialtoken_nullable_app.py
│ │ │ ├── 0006_alter_socialaccount_extra_data.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── providers/
│ │ │ ├── __init__.py
│ │ │ ├── agave/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── amazon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── amazon_cognito/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── angellist/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── apple/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── apple_session.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── asana/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── atlassian/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── auth0/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── authentiq/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── baidu/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── base/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── basecamp/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── battlenet/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── validators.py
│ │ │ │ └── views.py
│ │ │ ├── bitbucket_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── bitly/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── box/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── cilogon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── clever/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── coinbase/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dataporten/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── daum/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── digitalocean/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dingtalk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── discogs/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── discord/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── disqus/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── douban/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── doximity/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── draugiem/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── drip/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dropbox/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dummy/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── templates/
│ │ │ │ │ └── dummy/
│ │ │ │ │ └── authenticate_form.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── dwolla/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── edmodo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── edx/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── eventbrite/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── eveonline/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── evernote/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── exist/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── facebook/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── data/
│ │ │ │ │ └── FacebookLocales.xml
│ │ │ │ ├── flows.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── locale.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── static/
│ │ │ │ │ └── facebook/
│ │ │ │ │ └── js/
│ │ │ │ │ └── fbconnect.js
│ │ │ │ ├── templates/
│ │ │ │ │ └── facebook/
│ │ │ │ │ └── fbconnect.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── feedly/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── feishu/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── figma/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── fivehundredpx/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── flickr/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── foursquare/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── frontier/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── fxa/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gitea/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── github/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gitlab/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── globus/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── google/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── gumroad/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── hubic/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── hubspot/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── instagram/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── jupyterhub/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── kakao/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── lemonldap/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── lichess/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── line/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── linkedin_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailchimp/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailcow/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mailru/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── mediawiki/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── meetup/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── microsoft/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── miro/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── naver/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── netiq/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── nextcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── notion/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── oauth/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── oauth1_auth.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── odnoklassniki/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── okta/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── openid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── admin.py
│ │ │ │ ├── forms.py
│ │ │ │ ├── migrations/
│ │ │ │ │ ├── 0001_initial.py
│ │ │ │ │ └── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── openid_connect/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── openstreetmap/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── orcid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── patreon/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── paypal/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── pinterest/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── pocket/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── questrade/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── quickbooks/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── reddit/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── robinhood/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── salesforce/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── saml/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ ├── utils.py
│ │ │ │ └── views.py
│ │ │ ├── sharefile/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── shopify/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── slack/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── snapchat/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── soundcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── spotify/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stackexchange/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── steam/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stocktwits/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── strava/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── stripe/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── telegram/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── static/
│ │ │ │ │ └── telegram/
│ │ │ │ │ └── js/
│ │ │ │ │ └── telegram.js
│ │ │ │ ├── templates/
│ │ │ │ │ └── telegram/
│ │ │ │ │ └── callback.html
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tiktok/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── scope.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── trainingpeaks/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── trello/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tumblr/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── tumblr_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twentythreeandme/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitch/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitter/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── twitter_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── untappd/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vimeo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vimeo_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── vk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── wahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── weibo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── weixin/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── windowslive/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── xing/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── yahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── yandex/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── ynab/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ ├── zoho/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── provider.py
│ │ │ │ ├── urls.py
│ │ │ │ └── views.py
│ │ │ └── zoom/
│ │ │ ├── __init__.py
│ │ │ ├── provider.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── sessions.py
│ │ ├── signals.py
│ │ ├── templatetags/
│ │ │ ├── __init__.py
│ │ │ └── socialaccount.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── templates/
│ │ ├── account/
│ │ │ ├── account_inactive.html
│ │ │ ├── base_confirm_code.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── base_manage_email.html
│ │ │ ├── base_manage_password.html
│ │ │ ├── base_manage_phone.html
│ │ │ ├── base_reauthenticate.html
│ │ │ ├── confirm_email_verification_code.html
│ │ │ ├── confirm_login_code.html
│ │ │ ├── confirm_password_reset_code.html
│ │ │ ├── confirm_phone_verification_code.html
│ │ │ ├── email/
│ │ │ │ ├── account_already_exists_message.txt
│ │ │ │ ├── account_already_exists_subject.txt
│ │ │ │ ├── base_message.txt
│ │ │ │ ├── base_notification.txt
│ │ │ │ ├── email_changed_message.txt
│ │ │ │ ├── email_changed_subject.txt
│ │ │ │ ├── email_confirm_message.txt
│ │ │ │ ├── email_confirm_subject.txt
│ │ │ │ ├── email_confirmation_message.txt
│ │ │ │ ├── email_confirmation_signup_message.txt
│ │ │ │ ├── email_confirmation_signup_subject.txt
│ │ │ │ ├── email_confirmation_subject.txt
│ │ │ │ ├── email_deleted_message.txt
│ │ │ │ ├── email_deleted_subject.txt
│ │ │ │ ├── login_code_message.txt
│ │ │ │ ├── login_code_subject.txt
│ │ │ │ ├── password_changed_message.txt
│ │ │ │ ├── password_changed_subject.txt
│ │ │ │ ├── password_reset_code_message.txt
│ │ │ │ ├── password_reset_code_subject.txt
│ │ │ │ ├── password_reset_key_message.txt
│ │ │ │ ├── password_reset_key_subject.txt
│ │ │ │ ├── password_reset_message.txt
│ │ │ │ ├── password_reset_subject.txt
│ │ │ │ ├── password_set_message.txt
│ │ │ │ ├── password_set_subject.txt
│ │ │ │ ├── unknown_account_message.txt
│ │ │ │ └── unknown_account_subject.txt
│ │ │ ├── email.html
│ │ │ ├── email_change.html
│ │ │ ├── email_confirm.html
│ │ │ ├── login.html
│ │ │ ├── logout.html
│ │ │ ├── messages/
│ │ │ │ ├── cannot_delete_primary_email.txt
│ │ │ │ ├── email_confirmation_failed.txt
│ │ │ │ ├── email_confirmation_sent.txt
│ │ │ │ ├── email_confirmed.txt
│ │ │ │ ├── email_deleted.txt
│ │ │ │ ├── logged_in.txt
│ │ │ │ ├── logged_out.txt
│ │ │ │ ├── login_code_sent.txt
│ │ │ │ ├── password_changed.txt
│ │ │ │ ├── password_set.txt
│ │ │ │ ├── phone_verification_sent.txt
│ │ │ │ ├── phone_verified.txt
│ │ │ │ ├── primary_email_set.txt
│ │ │ │ └── unverified_primary_email.txt
│ │ │ ├── password_change.html
│ │ │ ├── password_reset.html
│ │ │ ├── password_reset_done.html
│ │ │ ├── password_reset_from_key.html
│ │ │ ├── password_reset_from_key_done.html
│ │ │ ├── password_set.html
│ │ │ ├── phone_change.html
│ │ │ ├── reauthenticate.html
│ │ │ ├── request_login_code.html
│ │ │ ├── signup.html
│ │ │ ├── signup_by_passkey.html
│ │ │ ├── signup_closed.html
│ │ │ ├── snippets/
│ │ │ │ ├── already_logged_in.html
│ │ │ │ └── warn_no_email.html
│ │ │ ├── verification_sent.html
│ │ │ └── verified_email_required.html
│ │ ├── allauth/
│ │ │ ├── elements/
│ │ │ │ ├── alert.html
│ │ │ │ ├── badge.html
│ │ │ │ ├── button.html
│ │ │ │ ├── button_group.html
│ │ │ │ ├── details.html
│ │ │ │ ├── field.html
│ │ │ │ ├── fields.html
│ │ │ │ ├── form.html
│ │ │ │ ├── h1.html
│ │ │ │ ├── h2.html
│ │ │ │ ├── hr.html
│ │ │ │ ├── img.html
│ │ │ │ ├── p.html
│ │ │ │ ├── panel.html
│ │ │ │ ├── provider.html
│ │ │ │ ├── provider_list.html
│ │ │ │ ├── table.html
│ │ │ │ ├── tbody.html
│ │ │ │ ├── td.html
│ │ │ │ ├── th.html
│ │ │ │ ├── thead.html
│ │ │ │ └── tr.html
│ │ │ └── layouts/
│ │ │ ├── base.html
│ │ │ ├── entrance.html
│ │ │ └── manage.html
│ │ ├── idp/
│ │ │ └── oidc/
│ │ │ ├── authorization_form.html
│ │ │ ├── base.html
│ │ │ ├── device_authorization_code_form.html
│ │ │ ├── device_authorization_confirm_form.html
│ │ │ ├── device_authorization_confirmed.html
│ │ │ ├── device_authorization_denied.html
│ │ │ ├── error.html
│ │ │ └── logout.html
│ │ ├── mfa/
│ │ │ ├── authenticate.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── email/
│ │ │ │ ├── recovery_codes_generated_message.txt
│ │ │ │ ├── recovery_codes_generated_subject.txt
│ │ │ │ ├── totp_activated_message.txt
│ │ │ │ ├── totp_activated_subject.txt
│ │ │ │ ├── totp_deactivated_message.txt
│ │ │ │ ├── totp_deactivated_subject.txt
│ │ │ │ ├── webauthn_added_message.txt
│ │ │ │ ├── webauthn_added_subject.txt
│ │ │ │ ├── webauthn_removed_message.txt
│ │ │ │ └── webauthn_removed_subject.txt
│ │ │ ├── index.html
│ │ │ ├── messages/
│ │ │ │ ├── recovery_codes_generated.txt
│ │ │ │ ├── totp_activated.txt
│ │ │ │ ├── totp_deactivated.txt
│ │ │ │ ├── webauthn_added.txt
│ │ │ │ └── webauthn_removed.txt
│ │ │ ├── reauthenticate.html
│ │ │ ├── recovery_codes/
│ │ │ │ ├── base.html
│ │ │ │ ├── download.txt
│ │ │ │ ├── generate.html
│ │ │ │ └── index.html
│ │ │ ├── totp/
│ │ │ │ ├── activate_form.html
│ │ │ │ ├── base.html
│ │ │ │ └── deactivate_form.html
│ │ │ ├── trust.html
│ │ │ └── webauthn/
│ │ │ ├── add_form.html
│ │ │ ├── authenticator_confirm_delete.html
│ │ │ ├── authenticator_list.html
│ │ │ ├── base.html
│ │ │ ├── edit_form.html
│ │ │ ├── reauthenticate.html
│ │ │ ├── signup_form.html
│ │ │ └── snippets/
│ │ │ ├── login_script.html
│ │ │ └── scripts.html
│ │ ├── openid/
│ │ │ ├── base.html
│ │ │ └── login.html
│ │ ├── socialaccount/
│ │ │ ├── authentication_error.html
│ │ │ ├── base_entrance.html
│ │ │ ├── base_manage.html
│ │ │ ├── connections.html
│ │ │ ├── email/
│ │ │ │ ├── account_connected_message.txt
│ │ │ │ ├── account_connected_subject.txt
│ │ │ │ ├── account_disconnected_message.txt
│ │ │ │ └── account_disconnected_subject.txt
│ │ │ ├── login.html
│ │ │ ├── login_cancelled.html
│ │ │ ├── login_redirect.html
│ │ │ ├── messages/
│ │ │ │ ├── account_connected.txt
│ │ │ │ ├── account_connected_other.txt
│ │ │ │ ├── account_connected_updated.txt
│ │ │ │ └── account_disconnected.txt
│ │ │ ├── signup.html
│ │ │ └── snippets/
│ │ │ ├── login.html
│ │ │ ├── login_extra.html
│ │ │ └── provider_list.html
│ │ └── usersessions/
│ │ ├── base_manage.html
│ │ ├── messages/
│ │ │ └── sessions_logged_out.txt
│ │ └── usersession_list.html
│ ├── templatetags/
│ │ ├── __init__.py
│ │ └── allauth.py
│ ├── urls.py
│ ├── usersessions/
│ │ ├── __init__.py
│ │ ├── adapter.py
│ │ ├── admin.py
│ │ ├── app_settings.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── flows/
│ │ │ ├── __init__.py
│ │ │ └── sessions.py
│ │ ├── middleware.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── signals.py
│ │ ├── urls.py
│ │ └── views.py
│ └── utils.py
├── devenv.nix
├── devenv.yaml
├── docs/
│ ├── Makefile
│ ├── account/
│ │ ├── adapter.rst
│ │ ├── advanced.rst
│ │ ├── configuration.rst
│ │ ├── decorators.rst
│ │ ├── email.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── phone.rst
│ │ ├── rate_limits.rst
│ │ ├── signals.rst
│ │ ├── templates.rst
│ │ └── views.rst
│ ├── common/
│ │ ├── admin.rst
│ │ ├── configuration.rst
│ │ ├── email.rst
│ │ ├── index.rst
│ │ ├── messages.rst
│ │ ├── rate_limits.rst
│ │ └── templates.rst
│ ├── conf.py
│ ├── faq.rst
│ ├── headless/
│ │ ├── adapter.rst
│ │ ├── api.rst
│ │ ├── configuration.rst
│ │ ├── cors.rst
│ │ ├── faq.rst
│ │ ├── index.rst
│ │ ├── installation.rst
│ │ ├── introduction.rst
│ │ ├── openapi-specification/
│ │ │ └── index.html
│ │ └── token-strategies/
│ │ ├── abstract-strategy.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── jwt-tokens.rst
│ │ └── session-tokens.rst
│ ├── idp/
│ │ ├── index.rst
│ │ └── openid-connect/
│ │ ├── adapter.rst
│ │ ├── clients.rst
│ │ ├── configuration.rst
│ │ ├── index.rst
│ │ ├── installation.rst
│ │ ├── integrations.rst
│ │ ├── introduction.rst
│ │ └── views.rst
│ ├── index.rst
│ ├── installation/
│ │ ├── examples.rst
│ │ ├── index.rst
│ │ ├── quickstart.rst
│ │ └── requirements.rst
│ ├── introduction/
│ │ └── index.rst
│ ├── mfa/
│ │ ├── adapter.rst
│ │ ├── configuration.rst
│ │ ├── django-allauth-2fa.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ └── webauthn.rst
│ ├── project/
│ │ ├── contributing.rst
│ │ ├── funding.rst
│ │ ├── index.rst
│ │ └── support.rst
│ ├── release-notes/
│ │ ├── 2012.rst
│ │ ├── 2013.rst
│ │ ├── 2014.rst
│ │ ├── 2015.rst
│ │ ├── 2016.rst
│ │ ├── 2017.rst
│ │ ├── 2018.rst
│ │ ├── 2019.rst
│ │ ├── 2020.rst
│ │ ├── 2021.rst
│ │ ├── 2022.rst
│ │ ├── 2023.rst
│ │ ├── 2024.rst
│ │ ├── history.rst
│ │ ├── index.rst
│ │ └── recent.rst
│ ├── requirements.txt
│ ├── settings.py
│ ├── socialaccount/
│ │ ├── adapter.rst
│ │ ├── advanced.rst
│ │ ├── configuration.rst
│ │ ├── forms.rst
│ │ ├── index.rst
│ │ ├── introduction.rst
│ │ ├── provider_configuration.rst
│ │ ├── providers/
│ │ │ ├── 23andme.rst
│ │ │ ├── 500px.rst
│ │ │ ├── agave.rst
│ │ │ ├── amazon.rst
│ │ │ ├── amazon_cognito.rst
│ │ │ ├── angellist.rst
│ │ │ ├── apple.rst
│ │ │ ├── atlassian.rst
│ │ │ ├── auth0.rst
│ │ │ ├── authelia.rst
│ │ │ ├── authentiq.rst
│ │ │ ├── baidu.rst
│ │ │ ├── basecamp.rst
│ │ │ ├── battlenet.rst
│ │ │ ├── bitbucket.rst
│ │ │ ├── box.rst
│ │ │ ├── cern.rst
│ │ │ ├── cilogon.rst
│ │ │ ├── clever.rst
│ │ │ ├── dataporten.rst
│ │ │ ├── daum.rst
│ │ │ ├── digitalocean.rst
│ │ │ ├── dingtalk.rst
│ │ │ ├── discogs.rst
│ │ │ ├── discord.rst
│ │ │ ├── doximity.rst
│ │ │ ├── draugiem.rst
│ │ │ ├── drip.rst
│ │ │ ├── dropbox.rst
│ │ │ ├── dwolla.rst
│ │ │ ├── edmodo.rst
│ │ │ ├── edx.rst
│ │ │ ├── eventbrite.rst
│ │ │ ├── eveonline.rst
│ │ │ ├── evernote.rst
│ │ │ ├── exist.rst
│ │ │ ├── facebook.rst
│ │ │ ├── feishu.rst
│ │ │ ├── figma.rst
│ │ │ ├── flickr.rst
│ │ │ ├── frontier.rst
│ │ │ ├── fxa.rst
│ │ │ ├── gitea.rst
│ │ │ ├── github.rst
│ │ │ ├── gitlab.rst
│ │ │ ├── globus.rst
│ │ │ ├── google.rst
│ │ │ ├── gumroad.rst
│ │ │ ├── hubspot.rst
│ │ │ ├── index.rst
│ │ │ ├── instagram.rst
│ │ │ ├── jupyterhub.rst
│ │ │ ├── kakao.rst
│ │ │ ├── keycloak.rst
│ │ │ ├── lemonldap.rst
│ │ │ ├── lichess.rst
│ │ │ ├── line.rst
│ │ │ ├── linkedin.rst
│ │ │ ├── mailchimp.rst
│ │ │ ├── mailcow.rst
│ │ │ ├── mediawiki.rst
│ │ │ ├── microsoft.rst
│ │ │ ├── miro.rst
│ │ │ ├── naver.rst
│ │ │ ├── netiq.rst
│ │ │ ├── nextcloud.rst
│ │ │ ├── notion.rst
│ │ │ ├── oauth2.rst
│ │ │ ├── odnoklassniki.rst
│ │ │ ├── okta.rst
│ │ │ ├── openid.rst
│ │ │ ├── openid_connect.rst
│ │ │ ├── openstreetmap.rst
│ │ │ ├── orcid.rst
│ │ │ ├── patreon.rst
│ │ │ ├── paypal.rst
│ │ │ ├── pinterest.rst
│ │ │ ├── pocket.rst
│ │ │ ├── questrade.rst
│ │ │ ├── quickbooks.rst
│ │ │ ├── reddit.rst
│ │ │ ├── salesforce.rst
│ │ │ ├── saml.rst
│ │ │ ├── sharefile.rst
│ │ │ ├── shopify.rst
│ │ │ ├── slack.rst
│ │ │ ├── snapchat.rst
│ │ │ ├── soundcloud.rst
│ │ │ ├── stackexchange.rst
│ │ │ ├── steam.rst
│ │ │ ├── stocktwits.rst
│ │ │ ├── strava.rst
│ │ │ ├── stripe.rst
│ │ │ ├── telegram.rst
│ │ │ ├── tiktok.rst
│ │ │ ├── trainingpeaks.rst
│ │ │ ├── trello.rst
│ │ │ ├── tumblr_oauth2.rst
│ │ │ ├── twitch.rst
│ │ │ ├── twitter.rst
│ │ │ ├── twitter_oauth2.rst
│ │ │ ├── untappd.rst
│ │ │ ├── vimeo.rst
│ │ │ ├── vimeo_oauth2.rst
│ │ │ ├── vk.rst
│ │ │ ├── wahoo.rst
│ │ │ ├── weibo.rst
│ │ │ ├── weixin.rst
│ │ │ ├── windowslive.rst
│ │ │ ├── xing.rst
│ │ │ ├── yahoo.rst
│ │ │ ├── yandex.rst
│ │ │ ├── ynab.rst
│ │ │ ├── zoho.rst
│ │ │ └── zoom.rst
│ │ ├── signals.rst
│ │ ├── templates.rst
│ │ └── views.rst
│ └── usersessions/
│ ├── adapter.rst
│ ├── configuration.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── introduction.rst
│ └── signals.rst
├── examples/
│ ├── react-spa/
│ │ ├── Makefile
│ │ ├── README.org
│ │ ├── backend/
│ │ │ ├── Dockerfile
│ │ │ ├── backend/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── asgi.py
│ │ │ │ ├── drf_demo/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── serializers.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ └── views.py
│ │ │ │ ├── ninja_demo/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ └── views.py
│ │ │ │ ├── settings.py
│ │ │ │ ├── urls.py
│ │ │ │ └── wsgi.py
│ │ │ ├── manage.py
│ │ │ └── requirements.txt
│ │ ├── docker-compose.dev.yml
│ │ ├── docker-compose.yml
│ │ ├── e2e.spec.js
│ │ ├── frontend/
│ │ │ ├── Dockerfile
│ │ │ ├── package.json
│ │ │ ├── public/
│ │ │ │ ├── css/
│ │ │ │ │ └── style.css
│ │ │ │ └── index.html
│ │ │ └── src/
│ │ │ ├── App.js
│ │ │ ├── Calculator.js
│ │ │ ├── Home.js
│ │ │ ├── NavBar.js
│ │ │ ├── Root.js
│ │ │ ├── Router.js
│ │ │ ├── account/
│ │ │ │ ├── AuthenticateFlow.js
│ │ │ │ ├── ChangeEmail.js
│ │ │ │ ├── ChangePassword.js
│ │ │ │ ├── ConfirmLoginCode.js
│ │ │ │ ├── ConfirmPasswordResetCode.js
│ │ │ │ ├── Login.js
│ │ │ │ ├── Logout.js
│ │ │ │ ├── Reauthenticate.js
│ │ │ │ ├── ReauthenticateFlow.js
│ │ │ │ ├── RequestLoginCode.js
│ │ │ │ ├── RequestPasswordReset.js
│ │ │ │ ├── ResetPassword.js
│ │ │ │ ├── Signup.js
│ │ │ │ ├── VerificationEmailSent.js
│ │ │ │ ├── VerifyEmail.js
│ │ │ │ └── VerifyEmailByCode.js
│ │ │ ├── auth/
│ │ │ │ ├── AuthContext.js
│ │ │ │ ├── hooks.js
│ │ │ │ ├── index.js
│ │ │ │ └── routing.js
│ │ │ ├── components/
│ │ │ │ ├── Button.js
│ │ │ │ └── FormErrors.js
│ │ │ ├── index.js
│ │ │ ├── init.js
│ │ │ ├── lib/
│ │ │ │ ├── allauth.js
│ │ │ │ └── django.js
│ │ │ ├── mfa/
│ │ │ │ ├── ActivateTOTP.js
│ │ │ │ ├── AddWebAuthn.js
│ │ │ │ ├── AuthenticateCode.js
│ │ │ │ ├── AuthenticateFlow.js
│ │ │ │ ├── AuthenticateRecoveryCodes.js
│ │ │ │ ├── AuthenticateTOTP.js
│ │ │ │ ├── AuthenticateWebAuthn.js
│ │ │ │ ├── CreateSignupPasskey.js
│ │ │ │ ├── DeactivateTOTP.js
│ │ │ │ ├── GenerateRecoveryCodes.js
│ │ │ │ ├── ListWebAuthn.js
│ │ │ │ ├── MFAOverview.js
│ │ │ │ ├── ReauthenticateCode.js
│ │ │ │ ├── ReauthenticateRecoveryCodes.js
│ │ │ │ ├── ReauthenticateTOTP.js
│ │ │ │ ├── ReauthenticateWebAuthn.js
│ │ │ │ ├── RecoveryCodes.js
│ │ │ │ ├── SignupByPasskey.js
│ │ │ │ ├── Trust.js
│ │ │ │ └── WebAuthnLoginButton.js
│ │ │ ├── socialaccount/
│ │ │ │ ├── GoogleOneTap.js
│ │ │ │ ├── ManageProviders.js
│ │ │ │ ├── ProviderCallback.js
│ │ │ │ ├── ProviderList.js
│ │ │ │ └── ProviderSignup.js
│ │ │ └── usersessions/
│ │ │ └── Sessions.js
│ │ └── traefik.toml
│ └── regular-django/
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── Makefile
│ ├── README.org
│ ├── db/
│ │ └── .gitignore
│ ├── docker-compose.yml
│ ├── example/
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── templates/
│ │ │ ├── 429.html
│ │ │ ├── account/
│ │ │ │ ├── base_manage_email.html
│ │ │ │ ├── base_manage_password.html
│ │ │ │ └── base_manage_phone.html
│ │ │ ├── allauth/
│ │ │ │ ├── elements/
│ │ │ │ │ ├── alert.html
│ │ │ │ │ ├── badge.html
│ │ │ │ │ ├── button.html
│ │ │ │ │ ├── button__entrance.html
│ │ │ │ │ ├── button_group.html
│ │ │ │ │ ├── field.html
│ │ │ │ │ ├── fields.html
│ │ │ │ │ ├── form.html
│ │ │ │ │ ├── form__entrance.html
│ │ │ │ │ ├── h1.html
│ │ │ │ │ ├── h1__entrance.html
│ │ │ │ │ ├── h2__entrance.html
│ │ │ │ │ ├── img.html
│ │ │ │ │ ├── panel.html
│ │ │ │ │ ├── provider.html
│ │ │ │ │ ├── provider_list.html
│ │ │ │ │ └── table.html
│ │ │ │ └── layouts/
│ │ │ │ ├── base.html
│ │ │ │ ├── entrance.html
│ │ │ │ └── manage.html
│ │ │ ├── index.html
│ │ │ ├── mfa/
│ │ │ │ └── base_manage.html
│ │ │ ├── profile.html
│ │ │ ├── socialaccount/
│ │ │ │ └── base_manage.html
│ │ │ └── usersessions/
│ │ │ └── base_manage.html
│ │ ├── urls.py
│ │ ├── users/
│ │ │ ├── __init__.py
│ │ │ ├── allauth.py
│ │ │ ├── apps.py
│ │ │ ├── migrations/
│ │ │ │ ├── 0001_initial.py
│ │ │ │ └── __init__.py
│ │ │ └── models.py
│ │ └── wsgi.py
│ ├── manage.py
│ └── requirements.txt
├── manage.py
├── mise.toml
├── noxfile.py
├── package.json
├── pyproject.toml
├── pytest.ini
├── requirements-dev.txt
├── setup.cfg
└── tests/
├── __init__.py
├── apps/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── test_emailkit.py
│ │ ├── test_adapter.py
│ │ ├── test_ajax.py
│ │ ├── test_auth_backends.py
│ │ ├── test_change_email.py
│ │ ├── test_change_password.py
│ │ ├── test_commands.py
│ │ ├── test_decorators.py
│ │ ├── test_email_verification.py
│ │ ├── test_email_verification_by_code.py
│ │ ├── test_login.py
│ │ ├── test_login_by_code.py
│ │ ├── test_logout.py
│ │ ├── test_middleware.py
│ │ ├── test_models.py
│ │ ├── test_phone.py
│ │ ├── test_ratelimit.py
│ │ ├── test_reauthentication.py
│ │ ├── test_reset_password.py
│ │ ├── test_reset_password_by_code.py
│ │ ├── test_security.py
│ │ ├── test_signup.py
│ │ └── test_utils.py
│ ├── core/
│ │ ├── __init__.py
│ │ └── internal/
│ │ ├── __init__.py
│ │ ├── test_cryptokit.py
│ │ ├── test_httpkit.py
│ │ ├── test_modelkit.py
│ │ └── test_ratelimit.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── account/
│ │ │ ├── __init__.py
│ │ │ ├── test_change_email.py
│ │ │ ├── test_change_password.py
│ │ │ ├── test_email_verification.py
│ │ │ ├── test_email_verification_by_code.py
│ │ │ ├── test_login.py
│ │ │ ├── test_login_by_code.py
│ │ │ ├── test_phone.py
│ │ │ ├── test_reauthentication.py
│ │ │ ├── test_reset_password.py
│ │ │ ├── test_reset_password_by_code.py
│ │ │ ├── test_session.py
│ │ │ └── test_signup.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ └── test_views.py
│ │ ├── conftest.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_security.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── test_authentication.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── test_authkit.py
│ │ ├── mfa/
│ │ │ ├── __init__.py
│ │ │ ├── test_recovery_codes.py
│ │ │ ├── test_totp.py
│ │ │ ├── test_trust.py
│ │ │ ├── test_views.py
│ │ │ └── test_webauthn.py
│ │ ├── socialaccount/
│ │ │ ├── __init__.py
│ │ │ ├── test_inputs.py
│ │ │ └── test_views.py
│ │ ├── spec/
│ │ │ ├── __init__.py
│ │ │ ├── internal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_openapikit.py
│ │ │ └── test_views.py
│ │ ├── tokens/
│ │ │ ├── test_jwttokenstrategy.py
│ │ │ └── test_tokens.py
│ │ └── usersessions/
│ │ ├── __init__.py
│ │ └── test_views.py
│ ├── idp/
│ │ ├── __init__.py
│ │ └── oidc/
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── contrib/
│ │ │ ├── __init__.py
│ │ │ ├── ninja/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_views.py
│ │ │ └── rest_framework/
│ │ │ ├── __init__.py
│ │ │ └── test_views.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ └── oauthlib/
│ │ │ ├── __init__.py
│ │ │ ├── test_request_validator.py
│ │ │ └── test_utils.py
│ │ ├── test_authorization.py
│ │ ├── test_device.py
│ │ ├── test_rp_initiated_logout.py
│ │ ├── test_tokens.py
│ │ ├── test_views.py
│ │ └── test_wildcards.py
│ ├── mfa/
│ │ ├── __init__.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── test_adapter.py
│ │ │ ├── test_trust.py
│ │ │ ├── test_trust_fingerprint.py
│ │ │ └── test_views.py
│ │ ├── recovery_codes/
│ │ │ ├── __init__.py
│ │ │ ├── test_auth.py
│ │ │ └── test_views.py
│ │ ├── totp/
│ │ │ ├── __init__.py
│ │ │ ├── test_unit.py
│ │ │ └── test_views.py
│ │ └── webauthn/
│ │ ├── __init__.py
│ │ └── test_views.py
│ ├── socialaccount/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── conftest.py
│ │ ├── internal/
│ │ │ ├── __init__.py
│ │ │ ├── test_jwtkit.py
│ │ │ └── test_statekit.py
│ │ ├── providers/
│ │ │ ├── __init__.py
│ │ │ ├── agave/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── amazon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── amazon_cognito/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── angellist/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── apple/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── asana/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── atlassian/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── auth0/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── authentiq/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── baidu/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── base/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_provider.py
│ │ │ ├── basecamp/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── battlenet/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── bitbucket_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── bitly/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── box/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── cilogon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── clever/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── coinbase/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dataporten/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── daum/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── digitalocean/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dingtalk/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── discogs/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── discord/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── disqus/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── douban/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── doximity/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── draugiem/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── drip/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dropbox/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dummy/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── dwolla/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── edmodo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── edx/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── eventbrite/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── eveonline/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── evernote/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── exist/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── facebook/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── feedly/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── feishu/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── figma/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── fivehundredpx/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── flickr/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── foursquare/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── frontier/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── fxa/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gitea/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── github/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gitlab/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── globus/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── google/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── gumroad/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── hubic/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── hubspot/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── instagram/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── jupyterhub/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── kakao/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── lemonldap/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── lichess/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── line/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── linkedin_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailchimp/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailcow/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mailru/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── mediawiki/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── meetup/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── microsoft/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── miro/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── naver/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── netiq/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── nextcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── notion/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests/
│ │ │ │ └── test_views.py
│ │ │ ├── odnoklassniki/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── okta/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openid/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openid_connect/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── openstreetmap/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── orcid/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── patreon/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── paypal/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── pinterest/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── pocket/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── questrade/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── quickbooks/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── reddit/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── robinhood/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── salesforce/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── saml/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ └── tests.py
│ │ │ ├── sharefile/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── shopify/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── slack/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── snapchat/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── soundcloud/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── spotify/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stackexchange/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── steam/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stocktwits/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── strava/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── stripe/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── telegram/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tiktok/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── trainingpeaks/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── trello/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tumblr/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── tumblr_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twentythreeandme/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitch/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitter/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── twitter_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── untappd/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vimeo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vimeo_oauth2/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── vk/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── wahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── weibo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── weixin/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── windowslive/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── xing/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── yahoo/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── yandex/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── ynab/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ ├── zoho/
│ │ │ │ ├── __init__.py
│ │ │ │ └── tests.py
│ │ │ └── zoom/
│ │ │ ├── __init__.py
│ │ │ └── tests.py
│ │ ├── test_adapter.py
│ │ ├── test_connect.py
│ │ ├── test_login.py
│ │ ├── test_phone.py
│ │ ├── test_registry.py
│ │ ├── test_signup.py
│ │ └── test_utils.py
│ ├── test_utils.py
│ └── usersessions/
│ ├── __init__.py
│ ├── test_middleware.py
│ └── test_views.py
├── conftest.py
├── mocking.py
└── projects/
├── account_only/
│ ├── __init__.py
│ ├── settings.py
│ ├── templates/
│ │ └── 429.html
│ └── urls.py
├── common/
│ ├── __init__.py
│ ├── account/
│ │ ├── __init__.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── adapters.py
│ ├── headless/
│ │ ├── __init__.py
│ │ ├── ninja/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── rest_framework/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── idp/
│ │ ├── __init__.py
│ │ ├── ninja/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── rest_framework/
│ │ │ ├── __init__.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── urls.py
│ ├── phone_stub.py
│ ├── settings.py
│ ├── templates/
│ │ └── test_403_csrf.html
│ └── urls.py
├── headless_only/
│ ├── __init__.py
│ ├── settings.py
│ └── urls.py
├── login_required_mw/
│ ├── __init__.py
│ ├── middleware.py
│ ├── settings.py
│ ├── templates/
│ │ └── 429.html
│ └── urls.py
└── regular/
├── __init__.py
├── settings.py
└── urls.py
Showing preview only (421K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4690 symbols across 782 files)
FILE: allauth/account/adapter.py
class DefaultAccountAdapter (line 51) | class DefaultAccountAdapter(BaseAdapter):
method stash_verified_email (line 102) | def stash_verified_email(self, request, email):
method unstash_verified_email (line 105) | def unstash_verified_email(self, request):
method is_email_verified (line 110) | def is_email_verified(self, request, email):
method can_delete_email (line 122) | def can_delete_email(self, email_address) -> bool:
method format_email_subject (line 154) | def format_email_subject(self, subject) -> str:
method get_from_email (line 164) | def get_from_email(self):
method render_mail (line 171) | def render_mail(self, template_prefix, email, context, headers=None):
method send_mail (line 211) | def send_mail(self, template_prefix: str, email: str, context: dict) -...
method get_signup_redirect_url (line 222) | def get_signup_redirect_url(self, request):
method get_login_redirect_url (line 228) | def get_login_redirect_url(self, request):
method get_logout_redirect_url (line 246) | def get_logout_redirect_url(self, request):
method get_email_verification_redirect_url (line 255) | def get_email_verification_redirect_url(self, email_address):
method get_password_change_redirect_url (line 272) | def get_password_change_redirect_url(self, request):
method is_open_for_signup (line 280) | def is_open_for_signup(self, request):
method new_user (line 289) | def new_user(self, request):
method populate_username (line 296) | def populate_username(self, request, user):
method generate_unique_username (line 317) | def generate_unique_username(self, txts, regex=None):
method save_user (line 320) | def save_user(self, request, user, form, commit=True):
method clean_username (line 359) | def clean_username(self, username, shallow=False):
method clean_email (line 382) | def clean_email(self, email: str) -> str:
method clean_password (line 389) | def clean_password(self, password, user=None):
method clean_phone (line 400) | def clean_phone(self, phone: str) -> str:
method validate_unique_email (line 407) | def validate_unique_email(self, email):
method add_message (line 410) | def add_message(
method ajax_response (line 443) | def ajax_response(self, request, response, redirect_to=None, form=None...
method ajax_response_form (line 468) | def ajax_response_form(self, form):
method pre_login (line 490) | def pre_login(
method post_login (line 504) | def post_login(
method login (line 543) | def login(self, request, user):
method logout (line 563) | def logout(self, request):
method confirm_email (line 566) | def confirm_email(self, request, email_address):
method set_password (line 574) | def set_password(self, user, password) -> None:
method get_user_search_fields (line 581) | def get_user_search_fields(self):
method is_safe_url (line 598) | def is_safe_url(self, url):
method send_password_reset_mail (line 622) | def send_password_reset_mail(self, user, email, context):
method get_reset_password_from_key_url (line 632) | def get_reset_password_from_key_url(self, key):
method get_email_confirmation_url (line 641) | def get_email_confirmation_url(self, request, emailconfirmation):
method should_send_confirmation_mail (line 654) | def should_send_confirmation_mail(self, request, email_address, signup...
method send_account_already_exists_mail (line 657) | def send_account_already_exists_mail(self, email: str) -> None:
method send_confirmation_mail (line 670) | def send_confirmation_mail(self, request, emailconfirmation, signup):
method respond_user_inactive (line 691) | def respond_user_inactive(self, request, user):
method respond_email_verification_sent (line 694) | def respond_email_verification_sent(self, request, user):
method _get_login_attempts_cache_key (line 697) | def _get_login_attempts_cache_key(self, request, **credentials):
method _delete_login_attempts_cached_email (line 702) | def _delete_login_attempts_cached_email(self, request, **credentials):
method _rollback_login_failed_rl_usage (line 714) | def _rollback_login_failed_rl_usage(self) -> None:
method pre_authenticate (line 719) | def pre_authenticate(self, request, **credentials):
method authenticate (line 730) | def authenticate(self, request, **credentials):
method authentication_failed (line 750) | def authentication_failed(self, request, **credentials):
method reauthenticate (line 753) | def reauthenticate(self, user, password):
method is_ajax (line 771) | def is_ajax(self, request):
method get_client_ip (line 780) | def get_client_ip(self, request) -> str:
method get_http_user_agent (line 789) | def get_http_user_agent(self, request: HttpRequest) -> str:
method generate_emailconfirmation_key (line 792) | def generate_emailconfirmation_key(self, email):
method get_login_stages (line 796) | def get_login_stages(self):
method get_reauthentication_methods (line 812) | def get_reauthentication_methods(self, user):
method send_notification_mail (line 847) | def send_notification_mail(self, template_prefix, user, context=None, ...
method generate_login_code (line 867) | def generate_login_code(self) -> str:
method generate_password_reset_code (line 873) | def generate_password_reset_code(self) -> str:
method generate_email_verification_code (line 879) | def generate_email_verification_code(self) -> str:
method generate_phone_verification_code (line 885) | def generate_phone_verification_code(self, *, user, phone: str) -> str:
method _generate_phone_verification_code_compat (line 891) | def _generate_phone_verification_code_compat(self, *, user, phone: str...
method is_login_by_code_required (line 902) | def is_login_by_code_required(self, login) -> bool:
method phone_form_field (line 922) | def phone_form_field(self, **kwargs):
method send_unknown_account_sms (line 930) | def send_unknown_account_sms(self, phone: str, **kwargs) -> None:
method send_account_already_exists_sms (line 938) | def send_account_already_exists_sms(self, phone: str) -> None:
method send_verification_code_sms (line 941) | def send_verification_code_sms(self, user, phone: str, code: str, **kw...
method _has_phone_impl (line 948) | def _has_phone_impl(self) -> bool:
method set_phone (line 964) | def set_phone(self, user, phone: str, verified: bool):
method get_phone (line 970) | def get_phone(self, user) -> tuple[str, bool] | None:
method set_phone_verified (line 978) | def set_phone_verified(self, user, phone: str):
method get_user_by_phone (line 986) | def get_user_by_phone(self, phone: str):
function get_adapter (line 994) | def get_adapter(request=None) -> DefaultAccountAdapter:
FILE: allauth/account/admin.py
class EmailAddressAdmin (line 9) | class EmailAddressAdmin(admin.ModelAdmin):
method get_search_fields (line 16) | def get_search_fields(self, request):
method make_verified (line 20) | def make_verified(self, request, queryset):
class EmailConfirmationAdmin (line 45) | class EmailConfirmationAdmin(admin.ModelAdmin):
FILE: allauth/account/app_settings.py
class AppSettings (line 8) | class AppSettings:
class AuthenticationMethod (line 9) | class AuthenticationMethod(str, Enum):
class LoginMethod (line 14) | class LoginMethod(str, Enum):
class EmailVerificationMethod (line 19) | class EmailVerificationMethod(str, Enum):
method __init__ (line 29) | def __init__(self, prefix):
method _setting (line 32) | def _setting(self, name, dflt):
method PREVENT_ENUMERATION (line 38) | def PREVENT_ENUMERATION(self):
method DEFAULT_HTTP_PROTOCOL (line 42) | def DEFAULT_HTTP_PROTOCOL(self):
method EMAIL_CONFIRMATION_EXPIRE_DAYS (line 46) | def EMAIL_CONFIRMATION_EXPIRE_DAYS(self):
method EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL (line 59) | def EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL(self):
method EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL (line 67) | def EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL(self):
method EMAIL_REQUIRED (line 79) | def EMAIL_REQUIRED(self):
method EMAIL_VERIFICATION (line 91) | def EMAIL_VERIFICATION(self):
method EMAIL_VERIFICATION_BY_CODE_ENABLED (line 104) | def EMAIL_VERIFICATION_BY_CODE_ENABLED(self):
method EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS (line 108) | def EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS(self):
method EMAIL_VERIFICATION_BY_CODE_TIMEOUT (line 112) | def EMAIL_VERIFICATION_BY_CODE_TIMEOUT(self):
method EMAIL_VERIFICATION_MAX_CHANGE_COUNT (line 116) | def EMAIL_VERIFICATION_MAX_CHANGE_COUNT(self) -> int:
method EMAIL_VERIFICATION_MAX_RESEND_COUNT (line 127) | def EMAIL_VERIFICATION_MAX_RESEND_COUNT(self) -> int:
method MAX_EMAIL_ADDRESSES (line 137) | def MAX_EMAIL_ADDRESSES(self):
method CHANGE_EMAIL (line 141) | def CHANGE_EMAIL(self):
method AUTHENTICATION_METHOD (line 145) | def AUTHENTICATION_METHOD(self):
method LOGIN_METHODS (line 161) | def LOGIN_METHODS(self) -> frozenset[LoginMethod]:
method EMAIL_MAX_LENGTH (line 174) | def EMAIL_MAX_LENGTH(self):
method PHONE_VERIFICATION_ENABLED (line 181) | def PHONE_VERIFICATION_ENABLED(self):
method PHONE_VERIFICATION_MAX_ATTEMPTS (line 185) | def PHONE_VERIFICATION_MAX_ATTEMPTS(self):
method PHONE_VERIFICATION_MAX_CHANGE_COUNT (line 189) | def PHONE_VERIFICATION_MAX_CHANGE_COUNT(self) -> int:
method PHONE_VERIFICATION_MAX_RESEND_COUNT (line 200) | def PHONE_VERIFICATION_MAX_RESEND_COUNT(self) -> int:
method PHONE_VERIFICATION_TIMEOUT (line 211) | def PHONE_VERIFICATION_TIMEOUT(self):
method UNIQUE_EMAIL (line 215) | def UNIQUE_EMAIL(self):
method SIGNUP_EMAIL_ENTER_TWICE (line 222) | def SIGNUP_EMAIL_ENTER_TWICE(self):
method SIGNUP_PASSWORD_ENTER_TWICE (line 233) | def SIGNUP_PASSWORD_ENTER_TWICE(self):
method SIGNUP_REDIRECT_URL (line 244) | def SIGNUP_REDIRECT_URL(self):
method PASSWORD_MIN_LENGTH (line 250) | def PASSWORD_MIN_LENGTH(self):
method RATE_LIMITS (line 262) | def RATE_LIMITS(self):
method EMAIL_SUBJECT_PREFIX (line 309) | def EMAIL_SUBJECT_PREFIX(self):
method SIGNUP_FORM_CLASS (line 316) | def SIGNUP_FORM_CLASS(self):
method SIGNUP_FORM_HONEYPOT_FIELD (line 323) | def SIGNUP_FORM_HONEYPOT_FIELD(self):
method SIGNUP_FIELDS (line 330) | def SIGNUP_FIELDS(self) -> dict:
method USERNAME_REQUIRED (line 359) | def USERNAME_REQUIRED(self):
method USERNAME_MIN_LENGTH (line 371) | def USERNAME_MIN_LENGTH(self):
method USERNAME_BLACKLIST (line 378) | def USERNAME_BLACKLIST(self):
method PASSWORD_INPUT_RENDER_VALUE (line 385) | def PASSWORD_INPUT_RENDER_VALUE(self):
method ADAPTER (line 392) | def ADAPTER(self):
method CONFIRM_EMAIL_ON_GET (line 396) | def CONFIRM_EMAIL_ON_GET(self):
method AUTHENTICATED_LOGIN_REDIRECTS (line 400) | def AUTHENTICATED_LOGIN_REDIRECTS(self):
method LOGIN_ON_EMAIL_CONFIRMATION (line 404) | def LOGIN_ON_EMAIL_CONFIRMATION(self):
method LOGIN_ON_PASSWORD_RESET (line 411) | def LOGIN_ON_PASSWORD_RESET(self):
method LOGOUT_REDIRECT_URL (line 419) | def LOGOUT_REDIRECT_URL(self):
method LOGOUT_ON_GET (line 425) | def LOGOUT_ON_GET(self):
method LOGOUT_ON_PASSWORD_CHANGE (line 429) | def LOGOUT_ON_PASSWORD_CHANGE(self):
method USER_MODEL_USERNAME_FIELD (line 433) | def USER_MODEL_USERNAME_FIELD(self):
method USER_MODEL_EMAIL_FIELD (line 437) | def USER_MODEL_EMAIL_FIELD(self):
method SESSION_COOKIE_AGE (line 441) | def SESSION_COOKIE_AGE(self):
method SESSION_REMEMBER (line 450) | def SESSION_REMEMBER(self):
method TEMPLATE_EXTENSION (line 459) | def TEMPLATE_EXTENSION(self):
method FORMS (line 466) | def FORMS(self):
method EMAIL_CONFIRMATION_HMAC (line 470) | def EMAIL_CONFIRMATION_HMAC(self):
method SALT (line 474) | def SALT(self):
method PRESERVE_USERNAME_CASING (line 478) | def PRESERVE_USERNAME_CASING(self):
method USERNAME_VALIDATORS (line 482) | def USERNAME_VALIDATORS(self):
method PASSWORD_RESET_BY_CODE_ENABLED (line 507) | def PASSWORD_RESET_BY_CODE_ENABLED(self):
method PASSWORD_RESET_BY_CODE_MAX_ATTEMPTS (line 511) | def PASSWORD_RESET_BY_CODE_MAX_ATTEMPTS(self):
method PASSWORD_RESET_BY_CODE_TIMEOUT (line 515) | def PASSWORD_RESET_BY_CODE_TIMEOUT(self):
method PASSWORD_RESET_TOKEN_GENERATOR (line 519) | def PASSWORD_RESET_TOKEN_GENERATOR(self):
method EMAIL_UNKNOWN_ACCOUNTS (line 531) | def EMAIL_UNKNOWN_ACCOUNTS(self):
method REAUTHENTICATION_TIMEOUT (line 535) | def REAUTHENTICATION_TIMEOUT(self):
method EMAIL_NOTIFICATIONS (line 539) | def EMAIL_NOTIFICATIONS(self):
method REAUTHENTICATION_REQUIRED (line 543) | def REAUTHENTICATION_REQUIRED(self):
method LOGIN_BY_CODE_ENABLED (line 547) | def LOGIN_BY_CODE_ENABLED(self):
method LOGIN_BY_CODE_TRUST_ENABLED (line 551) | def LOGIN_BY_CODE_TRUST_ENABLED(self):
method LOGIN_BY_CODE_MAX_ATTEMPTS (line 555) | def LOGIN_BY_CODE_MAX_ATTEMPTS(self):
method LOGIN_BY_CODE_MAX_RESEND_COUNT (line 559) | def LOGIN_BY_CODE_MAX_RESEND_COUNT(self) -> int:
method LOGIN_BY_CODE_TIMEOUT (line 569) | def LOGIN_BY_CODE_TIMEOUT(self):
method LOGIN_TIMEOUT (line 573) | def LOGIN_TIMEOUT(self):
method LOGIN_BY_CODE_REQUIRED (line 582) | def LOGIN_BY_CODE_REQUIRED(self) -> bool | set[str]:
method LOGIN_BY_CODE_FORMAT (line 596) | def LOGIN_BY_CODE_FORMAT(self) -> UserCodeFormat:
method PHONE_VERIFICATION_CODE_FORMAT (line 603) | def PHONE_VERIFICATION_CODE_FORMAT(self) -> UserCodeFormat:
method PASSWORD_RESET_BY_CODE_FORMAT (line 612) | def PASSWORD_RESET_BY_CODE_FORMAT(self) -> UserCodeFormat:
method EMAIL_VERIFICATION_BY_CODE_FORMAT (line 621) | def EMAIL_VERIFICATION_BY_CODE_FORMAT(self) -> UserCodeFormat:
function __getattr__ (line 633) | def __getattr__(name):
FILE: allauth/account/apps.py
class AccountConfig (line 9) | class AccountConfig(AppConfig):
method ready (line 14) | def ready(self):
FILE: allauth/account/auth_backends.py
class AuthenticationBackend (line 16) | class AuthenticationBackend(ModelBackend):
method authenticate (line 17) | def authenticate(self, request, **credentials):
method _authenticate (line 27) | def _authenticate(self, request, **credentials):
method _authenticate_by_phone (line 57) | def _authenticate_by_phone(self, phone: str, password: str):
method _authenticate_by_username (line 64) | def _authenticate_by_username(self, username: str, password: str):
method _authenticate_by_email (line 74) | def _authenticate_by_email(
method _mitigate_timing_attack (line 87) | def _mitigate_timing_attack(self, password):
method _check_password (line 90) | def _check_password(self, user, password):
method _stash_user (line 102) | def _stash_user(cls, user):
method unstash_authenticated_user (line 130) | def unstash_authenticated_user(cls):
FILE: allauth/account/authentication.py
function get_authentication_records (line 4) | def get_authentication_records(request):
FILE: allauth/account/checks.py
function adapter_check (line 5) | def adapter_check(app_configs, **kwargs):
function settings_check (line 20) | def settings_check(app_configs, **kwargs):
FILE: allauth/account/decorators.py
function verified_email_required (line 22) | def verified_email_required(
function reauthentication_required (line 60) | def reauthentication_required(
function secure_admin_login (line 88) | def secure_admin_login(function=None):
FILE: allauth/account/fields.py
class EmailField (line 10) | class EmailField(forms.EmailField):
method __init__ (line 11) | def __init__(self, *args, **kwargs) -> None:
method clean (line 25) | def clean(self, value):
class PasswordField (line 29) | class PasswordField(forms.CharField):
method __init__ (line 30) | def __init__(self, *args, **kwargs):
class SetPasswordField (line 44) | class SetPasswordField(PasswordField):
method __init__ (line 45) | def __init__(self, *args, **kwargs):
method clean (line 53) | def clean(self, value):
class PhoneField (line 59) | class PhoneField(forms.CharField):
method __init__ (line 66) | def __init__(self, *args, **kwargs):
method clean (line 75) | def clean(self, value):
FILE: allauth/account/forms.py
class EmailAwarePasswordResetTokenGenerator (line 37) | class EmailAwarePasswordResetTokenGenerator(PasswordResetTokenGenerator):
method _make_hash_value (line 38) | def _make_hash_value(self, user, timestamp):
class PasswordVerificationMixin (line 53) | class PasswordVerificationMixin:
method clean (line 54) | def clean(self):
class LoginForm (line 63) | class LoginForm(forms.Form):
method __init__ (line 69) | def __init__(self, *args, **kwargs) -> None:
method _get_login_field_placeholder (line 103) | def _get_login_field_placeholder(self):
method _setup_password_field (line 125) | def _setup_password_field(self):
method user_credentials (line 148) | def user_credentials(self) -> dict:
method clean_login (line 172) | def clean_login(self) -> str:
method clean (line 176) | def clean(self):
method _clean_without_password (line 187) | def _clean_without_password(self, email: str | None, phone: str | None):
method _clean_with_password (line 210) | def _clean_with_password(self, credentials: dict):
method login (line 226) | def login(self, request, redirect_url=None):
method _login_by_code (line 232) | def _login_by_code(self, request, redirect_url, credentials):
method _login_with_password (line 248) | def _login_with_password(self, request, redirect_url, credentials):
class BaseSignupForm (line 262) | class BaseSignupForm(base_signup_form_class()): # type: ignore[misc]
method __init__ (line 272) | def __init__(self, *args, **kwargs) -> None:
method _get_signup_fields (line 332) | def _get_signup_fields(self, kwargs):
method clean_username (line 353) | def clean_username(self) -> str:
method clean_email (line 364) | def clean_email(self) -> str:
method clean_email2 (line 371) | def clean_email2(self) -> str:
method validate_unique_email (line 375) | def validate_unique_email(self, value) -> str:
method clean (line 381) | def clean(self) -> dict:
method _clean_phone (line 393) | def _clean_phone(self):
method custom_signup (line 408) | def custom_signup(self, request, user) -> None:
method try_save (line 411) | def try_save(self, request):
method save (line 430) | def save(self, request):
class SignupForm (line 443) | class SignupForm(BaseSignupForm):
method __init__ (line 444) | def __init__(self, *args, **kwargs) -> None:
method try_save (line 479) | def try_save(self, request):
method clean (line 498) | def clean(self) -> dict:
class UserForm (line 528) | class UserForm(forms.Form):
method __init__ (line 529) | def __init__(self, user=None, *args, **kwargs) -> None:
class AddEmailForm (line 534) | class AddEmailForm(UserForm):
method clean_email (line 537) | def clean_email(self) -> str:
method save (line 570) | def save(self, request):
class ChangePasswordForm (line 588) | class ChangePasswordForm(PasswordVerificationMixin, UserForm):
method __init__ (line 595) | def __init__(self, *args, **kwargs):
method clean_oldpassword (line 599) | def clean_oldpassword(self) -> str:
method save (line 604) | def save(self) -> None:
class SetPasswordForm (line 608) | class SetPasswordForm(PasswordVerificationMixin, UserForm):
method __init__ (line 612) | def __init__(self, *args, **kwargs):
method save (line 616) | def save(self) -> None:
class ResetPasswordForm (line 620) | class ResetPasswordForm(forms.Form):
method clean_email (line 623) | def clean_email(self) -> str:
method save (line 631) | def save(self, request, **kwargs) -> str:
class ResetPasswordKeyForm (line 647) | class ResetPasswordKeyForm(PasswordVerificationMixin, forms.Form):
method __init__ (line 651) | def __init__(self, *args, **kwargs):
method save (line 657) | def save(self) -> None:
class UserTokenForm (line 661) | class UserTokenForm(forms.Form):
method _get_user (line 668) | def _get_user(self, uidb36):
method clean (line 676) | def clean(self):
class ReauthenticateForm (line 694) | class ReauthenticateForm(forms.Form):
method __init__ (line 697) | def __init__(self, *args, **kwargs) -> None:
method clean_password (line 701) | def clean_password(self) -> str:
class RequestLoginCodeForm (line 708) | class RequestLoginCodeForm(forms.Form):
method __init__ (line 711) | def __init__(self, *args, **kwargs) -> None:
method clean (line 726) | def clean(self):
method clean_phone (line 735) | def clean_phone(self) -> str:
method clean_email (line 748) | def clean_email(self) -> str:
class BaseConfirmCodeForm (line 764) | class BaseConfirmCodeForm(forms.Form):
method __init__ (line 772) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 776) | def clean_code(self) -> str:
class ConfirmLoginCodeForm (line 783) | class ConfirmLoginCodeForm(BaseConfirmCodeForm):
class ConfirmEmailVerificationCodeForm (line 787) | class ConfirmEmailVerificationCodeForm(BaseConfirmCodeForm):
method __init__ (line 788) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 793) | def clean_code(self) -> str:
class ConfirmPasswordResetCodeForm (line 801) | class ConfirmPasswordResetCodeForm(BaseConfirmCodeForm):
class VerifyPhoneForm (line 805) | class VerifyPhoneForm(BaseConfirmCodeForm):
method __init__ (line 806) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 811) | def clean_code(self) -> str:
class ChangePhoneForm (line 819) | class ChangePhoneForm(forms.Form):
method __init__ (line 820) | def __init__(self, *args, **kwargs) -> None:
method clean_phone (line 827) | def clean_phone(self) -> str:
class ChangeEmailForm (line 836) | class ChangeEmailForm(forms.Form):
method __init__ (line 839) | def __init__(self, *args, **kwargs) -> None:
method clean_email (line 843) | def clean_email(self) -> str:
FILE: allauth/account/internal/constants.py
class LoginStageKey (line 4) | class LoginStageKey(str, Enum):
FILE: allauth/account/internal/decorators.py
function _dummy_login_not_required (line 12) | def _dummy_login_not_required(view_func):
function login_stage_required (line 21) | def login_stage_required(stage: str, redirect_urlname: str):
FILE: allauth/account/internal/emailkit.py
function valid_email_or_none (line 8) | def valid_email_or_none(email: str | None) -> str | None:
FILE: allauth/account/internal/flows/code_verification.py
class AbstractCodeVerificationProcess (line 10) | class AbstractCodeVerificationProcess(abc.ABC):
method __init__ (line 11) | def __init__(
method user (line 24) | def user(self):
method code (line 35) | def code(self):
method initial_state (line 39) | def initial_state(cls, user, email: str | None = None, phone: str | No...
method record_invalid_attempt (line 54) | def record_invalid_attempt(self) -> bool:
method abort_if_invalid (line 62) | def abort_if_invalid(self):
method is_valid (line 68) | def is_valid(self) -> bool:
method persist (line 72) | def persist(self): ... # noqa: E704
method send (line 75) | def send(self): ... # noqa: E704
method abort (line 78) | def abort(self): ... # noqa: E704
method is_resend_quota_reached (line 80) | def is_resend_quota_reached(self, quota: int) -> bool:
method is_change_quota_reached (line 83) | def is_change_quota_reached(self, quota: int) -> bool:
method record_change (line 86) | def record_change(
method record_resend (line 95) | def record_resend(self):
method can_resend (line 99) | def can_resend(self) -> bool:
method can_change (line 103) | def can_change(self) -> bool:
FILE: allauth/account/internal/flows/email_verification.py
function verify_email_indirectly (line 22) | def verify_email_indirectly(
function verify_email_and_resume (line 35) | def verify_email_and_resume(
function verify_email (line 45) | def verify_email(request: HttpRequest, email_address: EmailAddress) -> b...
function get_email_verification_url (line 92) | def get_email_verification_url(request: HttpRequest, emailconfirmation) ...
function login_on_verification (line 106) | def login_on_verification(request, email_address) -> HttpResponse | None:
function consume_email_verification_rate_limit (line 148) | def consume_email_verification_rate_limit(
function handle_verification_email_rate_limit (line 167) | def handle_verification_email_rate_limit(
function get_address_for_user (line 188) | def get_address_for_user(user: AbstractBaseUser) -> EmailAddress | None:
function get_address_for_login (line 199) | def get_address_for_login(login: Login):
function send_verification_email_for_user (line 213) | def send_verification_email_for_user(
function send_verification_email_to_address (line 225) | def send_verification_email_to_address(
function send_verification_email_at_login (line 279) | def send_verification_email_at_login(request: HttpRequest, login: Login)...
function send_verification_email_at_real_login (line 296) | def send_verification_email_at_real_login(request: HttpRequest, login: L...
function send_verification_email_at_fake_login (line 309) | def send_verification_email_at_fake_login(request: HttpRequest, login: L...
function add_email_verification_sent_message (line 322) | def add_email_verification_sent_message(request: HttpRequest, email: str...
function is_verification_rate_limited (line 331) | def is_verification_rate_limited(request: HttpRequest, login: Login) -> ...
function mark_email_address_as_verified (line 354) | def mark_email_address_as_verified(
FILE: allauth/account/internal/flows/email_verification_by_code.py
class EmailVerificationProcess (line 19) | class EmailVerificationProcess(AbstractCodeVerificationProcess):
method __init__ (line 20) | def __init__(self, request, state: dict, user=None) -> None:
method email (line 30) | def email(self) -> str:
method persist (line 33) | def persist(self) -> None:
method abort (line 36) | def abort(self) -> None:
method send (line 40) | def send(self, skip_enumeration_mails: bool = False) -> None:
method email_address (line 58) | def email_address(self) -> EmailAddress:
method finish (line 68) | def finish(self) -> EmailAddress | None:
method generate_code (line 78) | def generate_code(self) -> None:
method initiate (line 82) | def initiate(cls, *, request, user, email: str) -> "EmailVerificationP...
method resume (line 91) | def resume(cls, request) -> Optional["EmailVerificationProcess"]:
method can_change (line 101) | def can_change(self) -> bool:
method change_to (line 113) | def change_to(self, email: str, account_already_exists: bool) -> None:
method can_resend (line 128) | def can_resend(self) -> bool:
method resend (line 133) | def resend(self) -> None:
method key (line 140) | def key(self):
FILE: allauth/account/internal/flows/login.py
function record_authentication (line 19) | def record_authentication(request, user, method: str, **extra_data) -> N...
function _get_login_hook_kwargs (line 60) | def _get_login_hook_kwargs(login: Login) -> dict[str, Any]:
function perform_password_login (line 74) | def perform_password_login(
function perform_login (line 86) | def perform_login(request: HttpRequest, login: Login) -> HttpResponse:
function resume_login (line 96) | def resume_login(request: HttpRequest, login: Login) -> HttpResponse:
function is_login_rate_limited (line 120) | def is_login_rate_limited(request, login: Login) -> bool:
function derive_login_method (line 130) | def derive_login_method(login: str) -> LoginMethod:
FILE: allauth/account/internal/flows/login_by_code.py
class LoginCodeVerificationProcess (line 20) | class LoginCodeVerificationProcess(AbstractCodeVerificationProcess):
method __init__ (line 21) | def __init__(self, stage):
method finish (line 31) | def finish(self, redirect_url: str | None):
method abort (line 55) | def abort(self) -> None:
method persist (line 58) | def persist(self) -> None:
method send (line 61) | def send(self, skip_enumeration_mails: bool = False) -> None:
method generate_code (line 71) | def generate_code(self) -> str:
method send_by_phone (line 86) | def send_by_phone(self, phone: str, skip_enumeration_mails: bool = Fal...
method send_by_email (line 98) | def send_by_email(self, email: str, skip_enumeration_mails: bool = Fal...
method add_sent_message (line 114) | def add_sent_message(self, context) -> None:
method initiate (line 123) | def initiate(
method resume (line 147) | def resume(cls, stage):
method can_resend (line 152) | def can_resend(self) -> bool:
method resend (line 157) | def resend(self) -> None:
FILE: allauth/account/internal/flows/logout.py
function logout (line 10) | def logout(request: HttpRequest, *, show_message: bool = True) -> None:
FILE: allauth/account/internal/flows/manage_email.py
function can_delete_email (line 14) | def can_delete_email(email_address: EmailAddress) -> bool:
function delete_email (line 19) | def delete_email(request: HttpRequest, email_address: EmailAddress) -> b...
function add_email (line 55) | def add_email(request: HttpRequest, form) -> None:
function can_mark_as_primary (line 69) | def can_mark_as_primary(email_address: EmailAddress) -> bool:
function mark_as_primary (line 80) | def mark_as_primary(request: HttpRequest, email_address: EmailAddress) -...
function emit_email_changed (line 112) | def emit_email_changed(
function assess_unique_email (line 137) | def assess_unique_email(
function list_email_addresses (line 184) | def list_email_addresses(
function email_already_exists (line 205) | def email_already_exists(
function sync_user_email_address (line 229) | def sync_user_email_address(user: AbstractBaseUser) -> EmailAddress | None:
function sync_email_address (line 243) | def sync_email_address(user: AbstractBaseUser, email: str) -> EmailAddre...
FILE: allauth/account/internal/flows/password_change.py
function change_password (line 11) | def change_password(user: AbstractBaseUser, password: str) -> None:
function finalize_password_change (line 15) | def finalize_password_change(request: HttpRequest, user: AbstractBaseUse...
function finalize_password_set (line 32) | def finalize_password_set(request: HttpRequest, user: AbstractBaseUser) ...
function logout_on_password_change (line 45) | def logout_on_password_change(request: HttpRequest, user: AbstractBaseUs...
FILE: allauth/account/internal/flows/password_reset.py
function reset_password (line 18) | def reset_password(user: AbstractBaseUser, password: str) -> None:
function perform_password_reset_login (line 22) | def perform_password_reset_login(
function finalize_password_reset (line 38) | def finalize_password_reset(
function get_reset_password_url (line 64) | def get_reset_password_url(request: HttpRequest) -> str:
function get_reset_password_from_key_url (line 71) | def get_reset_password_from_key_url(request: HttpRequest, key: str) -> str:
function request_password_reset (line 89) | def request_password_reset(request, email: str, users, token_generator) ...
FILE: allauth/account/internal/flows/password_reset_by_code.py
class PasswordResetVerificationProcess (line 20) | class PasswordResetVerificationProcess(AbstractCodeVerificationProcess):
method __init__ (line 21) | def __init__(self, request, state, user=None):
method abort (line 30) | def abort(self):
method confirm_code (line 33) | def confirm_code(self):
method finish (line 40) | def finish(self) -> HttpResponse | None:
method persist (line 46) | def persist(self):
method send (line 49) | def send(self):
method initiate (line 64) | def initiate(cls, *, request, user, email: str):
method resume (line 72) | def resume(
FILE: allauth/account/internal/flows/phone_verification.py
function verify_phone_indirectly (line 23) | def verify_phone_indirectly(request: HttpRequest, user, phone: str) -> N...
class PhoneVerificationProcess (line 27) | class PhoneVerificationProcess(AbstractCodeVerificationProcess):
method __init__ (line 28) | def __init__(self, user, state):
method phone (line 37) | def phone(self) -> str:
method send (line 40) | def send(self, skip_enumeration_sms: bool = False) -> None:
method send_sms (line 65) | def send_sms(self, skip_enumeration_sms: bool) -> None:
method finish (line 80) | def finish(self) -> None:
class PhoneVerificationStageProcess (line 92) | class PhoneVerificationStageProcess(PhoneVerificationProcess):
method __init__ (line 93) | def __init__(self, stage):
method abort (line 97) | def abort(self):
method persist (line 100) | def persist(self):
method initiate (line 104) | def initiate(cls, *, stage, phone: str):
method resume (line 112) | def resume(cls, stage) -> Optional["PhoneVerificationStageProcess"]:
method change_to (line 119) | def change_to(self, phone: str, account_already_exists: bool) -> None:
method resend (line 128) | def resend(self):
method can_resend (line 133) | def can_resend(self) -> bool:
method can_change (line 139) | def can_change(self) -> bool:
class ChangePhoneVerificationProcess (line 152) | class ChangePhoneVerificationProcess(PhoneVerificationProcess):
method __init__ (line 153) | def __init__(self, request: HttpRequest, state: dict):
method abort (line 160) | def abort(self):
method persist (line 163) | def persist(self):
method finish (line 166) | def finish(self):
method initiate (line 171) | def initiate(cls, request: HttpRequest, phone: str):
method resume (line 181) | def resume(cls, request: HttpRequest) -> Optional["ChangePhoneVerifica...
function phone_already_exists (line 189) | def phone_already_exists(user, phone: str, always_raise: bool = False) -...
FILE: allauth/account/internal/flows/reauthentication.py
function reauthenticate_by_password (line 21) | def reauthenticate_by_password(request: HttpRequest) -> None:
function stash_and_reauthenticate (line 27) | def stash_and_reauthenticate(
function suspend_request (line 37) | def suspend_request(request: HttpRequest, redirect_to: str) -> HttpRespo...
function resume_request (line 46) | def resume_request(request: HttpRequest) -> HttpResponseRedirect | None:
function raise_if_reauthentication_required (line 65) | def raise_if_reauthentication_required(request: HttpRequest) -> None:
function did_recently_authenticate (line 70) | def did_recently_authenticate(request: HttpRequest) -> bool:
function get_reauthentication_flows (line 88) | def get_reauthentication_flows(user) -> list[dict]:
FILE: allauth/account/internal/flows/signup.py
class DummyCustomSignupForm (line 17) | class DummyCustomSignupForm(forms.Form):
method signup (line 18) | def signup(self, request, user) -> None:
function base_signup_form_class (line 25) | def base_signup_form_class():
function prevent_enumeration (line 65) | def prevent_enumeration(
function send_unknown_account_mail (line 72) | def send_unknown_account_mail(request: HttpRequest, email: str) -> None:
function get_signup_url (line 83) | def get_signup_url(request: HttpRequest) -> str:
function complete_signup (line 90) | def complete_signup(
FILE: allauth/account/internal/stagekit.py
function get_pending_stage (line 14) | def get_pending_stage(request) -> LoginStage | None:
function redirect_to_pending_stage (line 24) | def redirect_to_pending_stage(request, stage: LoginStage):
function clear_login (line 31) | def clear_login(request) -> None:
function unstash_login (line 35) | def unstash_login(request, peek: bool = False):
function stash_login (line 55) | def stash_login(request, login) -> None:
FILE: allauth/account/internal/userkit.py
function user_id_to_str (line 11) | def user_id_to_str(user) -> str:
function str_to_user_id (line 15) | def str_to_user_id(value: str):
function user_field (line 19) | def user_field(user, field, *args, commit=False):
function did_user_login (line 48) | def did_user_login(user: AbstractBaseUser) -> bool:
function default_user_display (line 55) | def default_user_display(user) -> str:
function user_display (line 62) | def user_display(user) -> str:
function user_username (line 70) | def user_username(user, *args, commit=False):
function user_email (line 76) | def user_email(user, *args, commit=False):
FILE: allauth/account/management/commands/account_unsetmultipleprimaryemails.py
class Command (line 9) | class Command(BaseCommand):
method handle (line 10) | def handle(self, *args, **options):
method get_users_with_multiple_primary_email (line 14) | def get_users_with_multiple_primary_email(self):
method unprimary_extra_primary_emails (line 25) | def unprimary_extra_primary_emails(self, user):
FILE: allauth/account/managers.py
class EmailAddressManager (line 18) | class EmailAddressManager(models.Manager["EmailAddress"]):
method can_add_email (line 19) | def can_add_email(self, user) -> bool:
method get_new (line 31) | def get_new(self, user):
method add_new_email (line 37) | def add_new_email(
method add_email (line 58) | def add_email(self, request, user, email, confirm=False, signup=False):
method get_verified (line 73) | def get_verified(self, user):
method get_primary (line 76) | def get_primary(self, user):
method get_primary_email (line 82) | def get_primary_email(self, user) -> str | None:
method get_users_for (line 92) | def get_users_for(self, email):
method fill_cache_for_user (line 99) | def fill_cache_for_user(self, user, addresses) -> None:
method get_for_user (line 108) | def get_for_user(self, user, email):
method is_verified (line 124) | def is_verified(self, email: str) -> bool:
method lookup (line 127) | def lookup(self, emails):
class EmailConfirmationManager (line 131) | class EmailConfirmationManager(models.Manager):
method all_expired (line 132) | def all_expired(self):
method all_valid (line 135) | def all_valid(self):
method expired_q (line 138) | def expired_q(self):
method delete_expired_confirmations (line 144) | def delete_expired_confirmations(self) -> None:
FILE: allauth/account/middleware.py
function AccountMiddleware (line 18) | def AccountMiddleware(get_response):
function _should_redirect_accounts (line 53) | def _should_redirect_accounts(request, response) -> bool:
function _async_get_user (line 81) | def _async_get_user(request):
function _aredirect_accounts (line 85) | async def _aredirect_accounts(request) -> HttpResponseRedirect:
function _redirect_accounts (line 96) | def _redirect_accounts(request) -> HttpResponseRedirect:
FILE: allauth/account/migrations/0001_initial.py
class Migration (line 9) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0002_email_max_length.py
class Migration (line 9) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0003_alter_emailaddress_create_unique_verified_email.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0004_alter_emailaddress_drop_unique_email.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0005_emailaddress_idx_upper_email.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0006_emailaddress_lower.py
function forwards (line 8) | def forwards(apps, schema_editor):
class Migration (line 21) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0007_emailaddress_idx_email.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0008_emailaddress_unique_primary_email_fixup.py
function forwards (line 6) | def forwards(apps, schema_editor):
class Migration (line 39) | class Migration(migrations.Migration):
FILE: allauth/account/migrations/0009_emailaddress_unique_primary_email.py
class Migration (line 6) | class Migration(migrations.Migration):
FILE: allauth/account/mixins.py
function _ajax_response (line 25) | def _ajax_response(request, response, form=None, data=None):
class RedirectAuthenticatedUserMixin (line 40) | class RedirectAuthenticatedUserMixin:
method dispatch (line 43) | def dispatch(self, request, *args, **kwargs):
method get_authenticated_redirect_url (line 56) | def get_authenticated_redirect_url(self):
class LogoutFunctionalityMixin (line 65) | class LogoutFunctionalityMixin:
method logout (line 66) | def logout(self):
class AjaxCapableProcessFormViewMixin (line 70) | class AjaxCapableProcessFormViewMixin:
method get (line 71) | def get(self, request, *args, **kwargs):
method post (line 78) | def post(self, request, *args, **kwargs):
method get_form (line 89) | def get_form(self, form_class=None):
method _get_ajax_data_if (line 96) | def _get_ajax_data_if(self):
method get_ajax_data (line 103) | def get_ajax_data(self):
class CloseableSignupMixin (line 107) | class CloseableSignupMixin:
method dispatch (line 112) | def dispatch(self, request, *args, **kwargs):
method is_open (line 120) | def is_open(self):
method closed (line 123) | def closed(self):
class NextRedirectMixin (line 131) | class NextRedirectMixin:
method get_context_data (line 134) | def get_context_data(self, **kwargs):
method get_success_url (line 154) | def get_success_url(self):
method get_default_success_url (line 184) | def get_default_success_url(self):
method get_next_url (line 187) | def get_next_url(self):
method passthrough_next_url (line 190) | def passthrough_next_url(self, url):
FILE: allauth/account/models.py
class EmailAddress (line 26) | class EmailAddress(models.Model):
class Meta (line 42) | class Meta:
method __str__ (line 62) | def __str__(self) -> str:
method clean (line 65) | def clean(self) -> None:
method can_set_verified (line 69) | def can_set_verified(self) -> bool:
method set_verified (line 81) | def set_verified(self, commit: bool = True) -> bool:
method set_as_primary (line 90) | def set_as_primary(self, conditional: bool = False) -> bool:
method send_confirmation (line 107) | def send_confirmation(
method remove (line 115) | def remove(self) -> None:
class EmailConfirmationMixin (line 131) | class EmailConfirmationMixin:
method confirm (line 132) | def confirm(self, request: HttpRequest) -> EmailAddress | None:
method send (line 140) | def send(self, request: HttpRequest | None = None, signup: bool = Fals...
class EmailConfirmation (line 144) | class EmailConfirmation(EmailConfirmationMixin, models.Model):
class Meta (line 156) | class Meta:
method __str__ (line 160) | def __str__(self) -> str:
method create (line 164) | def create(cls, email_address: EmailAddress) -> EmailConfirmation:
method from_key (line 169) | def from_key(cls, key: str) -> EmailConfirmation | None:
method key_expired (line 175) | def key_expired(self) -> bool:
method confirm (line 184) | def confirm(self, request: HttpRequest) -> EmailAddress | None:
method send (line 189) | def send(self, request: HttpRequest | None = None, signup: bool = Fals...
class EmailConfirmationHMAC (line 195) | class EmailConfirmationHMAC(EmailConfirmationMixin):
method __init__ (line 196) | def __init__(self, email_address: EmailAddress) -> None:
method create (line 200) | def create(cls, email_address: EmailAddress) -> EmailConfirmationHMAC:
method key (line 204) | def key(self) -> str:
method from_key (line 208) | def from_key(cls, key: str) -> EmailConfirmationHMAC | None:
method key_expired (line 221) | def key_expired(self) -> bool:
class _SerializedLogin (line 225) | class _SerializedLogin(TypedDict):
class Login (line 237) | class Login:
method __init__ (line 260) | def __init__(
method serialize (line 284) | def serialize(self) -> _SerializedLogin:
method deserialize (line 309) | def deserialize(cls, data: dict[str, Any]) -> Login:
function get_emailconfirmation_model (line 344) | def get_emailconfirmation_model() -> (
FILE: allauth/account/stages.py
class LoginStage (line 19) | class LoginStage:
method __init__ (line 24) | def __init__(self, controller, request, login):
method handle (line 36) | def handle(self):
method exit (line 39) | def exit(self):
method abort (line 45) | def abort(self):
method is_resumable (line 51) | def is_resumable(self, request):
class LoginStageController (line 55) | class LoginStageController:
method __init__ (line 56) | def __init__(self, request, login):
method enter (line 62) | def enter(cls, request, stage_key):
method set_current (line 77) | def set_current(self, stage_key):
method is_handled (line 80) | def is_handled(self, stage_key):
method set_handled (line 83) | def set_handled(self, stage_key):
method get_pending_stage (line 87) | def get_pending_stage(self) -> LoginStage | None:
method get_stage (line 97) | def get_stage(self, key: str) -> LoginStage | None:
method get_stages (line 103) | def get_stages(self) -> list[LoginStage]:
method handle (line 113) | def handle(self):
class EmailVerificationStage (line 138) | class EmailVerificationStage(LoginStage):
method is_resumable (line 142) | def is_resumable(self, request):
method handle (line 145) | def handle(self):
class LoginByCodeStage (line 166) | class LoginByCodeStage(LoginStage):
method handle (line 170) | def handle(self):
method _is_trusted (line 205) | def _is_trusted(self) -> bool:
class PhoneVerificationStage (line 218) | class PhoneVerificationStage(LoginStage):
method handle (line 222) | def handle(self):
FILE: allauth/account/static/account/js/account.js
function manageEmailForm (line 4) | function manageEmailForm (o) {
FILE: allauth/account/templatetags/account.py
function user_display_tag (line 10) | def user_display_tag(user):
FILE: allauth/account/utils.py
function _unicode_ci_compare (line 23) | def _unicode_ci_compare(s1: str, s2: str) -> bool:
function get_next_redirect_url (line 34) | def get_next_redirect_url(
function get_login_redirect_url (line 47) | def get_login_redirect_url(
function has_verified_email (line 65) | def has_verified_email(user, email=None) -> bool:
function perform_login (line 81) | def perform_login(
function complete_signup (line 101) | def complete_signup(request, user, email_verification, success_url, sign...
function cleanup_email_addresses (line 111) | def cleanup_email_addresses(request, addresses):
function setup_user_email (line 184) | def setup_user_email(request, user, addresses):
function filter_users_by_username (line 221) | def filter_users_by_username(*username):
function filter_users_by_email (line 242) | def filter_users_by_email(
function passthrough_next_redirect_url (line 284) | def passthrough_next_redirect_url(request, url: str, redirect_field_name...
function user_pk_to_url_str (line 291) | def user_pk_to_url_str(user) -> str:
function url_str_to_user_pk (line 306) | def url_str_to_user_pk(pk_str):
FILE: allauth/account/views.py
class LoginView (line 80) | class LoginView(
method dispatch (line 94) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_form_kwargs (line 99) | def get_form_kwargs(self) -> dict:
method get_form_class (line 104) | def get_form_class(self):
method form_valid (line 107) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 114) | def get_context_data(self, **kwargs) -> dict:
class SignupView (line 152) | class SignupView(
method dispatch (line 166) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_form_class (line 169) | def get_form_class(self):
method form_valid (line 172) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 187) | def get_context_data(self, **kwargs) -> dict:
method get_initial (line 223) | def get_initial(self) -> dict:
class SignupByPasskeyView (line 240) | class SignupByPasskeyView(SignupView):
method get_form_kwargs (line 243) | def get_form_kwargs(self) -> dict:
class ConfirmEmailView (line 253) | class ConfirmEmailView(NextRedirectMixin, LogoutFunctionalityMixin, Temp...
method get (line 256) | def get(self, *args, **kwargs) -> HttpResponse:
method logout_other_user (line 272) | def logout_other_user(self, confirmation) -> None:
method post (line 284) | def post(self, *args, **kwargs) -> HttpResponse:
method respond (line 297) | def respond(self, success):
method get_object (line 304) | def get_object(self, queryset=None):
method get_queryset (line 312) | def get_queryset(self):
method get_ajax_data (line 317) | def get_ajax_data(self) -> dict:
method get_context_data (line 326) | def get_context_data(self, **kwargs) -> dict:
method get_redirect_url (line 341) | def get_redirect_url(self) -> str:
class EmailView (line 355) | class EmailView(AjaxCapableProcessFormViewMixin, FormView):
method get_form_class (line 364) | def get_form_class(self):
method dispatch (line 367) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_form_kwargs (line 372) | def get_form_kwargs(self) -> dict:
method form_valid (line 377) | def form_valid(self, form) -> HttpResponse:
method post (line 382) | def post(self, request, *args, **kwargs) -> HttpResponse:
method _get_email_address (line 404) | def _get_email_address(self, request):
method _action_send (line 415) | def _action_send(self, request, *args, **kwargs):
method _action_remove (line 429) | def _action_remove(self, request, *args, **kwargs):
method _action_primary (line 435) | def _action_primary(self, request, *args, **kwargs):
method get_context_data (line 441) | def get_context_data(self, **kwargs):
method get_ajax_data (line 472) | def get_ajax_data(self):
method get_success_url (line 485) | def get_success_url(self):
class PasswordChangeView (line 499) | class PasswordChangeView(AjaxCapableProcessFormViewMixin, NextRedirectMi...
method get_form_class (line 503) | def get_form_class(self):
method dispatch (line 507) | def dispatch(self, request, *args, **kwargs):
method get_form_kwargs (line 512) | def get_form_kwargs(self) -> dict:
method get_default_success_url (line 517) | def get_default_success_url(self):
method form_valid (line 520) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 525) | def get_context_data(self, **kwargs) -> dict:
class PasswordSetView (line 543) | class PasswordSetView(AjaxCapableProcessFormViewMixin, NextRedirectMixin...
method get_form_class (line 547) | def get_form_class(self):
method dispatch (line 551) | def dispatch(self, request, *args, **kwargs):
method get_form_kwargs (line 556) | def get_form_kwargs(self) -> dict:
method get_default_success_url (line 561) | def get_default_success_url(self):
method form_valid (line 564) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 569) | def get_context_data(self, **kwargs) -> dict:
class PasswordResetView (line 581) | class PasswordResetView(NextRedirectMixin, AjaxCapableProcessFormViewMix...
method get_success_url (line 586) | def get_success_url(self) -> str:
method get_form_class (line 591) | def get_form_class(self):
method form_valid (line 594) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 605) | def get_context_data(self, **kwargs) -> dict:
class PasswordResetDoneView (line 619) | class PasswordResetDoneView(TemplateView):
class PasswordResetFromKeyView (line 628) | class PasswordResetFromKeyView(
method get_form_class (line 639) | def get_form_class(self):
method dispatch (line 644) | def dispatch(self, request, uidb36, key, **kwargs) -> HttpResponseBase:
method get_context_data (line 688) | def get_context_data(self, **kwargs) -> dict:
method get_form_kwargs (line 699) | def get_form_kwargs(self) -> dict:
method form_valid (line 705) | def form_valid(self, form) -> HttpResponse:
class PasswordResetFromKeyDoneView (line 719) | class PasswordResetFromKeyDoneView(TemplateView):
class CompletePasswordResetView (line 730) | class CompletePasswordResetView(
method dispatch (line 738) | def dispatch(self, request, **kwargs) -> HttpResponseBase:
method get_form_class (line 752) | def get_form_class(self):
method get_context_data (line 757) | def get_context_data(self, **kwargs) -> dict:
method get_form_kwargs (line 762) | def get_form_kwargs(self):
method form_valid (line 767) | def form_valid(self, form):
class ConfirmPasswordResetCodeView (line 778) | class ConfirmPasswordResetCodeView(NextRedirectMixin, FormView):
method dispatch (line 785) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_form_class (line 797) | def get_form_class(self):
method get_form_kwargs (line 802) | def get_form_kwargs(self):
method get_context_data (line 807) | def get_context_data(self, **kwargs):
method form_valid (line 813) | def form_valid(self, form):
method form_invalid (line 819) | def form_invalid(self, form):
class LogoutView (line 835) | class LogoutView(NextRedirectMixin, LogoutFunctionalityMixin, TemplateVi...
method get (line 838) | def get(self, *args, **kwargs) -> HttpResponse:
method post (line 848) | def post(self, *args, **kwargs) -> HttpResponse:
method get_redirect_url (line 854) | def get_redirect_url(self) -> str:
class AccountInactiveView (line 864) | class AccountInactiveView(TemplateView):
class EmailVerificationSentView (line 872) | class EmailVerificationSentView(TemplateView):
class ConfirmEmailVerificationCodeView (line 876) | class ConfirmEmailVerificationCodeView(NextRedirectMixin, FormView):
method dispatch (line 882) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method _action (line 907) | def _action(self):
method get_form_class (line 918) | def get_form_class(self):
method _get_change_form_class (line 925) | def _get_change_form_class(self):
method _get_verify_form_class (line 928) | def _get_verify_form_class(self):
method get_form_kwargs (line 933) | def get_form_kwargs(self):
method get_context_data (line 943) | def get_context_data(self, **kwargs):
method form_valid (line 957) | def form_valid(self, form) -> HttpResponse:
method _resend_form_valid (line 964) | def _resend_form_valid(self, form):
method _change_form_valid (line 978) | def _change_form_valid(self, form):
method _verify_form_valid (line 984) | def _verify_form_valid(self, form):
method form_invalid (line 1001) | def form_invalid(self, form):
method _verify_form_invalid (line 1006) | def _verify_form_invalid(self, form):
function email_verification_sent (line 1020) | def email_verification_sent(request) -> HttpResponseBase:
class BaseReauthenticateView (line 1027) | class BaseReauthenticateView(NextRedirectMixin, FormView):
method dispatch (line 1028) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method _check_ratelimit (line 1037) | def _check_ratelimit(self, request):
method _check_reauthentication_method_available (line 1044) | def _check_reauthentication_method_available(self, request):
method get_default_success_url (line 1055) | def get_default_success_url(self):
method form_valid (line 1059) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 1065) | def get_context_data(self, **kwargs) -> dict:
method get_reauthentication_alternatives (line 1074) | def get_reauthentication_alternatives(self):
class ReauthenticateView (line 1088) | class ReauthenticateView(BaseReauthenticateView):
method get_form_class (line 1092) | def get_form_class(self):
method get_form_kwargs (line 1095) | def get_form_kwargs(self) -> dict:
method form_valid (line 1100) | def form_valid(self, form) -> HttpResponse:
class RequestLoginCodeView (line 1108) | class RequestLoginCodeView(RedirectAuthenticatedUserMixin, NextRedirectM...
method get_form_class (line 1112) | def get_form_class(self):
method form_valid (line 1115) | def form_valid(self, form) -> HttpResponse:
method get_success_url (line 1124) | def get_success_url(self):
method get_context_data (line 1131) | def get_context_data(self, **kwargs) -> dict:
function _login_by_code_urlname (line 1141) | def _login_by_code_urlname() -> str:
class ConfirmLoginCodeView (line 1157) | class ConfirmLoginCodeView(NextRedirectMixin, FormView):
method dispatch (line 1162) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method _action (line 1172) | def _action(self) -> str:
method get_form_class (line 1181) | def get_form_class(self):
method get_form_kwargs (line 1186) | def get_form_kwargs(self) -> dict:
method form_valid (line 1194) | def form_valid(self, form) -> HttpResponse:
method _resend_form_valid (line 1199) | def _resend_form_valid(self, form) -> HttpResponse:
method _verify_form_valid (line 1213) | def _verify_form_valid(self, form) -> HttpResponse:
method form_invalid (line 1217) | def form_invalid(self, form) -> HttpResponse:
method get_context_data (line 1235) | def get_context_data(self, **kwargs) -> dict:
class _BaseVerifyPhoneView (line 1255) | class _BaseVerifyPhoneView(NextRedirectMixin, FormView):
method _action (line 1262) | def _action(self):
method get_form_class (line 1273) | def get_form_class(self):
method _get_change_form_class (line 1280) | def _get_change_form_class(self):
method _get_verify_form_class (line 1283) | def _get_verify_form_class(self):
method get_form_kwargs (line 1286) | def get_form_kwargs(self):
method form_valid (line 1299) | def form_valid(self, form) -> HttpResponse:
method _resend_form_valid (line 1306) | def _resend_form_valid(self, form):
method _change_form_valid (line 1320) | def _change_form_valid(self, form):
method _verify_form_valid (line 1326) | def _verify_form_valid(self, form):
method form_invalid (line 1330) | def form_invalid(self, form) -> HttpResponse:
method _change_form_invalid (line 1335) | def _change_form_invalid(self, form):
method _verify_form_invalid (line 1338) | def _verify_form_invalid(self, form):
method get_context_data (line 1345) | def get_context_data(self, **kwargs):
class _VerifyPhoneSignupView (line 1372) | class _VerifyPhoneSignupView(_BaseVerifyPhoneView):
method dispatch (line 1374) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method respond_process_succeeded (line 1383) | def respond_process_succeeded(self, form):
method respond_process_failed (line 1386) | def respond_process_failed(self, form):
class _VerifyPhoneChangeView (line 1396) | class _VerifyPhoneChangeView(_BaseVerifyPhoneView):
method dispatch (line 1398) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method respond_process_succeeded (line 1406) | def respond_process_succeeded(self, form):
method respond_process_failed (line 1409) | def respond_process_failed(self, form):
method get_context_data (line 1412) | def get_context_data(self, **kwargs) -> dict:
function verify_phone (line 1419) | def verify_phone(request):
class ChangePhoneView (line 1427) | class ChangePhoneView(FormView):
method get_form_class (line 1432) | def get_form_class(self):
method get_form_kwargs (line 1435) | def get_form_kwargs(self) -> dict:
method form_valid (line 1452) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 1458) | def get_context_data(self, **kwargs) -> dict:
FILE: allauth/app_settings.py
class AppSettings (line 6) | class AppSettings:
method __init__ (line 7) | def __init__(self, prefix: str) -> None:
method _setting (line 10) | def _setting(self, name: str, dflt):
method SITES_ENABLED (line 16) | def SITES_ENABLED(self) -> bool:
method SOCIALACCOUNT_ENABLED (line 20) | def SOCIALACCOUNT_ENABLED(self) -> bool:
method SOCIALACCOUNT_ONLY (line 24) | def SOCIALACCOUNT_ONLY(self) -> bool:
method MFA_ENABLED (line 30) | def MFA_ENABLED(self) -> bool:
method USERSESSIONS_ENABLED (line 34) | def USERSESSIONS_ENABLED(self) -> bool:
method HEADLESS_ENABLED (line 38) | def HEADLESS_ENABLED(self) -> bool:
method HEADLESS_ONLY (line 42) | def HEADLESS_ONLY(self) -> bool:
method DEFAULT_AUTO_FIELD (line 48) | def DEFAULT_AUTO_FIELD(self):
method TRUSTED_PROXY_COUNT (line 52) | def TRUSTED_PROXY_COUNT(self) -> int:
method TRUSTED_CLIENT_IP_HEADER (line 62) | def TRUSTED_CLIENT_IP_HEADER(self) -> str | None:
method USER_CODE_FORMAT (line 72) | def USER_CODE_FORMAT(self) -> UserCodeFormat:
function __getattr__ (line 83) | def __getattr__(name):
FILE: allauth/core/context.py
function __getattr__ (line 8) | def __getattr__(name):
function request_context (line 15) | def request_context(request):
FILE: allauth/core/exceptions.py
class ImmediateHttpResponse (line 1) | class ImmediateHttpResponse(Exception):
method __init__ (line 7) | def __init__(self, response):
class ReauthenticationRequired (line 11) | class ReauthenticationRequired(Exception):
class SignupClosedException (line 20) | class SignupClosedException(Exception):
class RateLimited (line 28) | class RateLimited(Exception):
FILE: allauth/core/internal/adapter.py
class BaseAdapter (line 6) | class BaseAdapter:
method __init__ (line 7) | def __init__(self, request=None):
method validation_error (line 12) | def validation_error(self, code, *args):
FILE: allauth/core/internal/cryptokit.py
class UserCodeFormat (line 8) | class UserCodeFormat(TypedDict, total=False):
function generate_user_code (line 18) | def generate_user_code(
function _strip_punctuation (line 41) | def _strip_punctuation(code: str) -> str:
function compare_user_code (line 51) | def compare_user_code(*, actual: str, expected: str) -> bool:
FILE: allauth/core/internal/httpkit.py
function serialize_request (line 22) | def serialize_request(request):
function deserialize_request (line 36) | def deserialize_request(s, request):
function redirect (line 48) | def redirect(to):
function del_query_params (line 55) | def del_query_params(url: str, *params: str) -> str:
function add_query_params (line 74) | def add_query_params(url: str, params: dict) -> str:
function render_url (line 92) | def render_url(request, url_template, **kwargs):
function default_get_frontend_url (line 111) | def default_get_frontend_url(request, urlname, **kwargs):
function get_frontend_url (line 125) | def get_frontend_url(request, urlname, **kwargs):
function headed_redirect_response (line 135) | def headed_redirect_response(viewname, query=None):
function is_headless_request (line 152) | def is_headless_request(request: HttpRequest) -> str | None:
function get_authorization_credential (line 162) | def get_authorization_credential(request: HttpRequest, auth_scheme: str)...
function clean_client_ip (line 172) | def clean_client_ip(ip: str) -> str | None:
function get_client_ip_from_xff (line 192) | def get_client_ip_from_xff(request: HttpRequest) -> str | None:
function get_client_ip (line 207) | def get_client_ip(request: HttpRequest) -> str | None:
FILE: allauth/core/internal/jwkkit.py
function jwk_thumbprint (line 20) | def jwk_thumbprint(jwk_dict: dict) -> str:
function load_pem (line 33) | def load_pem(pem: str) -> RSAPrivateKey:
function load_jwk_from_pem (line 43) | def load_jwk_from_pem(pem: str) -> tuple[dict, RSAPrivateKey]:
FILE: allauth/core/internal/modelkit.py
function serialize_instance (line 16) | def serialize_instance(instance) -> dict:
function deserialize_instance (line 52) | def deserialize_instance(model, data):
FILE: allauth/core/internal/ratelimit.py
class SingleRateLimitUsage (line 32) | class SingleRateLimitUsage:
method rollback (line 37) | def rollback(self) -> None:
class RateLimitUsage (line 44) | class RateLimitUsage:
method rollback (line 47) | def rollback(self) -> None:
function parse_duration (line 52) | def parse_duration(duration) -> int | float:
function parse_rate (line 67) | def parse_rate(rate: str) -> Rate:
function parse_rates (line 81) | def parse_rates(rates: str | None) -> list[Rate]:
function get_cache_key (line 92) | def get_cache_key(request, *, action: str, rate: Rate, key=None, user=No...
function _consume_single_rate (line 119) | def _consume_single_rate(
function consume (line 149) | def consume(
function handler429 (line 184) | def handler429(request) -> HttpResponse:
function clear (line 208) | def clear(request, *, config: dict, action: str, key=None, user=None) ->...
FILE: allauth/core/internal/sessionkit.py
function get_session_user (line 6) | def get_session_user(session: SessionBase):
FILE: allauth/core/internal/urlkit.py
function script_aware_resolve (line 5) | def script_aware_resolve(path: str):
FILE: allauth/core/ratelimit.py
function clear (line 11) | def clear(request, *, action: str, key=None, user=None) -> None:
function consume (line 23) | def consume(
function respond_429 (line 53) | def respond_429(request) -> HttpResponse:
function consume_or_429 (line 67) | def consume_or_429(request, *args, **kwargs) -> HttpResponse | None:
FILE: allauth/decorators.py
function rate_limit (line 6) | def rate_limit(*, action, **rl_kwargs):
FILE: allauth/headless/account/inputs.py
class SignupInput (line 27) | class SignupInput(BaseSignupForm, inputs.Input):
method __init__ (line 30) | def __init__(self, *args, **kwargs):
method clean_password (line 38) | def clean_password(self):
class LoginInput (line 45) | class LoginInput(inputs.Input):
method __init__ (line 52) | def __init__(self, *args, **kwargs):
method clean (line 60) | def clean(self):
class VerifyEmailInput (line 90) | class VerifyEmailInput(inputs.Input):
method __init__ (line 93) | def __init__(self, *args, **kwargs):
method clean_key (line 97) | def clean_key(self):
class RequestPasswordResetInput (line 121) | class RequestPasswordResetInput(ResetPasswordForm, inputs.Input):
class ResetPasswordKeyInput (line 125) | class ResetPasswordKeyInput(inputs.Input):
method __init__ (line 128) | def __init__(self, *args, **kwargs):
method clean_key (line 133) | def clean_key(self):
method _clean_key_code (line 139) | def _clean_key_code(self):
method _clean_key_link (line 145) | def _clean_key_link(self):
class ResetPasswordInput (line 155) | class ResetPasswordInput(ResetPasswordKeyInput):
method clean (line 158) | def clean(self):
class ChangePasswordInput (line 169) | class ChangePasswordInput(inputs.Input):
method __init__ (line 173) | def __init__(self, *args, **kwargs):
method clean_current_password (line 178) | def clean_current_password(self):
method clean_new_password (line 185) | def clean_new_password(self):
class AddEmailInput (line 191) | class AddEmailInput(AddEmailForm, inputs.Input):
class SelectEmailInput (line 195) | class SelectEmailInput(inputs.Input):
method __init__ (line 198) | def __init__(self, *args, **kwargs):
method clean_email (line 202) | def clean_email(self):
class DeleteEmailInput (line 228) | class DeleteEmailInput(SelectEmailInput):
method clean_email (line 229) | def clean_email(self):
class MarkAsPrimaryEmailInput (line 236) | class MarkAsPrimaryEmailInput(SelectEmailInput):
method clean_email (line 239) | def clean_email(self):
class ResendEmailVerificationInput (line 246) | class ResendEmailVerificationInput(SelectEmailInput):
class ReauthenticateInput (line 250) | class ReauthenticateInput(ReauthenticateForm, inputs.Input):
class RequestLoginCodeInput (line 254) | class RequestLoginCodeInput(RequestLoginCodeForm, inputs.Input):
class ConfirmLoginCodeInput (line 258) | class ConfirmLoginCodeInput(ConfirmLoginCodeForm, inputs.Input):
class VerifyPhoneInput (line 262) | class VerifyPhoneInput(VerifyPhoneForm, inputs.Input):
class ChangePhoneInput (line 266) | class ChangePhoneInput(ChangePhoneForm, inputs.Input):
class ChangeEmailInput (line 270) | class ChangeEmailInput(ChangeEmailForm, inputs.Input):
FILE: allauth/headless/account/response.py
function email_address_data (line 7) | def email_address_data(addr) -> dict:
class RequestEmailVerificationResponse (line 15) | class RequestEmailVerificationResponse(APIResponse):
method __init__ (line 16) | def __init__(self, request, verification_sent):
class VerifyEmailResponse (line 22) | class VerifyEmailResponse(APIResponse):
method __init__ (line 23) | def __init__(self, request, email_address, stage):
class EmailAddressesResponse (line 35) | class EmailAddressesResponse(APIResponse):
method __init__ (line 36) | def __init__(self, request, email_addresses):
class PhoneNumbersResponse (line 41) | class PhoneNumbersResponse(APIResponse):
method __init__ (line 42) | def __init__(self, request, phone_numbers, status=HTTPStatus.OK):
class RequestPasswordResponse (line 46) | class RequestPasswordResponse(APIResponse):
class PasswordResetKeyResponse (line 50) | class PasswordResetKeyResponse(APIResponse):
method __init__ (line 51) | def __init__(self, request, user):
FILE: allauth/headless/account/urls.py
function build_urlpatterns (line 8) | def build_urlpatterns(client):
FILE: allauth/headless/account/views.py
class RequestLoginCodeView (line 66) | class RequestLoginCodeView(APIView):
method post (line 69) | def post(self, request, *args, **kwargs):
class ResendLoginCodeView (line 79) | class ResendLoginCodeView(APIView):
method post (line 82) | def post(self, request, *args, **kwargs):
class ConfirmLoginCodeView (line 96) | class ConfirmLoginCodeView(APIView):
method dispatch (line 99) | def dispatch(self, request, *args, **kwargs):
method post (line 111) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 115) | def get_input_kwargs(self) -> dict:
method handle_invalid_input (line 120) | def handle_invalid_input(self, input):
class LoginView (line 126) | class LoginView(APIView):
method post (line 129) | def post(self, request, *args, **kwargs):
class SignupView (line 140) | class SignupView(APIView):
method post (line 144) | def post(self, request, *args, **kwargs):
class SessionView (line 160) | class SessionView(APIView):
method get (line 161) | def get(self, request, *args, **kwargs) -> HttpResponse:
method delete (line 164) | def delete(self, request, *args, **kwargs):
class VerifyEmailView (line 170) | class VerifyEmailView(APIView):
method handle (line 173) | def handle(self, request, *args, **kwargs):
method get_input_kwargs (line 192) | def get_input_kwargs(self) -> dict:
method handle_invalid_input (line 195) | def handle_invalid_input(self, input: VerifyEmailInput):
method get (line 200) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 213) | def post(self, request, *args, **kwargs):
class VerifyPhoneView (line 230) | class VerifyPhoneView(APIView):
method handle (line 233) | def handle(self, request, *args, **kwargs):
method get_input_kwargs (line 251) | def get_input_kwargs(self) -> dict:
method handle_invalid_input (line 258) | def handle_invalid_input(self, input: VerifyPhoneInput):
method post (line 262) | def post(self, request, *args, **kwargs):
class ResendPhoneVerificationCodeView (line 270) | class ResendPhoneVerificationCodeView(APIView):
method post (line 273) | def post(self, request, *args, **kwargs):
class ResendEmailVerificationCodeView (line 289) | class ResendEmailVerificationCodeView(APIView):
method post (line 292) | def post(self, request, *args, **kwargs):
class RequestPasswordResetView (line 307) | class RequestPasswordResetView(APIView):
method post (line 310) | def post(self, request, *args, **kwargs):
class ResetPasswordView (line 325) | class ResetPasswordView(APIView):
method handle_invalid_input (line 328) | def handle_invalid_input(self, input: ResetPasswordInput):
method handle (line 333) | def handle(self, request, *args, **kwargs):
method get (line 345) | def get(self, request, *args, **kwargs) -> HttpResponse:
method get_input_kwargs (line 360) | def get_input_kwargs(self) -> dict:
method post (line 366) | def post(self, request, *args, **kwargs):
class ChangePasswordView (line 378) | class ChangePasswordView(AuthenticatedAPIView):
method post (line 381) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 392) | def get_input_kwargs(self) -> dict:
class ManageEmailView (line 396) | class ManageEmailView(APIView):
method dispatch (line 404) | def dispatch(self, request, *args, **kwargs):
method get (line 423) | def get(self, request, *args, **kwargs) -> HttpResponse:
method _respond_email_list (line 426) | def _respond_email_list(self):
method post (line 430) | def post(self, request, *args, **kwargs):
method delete (line 440) | def delete(self, request, *args, **kwargs):
method patch (line 448) | def patch(self, request, *args, **kwargs):
method put (line 453) | def put(self, request, *args, **kwargs):
method get_input_class (line 469) | def get_input_class(self):
method get_input_kwargs (line 474) | def get_input_kwargs(self) -> dict:
class ManagePhoneView (line 480) | class ManagePhoneView(APIView):
method dispatch (line 483) | def dispatch(self, request, *args, **kwargs):
method get (line 506) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 515) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 537) | def get_input_kwargs(self) -> dict:
class ReauthenticateView (line 546) | class ReauthenticateView(AuthenticatedAPIView):
method post (line 549) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 553) | def get_input_kwargs(self) -> dict:
FILE: allauth/headless/adapter.py
class DefaultHeadlessAdapter (line 18) | class DefaultHeadlessAdapter(BaseAdapter):
method serialize_user (line 39) | def serialize_user(self, user) -> dict[str, Any]:
method get_frontend_url (line 55) | def get_frontend_url(self, urlname: str, **kwargs) -> str | None:
method user_as_dataclass (line 59) | def user_as_dataclass(self, user):
method get_user_dataclass (line 90) | def get_user_dataclass(self):
function get_adapter (line 146) | def get_adapter() -> DefaultHeadlessAdapter:
FILE: allauth/headless/app_settings.py
class AppSettings (line 1) | class AppSettings:
method __init__ (line 2) | def __init__(self, prefix: str) -> None:
method _setting (line 5) | def _setting(self, name: str, dflt):
method ADAPTER (line 11) | def ADAPTER(self) -> str:
method TOKEN_STRATEGY (line 17) | def TOKEN_STRATEGY(self):
method SERVE_SPECIFICATION (line 28) | def SERVE_SPECIFICATION(self) -> bool:
method SPECIFICATION_TEMPLATE_NAME (line 32) | def SPECIFICATION_TEMPLATE_NAME(self) -> str | None:
method CLIENTS (line 38) | def CLIENTS(self) -> tuple[str]:
method FRONTEND_URLS (line 42) | def FRONTEND_URLS(self) -> dict:
method JWT_ALGORITHM (line 46) | def JWT_ALGORITHM(self) -> str:
method JWT_PRIVATE_KEY (line 50) | def JWT_PRIVATE_KEY(self) -> str:
method JWT_ACCESS_TOKEN_EXPIRES_IN (line 54) | def JWT_ACCESS_TOKEN_EXPIRES_IN(self) -> int:
method JWT_REFRESH_TOKEN_EXPIRES_IN (line 58) | def JWT_REFRESH_TOKEN_EXPIRES_IN(self) -> int:
method JWT_AUTHORIZATION_HEADER_SCHEME (line 62) | def JWT_AUTHORIZATION_HEADER_SCHEME(self) -> str:
method JWT_STATEFUL_VALIDATION_ENABLED (line 66) | def JWT_STATEFUL_VALIDATION_ENABLED(self) -> bool:
method JWT_ROTATE_REFRESH_TOKEN (line 70) | def JWT_ROTATE_REFRESH_TOKEN(self) -> bool:
function __getattr__ (line 77) | def __getattr__(name):
FILE: allauth/headless/apps.py
class HeadlessConfig (line 5) | class HeadlessConfig(AppConfig):
method ready (line 9) | def ready(self):
FILE: allauth/headless/base/response.py
class BaseAuthenticationResponse (line 17) | class BaseAuthenticationResponse(APIResponse):
method __init__ (line 18) | def __init__(self, request, user=None, status=None):
method _get_flows (line 39) | def _get_flows(self, request, user):
method _upsert_pending_flow (line 93) | def _upsert_pending_flow(self, flows, pending_flow):
method _enrich_mfa_flow (line 100) | def _enrich_mfa_flow(self, stage, flow: dict) -> None:
class AuthenticationResponse (line 112) | class AuthenticationResponse(BaseAuthenticationResponse):
method __init__ (line 113) | def __init__(self, request):
method from_response (line 117) | def from_response(cls, request, response):
class ReauthenticationResponse (line 130) | class ReauthenticationResponse(BaseAuthenticationResponse):
method __init__ (line 131) | def __init__(self, request):
class UnauthorizedResponse (line 135) | class UnauthorizedResponse(BaseAuthenticationResponse):
method __init__ (line 136) | def __init__(self, request, status=HTTPStatus.UNAUTHORIZED):
class ForbiddenResponse (line 140) | class ForbiddenResponse(APIResponse):
method __init__ (line 141) | def __init__(self, request):
class ConflictResponse (line 145) | class ConflictResponse(APIResponse):
method __init__ (line 146) | def __init__(self, request):
function get_config_data (line 150) | def get_config_data(request) -> dict:
class ConfigResponse (line 170) | class ConfigResponse(APIResponse):
method __init__ (line 171) | def __init__(self, request):
class RateLimitResponse (line 194) | class RateLimitResponse(APIResponse):
method __init__ (line 195) | def __init__(self, request):
FILE: allauth/headless/base/urls.py
function build_urlpatterns (line 6) | def build_urlpatterns(client):
FILE: allauth/headless/base/views.py
class APIView (line 11) | class APIView(RESTView):
method as_api_view (line 15) | def as_api_view(cls, **initkwargs):
method dispatch (line 23) | def dispatch(self, request, *args, **kwargs):
class AuthenticationStageAPIView (line 30) | class AuthenticationStageAPIView(APIView):
method handle (line 33) | def handle(self, request, *args, **kwargs):
method respond_stage_error (line 39) | def respond_stage_error(self) -> response.UnauthorizedResponse:
method respond_next_stage (line 42) | def respond_next_stage(self) -> response.AuthenticationResponse:
class AuthenticatedAPIView (line 47) | class AuthenticatedAPIView(APIView):
method dispatch (line 48) | def dispatch(self, request, *args, **kwargs):
class ConfigView (line 54) | class ConfigView(APIView):
method get (line 55) | def get(self, request, *args, **kwargs):
FILE: allauth/headless/checks.py
function settings_check (line 5) | def settings_check(app_configs, **kwargs):
FILE: allauth/headless/constants.py
class Client (line 7) | class Client(str, Enum):
class Flow (line 12) | class Flow(str, Enum):
FILE: allauth/headless/contrib/ninja/security.py
class XSessionTokenAuth (line 11) | class XSessionTokenAuth(AuthBase):
method __call__ (line 19) | def __call__(self, request: HttpRequest):
method get_session_token (line 27) | def get_session_token(self, request: HttpRequest) -> str | None:
class JWTTokenAuth (line 39) | class JWTTokenAuth(AuthBase):
method __call__ (line 43) | def __call__(self, request: HttpRequest):
FILE: allauth/headless/contrib/rest_framework/authentication.py
class XSessionTokenAuthentication (line 10) | class XSessionTokenAuthentication(authentication.BaseAuthentication):
method authenticate (line 16) | def authenticate(self, request: HttpRequest):
method get_session_token (line 22) | def get_session_token(self, request: HttpRequest) -> str | None:
class JWTTokenAuthentication (line 31) | class JWTTokenAuthentication(authentication.TokenAuthentication):
method keyword (line 34) | def keyword(self) -> str:
method authenticate_credentials (line 40) | def authenticate_credentials(self, key: str):
FILE: allauth/headless/internal/authkit.py
class AuthenticationStatus (line 14) | class AuthenticationStatus:
method __init__ (line 15) | def __init__(self, request) -> None:
method is_authenticated (line 19) | def is_authenticated(self) -> bool:
method get_pending_stage (line 22) | def get_pending_stage(self):
method has_pending_signup (line 26) | def has_pending_signup(self) -> bool:
function purge_request_user_cache (line 34) | def purge_request_user_cache(request) -> None:
function authentication_context (line 43) | def authentication_context(request):
function expose_access_token (line 73) | def expose_access_token(request) -> dict[str, Any] | None:
FILE: allauth/headless/internal/decorators.py
function mark_request_as_headless (line 12) | def mark_request_as_headless(request, client) -> None:
function app_view (line 17) | def app_view(
function browser_view (line 36) | def browser_view(
FILE: allauth/headless/internal/restkit/inputs.py
class Input (line 25) | class Input(Form):
FILE: allauth/headless/internal/restkit/response.py
class APIResponse (line 11) | class APIResponse(JsonResponse):
method __init__ (line 12) | def __init__(
method _add_session_meta (line 31) | def _add_session_meta(self, request, meta: dict | None) -> dict | None:
class ErrorResponse (line 43) | class ErrorResponse(APIResponse):
method __init__ (line 44) | def __init__(
FILE: allauth/headless/internal/restkit/views.py
class RESTView (line 11) | class RESTView(View):
method dispatch (line 15) | def dispatch(self, request, *args, **kwargs):
method handle (line 18) | def handle(self, request, *args, **kwargs):
method get_input_class (line 26) | def get_input_class(self):
method get_input_kwargs (line 32) | def get_input_kwargs(self) -> dict:
method handle_input (line 35) | def handle_input(self, data):
method handle_invalid_input (line 47) | def handle_invalid_input(self, input):
method _parse_json (line 50) | def _parse_json(self, request):
FILE: allauth/headless/internal/sessionkit.py
function session_store (line 11) | def session_store(session_key=None):
function new_session (line 16) | def new_session() -> SessionBase:
function expose_session_token (line 20) | def expose_session_token(request):
function authenticate_by_x_session_token (line 33) | def authenticate_by_x_session_token(token: str) -> tuple | None:
function lookup_session (line 48) | def lookup_session(session_key: str) -> SessionBase | None:
FILE: allauth/headless/mfa/inputs.py
class AuthenticateInput (line 16) | class AuthenticateInput(AuthenticateForm, inputs.Input):
class ActivateTOTPInput (line 20) | class ActivateTOTPInput(ActivateTOTPForm, inputs.Input):
class GenerateRecoveryCodesInput (line 24) | class GenerateRecoveryCodesInput(GenerateRecoveryCodesForm, inputs.Input):
class AddWebAuthnInput (line 28) | class AddWebAuthnInput(AddWebAuthnForm, inputs.Input):
class CreateWebAuthnInput (line 32) | class CreateWebAuthnInput(SignupWebAuthnForm, inputs.Input):
class UpdateWebAuthnInput (line 36) | class UpdateWebAuthnInput(inputs.Input):
method __init__ (line 40) | def __init__(self, *args, **kwargs):
class DeleteWebAuthnInput (line 48) | class DeleteWebAuthnInput(inputs.Input):
method __init__ (line 53) | def __init__(self, *args, **kwargs):
class ReauthenticateWebAuthnInput (line 61) | class ReauthenticateWebAuthnInput(ReauthenticateWebAuthnForm, inputs.Inp...
class AuthenticateWebAuthnInput (line 65) | class AuthenticateWebAuthnInput(AuthenticateWebAuthnForm, inputs.Input):
class LoginWebAuthnInput (line 69) | class LoginWebAuthnInput(LoginWebAuthnForm, inputs.Input):
class SignupWebAuthnInput (line 73) | class SignupWebAuthnInput(BaseSignupForm, inputs.Input):
class TrustInput (line 77) | class TrustInput(inputs.Input):
FILE: allauth/headless/mfa/response.py
function get_config_data (line 7) | def get_config_data(request) -> dict:
function _authenticator_data (line 17) | def _authenticator_data(authenticator, sensitive: bool = False) -> dict:
class AuthenticatorDeletedResponse (line 50) | class AuthenticatorDeletedResponse(APIResponse):
class AuthenticatorsDeletedResponse (line 54) | class AuthenticatorsDeletedResponse(APIResponse):
class TOTPNotFoundResponse (line 58) | class TOTPNotFoundResponse(APIResponse):
method __init__ (line 59) | def __init__(self, request, secret, totp_url):
class TOTPResponse (line 70) | class TOTPResponse(APIResponse):
method __init__ (line 71) | def __init__(self, request, authenticator):
class AuthenticatorsResponse (line 76) | class AuthenticatorsResponse(APIResponse):
method __init__ (line 77) | def __init__(self, request, authenticators):
class AuthenticatorResponse (line 82) | class AuthenticatorResponse(APIResponse):
method __init__ (line 83) | def __init__(self, request, authenticator, meta=None):
class RecoveryCodesNotFoundResponse (line 88) | class RecoveryCodesNotFoundResponse(APIResponse):
method __init__ (line 89) | def __init__(self, request):
class RecoveryCodesResponse (line 93) | class RecoveryCodesResponse(APIResponse):
method __init__ (line 94) | def __init__(self, request, authenticator):
class AddWebAuthnResponse (line 99) | class AddWebAuthnResponse(APIResponse):
method __init__ (line 100) | def __init__(self, request, registration_data):
class WebAuthnRequestOptionsResponse (line 104) | class WebAuthnRequestOptionsResponse(APIResponse):
method __init__ (line 105) | def __init__(self, request, request_options):
FILE: allauth/headless/mfa/urls.py
function build_urlpatterns (line 8) | def build_urlpatterns(client):
FILE: allauth/headless/mfa/views.py
function _validate_can_add_authenticator (line 46) | def _validate_can_add_authenticator(request):
class AuthenticateView (line 53) | class AuthenticateView(AuthenticationStageAPIView):
method post (line 57) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 61) | def get_input_kwargs(self) -> dict:
class ReauthenticateView (line 65) | class ReauthenticateView(AuthenticatedAPIView):
method post (line 68) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 72) | def get_input_kwargs(self) -> dict:
class AuthenticatorsView (line 76) | class AuthenticatorsView(AuthenticatedAPIView):
method get (line 77) | def get(self, request, *args, **kwargs) -> HttpResponse:
class ManageTOTPView (line 82) | class ManageTOTPView(AuthenticatedAPIView):
method get (line 85) | def get(self, request, *args, **kwargs) -> APIResponse:
method _get_authenticator (line 97) | def _get_authenticator(self):
method get_input_kwargs (line 102) | def get_input_kwargs(self) -> dict:
method post (line 105) | def post(self, request, *args, **kwargs):
method delete (line 109) | def delete(self, request, *args, **kwargs):
class ManageRecoveryCodesView (line 116) | class ManageRecoveryCodesView(AuthenticatedAPIView):
method get (line 119) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 125) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 129) | def get_input_kwargs(self) -> dict:
class ManageWebAuthnView (line 133) | class ManageWebAuthnView(AuthenticatedAPIView):
method handle (line 140) | def handle(self, request, *args, **kwargs):
method get (line 147) | def get(self, request, *args, **kwargs) -> HttpResponse:
method get_input_kwargs (line 154) | def get_input_kwargs(self) -> dict:
method post (line 157) | def post(self, request, *args, **kwargs):
method put (line 170) | def put(self, request, *args, **kwargs):
method delete (line 177) | def delete(self, request, *args, **kwargs):
class ReauthenticateWebAuthnView (line 183) | class ReauthenticateWebAuthnView(AuthenticatedAPIView):
method get (line 188) | def get(self, request, *args, **kwargs) -> HttpResponse:
method get_input_kwargs (line 192) | def get_input_kwargs(self) -> dict:
method post (line 195) | def post(self, request, *args, **kwargs):
class AuthenticateWebAuthnView (line 201) | class AuthenticateWebAuthnView(AuthenticationStageAPIView):
method get (line 207) | def get(self, request, *args, **kwargs) -> HttpResponse:
method get_input_kwargs (line 211) | def get_input_kwargs(self) -> dict:
method post (line 214) | def post(self, request, *args, **kwargs):
class LoginWebAuthnView (line 219) | class LoginWebAuthnView(APIView):
method get (line 224) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 228) | def post(self, request, *args, **kwargs):
class SignupWebAuthnView (line 236) | class SignupWebAuthnView(SignupView):
method get (line 243) | def get(self, request, *args, **kwargs) -> HttpResponse:
method _prep_stage (line 252) | def _prep_stage(self):
method _require_stage (line 258) | def _require_stage(self):
method get_input_kwargs (line 264) | def get_input_kwargs(self) -> dict:
method put (line 271) | def put(self, request, *args, **kwargs):
class TrustView (line 285) | class TrustView(AuthenticationStageAPIView):
method post (line 289) | def post(self, request, *args, **kwargs):
FILE: allauth/headless/socialaccount/forms.py
class RedirectToProviderForm (line 11) | class RedirectToProviderForm(forms.Form):
method clean_callback_url (line 21) | def clean_callback_url(self) -> str:
method clean_provider (line 27) | def clean_provider(self):
FILE: allauth/headless/socialaccount/inputs.py
class SignupInput (line 14) | class SignupInput(SignupForm, inputs.Input):
class DeleteProviderAccountInput (line 18) | class DeleteProviderAccountInput(inputs.Input):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method clean (line 26) | def clean(self):
class ProviderTokenInput (line 43) | class ProviderTokenInput(inputs.Input):
method clean (line 53) | def clean(self):
FILE: allauth/headless/socialaccount/internal.py
function on_authentication_error (line 16) | def on_authentication_error(
function complete_token_login (line 51) | def complete_token_login(request, sociallogin):
function complete_login (line 55) | def complete_login(request, sociallogin):
FILE: allauth/headless/socialaccount/response.py
function _socialaccount_data (line 10) | def _socialaccount_data(request, account):
function _provider_data (line 18) | def _provider_data(request, provider):
function provider_flows (line 32) | def provider_flows(request):
function _signup_flow (line 60) | def _signup_flow(request, sociallogin):
function _is_provider_supported (line 70) | def _is_provider_supported(provider, client):
function _list_supported_providers (line 78) | def _list_supported_providers(request):
function get_config_data (line 89) | def get_config_data(request):
class SocialAccountsResponse (line 99) | class SocialAccountsResponse(APIResponse):
method __init__ (line 100) | def __init__(self, request, accounts):
class SocialLoginResponse (line 105) | class SocialLoginResponse(APIResponse):
method __init__ (line 106) | def __init__(self, request, sociallogin):
FILE: allauth/headless/socialaccount/urls.py
function build_urlpatterns (line 6) | def build_urlpatterns(client):
FILE: allauth/headless/socialaccount/views.py
class ProviderSignupView (line 29) | class ProviderSignupView(APIView):
method handle (line 32) | def handle(self, request, *args, **kwargs):
method get (line 42) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 45) | def post(self, request, *args, **kwargs):
method get_input_kwargs (line 51) | def get_input_kwargs(self) -> dict:
class RedirectToProviderView (line 55) | class RedirectToProviderView(APIView):
method post (line 58) | def post(self, request, *args, **kwargs):
class ManageProvidersView (line 77) | class ManageProvidersView(AuthenticatedAPIView):
method get (line 82) | def get(self, request, *args, **kwargs) -> HttpResponse:
method respond_provider_accounts (line 86) | def respond_provider_accounts(self, request):
method delete (line 90) | def delete(self, request, *args, **kwargs):
method get_input_kwargs (line 94) | def get_input_kwargs(self) -> dict:
class ProviderTokenView (line 98) | class ProviderTokenView(APIView):
method post (line 101) | def post(self, request, *args, **kwargs):
FILE: allauth/headless/spec/internal/openapikit.py
function spec_for_field (line 28) | def spec_for_field(field: forms.Field) -> dict[str, Any]:
function unwrap_optional_type (line 40) | def unwrap_optional_type(typ):
function spec_for_dataclass (line 49) | def spec_for_dataclass(dc) -> tuple[dict, dict]:
FILE: allauth/headless/spec/internal/schema.py
function get_schema (line 14) | def get_schema() -> dict:
function chroot (line 39) | def chroot(spec: dict) -> None:
function pin_client (line 49) | def pin_client(spec: dict) -> None:
function drop_unused_client_parameter (line 103) | def drop_unused_client_parameter(spec: dict) -> None:
function drop_unused_paths (line 112) | def drop_unused_paths(spec: dict) -> set:
function drop_unused_tags (line 132) | def drop_unused_tags(spec: dict, used_tags: set) -> None:
function drop_unused_tag_groups (line 141) | def drop_unused_tag_groups(spec: dict, used_tags: set) -> None:
function specify_signup_fields (line 149) | def specify_signup_fields(spec: dict) -> None:
function specify_custom_signup_form (line 168) | def specify_custom_signup_form(spec: dict) -> None:
function specify_user (line 179) | def specify_user(spec: dict) -> None:
FILE: allauth/headless/spec/views.py
class OpenAPIYAMLView (line 13) | class OpenAPIYAMLView(View):
method get (line 14) | def get(self, request) -> HttpResponse:
class OpenAPIJSONView (line 27) | class OpenAPIJSONView(View):
method get (line 28) | def get(self, request) -> HttpResponse:
class OpenAPIHTMLView (line 39) | class OpenAPIHTMLView(TemplateView):
method get_template_names (line 40) | def get_template_names(self) -> list[str]:
FILE: allauth/headless/tokens/inputs.py
class RefreshTokenInput (line 4) | class RefreshTokenInput(inputs.Input):
FILE: allauth/headless/tokens/response.py
class RefreshTokenResponse (line 6) | class RefreshTokenResponse(APIResponse):
method __init__ (line 7) | def __init__(
FILE: allauth/headless/tokens/strategies/base.py
class AbstractTokenStrategy (line 8) | class AbstractTokenStrategy(abc.ABC):
method get_session_token (line 9) | def get_session_token(self, request: HttpRequest) -> str | None:
method create_access_token_payload (line 16) | def create_access_token_payload(
method create_access_token (line 29) | def create_access_token(self, request: HttpRequest) -> str | None:
method create_session_token (line 48) | def create_session_token(self, request: HttpRequest) -> str:
method lookup_session (line 55) | def lookup_session(self, session_token: str) -> SessionBase | None:
method refresh_token (line 62) | def refresh_token(self, refresh_token: str) -> tuple[str, str] | None:
FILE: allauth/headless/tokens/strategies/jwt/internal.py
class JWTConfig (line 26) | class JWTConfig:
function validate_access_token (line 33) | def validate_access_token(token: str) -> tuple[Any, dict[str, Any]] | None:
function get_session_key_cipher (line 47) | def get_session_key_cipher(initialization_vector: bytes) -> Cipher:
function session_key_to_sid (line 56) | def session_key_to_sid(session_key: str) -> str:
function session_key_from_sid (line 71) | def session_key_from_sid(sid: str) -> str | None:
function validate_token_user (line 89) | def validate_token_user(token: dict[str, Any], session: SessionBase):
function validate_refresh_token (line 99) | def validate_refresh_token(
function get_token_session (line 118) | def get_token_session(payload: dict[str, Any]) -> SessionBase | None:
function _get_jwt_config (line 131) | def _get_jwt_config() -> JWTConfig:
function get_jwt_headers (line 151) | def get_jwt_headers(config: JWTConfig) -> dict[str, Any]:
function decode_token (line 160) | def decode_token(token: str, use: str) -> dict[str, Any] | None:
function create_token (line 186) | def create_token(
function get_refresh_token_state (line 221) | def get_refresh_token_state(session: SessionBase) -> dict[str, int]:
function create_refresh_token (line 225) | def create_refresh_token(user, session: SessionBase) -> str:
function create_access_token (line 241) | def create_access_token(user, session: SessionBase, claims: dict[str, An...
function invalidate_refresh_token (line 255) | def invalidate_refresh_token(session: SessionBase, token: dict[str, Any]...
FILE: allauth/headless/tokens/strategies/jwt/strategy.py
class JWTTokenStrategy (line 13) | class JWTTokenStrategy(AbstractTokenStrategy):
method get_session_token (line 14) | def get_session_token(self, request: HttpRequest) -> str | None:
method _get_access_token (line 23) | def _get_access_token(self, request: HttpRequest):
method create_session_token (line 34) | def create_session_token(self, request: HttpRequest) -> str:
method create_access_token_payload (line 42) | def create_access_token_payload(
method lookup_session (line 52) | def lookup_session(self, session_token: str) -> SessionBase | None:
method create_access_token (line 55) | def create_access_token(self, request: HttpRequest) -> str | None:
method get_claims (line 59) | def get_claims(self, user) -> dict[str, Any]:
method refresh_token (line 72) | def refresh_token(self, refresh_token: str) -> tuple[str, str] | None:
FILE: allauth/headless/tokens/strategies/sessions.py
class SessionTokenStrategy (line 8) | class SessionTokenStrategy(AbstractTokenStrategy):
method create_session_token (line 9) | def create_session_token(self, request: HttpRequest) -> str:
method lookup_session (line 17) | def lookup_session(self, session_token: str) -> SessionBase | None:
FILE: allauth/headless/tokens/urls.py
function build_urlpatterns (line 6) | def build_urlpatterns(client):
FILE: allauth/headless/tokens/views.py
class RefreshTokenView (line 11) | class RefreshTokenView(APIView):
method post (line 14) | def post(self, request: HttpRequest):
FILE: allauth/headless/urls.py
function build_urlpatterns (line 11) | def build_urlpatterns(client):
FILE: allauth/headless/usersessions/inputs.py
class SelectSessionsInput (line 5) | class SelectSessionsInput(inputs.Input):
method __init__ (line 8) | def __init__(self, *args, **kwargs):
FILE: allauth/headless/usersessions/response.py
class SessionsResponse (line 5) | class SessionsResponse(APIResponse):
method __init__ (line 6) | def __init__(self, request, sessions):
method _session_data (line 9) | def _session_data(self, session) -> dict:
function get_config_data (line 22) | def get_config_data(request) -> dict:
FILE: allauth/headless/usersessions/urls.py
function build_urlpatterns (line 6) | def build_urlpatterns(client):
FILE: allauth/headless/usersessions/views.py
class SessionsView (line 11) | class SessionsView(AuthenticatedAPIView):
method delete (line 14) | def delete(self, request, *args, **kwargs):
method get (line 21) | def get(self, request, *args, **kwargs) -> HttpResponse:
method _respond_session_list (line 24) | def _respond_session_list(self):
method get_input_kwargs (line 28) | def get_input_kwargs(self) -> dict:
FILE: allauth/idp/oidc/adapter.py
class DefaultOIDCAdapter (line 22) | class DefaultOIDCAdapter(BaseAdapter):
method generate_client_id (line 36) | def generate_client_id(self) -> str:
method generate_client_secret (line 42) | def generate_client_secret(self) -> str:
method generate_user_code (line 48) | def generate_user_code(self) -> str:
method hash_token (line 51) | def hash_token(self, token: str) -> str:
method get_issuer (line 58) | def get_issuer(self) -> str:
method populate_id_token (line 64) | def populate_id_token(
method populate_access_token (line 74) | def populate_access_token(
method get_claims (line 83) | def get_claims(
method get_user_sub (line 127) | def get_user_sub(self, client, user) -> str:
method get_user_by_sub (line 133) | def get_user_by_sub(self, client, sub: str):
function get_adapter (line 148) | def get_adapter() -> DefaultOIDCAdapter:
FILE: allauth/idp/oidc/admin.py
class ClientAdmin (line 10) | class ClientAdmin(admin.ModelAdmin):
method save_model (line 24) | def save_model(self, request, obj, form, change):
class TokenAdmin (line 40) | class TokenAdmin(admin.ModelAdmin):
FILE: allauth/idp/oidc/app_settings.py
class AppSettings (line 5) | class AppSettings:
method __init__ (line 6) | def __init__(self, prefix: str) -> None:
method _setting (line 9) | def _setting(self, name: str, dflt):
method ADAPTER (line 15) | def ADAPTER(self) -> str:
method ID_TOKEN_EXPIRES_IN (line 22) | def ID_TOKEN_EXPIRES_IN(self) -> int:
method PRIVATE_KEY (line 26) | def PRIVATE_KEY(self) -> str:
method ACCESS_TOKEN_EXPIRES_IN (line 30) | def ACCESS_TOKEN_EXPIRES_IN(self) -> int:
method ACCESS_TOKEN_FORMAT (line 34) | def ACCESS_TOKEN_FORMAT(self) -> str:
method AUTHORIZATION_CODE_EXPIRES_IN (line 38) | def AUTHORIZATION_CODE_EXPIRES_IN(self) -> int:
method ROTATE_REFRESH_TOKEN (line 42) | def ROTATE_REFRESH_TOKEN(self) -> bool:
method DEVICE_CODE_EXPIRES_IN (line 46) | def DEVICE_CODE_EXPIRES_IN(self) -> int:
method DEVICE_CODE_INTERVAL (line 50) | def DEVICE_CODE_INTERVAL(self) -> int:
method USER_CODE_FORMAT (line 54) | def USER_CODE_FORMAT(self) -> UserCodeFormat:
method RATE_LIMITS (line 58) | def RATE_LIMITS(self) -> dict:
method RP_INITIATED_LOGOUT_ASKS_FOR_OP_LOGOUT (line 70) | def RP_INITIATED_LOGOUT_ASKS_FOR_OP_LOGOUT(self) -> bool:
method USERINFO_ENDPOINT (line 83) | def USERINFO_ENDPOINT(self) -> str | None:
function __getattr__ (line 95) | def __getattr__(name):
FILE: allauth/idp/oidc/apps.py
class OIDCConfig (line 6) | class OIDCConfig(AppConfig):
FILE: allauth/idp/oidc/contrib/ninja/security.py
class TokenAuth (line 10) | class TokenAuth(AuthBase):
method __init__ (line 19) | def __init__(self, scope: str | list | dict):
method __call__ (line 32) | def __call__(self, request: HttpRequest):
FILE: allauth/idp/oidc/contrib/rest_framework/authentication.py
class TokenAuthentication (line 7) | class TokenAuthentication(BaseAuthentication):
method authenticate (line 12) | def authenticate(self, request):
FILE: allauth/idp/oidc/contrib/rest_framework/permissions.py
class TokenPermission (line 7) | class TokenPermission(BasePermission):
method has_permission (line 10) | def has_permission(self, request, view) -> bool:
method has_scope (line 20) | def has_scope(cls, scope: str | list | dict):
FILE: allauth/idp/oidc/forms.py
class AuthorizationForm (line 19) | class AuthorizationForm(forms.Form):
method __init__ (line 22) | def __init__(self, *args, **kwargs) -> None:
class ConfirmCodeForm (line 49) | class ConfirmCodeForm(forms.Form):
method __init__ (line 58) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 62) | def clean_code(self) -> str:
class DeviceAuthorizationForm (line 76) | class DeviceAuthorizationForm(forms.Form):
class RPInitiatedLogoutForm (line 80) | class RPInitiatedLogoutForm(forms.Form):
method clean_id_token_hint (line 136) | def clean_id_token_hint(self):
method clean (line 143) | def clean(self) -> dict[str, Any] | None:
FILE: allauth/idp/oidc/internal/clientkit.py
function is_loopback (line 11) | def is_loopback(parsed_uri: ParseResult) -> bool:
function _validate_uri_wildcard_format (line 18) | def _validate_uri_wildcard_format(uri: str, allow_uri_wildcards: bool) -...
function _wildcard_to_regex (line 43) | def _wildcard_to_regex(wildcard: str) -> Pattern:
function _is_scheme_hostname_allowed (line 48) | def _is_scheme_hostname_allowed(
function is_parsed_redirect_uri_allowed (line 70) | def is_parsed_redirect_uri_allowed(
function is_redirect_uri_allowed (line 95) | def is_redirect_uri_allowed(
function is_origin_allowed (line 105) | def is_origin_allowed(
function get_used_schemes (line 127) | def get_used_schemes(client: Client) -> set[str]:
function clean_post_logout_redirect_uri (line 136) | def clean_post_logout_redirect_uri(
FILE: allauth/idp/oidc/internal/flows.py
function rp_initiated_logout (line 7) | def rp_initiated_logout(
FILE: allauth/idp/oidc/internal/oauthlib/authorization_codes.py
function cache_key (line 9) | def cache_key(client_id: str, code: str) -> str:
function create (line 13) | def create(client: Client, code: dict, request) -> None:
function lookup (line 41) | def lookup(client_id: str, code: str) -> dict | None:
function invalidate (line 45) | def invalidate(client_id: str, code: str) -> None:
function validate (line 49) | def validate(client_id: str, code: str, request) -> bool:
FILE: allauth/idp/oidc/internal/oauthlib/device_codes.py
function cache_user_code_key (line 26) | def cache_user_code_key(user_code: str):
function cache_device_code_key (line 30) | def cache_device_code_key(device_code: str):
function create (line 34) | def create(client_id: str, scope: list[str] | None, data: dict):
function lookup_client (line 54) | def lookup_client(client_id: str) -> Client | None:
function validate_user_code (line 63) | def validate_user_code(code: str) -> tuple[str, Client]:
function confirm_or_deny_device_code (line 80) | def confirm_or_deny_device_code(user, device_code: str, confirm: bool) -...
function update_device_state (line 89) | def update_device_state(device_code: str, data: dict) -> bool:
function poll_device_code (line 97) | def poll_device_code(
FILE: allauth/idp/oidc/internal/oauthlib/request_validator.py
class OAuthLibRequestValidator (line 22) | class OAuthLibRequestValidator(RequestValidator):
method validate_client_id (line 24) | def validate_client_id(self, client_id: str, request):
method validate_redirect_uri (line 31) | def validate_redirect_uri(self, client_id, redirect_uri, request, *arg...
method validate_response_type (line 38) | def validate_response_type(
method validate_scopes (line 43) | def validate_scopes(self, client_id, scopes, client, request, *args, *...
method get_default_scopes (line 46) | def get_default_scopes(self, client_id, request, *args, **kwargs):
method save_authorization_code (line 49) | def save_authorization_code(self, client_id, code, request, *args, **k...
method authenticate_client_id (line 60) | def authenticate_client_id(self, client_id, request, *args, **kwargs) ...
method authenticate_client (line 68) | def authenticate_client(self, request, *args, **kwargs) -> bool:
method validate_grant_type (line 85) | def validate_grant_type(
method validate_code (line 90) | def validate_code(self, client_id, code, client, request, *args, **kwa...
method confirm_redirect_uri (line 93) | def confirm_redirect_uri(
method save_bearer_token (line 101) | def save_bearer_token(self, token: dict, request, *args, **kwargs):
method invalidate_authorization_code (line 165) | def invalidate_authorization_code(self, client_id, code, request, *arg...
method validate_user_match (line 168) | def validate_user_match(self, id_token_hint, scopes, claims, request) ...
method get_authorization_code_scopes (line 196) | def get_authorization_code_scopes(
method get_authorization_code_nonce (line 204) | def get_authorization_code_nonce(self, client_id, code, redirect_uri, ...
method get_code_challenge (line 208) | def get_code_challenge(self, code, request):
method get_code_challenge_method (line 217) | def get_code_challenge_method(self, code, request):
method is_pkce_required (line 226) | def is_pkce_required(self, client_id, request) -> bool:
method finalize_id_token (line 230) | def finalize_id_token(self, id_token: dict, token: dict, token_handler...
method validate_bearer_token (line 250) | def validate_bearer_token(self, token, scopes, request) -> bool:
method revoke_token (line 273) | def revoke_token(self, token, token_type_hint, request, *args, **kwargs):
method get_userinfo_claims (line 282) | def get_userinfo_claims(self, request):
method get_default_redirect_uri (line 288) | def get_default_redirect_uri(self, client_id, request, *args, **kwargs):
method validate_user (line 294) | def validate_user(self, username, password, client, request, *args, **...
method validate_refresh_token (line 313) | def validate_refresh_token(self, refresh_token, client, request, *args...
method get_original_scopes (line 325) | def get_original_scopes(self, refresh_token, request, *args, **kwargs):
method client_authentication_required (line 328) | def client_authentication_required(self, request, *args, **kwargs) -> ...
method _lookup_client (line 337) | def _lookup_client(self, request, client_id) -> Client | None:
method _use_client (line 357) | def _use_client(self, request, client: Client) -> None:
method _lookup_authorization_code (line 361) | def _lookup_authorization_code(
method is_origin_allowed (line 373) | def is_origin_allowed(self, client_id, origin, request, *args, **kwarg...
method rotate_refresh_token (line 382) | def rotate_refresh_token(self, request):
method validate_silent_login (line 385) | def validate_silent_login(self, request) -> bool:
method validate_silent_authorization (line 391) | def validate_silent_authorization(self, request) -> bool:
method validate_jwt_bearer_token (line 401) | def validate_jwt_bearer_token(self, token, scopes, request):
FILE: allauth/idp/oidc/internal/oauthlib/server.py
function generate_opaque_token (line 20) | def generate_opaque_token(request):
function generate_jwt_access_token (line 28) | def generate_jwt_access_token(request) -> str:
function generate_access_token (line 53) | def generate_access_token(request) -> str:
function generate_refresh_token (line 63) | def generate_refresh_token(request) -> str:
class OAuthLibServer (line 67) | class OAuthLibServer(Server):
method __init__ (line 68) | def __init__(self, **kwargs):
class DeviceOAuthLibServer (line 78) | class DeviceOAuthLibServer(DeviceApplicationServer):
method __init__ (line 79) | def __init__(self):
function get_server (line 93) | def get_server(**kwargs):
function get_device_server (line 97) | def get_device_server():
FILE: allauth/idp/oidc/internal/oauthlib/utils.py
function get_uri (line 13) | def get_uri(request: HttpRequest) -> str:
function extract_params (line 25) | def extract_params(request: HttpRequest) -> tuple[str, str, str, dict[st...
function extract_headers (line 34) | def extract_headers(request) -> dict[str, str]:
function convert_response (line 52) | def convert_response(headers, body, status):
function respond_html_error (line 62) | def respond_html_error(
function respond_json_error (line 76) | def respond_json_error(request: HttpRequest, error: OAuth2Error) -> Http...
FILE: allauth/idp/oidc/internal/scope.py
function _is_scope_granted (line 4) | def _is_scope_granted(
function is_scope_granted (line 25) | def is_scope_granted(
FILE: allauth/idp/oidc/internal/tokens.py
function decode_jwt_token (line 8) | def decode_jwt_token(
FILE: allauth/idp/oidc/migrations/0001_initial.py
class Migration (line 9) | class Migration(migrations.Migration):
FILE: allauth/idp/oidc/migrations/0002_client_default_scopes.py
class Migration (line 4) | class Migration(migrations.Migration):
FILE: allauth/idp/oidc/migrations/0003_client_allow_uri_wildcards.py
class Migration (line 4) | class Migration(migrations.Migration):
FILE: allauth/idp/oidc/models.py
function default_client_id (line 11) | def default_client_id() -> str:
function default_client_secret (line 17) | def default_client_secret() -> str:
function _values_from_text (line 23) | def _values_from_text(text) -> list[str]:
function _values_to_text (line 27) | def _values_to_text(values) -> str:
class Client (line 33) | class Client(models.Model):
class GrantType (line 34) | class GrantType(models.TextChoices):
class Type (line 40) | class Type(models.TextChoices):
class Meta (line 112) | class Meta:
method get_redirect_uris (line 116) | def get_redirect_uris(self) -> list[str]:
method set_redirect_uris (line 119) | def set_redirect_uris(self, uris: list[str]) -> None:
method get_cors_origins (line 122) | def get_cors_origins(self) -> list[str]:
method set_cors_origins (line 125) | def set_cors_origins(self, uris: list[str]) -> None:
method get_scopes (line 128) | def get_scopes(self) -> list[str]:
method set_scopes (line 131) | def set_scopes(self, scopes: list[str]) -> None:
method get_default_scopes (line 134) | def get_default_scopes(self) -> list[str]:
method set_default_scopes (line 137) | def set_default_scopes(self, scopes: list[str]) -> None:
method get_response_types (line 140) | def get_response_types(self) -> list[str]:
method set_response_types (line 143) | def set_response_types(self, response_types: list[str]) -> None:
method get_grant_types (line 146) | def get_grant_types(self) -> list[str]:
method set_grant_types (line 149) | def set_grant_types(self, grant_types: list[str]) -> None:
method set_secret (line 152) | def set_secret(self, secret) -> None:
method check_secret (line 155) | def check_secret(self, secret: str) -> bool:
method clean_redirect_uris (line 158) | def clean_redirect_uris(self) -> list[str]:
method clean_cors_origins (line 166) | def clean_cors_origins(self) -> list[str]:
method clean (line 174) | def clean(self) -> None:
method __str__ (line 179) | def __str__(self) -> str:
class TokenQuerySet (line 183) | class TokenQuerySet(models.query.QuerySet):
method valid (line 184) | def valid(self):
method by_value (line 189) | def by_value(self, value: str):
method lookup (line 192) | def lookup(self, type, value):
class Token (line 196) | class Token(models.Model):
class Type (line 199) | class Type(models.TextChoices):
class Meta (line 216) | class Meta:
method __str__ (line 219) | def __str__(self) -> str:
method get_scopes (line 224) | def get_scopes(self) -> list[str]:
method set_scopes (line 227) | def set_scopes(self, scopes: list[str]) -> None:
method set_scope_email (line 230) | def set_scope_email(self, email: str) -> None:
method get_scope_email (line 239) | def get_scope_email(self) -> str | None:
FILE: allauth/idp/oidc/views.py
function _enforce_csrf (line 55) | def _enforce_csrf(request) -> HttpResponseForbidden | None:
class ConfigurationView (line 69) | class ConfigurationView(View):
method get (line 70) | def get(self, request) -> JsonResponse:
method _get_response_types_supported (line 101) | def _get_response_types_supported(self) -> list[str]:
class AuthorizationView (line 114) | class AuthorizationView(FormView):
method get (line 118) | def get(self, request, *args, **kwargs) -> HttpResponse:
method post (line 143) | def post(self, request, *args, **kwargs) -> HttpResponse:
method _login_required (line 166) | def _login_required(self, request) -> HttpResponse | None:
method _handle_login_prompt (line 179) | def _handle_login_prompt(
method _skip_consent (line 197) | def _skip_consent(self):
method _respond_with_access_denied (line 210) | def _respond_with_access_denied(self):
method get_form_kwargs (line 218) | def get_form_kwargs(self) -> dict:
method get_initial (line 223) | def get_initial(self) -> dict:
method form_valid (line 234) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 251) | def get_context_data(self, **kwargs) -> dict:
class DeviceCodeView (line 267) | class DeviceCodeView(View):
method post (line 268) | def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
class DeviceAuthorizationView (line 295) | class DeviceAuthorizationView(View):
method dispatch (line 296) | def dispatch(self, request, *args, **kwargs) -> HttpResponse:
method _dispatch_authorization (line 318) | def _dispatch_authorization(
class TokenView (line 354) | class TokenView(View):
method post (line 356) | def post(self, request) -> HttpResponse:
method _create_token_response (line 361) | def _create_token_response(
method _pre_token (line 374) | def _pre_token(self, orequest, user: AbstractBaseUser | None, data: di...
method _post_device_token (line 382) | def _post_device_token(self, request):
class UserInfoView (line 398) | class UserInfoView(View):
method get (line 403) | def get(self, request: HttpRequest) -> HttpResponse:
method post (line 406) | def post(self, request: HttpRequest) -> HttpResponse:
method _respond (line 409) | def _respond(self, request: HttpRequest) -> HttpResponse:
class JwksView (line 422) | class JwksView(View):
method get (line 423) | def get(self, request, *args, **kwargs) -> JsonResponse:
class RevokeView (line 438) | class RevokeView(View):
method post (line 439) | def post(self, request, *args, **kwargs) -> HttpResponse:
class LogoutView (line 450) | class LogoutView(FormView):
method get (line 458) | def get(self, request) -> HttpResponse:
method form_invalid (line 466) | def form_invalid(self, form) -> HttpResponse:
method form_valid (line 469) | def form_valid(self, form) -> HttpResponse:
method _handle (line 487) | def _handle(
method _must_ask (line 506) | def _must_ask(self, form: RPInitiatedLogoutForm) -> bool:
FILE: allauth/mfa/adapter.py
class DefaultMFAAdapter (line 21) | class DefaultMFAAdapter(BaseAdapter):
method get_totp_label (line 45) | def get_totp_label(self, user) -> str:
method _get_user_identifier (line 51) | def _get_user_identifier(self, user) -> str:
method get_totp_issuer (line 62) | def get_totp_issuer(self) -> str:
method build_totp_url (line 71) | def build_totp_url(self, user, secret: str) -> str:
method build_totp_svg (line 86) | def build_totp_svg(self, url: str) -> str:
method _get_site_name (line 95) | def _get_site_name(self) -> str:
method encrypt (line 103) | def encrypt(self, text: str) -> str:
method decrypt (line 110) | def decrypt(self, encrypted_text: str) -> str:
method can_delete_authenticator (line 115) | def can_delete_authenticator(self, authenticator: Authenticator) -> bool:
method send_notification_mail (line 118) | def send_notification_mail(self, *args, **kwargs):
method is_mfa_enabled (line 121) | def is_mfa_enabled(self, user, types=None) -> bool:
method generate_authenticator_name (line 132) | def generate_authenticator_name(self, user, type: Authenticator.Type) ...
method get_public_key_credential_rp_entity (line 144) | def get_public_key_credential_rp_entity(self) -> dict[str, str]:
method get_public_key_credential_user_entity (line 151) | def get_public_key_credential_user_entity(self, user) -> dict:
function get_adapter (line 159) | def get_adapter() -> DefaultMFAAdapter:
FILE: allauth/mfa/admin.py
class AuthenticatorAdmin (line 7) | class AuthenticatorAdmin(admin.ModelAdmin):
FILE: allauth/mfa/app_settings.py
class AppSettings (line 4) | class AppSettings:
method __init__ (line 5) | def __init__(self, prefix: str) -> None:
method _setting (line 8) | def _setting(self, name: str, dflt):
method ADAPTER (line 14) | def ADAPTER(self) -> str:
method ALLOW_UNVERIFIED_EMAIL (line 18) | def ALLOW_UNVERIFIED_EMAIL(self) -> bool:
method FORMS (line 22) | def FORMS(self) -> dict:
method RECOVERY_CODE_COUNT (line 26) | def RECOVERY_CODE_COUNT(self) -> int:
method RECOVERY_CODE_DIGITS (line 33) | def RECOVERY_CODE_DIGITS(self) -> int:
method TOTP_PERIOD (line 40) | def TOTP_PERIOD(self) -> int:
method TOTP_DIGITS (line 47) | def TOTP_DIGITS(self) -> int:
method TOTP_ISSUER (line 54) | def TOTP_ISSUER(self) -> str:
method TOTP_INSECURE_BYPASS_CODE (line 61) | def TOTP_INSECURE_BYPASS_CODE(self):
method TOTP_TOLERANCE (line 76) | def TOTP_TOLERANCE(self) -> int:
method SUPPORTED_TYPES (line 83) | def SUPPORTED_TYPES(self) -> list[str]:
method WEBAUTHN_ALLOW_INSECURE_ORIGIN (line 88) | def WEBAUTHN_ALLOW_INSECURE_ORIGIN(self) -> bool:
method PASSKEY_LOGIN_ENABLED (line 92) | def PASSKEY_LOGIN_ENABLED(self) -> bool:
method PASSKEY_SIGNUP_ENABLED (line 98) | def PASSKEY_SIGNUP_ENABLED(self) -> bool:
method TRUST_ENABLED (line 104) | def TRUST_ENABLED(self) -> bool:
method _TRUST_STAGE_ENABLED (line 108) | def _TRUST_STAGE_ENABLED(self) -> bool:
method TRUST_COOKIE_AGE (line 114) | def TRUST_COOKIE_AGE(self) -> timedelta:
method TRUST_COOKIE_NAME (line 121) | def TRUST_COOKIE_NAME(self) -> str:
method TRUST_COOKIE_DOMAIN (line 125) | def TRUST_COOKIE_DOMAIN(self) -> str | None:
method TRUST_COOKIE_HTTPONLY (line 131) | def TRUST_COOKIE_HTTPONLY(self) -> bool:
method TRUST_COOKIE_PATH (line 137) | def TRUST_COOKIE_PATH(self) -> str:
method TRUST_COOKIE_SAMESITE (line 143) | def TRUST_COOKIE_SAMESITE(self) -> str:
method TRUST_COOKIE_SECURE (line 149) | def TRUST_COOKIE_SECURE(self) -> str | None:
function __getattr__ (line 158) | def __getattr__(name):
FILE: allauth/mfa/apps.py
class MFAConfig (line 7) | class MFAConfig(AppConfig):
method ready (line 14) | def ready(self):
FILE: allauth/mfa/base/forms.py
class BaseAuthenticateForm (line 10) | class BaseAuthenticateForm(forms.Form):
method __init__ (line 18) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 22) | def clean_code(self) -> str:
class AuthenticateForm (line 38) | class AuthenticateForm(BaseAuthenticateForm):
method save (line 39) | def save(self) -> None:
class ReauthenticateForm (line 43) | class ReauthenticateForm(BaseAuthenticateForm):
method save (line 44) | def save(self) -> None:
FILE: allauth/mfa/base/internal/flows.py
function delete_dangling_recovery_codes (line 10) | def delete_dangling_recovery_codes(user) -> Authenticator | None:
function delete_and_cleanup (line 19) | def delete_and_cleanup(request, authenticator) -> None:
function post_authentication (line 32) | def post_authentication(
function check_rate_limit (line 50) | def check_rate_limit(user) -> Callable[[], None]:
FILE: allauth/mfa/base/views.py
class AuthenticateView (line 28) | class AuthenticateView(TemplateView):
method dispatch (line 33) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method post (line 43) | def post(self, request, *args, **kwargs) -> HttpResponse:
method _build_forms (line 49) | def _build_forms(self):
method get_form_class (line 79) | def get_form_class(self):
method get_webauthn_form_class (line 82) | def get_webauthn_form_class(self):
method form_valid (line 87) | def form_valid(self, form) -> HttpResponse:
method form_invalid (line 91) | def form_invalid(self, form) -> HttpResponse:
method get_context_data (line 94) | def get_context_data(self, **kwargs) -> dict:
class ReauthenticateView (line 117) | class ReauthenticateView(BaseReauthenticateView):
method get_form_kwargs (line 121) | def get_form_kwargs(self) -> dict:
method get_form_class (line 126) | def get_form_class(self):
method form_valid (line 129) | def form_valid(self, form) -> HttpResponse:
class IndexView (line 138) | class IndexView(TemplateView):
method get_context_data (line 141) | def get_context_data(self, **kwargs):
class TrustView (line 163) | class TrustView(FormView):
method form_valid (line 167) | def form_valid(self, form):
method get_context_data (line 175) | def get_context_data(self, **kwargs) -> dict:
FILE: allauth/mfa/checks.py
function settings_check (line 5) | def settings_check(app_configs, **kwargs):
FILE: allauth/mfa/internal/constants.py
class LoginStageKey (line 4) | class LoginStageKey(str, Enum):
FILE: allauth/mfa/internal/flows/add.py
function validate_can_add_authenticator (line 15) | def validate_can_add_authenticator(user: AbstractBaseUser) -> None:
function redirect_if_add_not_allowed (line 30) | def redirect_if_add_not_allowed(function=None):
FILE: allauth/mfa/internal/flows/trust.py
class IssuedTrust (line 14) | class IssuedTrust:
function create_config_fingerprint (line 19) | def create_config_fingerprint(user: AbstractBaseUser) -> str:
function decode_trust_cookie (line 37) | def decode_trust_cookie(request: HttpRequest) -> list[IssuedTrust]:
function encode_trust_cookie (line 56) | def encode_trust_cookie(trusts: list[IssuedTrust]) -> str:
function trust_browser (line 61) | def trust_browser(
function is_trusted_browser (line 79) | def is_trusted_browser(request: HttpRequest, user: AbstractBaseUser) -> ...
FILE: allauth/mfa/migrations/0001_initial.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: allauth/mfa/migrations/0002_authenticator_timestamps.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: allauth/mfa/migrations/0003_authenticator_type_uniq.py
class Migration (line 6) | class Migration(migrations.Migration):
FILE: allauth/mfa/models.py
class AuthenticatorManager (line 18) | class AuthenticatorManager(models.Manager):
class Authenticator (line 22) | class Authenticator(models.Model):
class Type (line 23) | class Type(models.TextChoices):
class Meta (line 36) | class Meta:
method __str__ (line 50) | def __str__(self) -> str:
method wrap (line 55) | def wrap(self):
method record_usage (line 66) | def record_usage(self) -> None:
FILE: allauth/mfa/recovery_codes/forms.py
class GenerateRecoveryCodesForm (line 7) | class GenerateRecoveryCodesForm(forms.Form):
method __init__ (line 8) | def __init__(self, *args, **kwargs) -> None:
method clean (line 12) | def clean(self):
FILE: allauth/mfa/recovery_codes/internal/auth.py
class RecoveryCodes (line 10) | class RecoveryCodes:
method __init__ (line 11) | def __init__(self, instance: Authenticator) -> None:
method activate (line 15) | def activate(cls, user) -> "RecoveryCodes":
method generate_seed (line 33) | def generate_seed(self) -> str:
method _get_migrated_codes (line 37) | def _get_migrated_codes(self) -> list[str] | None:
method generate_codes (line 43) | def generate_codes(self) -> list[str]:
method _is_code_used (line 62) | def _is_code_used(self, i: int) -> bool:
method _mark_code_used (line 66) | def _mark_code_used(self, i: int) -> None:
method get_unused_codes (line 72) | def get_unused_codes(self) -> list[str]:
method _validate_migrated_code (line 84) | def _validate_migrated_code(self, code: str) -> bool | None:
method validate_code (line 100) | def validate_code(self, code: str) -> bool:
FILE: allauth/mfa/recovery_codes/internal/flows.py
function can_generate_recovery_codes (line 12) | def can_generate_recovery_codes(user) -> bool:
function generate_recovery_codes (line 20) | def generate_recovery_codes(request) -> Authenticator:
function view_recovery_codes (line 41) | def view_recovery_codes(request) -> Authenticator | None:
function auto_generate_recovery_codes (line 52) | def auto_generate_recovery_codes(request) -> Authenticator | None:
FILE: allauth/mfa/recovery_codes/views.py
class GenerateRecoveryCodesView (line 19) | class GenerateRecoveryCodesView(FormView):
method form_valid (line 24) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 28) | def get_context_data(self, **kwargs):
method get_form_kwargs (line 39) | def get_form_kwargs(self) -> dict:
method get_form_class (line 44) | def get_form_class(self):
class DownloadRecoveryCodesView (line 55) | class DownloadRecoveryCodesView(TemplateView):
method dispatch (line 59) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_context_data (line 68) | def get_context_data(self, **kwargs) -> dict:
method render_to_response (line 73) | def render_to_response(self, context, **response_kwargs):
class ViewRecoveryCodesView (line 83) | class ViewRecoveryCodesView(TemplateView):
method get_context_data (line 86) | def get_context_data(self, **kwargs) -> dict:
FILE: allauth/mfa/signals.py
function on_add_email (line 22) | def on_add_email(sender, email, user, **kwargs):
FILE: allauth/mfa/stages.py
class AuthenticateStage (line 13) | class AuthenticateStage(LoginStage):
method handle (line 17) | def handle(self):
method _should_handle (line 24) | def _should_handle(self, request) -> bool:
class TrustStage (line 38) | class TrustStage(LoginStage):
method handle (line 42) | def handle(self):
FILE: allauth/mfa/static/mfa/js/webauthn-json.js
function base64urlToBuffer (line 39) | function base64urlToBuffer (baseurl64String) {
function bufferToBase64url (line 50) | function bufferToBase64url (buffer) {
function convert (line 67) | function convert (conversionFn, schema2, input) {
function derived (line 105) | function derived (schema2, derive) {
function required (line 112) | function required (schema2) {
function optional (line 118) | function optional (schema2) {
function createRequestFromJSON (line 216) | function createRequestFromJSON (requestJSON) {
function createResponseToJSON (line 219) | function createResponseToJSON (credential) {
function create (line 226) | function create (requestJSON) {
function getRequestFromJSON (line 234) | function getRequestFromJSON (requestJSON) {
function getResponseToJSON (line 237) | function getResponseToJSON (credential) {
function get (line 244) | function get (requestJSON) {
function supported (line 254) | function supported () {
FILE: allauth/mfa/static/mfa/js/webauthn.js
function dispatchError (line 5) | function dispatchError (exception) {
function createCredentials (line 13) | async function createCredentials (credentials, passwordless) {
function signupForm (line 24) | function signupForm (o) {
function addForm (line 29) | function addForm (o) {
function getData (line 36) | function getData (o) {
function addOrSignupForm (line 43) | function addOrSignupForm (o, actionBtn, passwordlessFn) {
function loginForm (line 58) | function loginForm (o) {
function authenticateForm (line 84) | function authenticateForm (o) {
FILE: allauth/mfa/totp/forms.py
class ActivateTOTPForm (line 9) | class ActivateTOTPForm(forms.Form):
method __init__ (line 17) | def __init__(self, *args, **kwargs) -> None:
method clean_code (line 22) | def clean_code(self) -> str:
class DeactivateTOTPForm (line 30) | class DeactivateTOTPForm(forms.Form):
method __init__ (line 31) | def __init__(self, *args, **kwargs) -> None:
method clean (line 35) | def clean(self):
FILE: allauth/mfa/totp/internal/auth.py
function generate_totp_secret (line 20) | def generate_totp_secret(length: int = 20) -> str:
function get_totp_secret (line 25) | def get_totp_secret(regenerate: bool = False) -> str:
function yield_hotp_counters_from_time (line 34) | def yield_hotp_counters_from_time() -> Iterator[int]:
function hotp_value (line 41) | def hotp_value(secret: str, counter: int) -> int:
function format_hotp_value (line 59) | def format_hotp_value(value: int) -> str:
function _is_insecure_bypass (line 63) | def _is_insecure_bypass(code: str) -> bool:
function validate_totp_code (line 67) | def validate_totp_code(secret: str, code: str) -> bool:
class TOTP (line 78) | class TOTP:
method __init__ (line 79) | def __init__(self, instance: Authenticator) -> None:
method activate (line 83) | def activate(cls, user, secret: str) -> "TOTP":
method validate_code (line 90) | def validate_code(self, code: str) -> bool:
method _get_used_cache_key (line 102) | def _get_used_cache_key(self, code: str) -> str:
method _is_code_used (line 105) | def _is_code_used(self, code: str) -> bool:
method _mark_code_used (line 108) | def _mark_code_used(self, code: str) -> None:
FILE: allauth/mfa/totp/internal/flows.py
function activate_totp (line 14) | def activate_totp(request, form) -> tuple[Authenticator, Authenticator |...
function deactivate_totp (line 30) | def deactivate_totp(request, authenticator: Authenticator) -> None:
FILE: allauth/mfa/totp/views.py
class ActivateTOTPView (line 24) | class ActivateTOTPView(FormView):
method dispatch (line 28) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method get_context_data (line 33) | def get_context_data(self, **kwargs) -> dict:
method get_form_kwargs (line 52) | def get_form_kwargs(self) -> dict:
method get_form_class (line 57) | def get_form_class(self):
method get_success_url (line 60) | def get_success_url(self) -> str:
method form_valid (line 65) | def form_valid(self, form) -> HttpResponse:
class DeactivateTOTPView (line 75) | class DeactivateTOTPView(FormView):
method dispatch (line 80) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method _dispatch (line 91) | def _dispatch(self, request, *args, **kwargs):
method get_form_kwargs (line 98) | def get_form_kwargs(self) -> dict:
method get_form_class (line 108) | def get_form_class(self):
method form_valid (line 111) | def form_valid(self, form) -> HttpResponse:
FILE: allauth/mfa/utils.py
function encrypt (line 4) | def encrypt(text: str) -> str:
function decrypt (line 8) | def decrypt(encrypted_text: str) -> str:
function is_mfa_enabled (line 12) | def is_mfa_enabled(user, types=None) -> bool:
FILE: allauth/mfa/webauthn/forms.py
class _BaseAddWebAuthnForm (line 12) | class _BaseAddWebAuthnForm(forms.Form):
method __init__ (line 16) | def __init__(self, *args, **kwargs) -> None:
method clean_name (line 27) | def clean_name(self) -> str:
method clean (line 41) | def clean(self):
class AddWebAuthnForm (line 53) | class AddWebAuthnForm(_BaseAddWebAuthnForm):
class SignupWebAuthnForm (line 64) | class SignupWebAuthnForm(_BaseAddWebAuthnForm):
class AuthenticateWebAuthnForm (line 68) | class AuthenticateWebAuthnForm(forms.Form):
method __init__ (line 73) | def __init__(self, *args, **kwargs) -> None:
method clean_credential (line 77) | def clean_credential(self) -> Authenticator:
method save (line 91) | def save(self) -> None:
class LoginWebAuthnForm (line 101) | class LoginWebAuthnForm(AuthenticateWebAuthnForm):
method __init__ (line 105) | def __init__(self, *args, **kwargs) -> None:
class ReauthenticateWebAuthnForm (line 109) | class ReauthenticateWebAuthnForm(AuthenticateWebAuthnForm):
class EditWebAuthnForm (line 114) | class EditWebAuthnForm(forms.Form):
method __init__ (line 117) | def __init__(self, *args, **kwargs) -> None:
method save (line 123) | def save(self) -> Authenticator:
FILE: allauth/mfa/webauthn/internal/auth.py
function build_user_payload (line 36) | def build_user_payload(user) -> PublicKeyCredentialUserEntity:
function get_state (line 41) | def get_state() -> dict | None:
function set_state (line 45) | def set_state(state: dict) -> None:
function clear_state (line 49) | def clear_state() -> None:
function get_server (line 53) | def get_server() -> Fido2Server:
function parse_registration_response (line 63) | def parse_registration_response(response: Any) -> RegistrationResponse:
function begin_registration (line 70) | def begin_registration(user, passwordless: bool) -> dict:
function complete_registration (line 92) | def complete_registration(credential: dict) -> AuthenticatorData:
function get_credentials (line 106) | def get_credentials(user) -> list[AttestedCredentialData]:
function get_authenticator_by_credential_id (line 118) | def get_authenticator_by_credential_id(
function parse_authentication_response (line 133) | def parse_authentication_response(response: Any) -> AuthenticationResponse:
function begin_authentication (line 140) | def begin_authentication(user=None) -> dict:
function extract_user_from_response (line 150) | def extract_user_from_response(response: dict):
function complete_authentication (line 162) | def complete_authentication(user, response: dict) -> Authenticator:
class WebAuthn (line 180) | class WebAuthn:
method __init__ (line 181) | def __init__(self, instance):
method add (line 185) | def add(cls, user, name: str, credential: dict) -> "WebAuthn":
method name (line 198) | def name(self) -> str:
method name (line 202) | def name(self, name: str) -> None:
method authenticator_data (line 206) | def authenticator_data(self) -> AuthenticatorData:
method is_passwordless (line 212) | def is_passwordless(self) -> bool | None:
FILE: allauth/mfa/webauthn/internal/flows.py
function begin_registration (line 20) | def begin_registration(
function signup_authenticator (line 29) | def signup_authenticator(request, user, name: str, credential: dict) -> ...
function add_authenticator (line 36) | def add_authenticator(
function _signup_or_add_authenticator (line 49) | def _signup_or_add_authenticator(
function remove_authenticators (line 77) | def remove_authenticators(request, authenticators: Iterable[Authenticato...
function remove_authenticator (line 83) | def remove_authenticator(request, authenticator: Authenticator) -> None:
function perform_passwordless_login (line 91) | def perform_passwordless_login(request, authenticator: Authenticator, lo...
function did_use_passwordless_login (line 96) | def did_use_passwordless_login(request: HttpRequest) -> bool:
function reauthenticate (line 105) | def reauthenticate(request: HttpRequest, authenticator: Authenticator) -...
function rename_authenticator (line 109) | def rename_authenticator(request, authenticator: Authenticator, name: st...
FILE: allauth/mfa/webauthn/stages.py
class PasskeySignupStage (line 6) | class PasskeySignupStage(LoginStage):
method handle (line 10) | def handle(self):
FILE: allauth/mfa/webauthn/views.py
class AddWebAuthnView (line 33) | class AddWebAuthnView(FormView):
method get_context_data (line 37) | def get_context_data(self, **kwargs) -> dict:
method get_form_class (line 43) | def get_form_class(self):
method get_form_kwargs (line 46) | def get_form_kwargs(self) -> dict:
method get_success_url (line 51) | def get_success_url(self) -> str:
method form_valid (line 56) | def form_valid(self, form) -> HttpResponse:
class ListWebAuthnView (line 70) | class ListWebAuthnView(ListView):
method get_queryset (line 76) | def get_queryset(self):
class RemoveWebAuthnView (line 86) | class RemoveWebAuthnView(NextRedirectMixin, DeleteView):
method get_queryset (line 94) | def get_queryset(self):
method form_valid (line 99) | def form_valid(self, form) -> HttpResponse:
class LoginWebAuthnView (line 108) | class LoginWebAuthnView(RedirectAuthenticatedUserMixin, FormView):
method get (line 111) | def get(self, request, *args, **kwargs) -> HttpResponse:
method get_form_class (line 118) | def get_form_class(self):
method form_invalid (line 121) | def form_invalid(self, form) -> HttpResponse:
method form_valid (line 128) | def form_valid(self, form) -> HttpResponse:
class ReauthenticateWebAuthnView (line 139) | class ReauthenticateWebAuthnView(BaseReauthenticateView):
method get_form_class (line 143) | def get_form_class(self):
method get_form_kwargs (line 148) | def get_form_kwargs(self) -> dict:
method form_invalid (line 153) | def form_invalid(self, form) -> HttpResponse:
method form_valid (line 160) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 165) | def get_context_data(self, **kwargs) -> dict:
class EditWebAuthnView (line 176) | class EditWebAuthnView(NextRedirectMixin, UpdateView):
method get_form_class (line 181) | def get_form_class(self):
method get_queryset (line 184) | def get_queryset(self):
class SignupWebAuthnView (line 199) | class SignupWebAuthnView(FormView):
method _login_stage (line 204) | def _login_stage(self):
method get_context_data (line 207) | def get_context_data(self, **kwargs) -> dict:
method get_form_class (line 214) | def get_form_class(self):
method get_form_kwargs (line 217) | def get_form_kwargs(self) -> dict:
method form_valid (line 223) | def form_valid(self, form) -> HttpResponse:
FILE: allauth/socialaccount/adapter.py
class DefaultSocialAccountAdapter (line 20) | class DefaultSocialAccountAdapter(BaseAdapter):
method pre_social_login (line 45) | def pre_social_login(self, request, sociallogin):
method on_authentication_error (line 60) | def on_authentication_error(
method new_user (line 88) | def new_user(self, request, sociallogin):
method save_user (line 94) | def save_user(self, request, sociallogin, form=None):
method populate_user (line 109) | def populate_user(self, request, sociallogin, data):
method get_connect_redirect_url (line 136) | def get_connect_redirect_url(self, request, socialaccount):
method validate_disconnect (line 144) | def validate_disconnect(self, account, accounts) -> None:
method is_auto_signup_allowed (line 151) | def is_auto_signup_allowed(self, request, sociallogin):
method is_open_for_signup (line 156) | def is_open_for_signup(self, request, sociallogin):
method get_signup_form_initial_data (line 165) | def get_signup_form_initial_data(self, sociallogin):
method deserialize_instance (line 178) | def deserialize_instance(self, model, data):
method serialize_instance (line 181) | def serialize_instance(self, instance):
method list_providers (line 184) | def list_providers(self, request):
method get_provider (line 204) | def get_provider(self, request, provider, client_id=None):
method list_apps (line 226) | def list_apps(self, request, provider=None, client_id=None):
method get_app (line 292) | def get_app(self, request, provider, client_id=None):
method send_notification_mail (line 305) | def send_notification_mail(self, *args, **kwargs):
method get_requests_session (line 308) | def get_requests_session(self):
method is_email_verified (line 317) | def is_email_verified(self, provider, email):
method can_authenticate_by_email (line 343) | def can_authenticate_by_email(self, login, email):
method generate_state_param (line 361) | def generate_state_param(self, state: dict) -> str:
function get_adapter (line 375) | def get_adapter(request=None):
FILE: allauth/socialaccount/admin.py
class SocialAppForm (line 10) | class SocialAppForm(forms.ModelForm):
class Meta (line 11) | class Meta:
method __init__ (line 20) | def __init__(self, *args, **kwargs):
class SocialAppAdmin (line 27) | class SocialAppAdmin(admin.ModelAdmin):
class SocialAccountAdmin (line 36) | class SocialAccountAdmin(admin.ModelAdmin):
method get_search_fields (line 42) | def get_search_fields(self, request):
class SocialTokenAdmin (line 48) | class SocialTokenAdmin(admin.ModelAdmin):
method truncated_token (line 56) | def truncated_token(self, token):
FILE: allauth/socialaccount/app_settings.py
class AppSettings (line 1) | class AppSettings:
method __init__ (line 2) | def __init__(self, prefix: str) -> None:
method _setting (line 5) | def _setting(self, name: str, dflt):
method QUERY_EMAIL (line 11) | def QUERY_EMAIL(self) -> bool:
method AUTO_SIGNUP (line 19) | def AUTO_SIGNUP(self) -> bool:
method PROVIDERS (line 28) | def PROVIDERS(self) -> dict:
method _migrate_oidc (line 38) | def _migrate_oidc(self, oidc: dict) -> dict:
method EMAIL_REQUIRED (line 63) | def EMAIL_REQUIRED(self) -> bool:
method EMAIL_VERIFICATION (line 74) | def EMAIL_VERIFICATION(self):
method EMAIL_AUTHENTICATION (line 90) | def EMAIL_AUTHENTICATION(self) -> bool:
method EMAIL_AUTHENTICATION_AUTO_CONNECT (line 109) | def EMAIL_AUTHENTICATION_AUTO_CONNECT(self) -> bool:
method ADAPTER (line 123) | def ADAPTER(self) -> str:
method FORMS (line 130) | def FORMS(self) -> dict:
method LOGIN_ON_GET (line 134) | def LOGIN_ON_GET(self) -> bool:
method STORE_TOKENS (line 138) | def STORE_TOKENS(self) -> bool:
method UID_MAX_LENGTH (line 142) | def UID_MAX_LENGTH(self) -> int:
method SOCIALACCOUNT_STR (line 146) | def SOCIALACCOUNT_STR(self):
method REQUESTS_TIMEOUT (line 150) | def REQUESTS_TIMEOUT(self) -> int:
method OPENID_CONNECT_URL_PREFIX (line 154) | def OPENID_CONNECT_URL_PREFIX(self) -> str:
function __getattr__ (line 161) | def __getattr__(name):
FILE: allauth/socialaccount/apps.py
class SocialAccountConfig (line 7) | class SocialAccountConfig(AppConfig):
method ready (line 12) | def ready(self):
FILE: allauth/socialaccount/checks.py
function settings_check (line 5) | def settings_check(app_configs, **kwargs):
FILE: allauth/socialaccount/forms.py
class SignupForm (line 11) | class SignupForm(BaseSignupForm):
method __init__ (line 12) | def __init__(self, *args, **kwargs) -> None:
method save (line 25) | def save(self, request):
method validate_unique_email (line 31) | def validate_unique_email(self, value) -> str:
class DisconnectForm (line 40) | class DisconnectForm(forms.Form):
method __init__ (line 47) | def __init__(self, *args, **kwargs):
method clean (line 53) | def clean(self):
method save (line 60) | def save(self) -> None:
FILE: allauth/socialaccount/helpers.py
function render_authentication_error (line 17) | def render_authentication_error(
function complete_social_login (line 65) | def complete_social_login(request, sociallogin):
function socialaccount_user_display (line 73) | def socialaccount_user_display(socialaccount):
FILE: allauth/socialaccount/internal/flows/connect.py
function validate_disconnect (line 16) | def validate_disconnect(request, account) -> None:
function disconnect (line 42) | def disconnect(request, account) -> None:
function resume_connect (line 66) | def resume_connect(request, serialized_state):
function connect (line 71) | def connect(request, sociallogin):
function do_connect (line 105) | def do_connect(request, sociallogin):
FILE: allauth/socialaccount/internal/flows/email_authentication.py
function wipe_password (line 5) | def wipe_password(request, user, email: str) -> None:
FILE: allauth/socialaccount/internal/flows/login.py
function _login (line 19) | def _login(request, sociallogin):
function pre_social_login (line 31) | def pre_social_login(request, sociallogin) -> None:
function complete_login (line 41) | def complete_login(request, sociallogin, raises=False):
function _redirect (line 67) | def _redirect(request, sociallogin):
function _authenticate (line 72) | def _authenticate(request, sociallogin):
function record_authentication (line 84) | def record_authentication(request, sociallogin) -> None:
FILE: allauth/socialaccount/internal/flows/signup.py
function get_pending_signup (line 15) | def get_pending_signup(request) -> SocialLogin | None:
function redirect_to_signup (line 24) | def redirect_to_signup(request, sociallogin):
function clear_pending_signup (line 29) | def clear_pending_signup(request) -> None:
function signup_by_form (line 33) | def signup_by_form(request, sociallogin, form):
function process_auto_signup (line 41) | def process_auto_signup(request, sociallogin):
function process_auto_signup_email (line 52) | def process_auto_signup_email(request, sociallogin):
function process_auto_signup_phone (line 91) | def process_auto_signup_phone(request, sociallogin):
function process_signup (line 106) | def process_signup(request, sociallogin):
function complete_social_signup (line 132) | def complete_social_signup(request, sociallogin):
FILE: allauth/socialaccount/internal/jwtkit.py
function lookup_kid_pem_x509_certificate (line 14) | def lookup_kid_pem_x509_certificate(keys_data, kid):
function lookup_kid_jwk (line 28) | def lookup_kid_jwk(keys_data, kid):
function fetch_key (line 50) | def fetch_key(credential, keys_url, lookup):
function verify_jti (line 65) | def verify_jti(data: dict) -> None:
function verify_and_decode (line 80) | def verify_and_decode(
FILE: allauth/socialaccount/internal/statekit.py
function get_oldest_state (line 12) | def get_oldest_state(
function gc_states (line 29) | def gc_states(states: dict[str, tuple[dict[str, Any], float]]) -> None:
function get_states (line 36) | def get_states(request) -> dict[str, tuple[dict[str, Any], float]]:
function stash_state (line 43) | def stash_state(request, state: dict[str, Any], state_id: str | None = N...
function unstash_state (line 53) | def unstash_state(request, state_id: str) -> dict[str, Any] | None:
function unstash_last_state (line 64) | def unstash_last_state(request) -> dict[str, Any] | None:
FILE: allauth/socialaccount/migrations/0001_initial.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/migrations/0002_token_max_lengths.py
class Migration (line 5) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/migrations/0003_extra_data_default_dict.py
class Migration (line 4) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/migrations/0004_app_provider_id_settings.py
class Migration (line 6) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/migrations/0005_socialtoken_nullable_app.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/migrations/0006_alter_socialaccount_extra_data.py
class Migration (line 6) | class Migration(migrations.Migration):
FILE: allauth/socialaccount/models.py
class SocialAppManager (line 32) | class SocialAppManager(models.Manager):
method on_site (line 33) | def on_site(self, request):
class SocialApp (line 40) | class SocialApp(models.Model):
class Meta (line 81) | class Meta:
method __str__ (line 85) | def __str__(self) -> str:
method get_provider (line 88) | def get_provider(self, request):
class SocialAccount (line 93) | class SocialAccount(models.Model):
class Meta (line 124) | class Meta:
method authenticate (line 129) | def authenticate(self):
method __str__ (line 132) | def __str__(self) -> str:
method get_profile_url (line 137) | def get_profile_url(self):
method get_avatar_url (line 140) | def get_avatar_url(self):
method get_provider (line 143) | def get_provider(self, request=None):
method get_provider_account (line 153) | def get_provider_account(self):
class SocialToken (line 157) | class SocialToken(models.Model):
class Meta (line 173) | class Meta:
method __str__ (line 178) | def __str__(self) -> str:
class SocialLogin (line 182) | class SocialLogin:
method __init__ (line 216) | def __init__(
method connect (line 238) | def connect(self, request, user) -> None:
method is_headless (line 255) | def is_headless(self) -> bool:
method serialize (line 258) | def serialize(self) -> dict[str, Any]:
method deserialize (line 274) | def deserialize(cls, data: dict[str, Any]) -> "SocialLogin":
method save (line 304) | def save(self, request, connect: bool = False) -> None:
method is_existing (line 327) | def is_existing(self) -> bool:
method lookup (line 335) | def lookup(self) -> None:
method _lookup_by_socialaccount (line 343) | def _lookup_by_socialaccount(self) -> bool:
method _store_token (line 362) | def _store_token(self) -> None:
method _lookup_by_email (line 386) | def _lookup_by_email(self) -> None:
method _accept_login (line 397) | def _accept_login(self, request) -> None:
method get_redirect_url (line 407) | def get_redirect_url(self, request) -> str | None:
method state_from_request (line 412) | def state_from_request(cls, request) -> dict[str, Any]:
method stash_state (line 426) | def stash_state(cls, request, state: dict[str, Any] | None = None) -> ...
method unstash_state (line 433) | def unstash_state(cls, request) -> dict[str, Any] | None:
FILE: allauth/socialaccount/providers/__init__.py
class ProviderRegistry (line 10) | class ProviderRegistry:
method __init__ (line 11) | def __init__(self):
method get_class_list (line 15) | def get_class_list(self):
method register (line 19) | def register(self, cls):
method get_class (line 22) | def get_class(self, id):
method as_choices (line 25) | def as_choices(self):
method load (line 30) | def load(self):
FILE: allauth/socialaccount/providers/agave/provider.py
class AgaveAccount (line 6) | class AgaveAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class AgaveProvider (line 14) | class AgaveProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
method get_default_scope (line 30) | def get_default_scope(self):
FILE: allauth/socialaccount/providers/agave/views.py
class AgaveAdapter (line 10) | class AgaveAdapter(OAuth2Adapter):
method complete_login (line 20) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/amazon/provider.py
class AmazonAccount (line 6) | class AmazonAccount(ProviderAccount):
class AmazonProvider (line 10) | class AmazonProvider(OAuth2Provider):
method get_default_scope (line 16) | def get_default_scope(self):
method extract_uid (line 19) | def extract_uid(self, data):
method extract_common_fields (line 22) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/amazon/views.py
class AmazonOAuth2Adapter (line 9) | class AmazonOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/amazon_cognito/provider.py
class AmazonCognitoAccount (line 12) | class AmazonCognitoAccount(ProviderAccount):
method get_avatar_url (line 13) | def get_avatar_url(self):
method get_profile_url (line 16) | def get_profile_url(self):
class AmazonCognitoProvider (line 20) | class AmazonCognitoProvider(OAuth2Provider):
method extract_uid (line 26) | def extract_uid(self, data):
method extract_common_fields (line 29) | def extract_common_fields(self, data):
method get_default_scope (line 36) | def get_default_scope(self):
method extract_email_addresses (line 39) | def extract_email_addresses(self, data):
method extract_extra_data (line 51) | def extract_extra_data(self, data):
method get_slug (line 63) | def get_slug(cls):
FILE: allauth/socialaccount/providers/amazon_cognito/utils.py
function convert_to_python_bool_if_value_is_json_string_bool (line 1) | def convert_to_python_bool_if_value_is_json_string_bool(s):
FILE: allauth/socialaccount/providers/amazon_cognito/views.py
class AmazonCognitoOAuth2Adapter (line 11) | class AmazonCognitoOAuth2Adapter(OAuth2Adapter):
method settings (line 19) | def settings(self):
method domain (line 23) | def domain(self):
method access_token_url (line 32) | def access_token_url(self):
method authorize_url (line 36) | def authorize_url(self):
method profile_url (line 40) | def profile_url(self):
method complete_login (line 43) | def complete_login(self, request, app, token: SocialToken, **kwargs):
FILE: allauth/socialaccount/providers/angellist/provider.py
class AngelListAccount (line 6) | class AngelListAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class AngelListProvider (line 14) | class AngelListProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/angellist/views.py
class AngelListOAuth2Adapter (line 9) | class AngelListOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/apple/apple_session.py
function get_apple_session (line 7) | def get_apple_session(request):
FILE: allauth/socialaccount/providers/apple/client.py
function jwt_encode (line 13) | def jwt_encode(*args, **kwargs):
class Scope (line 21) | class Scope:
class AppleOAuth2Client (line 26) | class AppleOAuth2Client(OAuth2Client):
method generate_client_secret (line 33) | def generate_client_secret(self) -> str:
method get_client_id (line 55) | def get_client_id(self) -> str:
method get_access_token (line 59) | def get_access_token(self, code, pkce_code_verifier=None):
method get_redirect_url (line 86) | def get_redirect_url(self, authorization_url, scope, extra_params) -> ...
FILE: allauth/socialaccount/providers/apple/provider.py
class AppleAccount (line 12) | class AppleAccount(ProviderAccount):
method to_str (line 13) | def to_str(self):
class AppleProvider (line 28) | class AppleProvider(OAuth2Provider):
method extract_uid (line 35) | def extract_uid(self, data):
method extract_common_fields (line 38) | def extract_common_fields(self, data):
method extract_email_addresses (line 49) | def extract_email_addresses(self, data):
method get_default_scope (line 65) | def get_default_scope(self):
method verify_token (line 71) | def verify_token(self, request, token):
method get_auds (line 86) | def get_auds(self):
FILE: allauth/socialaccount/providers/apple/views.py
class AppleOAuth2Adapter (line 24) | class AppleOAuth2Adapter(OAuth2Adapter):
method get_verified_identity_data (line 32) | def get_verified_identity_data(cls, provider, id_token):
method parse_token (line 42) | def parse_token(self, data):
method complete_login (line 61) | def complete_login(self, request, app, token, **kwargs):
method get_user_scope_data (line 73) | def get_user_scope_data(self, request):
method get_access_token_data (line 82) | def get_access_token_data(self, request, app, client, pkce_code_verifi...
function apple_post_callback (line 106) | def apple_post_callback(request, finish_endpoint_name="apple_finish_call...
FILE: allauth/socialaccount/providers/asana/provider.py
class AsanaAccount (line 6) | class AsanaAccount(ProviderAccount):
class AsanaProvider (line 10) | class AsanaProvider(OAuth2Provider):
method extract_uid (line 16) | def extract_uid(self, data):
method extract_common_fields (line 22) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/asana/views.py
class AsanaOAuth2Adapter (line 9) | class AsanaOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/atlassian/provider.py
class AtlassianAccount (line 6) | class AtlassianAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
class AtlassianProvider (line 11) | class AtlassianProvider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
method extract_common_fields (line 20) | def extract_common_fields(self, data):
method get_default_scope (line 28) | def get_default_scope(self):
method get_auth_params (line 31) | def get_auth_params(self):
FILE: allauth/socialaccount/providers/atlassian/views.py
class AtlassianOAuth2Adapter (line 10) | class AtlassianOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token: SocialToken, **kwargs):
FILE: allauth/socialaccount/providers/auth0/provider.py
class Auth0Account (line 6) | class Auth0Account(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class Auth0Provider (line 11) | class Auth0Provider(OAuth2Provider):
method get_default_scope (line 17) | def get_default_scope(self):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/auth0/views.py
class Auth0OAuth2Adapter (line 10) | class Auth0OAuth2Adapter(OAuth2Adapter):
method complete_login (line 20) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/authentiq/provider.py
class Scope (line 8) | class Scope:
class AuthentiqAccount (line 44) | class AuthentiqAccount(ProviderAccount):
method get_profile_url (line 45) | def get_profile_url(self):
method get_avatar_url (line 48) | def get_avatar_url(self):
class AuthentiqProvider (line 52) | class AuthentiqProvider(OAuth2Provider):
method get_scope_from_request (line 58) | def get_scope_from_request(self, request):
method get_default_scope (line 73) | def get_default_scope(self):
method get_auth_params_from_request (line 79) | def get_auth_params_from_request(self, request, action):
method extract_uid (line 85) | def extract_uid(self, data):
method extract_common_fields (line 88) | def extract_common_fields(self, data):
method extract_extra_data (line 97) | def extract_extra_data(self, data):
method extract_email_addresses (line 100) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/authentiq/views.py
class AuthentiqOAuth2Adapter (line 12) | class AuthentiqOAuth2Adapter(OAuth2Adapter):
method complete_login (line 25) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/baidu/provider.py
class BaiduAccount (line 6) | class BaiduAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
method to_str (line 14) | def to_str(self):
class BaiduProvider (line 19) | class BaiduProvider(OAuth2Provider):
method extract_uid (line 25) | def extract_uid(self, data):
method extract_common_fields (line 28) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/baidu/views.py
class BaiduOAuth2Adapter (line 9) | class BaiduOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/base/constants.py
class AuthProcess (line 1) | class AuthProcess:
class AuthAction (line 7) | class AuthAction:
class AuthError (line 13) | class AuthError:
FILE: allauth/socialaccount/providers/base/provider.py
class ProviderException (line 20) | class ProviderException(Exception):
class Provider (line 24) | class Provider:
method __init__ (line 35) | def __init__(self, request, app=None) -> None:
method __str__ (line 41) | def __str__(self) -> str:
method get_slug (line 45) | def get_slug(cls) -> str:
method get_login_url (line 48) | def get_login_url(self, request, next=None, **kwargs) -> str:
method redirect_from_request (line 55) | def redirect_from_request(self, request) -> HttpResponse:
method get_redirect_from_request_kwargs (line 59) | def get_redirect_from_request_kwargs(self, request) -> dict:
method redirect (line 67) | def redirect(
method verify_token (line 75) | def verify_token(self, request, token):
method media_js (line 82) | def media_js(self, request) -> str:
method wrap_account (line 88) | def wrap_account(self, social_account):
method get_settings (line 91) | def get_settings(self) -> dict:
method sociallogin_from_response (line 94) | def sociallogin_from_response(self, request, response):
method extract_uid (line 164) | def extract_uid(self, data) -> str:
method extract_extra_data (line 172) | def extract_extra_data(self, data) -> dict:
method extract_common_fields (line 182) | def extract_common_fields(self, data) -> dict:
method cleanup_email_addresses (line 196) | def cleanup_email_addresses(
method extract_email_addresses (line 230) | def extract_email_addresses(self, data) -> list:
method get_package (line 241) | def get_package(cls) -> str:
method stash_redirect_state (line 247) | def stash_redirect_state(
method unstash_redirect_state (line 260) | def unstash_redirect_state(self, request, state_id):
method sub_id (line 267) | def sub_id(self) -> str:
method serialize (line 272) | def serialize(self) -> dict[str, Any]:
method deserialize (line 279) | def deserialize(cls, data: Any) -> "Provider":
class ProviderAccount (line 295) | class ProviderAccount:
method __init__ (line 296) | def __init__(self, social_account):
method get_profile_url (line 299) | def get_profile_url(self) -> str | None:
method get_avatar_url (line 302) | def get_avatar_url(self) -> str | None:
method get_brand (line 305) | def get_brand(self) -> dict:
method __str__ (line 318) | def __str__(self) -> str:
method get_user_data (line 321) | def get_user_data(self) -> dict | None:
method to_str (line 332) | def to_str(self) -> str:
FILE: allauth/socialaccount/providers/base/utils.py
function respond_to_login_on_get (line 7) | def respond_to_login_on_get(request, provider):
FILE: allauth/socialaccount/providers/base/views.py
class BaseLoginView (line 9) | class BaseLoginView(View):
method dispatch (line 12) | def dispatch(self, request, *args, **kwargs) -> HttpResponse:
method get_provider (line 21) | def get_provider(self):
FILE: allauth/socialaccount/providers/basecamp/provider.py
class BasecampAccount (line 6) | class BasecampAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
method get_user_data (line 10) | def get_user_data(self):
class BasecampProvider (line 14) | class BasecampProvider(OAuth2Provider):
method get_auth_params_from_request (line 20) | def get_auth_params_from_request(self, request, action):
method extract_uid (line 25) | def extract_uid(self, data):
method extract_common_fields (line 29) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/basecamp/views.py
class BasecampOAuth2Adapter (line 9) | class BasecampOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/battlenet/provider.py
class BattleNetAccount (line 6) | class BattleNetAccount(ProviderAccount):
method to_str (line 7) | def to_str(self):
class BattleNetProvider (line 12) | class BattleNetProvider(OAuth2Provider):
method extract_uid (line 18) | def extract_uid(self, data):
method extract_common_fields (line 25) | def extract_common_fields(self, data):
method get_default_scope (line 28) | def get_default_scope(self):
FILE: allauth/socialaccount/providers/battlenet/views.py
class Region (line 29) | class Region:
function _check_errors (line 39) | def _check_errors(response):
class BattleNetOAuth2Adapter (line 70) | class BattleNetOAuth2Adapter(OAuth2Adapter):
method battlenet_region (line 93) | def battlenet_region(self):
method battlenet_base_url (line 115) | def battlenet_base_url(self):
method access_token_url (line 122) | def access_token_url(self):
method authorize_url (line 126) | def authorize_url(self):
method profile_url (line 130) | def profile_url(self):
method complete_login (line 133) | def complete_login(self, request, app, token, **kwargs):
method get_callback_url (line 144) | def get_callback_url(self, request, app):
FILE: allauth/socialaccount/providers/bitbucket_oauth2/provider.py
class BitbucketOAuth2Account (line 8) | class BitbucketOAuth2Account(ProviderAccount):
method get_profile_url (line 9) | def get_profile_url(self):
method get_avatar_url (line 12) | def get_avatar_url(self):
class BitbucketOAuth2Provider (line 16) | class BitbucketOAuth2Provider(OAuth2Provider):
method extract_uid (line 22) | def extract_uid(self, data):
method extract_common_fields (line 25) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/bitbucket_oauth2/views.py
class BitbucketOAuth2Adapter (line 10) | class BitbucketOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
method get_email (line 26) | def get_email(self, token) -> str:
FILE: allauth/socialaccount/providers/bitly/provider.py
class BitlyAccount (line 6) | class BitlyAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class BitlyProvider (line 14) | class BitlyProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/bitly/views.py
class BitlyOAuth2Adapter (line 9) | class BitlyOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/box/provider.py
class BoxOAuth2Account (line 6) | class BoxOAuth2Account(ProviderAccount):
class BoxOAuth2Provider (line 10) | class BoxOAuth2Provider(OAuth2Provider):
method extract_uid (line 16) | def extract_uid(self, data):
method extract_common_fields (line 19) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/box/views.py
class BoxOAuth2Adapter (line 9) | class BoxOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/cilogon/provider.py
class Scope (line 8) | class Scope:
class CILogonAccount (line 15) | class CILogonAccount(ProviderAccount):
class CILogonProvider (line 19) | class CILogonProvider(OAuth2Provider):
method get_default_scope (line 25) | def get_default_scope(self):
method get_auth_params_from_request (line 31) | def get_auth_params_from_request(self, request, action):
method extract_uid (line 37) | def extract_uid(self, data):
method extract_common_fields (line 40) | def extract_common_fields(self, data):
method extract_email_addresses (line 48) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/cilogon/views.py
class CILogonOAuth2Adapter (line 9) | class CILogonOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/clever/provider.py
class CleverAccount (line 7) | class CleverAccount(ProviderAccount):
method get_avatar_url (line 8) | def get_avatar_url(self):
method get_user_data (line 12) | def get_user_data(self):
class CleverProvider (line 16) | class CleverProvider(OAuth2Provider):
method extract_uid (line 22) | def extract_uid(self, data):
method get_user_type (line 25) | def get_user_type(self, data):
method extract_common_fields (line 28) | def extract_common_fields(self, data):
method get_default_scope (line 40) | def get_default_scope(self):
FILE: allauth/socialaccount/providers/clever/views.py
class CleverOAuth2Adapter (line 12) | class CleverOAuth2Adapter(OAuth2Adapter):
method complete_login (line 20) | def complete_login(self, request, app, token, **kwargs):
method get_data (line 24) | def get_data(self, token):
FILE: allauth/socialaccount/providers/coinbase/provider.py
class CoinbaseAccount (line 6) | class CoinbaseAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class CoinbaseProvider (line 11) | class CoinbaseProvider(OAuth2Provider):
method get_default_scope (line 17) | def get_default_scope(self):
method extract_uid (line 21) | def extract_uid(self, data):
method extract_common_fields (line 24) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/coinbase/views.py
class CoinbaseOAuth2Adapter (line 9) | class CoinbaseOAuth2Adapter(OAuth2Adapter):
method authorize_url (line 13) | def authorize_url(self):
method access_token_url (line 17) | def access_token_url(self):
method profile_url (line 21) | def profile_url(self):
method complete_login (line 24) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/dataporten/provider.py
class DataportenAccount (line 6) | class DataportenAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class DataportenProvider (line 17) | class DataportenProvider(OAuth2Provider):
method extract_uid (line 23) | def extract_uid(self, data):
method extract_extra_data (line 30) | def extract_extra_data(self, data):
method extract_common_fields (line 51) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/dataporten/views.py
class DataportenOAuth2Adapter (line 10) | class DataportenOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/daum/provider.py
class DaumAccount (line 6) | class DaumAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class DaumProvider (line 11) | class DaumProvider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
FILE: allauth/socialaccount/providers/daum/views.py
class DaumOAuth2Adapter (line 9) | class DaumOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/digitalocean/provider.py
class DigitalOceanAccount (line 6) | class DigitalOceanAccount(ProviderAccount):
method get_user_data (line 7) | def get_user_data(self):
class DigitalOceanProvider (line 11) | class DigitalOceanProvider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
method extract_common_fields (line 20) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/digitalocean/views.py
class DigitalOceanOAuth2Adapter (line 9) | class DigitalOceanOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/dingtalk/client.py
class DingTalkOAuth2Client (line 5) | class DingTalkOAuth2Client(OAuth2Client):
method get_access_token (line 6) | def get_access_token(self, code, pkce_code_verifier=None):
FILE: allauth/socialaccount/providers/dingtalk/provider.py
class DingTalkAccount (line 6) | class DingTalkAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
method to_str (line 10) | def to_str(self):
class DingTalkProvider (line 14) | class DingTalkProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method get_default_scope (line 23) | def get_default_scope(self):
method extract_common_fields (line 26) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/dingtalk/views.py
class DingTalkOAuth2Adapter (line 11) | class DingTalkOAuth2Adapter(OAuth2Adapter):
method __init__ (line 18) | def __init__(self, request):
method complete_login (line 27) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/discogs/provider.py
class DiscogsAccount (line 6) | class DiscogsAccount(ProviderAccount):
method get_username (line 7) | def get_username(self):
method get_profile_url (line 10) | def get_profile_url(self):
class DiscogsProvider (line 14) | class DiscogsProvider(OAuthProvider):
method extract_uid (line 20) | def extract_uid(self, data):
FILE: allauth/socialaccount/providers/discogs/views.py
class DiscogsAPI (line 9) | class DiscogsAPI(OAuth):
method get_user_info (line 12) | def get_user_info(self):
class DiscogsOAuthAdapter (line 17) | class DiscogsOAuthAdapter(OAuthAdapter):
method complete_login (line 23) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/discord/provider.py
class DiscordAccount (line 7) | class DiscordAccount(ProviderAccount):
method validate_descriminator (line 8) | def validate_descriminator(self, discriminator):
method is_new_username_system (line 17) | def is_new_username_system(self):
method to_str (line 31) | def to_str(self):
method get_avatar_url (line 63) | def get_avatar_url(self):
class DiscordProvider (line 73) | class DiscordProvider(OAuth2Provider):
method extract_uid (line 79) | def extract_uid(self, data):
method extract_common_fields (line 82) | def extract_common_fields(self, data):
method get_auth_params_from_request (line 89) | def get_auth_params_from_request(self, request, action):
method get_default_scope (line 95) | def get_default_scope(self):
method extract_email_addresses (line 98) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/discord/views.py
class DiscordOAuth2Adapter (line 9) | class DiscordOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/disqus/provider.py
class DisqusAccount (line 8) | class DisqusAccount(ProviderAccount):
method get_profile_url (line 9) | def get_profile_url(self):
method get_avatar_url (line 12) | def get_avatar_url(self):
class DisqusProvider (line 16) | class DisqusProvider(OAuth2Provider):
method get_default_scope (line 22) | def get_default_scope(self):
method extract_uid (line 28) | def extract_uid(self, data):
method extract_common_fields (line 31) | def extract_common_fields(self, data):
method extract_email_addresses (line 38) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/disqus/views.py
class DisqusOAuth2Adapter (line 9) | class DisqusOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/douban/provider.py
class DoubanAccount (line 6) | class DoubanAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class DoubanProvider (line 14) | class DoubanProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/douban/views.py
class DoubanOAuth2Adapter (line 13) | class DoubanOAuth2Adapter(OAuth2Adapter):
method complete_login (line 19) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/doximity/provider.py
class DoximityAccount (line 6) | class DoximityAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class DoximityProvider (line 14) | class DoximityProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
method get_default_scope (line 32) | def get_default_scope(self):
FILE: allauth/socialaccount/providers/doximity/views.py
class DoximityOAuth2Adapter (line 9) | class DoximityOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/draugiem/provider.py
class DraugiemAccount (line 7) | class DraugiemAccount(ProviderAccount):
method get_avatar_url (line 8) | def get_avatar_url(self):
class DraugiemProvider (line 26) | class DraugiemProvider(Provider):
method get_login_url (line 31) | def get_login_url(self, request, **kwargs):
method extract_uid (line 37) | def extract_uid(self, data):
method extract_common_fields (line 40) | def extract_common_fields(self, data):
method extract_extra_data (line 48) | def extract_extra_data(self, data):
FILE: allauth/socialaccount/providers/draugiem/views.py
class DraugiemApiError (line 20) | class DraugiemApiError(Exception):
function login (line 28) | def login(request):
function callback (line 43) | def callback(request):
function draugiem_complete_login (line 73) | def draugiem_complete_login(request, app, code):
FILE: allauth/socialaccount/providers/drip/provider.py
class DripAccount (line 7) | class DripAccount(ProviderAccount):
class DripProvider (line 11) | class DripProvider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
method extract_common_fields (line 22) | def extract_common_fields(self, data):
method extract_email_addresses (line 25) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/drip/views.py
class DripOAuth2Adapter (line 11) | class DripOAuth2Adapter(OAuth2Adapter):
method complete_login (line 20) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/dropbox/provider.py
class DropboxOAuth2Account (line 7) | class DropboxOAuth2Account(ProviderAccount):
class DropboxOAuth2Provider (line 11) | class DropboxOAuth2Provider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
method extract_common_fields (line 20) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/dropbox/views.py
class DropboxOAuth2Adapter (line 9) | class DropboxOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/dummy/forms.py
class AuthenticateForm (line 6) | class AuthenticateForm(forms.Form):
FILE: allauth/socialaccount/providers/dummy/provider.py
class DummyAccount (line 13) | class DummyAccount(ProviderAccount):
class DummyProvider (line 17) | class DummyProvider(Provider):
method get_login_url (line 25) | def get_login_url(self, request, **kwargs):
method extract_uid (line 31) | def extract_uid(self, data):
method extract_common_fields (line 34) | def extract_common_fields(self, data):
method redirect (line 48) | def redirect(self, request, process, next_url=None, data=None, **kwargs):
method extract_email_addresses (line 60) | def extract_email_addresses(self, data):
method verify_token (line 74) | def verify_token(self, request, token):
FILE: allauth/socialaccount/providers/dummy/views.py
class LoginView (line 22) | class LoginView(BaseLoginView):
class AuthenticateView (line 29) | class AuthenticateView(FormView):
method dispatch (line 34) | def dispatch(self, request, *args, **kwargs) -> HttpResponseBase:
method form_valid (line 49) | def form_valid(self, form) -> HttpResponse:
method get_context_data (line 54) | def get_context_data(self, **kwargs) -> dict:
FILE: allauth/socialaccount/providers/dwolla/provider.py
class DwollaAccount (line 8) | class DwollaAccount(ProviderAccount):
class DwollaProvider (line 12) | class DwollaProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/dwolla/views.py
class DwollaOAuth2Adapter (line 32) | class DwollaOAuth2Adapter(OAuth2Adapter):
method complete_login (line 41) | def complete_login(self, request, app, token, response, **kwargs):
FILE: allauth/socialaccount/providers/edmodo/provider.py
class EdmodoAccount (line 6) | class EdmodoAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class EdmodoProvider (line 14) | class EdmodoProvider(OAuth2Provider):
method get_default_scope (line 20) | def get_default_scope(self):
method extract_uid (line 23) | def extract_uid(self, data):
method extract_common_fields (line 26) | def extract_common_fields(self, data):
method extract_extra_data (line 33) | def extract_extra_data(self, data):
FILE: allauth/socialaccount/providers/edmodo/views.py
class EdmodoOAuth2Adapter (line 9) | class EdmodoOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/edx/provider.py
class EdxAccount (line 6) | class EdxAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
class EdxProvider (line 12) | class EdxProvider(OAuth2Provider):
method get_default_scope (line 18) | def get_default_scope(self):
method extract_uid (line 21) | def extract_uid(self, data):
method extract_common_fields (line 25) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/edx/views.py
class EdxOAuth2Adapter (line 10) | class EdxOAuth2Adapter(OAuth2Adapter):
method complete_login (line 24) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/eventbrite/provider.py
class EventbriteAccount (line 9) | class EventbriteAccount(ProviderAccount):
method get_avatar_url (line 12) | def get_avatar_url(self):
method to_str (line 16) | def to_str(self):
class EventbriteProvider (line 23) | class EventbriteProvider(OAuth2Provider):
method extract_uid (line 31) | def extract_uid(self, data):
method get_default_scope (line 35) | def get_default_scope(self):
method extract_common_fields (line 39) | def extract_common_fields(self, data):
method extract_email_addresses (line 56) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/eventbrite/views.py
class EventbriteOAuth2Adapter (line 11) | class EventbriteOAuth2Adapter(OAuth2Adapter):
method complete_login (line 20) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/eveonline/provider.py
class EveOnlineAccount (line 7) | class EveOnlineAccount(ProviderAccount):
method get_profile_url (line 8) | def get_profile_url(self):
method get_avatar_url (line 13) | def get_avatar_url(self):
method to_str (line 18) | def to_str(self):
class EveOnlineProvider (line 31) | class EveOnlineProvider(OAuth2Provider):
method get_default_scope (line 37) | def get_default_scope(self):
method extract_uid (line 43) | def extract_uid(self, data):
method extract_common_fields (line 46) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/eveonline/views.py
class EveOnlineOAuth2Adapter (line 9) | class EveOnlineOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/evernote/provider.py
class EvernoteAccount (line 6) | class EvernoteAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class EvernoteProvider (line 14) | class EvernoteProvider(OAuthProvider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/evernote/views.py
class EvernoteOAuthAdapter (line 11) | class EvernoteOAuthAdapter(OAuthAdapter):
method complete_login (line 20) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/exist/provider.py
class ExistAccount (line 6) | class ExistAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
class ExistProvider (line 14) | class ExistProvider(OAuth2Provider):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
method get_default_scope (line 35) | def get_default_scope(self):
FILE: allauth/socialaccount/providers/exist/views.py
class ExistOAuth2Adapter (line 9) | class ExistOAuth2Adapter(OAuth2Adapter):
method complete_login (line 15) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/facebook/flows.py
function compute_appsecret_proof (line 27) | def compute_appsecret_proof(app, token) -> str:
function complete_login (line 36) | def complete_login(request, provider, token):
function get_app_token (line 49) | def get_app_token(provider):
function inspect_token (line 69) | def inspect_token(provider, input_token) -> None:
function verify_token (line 84) | def verify_token(
function verify_limited_login_token (line 132) | def verify_limited_login_token(
FILE: allauth/socialaccount/providers/facebook/forms.py
class FacebookConnectForm (line 4) | class FacebookConnectForm(forms.Form):
FILE: allauth/socialaccount/providers/facebook/locale.py
function _build_locale_table (line 9) | def _build_locale_table(filename_or_file):
function get_default_locale_callable (line 41) | def get_default_locale_callable():
FILE: allauth/socialaccount/providers/facebook/provider.py
class FacebookAccount (line 34) | class FacebookAccount(ProviderAccount):
method get_profile_url (line 35) | def get_profile_url(self):
class FacebookProvider (line 39) | class FacebookProvider(OAuth2Provider):
method __init__ (line 53) | def __init__(self, *args, **kwargs):
method get_method (line 57) | def get_method(self):
method get_login_url (line 60) | def get_login_url(self, request, **kwargs):
method _get_locale_callable (line 75) | def _get_locale_callable(self):
method get_locale_for_request (line 80) | def get_locale_for_request(self, request):
method get_default_scope (line 85) | def get_default_scope(self):
method get_fields (line 91) | def get_fields(self):
method get_auth_params_from_request (line 108) | def get_auth_params_from_request(self, request, action):
method get_init_params (line 116) | def get_init_params(self, request, app):
method get_fb_login_options (line 122) | def get_fb_login_options(self, request):
method get_sdk_url (line 129) | def get_sdk_url(self, request):
method media_js (line 140) | def media_js(self, request):
method get_nonce (line 165) | def get_nonce(self, request, or_create=False, pop=False):
method extract_uid (line 175) | def extract_uid(self, data):
method extract_common_fields (line 178) | def extract_common_fields(self, data):
method extract_email_addresses (line 187) | def extract_email_addresses(self, data):
method verify_token (line 196) | def verify_token(self, request, token: dict):
FILE: allauth/socialaccount/providers/facebook/static/facebook/js/fbconnect.js
function postForm (line 5) | function postForm (action, data) {
function setLocationHref (line 21) | function setLocationHref (url) {
FILE: allauth/socialaccount/providers/facebook/views.py
class FacebookOAuth2Adapter (line 35) | class FacebookOAuth2Adapter(OAuth2Adapter):
method complete_login (line 48) | def complete_login(self, request, app, access_token, **kwargs):
class LoginByTokenView (line 57) | class LoginByTokenView(View):
method dispatch (line 59) | def dispatch(self, request):
method get (line 71) | def get(self, request):
method post (line 76) | def post(self, request):
FILE: allauth/socialaccount/providers/feedly/provider.py
class FeedlyAccount (line 6) | class FeedlyAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class FeedlyProvider (line 11) | class FeedlyProvider(OAuth2Provider):
method get_default_scope (line 17) | def get_default_scope(self):
method extract_uid (line 20) | def extract_uid(self, data):
method extract_common_fields (line 23) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/feedly/views.py
class FeedlyOAuth2Adapter (line 10) | class FeedlyOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/feishu/client.py
class FeishuOAuth2Client (line 10) | class FeishuOAuth2Client(OAuth2Client):
method get_redirect_url (line 15) | def get_redirect_url(self, authorization_url, scope, extra_params):
method app_access_token (line 31) | def app_access_token(self):
method get_access_token (line 49) | def get_access_token(self, code, pkce_code_verifier=None):
FILE: allauth/socialaccount/providers/feishu/provider.py
class FeishuAccount (line 6) | class FeishuAccount(ProviderAccount):
method get_avatar_url (line 7) | def get_avatar_url(self):
class FeishuProvider (line 11) | class FeishuProvider(OAuth2Provider):
method extract_uid (line 17) | def extract_uid(self, data):
method extract_common_fields (line 20) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/feishu/views.py
class FeishuOAuth2Adapter (line 16) | class FeishuOAuth2Adapter(OAuth2Adapter):
method authorize_url (line 29) | def authorize_url(self):
method complete_login (line 34) | def complete_login(self, request, app, token, **kwargs):
method get_client (line 49) | def get_client(self, request, app):
FILE: allauth/socialaccount/providers/figma/provider.py
class FigmaAccount (line 8) | class FigmaAccount(ProviderAccount):
method get_avatar_url (line 9) | def get_avatar_url(self):
class FigmaProvider (line 13) | class FigmaProvider(OAuth2Provider):
method extract_uid (line 19) | def extract_uid(self, data):
method extract_common_fields (line 22) | def extract_common_fields(self, data):
method extract_email_addresses (line 28) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/figma/views.py
class FigmaOAuth2Adapter (line 9) | class FigmaOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/fivehundredpx/provider.py
class FiveHundredPxAccount (line 8) | class FiveHundredPxAccount(ProviderAccount):
method get_profile_url (line 9) | def get_profile_url(self):
method get_avatar_url (line 12) | def get_avatar_url(self):
class FiveHundredPxProvider (line 16) | class FiveHundredPxProvider(OAuthProvider):
method get_default_scope (line 23) | def get_default_scope(self):
method extract_uid (line 26) | def extract_uid(self, data):
method extract_common_fields (line 29) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/fivehundredpx/views.py
class FiveHundredPxAPI (line 12) | class FiveHundredPxAPI(OAuth):
method get_user_info (line 19) | def get_user_info(self):
class FiveHundredPxOAuthAdapter (line 23) | class FiveHundredPxOAuthAdapter(OAuthAdapter):
method complete_login (line 29) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/flickr/provider.py
class FlickrAccount (line 6) | class FlickrAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
method to_str (line 13) | def to_str(self):
class FlickrProvider (line 31) | class FlickrProvider(OAuthProvider):
method get_default_scope (line 37) | def get_default_scope(self):
method get_auth_params_from_request (line 41) | def get_auth_params_from_request(self, request, action):
method get_profile_fields (line 47) | def get_profile_fields(self):
method extract_uid (line 59) | def extract_uid(self, data):
method extract_common_fields (line 62) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/flickr/views.py
class FlickrAPI (line 11) | class FlickrAPI(OAuth):
method get_user_info (line 14) | def get_user_info(self):
class FlickrOAuthAdapter (line 27) | class FlickrOAuthAdapter(OAuthAdapter):
method complete_login (line 33) | def complete_login(self, request, app, token, response):
FILE: allauth/socialaccount/providers/foursquare/provider.py
class FoursquareAccount (line 6) | class FoursquareAccount(ProviderAccount):
method get_profile_url (line 7) | def get_profile_url(self):
method get_avatar_url (line 10) | def get_avatar_url(self):
method to_str (line 13) | def to_str(self):
class FoursquareProvider (line 18) | class FoursquareProvider(OAuth2Provider):
method extract_uid (line 24) | def extract_uid(self, data):
method extract_common_fields (line 27) | def extract_common_fields(self, data):
FILE: allauth/socialaccount/providers/foursquare/views.py
class FoursquareOAuth2Adapter (line 9) | class FoursquareOAuth2Adapter(OAuth2Adapter):
method complete_login (line 17) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/frontier/provider.py
class FrontierAccount (line 9) | class FrontierAccount(ProviderAccount):
method get_profile_url (line 10) | def get_profile_url(self):
method get_avatar_url (line 13) | def get_avatar_url(self):
class FrontierProvider (line 20) | class FrontierProvider(OAuth2Provider):
method get_default_scope (line 26) | def get_default_scope(self):
method extract_uid (line 30) | def extract_uid(self, data):
method extract_common_fields (line 33) | def extract_common_fields(self, data):
method extract_email_addresses (line 41) | def extract_email_addresses(self, data):
FILE: allauth/socialaccount/providers/frontier/views.py
class FrontierOAuth2Adapter (line 9) | class FrontierOAuth2Adapter(OAuth2Adapter):
method complete_login (line 16) | def complete_login(self, request, app, token, **kwargs):
FILE: allauth/socialaccount/providers/fxa/provider.py
class FirefoxAccountsAccount (line 7) | class FirefoxAccountsAccount(ProviderAccount):
class FirefoxAccountsProvider (line 11) | class FirefoxAccountsProvider(OAuth2Provider):
method get_default_scope (line 17) | def get_default_scope(self):
method
Condensed preview — 1853 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,130K chars).
[
{
"path": ".dir-locals.el",
"chars": 117,
"preview": ";;; This file contains project-specific emacs configuration\n((python-mode . ((apheleia-formatter . (black isort)))))\n"
},
{
"path": ".djlintrc",
"chars": 43,
"preview": "{\n\"custom_blocks\": \"element,slot,setvar\"\n}\n"
},
{
"path": ".editorconfig",
"chars": 365,
"preview": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_"
},
{
"path": ".envrc",
"chars": 220,
"preview": "export DIRENV_WARN_TIMEOUT=20s\n\neval \"$(devenv direnvrc)\"\n\n# The use_devenv function supports passing flags to the deven"
},
{
"path": ".gitea/ISSUE_TEMPLATE/discussion.md",
"chars": 125,
"preview": "---\nname: \"Discussion\"\nabout: \"Overall discussions and general questions\"\ntitle: \"\"\nassignees: []\nlabels:\n- \"Discussion\""
},
{
"path": ".gitea/ISSUE_TEMPLATE/issue.md",
"chars": 123,
"preview": "---\nname: \"Issue\"\nabout: \"For cases clearly pointing to an issue in django-allauth\"\ntitle: \"\"\nlabels: \"\"\nassignees: []\n\n"
},
{
"path": ".gitea/pull_request_template.md",
"chars": 1107,
"preview": "# Submitting Pull Requests\n\n## General\n\n - [ ] Make sure you use [semantic commit messages](https://seesparkbox.com/foun"
},
{
"path": ".github/FUNDING.yml",
"chars": 642,
"preview": "# These are supported funding model platforms\n\ngithub: pennersr\npatreon: # Replace with a single Patreon username\nopen_c"
},
{
"path": ".github/ISSUE_TEMPLATE/issue.md",
"chars": 296,
"preview": "---\nname: \"Issue (when not using Codeberg)\"\nabout: \"\\U0001F6D1 Please use https://codeberg.org/allauth/django-allauth/is"
},
{
"path": ".github/SECURITY.md",
"chars": 79,
"preview": "# Security Policy\n\nPlease report security issues only to security@allauth.org.\n"
},
{
"path": ".github/dependabot.yml",
"chars": 231,
"preview": "version: 2\nupdates:\n- package-ecosystem: \"github-actions\"\n directory: \"/\"\n groups:\n GitHub_Actions:\n patterns:"
},
{
"path": ".github/pull_request_template.md",
"chars": 124,
"preview": "# 🛑 Stop\n\nThe project has been moved to https://codeberg.org/allauth/django-allauth.\nPlease submit your pull request the"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1910,
"preview": "name: CI\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n test:\n runs-on: ubuntu-2"
},
{
"path": ".gitignore",
"chars": 465,
"preview": "*.pyc\n*~\n.idea\n.project\n.pydevproject\n*.geany\ndocs/_build\nbuild\ndist\n*.egg*\nexamples/**/local_settings.py\nnode_modules/\n"
},
{
"path": ".readthedocs.yaml",
"chars": 604,
"preview": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
},
{
"path": ".woodpecker.yaml",
"chars": 1140,
"preview": "when:\n - event: pull_request\n - event: [push, tag, manual]\n branch: main\n\nsteps:\n test:\n image: python:${PYTHON"
},
{
"path": "AUTHORS",
"chars": 3011,
"preview": "django-allauth was started by Raymond Penners\n(<raymond.penners@intenct.nl> or @pennersr) in October 2010, inspired\nby a"
},
{
"path": "CONTRIBUTING.rst",
"chars": 5585,
"preview": "Contributing to django-allauth\n==============================\n\n.. begin-contributing\n\nThank you for considering contribu"
},
{
"path": "ChangeLog.rst",
"chars": 16678,
"preview": "65.15.0 (2025-03-09)\n********************\n\n.. note::\n\n 💙 **Is django-allauth's authentication the entrance to your bu"
},
{
"path": "LICENSE",
"chars": 1104,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2010-2026 Raymond Penners and contributors\n\nPermission is hereby granted, free of c"
},
{
"path": "Makefile",
"chars": 1411,
"preview": "PYTHON = python\n\n.PHONY: usage\nusage:\n\t@echo 'Usage: make [target]'\n\n.PHONY: po\npo:\n\t( cd allauth ; $(PYTHON) ../manage."
},
{
"path": "README.rst",
"chars": 6473,
"preview": "\n==========================\nWelcome to django-allauth!\n==========================\n\n.. image:: https://codeberg.org/allau"
},
{
"path": "allauth/__init__.py",
"chars": 683,
"preview": "r\"\"\"\n _ ___ __ __ .___________. __ __\n /\\| |/\\ / \\ | | | | | || | | |\n \\ `"
},
{
"path": "allauth/account/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/account/adapter.py",
"chars": 36334,
"preview": "import html\nimport inspect\nimport json\nimport warnings\nfrom http import HTTPStatus\nfrom urllib.parse import urlparse\n\nfr"
},
{
"path": "allauth/account/admin.py",
"chars": 1993,
"preview": "from django.contrib import admin, messages\nfrom django.utils.translation import gettext_lazy as _\n\nfrom allauth.account "
},
{
"path": "allauth/account/app_settings.py",
"chars": 20401,
"preview": "import warnings\nfrom enum import Enum\n\nfrom allauth import app_settings as allauth_settings\nfrom allauth.core.internal.c"
},
{
"path": "allauth/account/apps.py",
"chars": 715,
"preview": "from django.apps import AppConfig\nfrom django.conf import settings\nfrom django.core.exceptions import ImproperlyConfigur"
},
{
"path": "allauth/account/auth_backends.py",
"chars": 4960,
"preview": "from threading import local\n\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.backends import Mod"
},
{
"path": "allauth/account/authentication.py",
"chars": 198,
"preview": "from allauth.account.internal.flows.login import AUTHENTICATION_METHODS_SESSION_KEY\n\n\ndef get_authentication_records(req"
},
{
"path": "allauth/account/checks.py",
"chars": 6399,
"preview": "from django.core.checks import Critical, Warning, register\n\n\n@register()\ndef adapter_check(app_configs, **kwargs):\n f"
},
{
"path": "allauth/account/decorators.py",
"chars": 4132,
"preview": "from functools import wraps\n\nfrom django.conf import settings\nfrom django.contrib.auth import REDIRECT_FIELD_NAME\nfrom d"
},
{
"path": "allauth/account/fields.py",
"chars": 2641,
"preview": "from django import forms\nfrom django.contrib.auth import password_validation\nfrom django.core.validators import RegexVal"
},
{
"path": "allauth/account/forms.py",
"chars": 32069,
"preview": "from django import forms\nfrom django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model, password_validation\nfrom d"
},
{
"path": "allauth/account/internal/__init__.py",
"chars": 65,
"preview": "from allauth.account.internal import flows\n\n\n__all__ = [\"flows\"]\n"
},
{
"path": "allauth/account/internal/constants.py",
"chars": 160,
"preview": "from enum import Enum\n\n\nclass LoginStageKey(str, Enum):\n LOGIN_BY_CODE = \"login_by_code\"\n VERIFY_EMAIL = \"verify_e"
},
{
"path": "allauth/account/internal/decorators.py",
"chars": 1150,
"preview": "from functools import wraps\n\nfrom django.contrib.auth import decorators\nfrom django.http import HttpResponseRedirect\nfro"
},
{
"path": "allauth/account/internal/emailkit.py",
"chars": 576,
"preview": "from django.core.exceptions import ValidationError\nfrom django.core.validators import validate_email\nfrom django.db.mode"
},
{
"path": "allauth/account/internal/flows/__init__.py",
"chars": 573,
"preview": "from allauth.account.internal.flows import (\n email_verification,\n email_verification_by_code,\n login,\n logi"
},
{
"path": "allauth/account/internal/flows/code_verification.py",
"chars": 2714,
"preview": "import abc\nimport time\nfrom typing import Any\n\nfrom django.contrib.auth import get_user_model\n\nfrom allauth.account.inte"
},
{
"path": "allauth/account/internal/flows/email_verification.py",
"chars": 12685,
"preview": "from django.contrib import messages\nfrom django.contrib.auth.base_user import AbstractBaseUser\nfrom django.http import H"
},
{
"path": "allauth/account/internal/flows/email_verification_by_code.py",
"chars": 5001,
"preview": "from typing import Optional\n\nfrom django.utils.functional import cached_property\n\nfrom allauth.account import app_settin"
},
{
"path": "allauth/account/internal/flows/login.py",
"chars": 4786,
"preview": "import time\nfrom typing import Any\n\nfrom django.core import exceptions, validators\nfrom django.http import HttpRequest, "
},
{
"path": "allauth/account/internal/flows/login_by_code.py",
"chars": 5802,
"preview": "from django.contrib import messages\n\nfrom allauth.account import app_settings\nfrom allauth.account.adapter import get_ad"
},
{
"path": "allauth/account/internal/flows/logout.py",
"chars": 843,
"preview": "from django.contrib import messages\nfrom django.http import HttpRequest\n\nfrom allauth.account.internal.flows.password_re"
},
{
"path": "allauth/account/internal/flows/manage_email.py",
"chars": 8309,
"preview": "from django.contrib import messages\nfrom django.contrib.auth.base_user import AbstractBaseUser\nfrom django.http import H"
},
{
"path": "allauth/account/internal/flows/password_change.py",
"chars": 1945,
"preview": "from django.contrib import messages\nfrom django.contrib.auth import update_session_auth_hash\nfrom django.contrib.auth.mo"
},
{
"path": "allauth/account/internal/flows/password_reset.py",
"chars": 4283,
"preview": "from urllib.parse import quote\n\nfrom django.contrib import messages\nfrom django.contrib.auth.models import AbstractBaseU"
},
{
"path": "allauth/account/internal/flows/password_reset_by_code.py",
"chars": 2771,
"preview": "from typing import Optional\n\nfrom django.http import HttpRequest, HttpResponse\n\nfrom allauth.account import app_settings"
},
{
"path": "allauth/account/internal/flows/phone_verification.py",
"chars": 6748,
"preview": "from typing import Optional\n\nfrom django.contrib import messages\nfrom django.http import HttpRequest\n\nfrom allauth.accou"
},
{
"path": "allauth/account/internal/flows/reauthentication.py",
"chars": 3976,
"preview": "import time\n\nfrom django.contrib.auth import REDIRECT_FIELD_NAME\nfrom django.http import HttpRequest, HttpResponseRedire"
},
{
"path": "allauth/account/internal/flows/signup.py",
"chars": 3527,
"preview": "from importlib import import_module\n\nfrom django import forms\nfrom django.core import exceptions\nfrom django.http import"
},
{
"path": "allauth/account/internal/stagekit.py",
"chars": 1619,
"preview": "import time\n\nfrom django.http import HttpResponseRedirect\nfrom django.urls import reverse\n\nfrom allauth.account import a"
},
{
"path": "allauth/account/internal/userkit.py",
"chars": 2333,
"preview": "from django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.models import A"
},
{
"path": "allauth/account/management/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/account/management/commands/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/account/management/commands/account_unsetmultipleprimaryemails.py",
"chars": 1643,
"preview": "from django.contrib.auth import get_user_model\nfrom django.core.management.base import BaseCommand\nfrom django.db.models"
},
{
"path": "allauth/account/managers.py",
"chars": 4916,
"preview": "from __future__ import annotations\n\nfrom datetime import timedelta\nfrom typing import TYPE_CHECKING\n\nfrom django.db impo"
},
{
"path": "allauth/account/middleware.py",
"chars": 3594,
"preview": "import os\nfrom http import HTTPStatus\nfrom types import SimpleNamespace\n\nfrom django.http import HttpResponseRedirect\nfr"
},
{
"path": "allauth/account/migrations/0001_initial.py",
"chars": 3320,
"preview": "import django.utils.timezone\nfrom django.conf import settings\nfrom django.db import migrations, models\n\n\nUNIQUE_EMAIL = "
},
{
"path": "allauth/account/migrations/0002_email_max_length.py",
"chars": 836,
"preview": "from django.conf import settings\nfrom django.db import migrations, models\n\n\nUNIQUE_EMAIL = getattr(settings, \"ACCOUNT_UN"
},
{
"path": "allauth/account/migrations/0003_alter_emailaddress_create_unique_verified_email.py",
"chars": 889,
"preview": "# Generated by Django 4.2.2 on 2023-06-14 12:52\n\nfrom django.conf import settings\nfrom django.db import migrations, mode"
},
{
"path": "allauth/account/migrations/0004_alter_emailaddress_drop_unique_email.py",
"chars": 550,
"preview": "from django.conf import settings\nfrom django.db import migrations, models\n\n\nEMAIL_MAX_LENGTH = getattr(settings, \"ACCOUN"
},
{
"path": "allauth/account/migrations/0005_emailaddress_idx_upper_email.py",
"chars": 530,
"preview": "# Generated by Django 4.2.4 on 2023-08-23 18:17\n\nimport django.db.models.functions.text\nfrom django.db import migrations"
},
{
"path": "allauth/account/migrations/0006_emailaddress_lower.py",
"chars": 820,
"preview": "from django.conf import settings\nfrom django.db import migrations\nfrom django.db.models.functions import Lower\n\nfrom all"
},
{
"path": "allauth/account/migrations/0007_emailaddress_idx_email.py",
"chars": 665,
"preview": "from django.conf import settings\nfrom django.db import migrations, models\n\n\nEMAIL_MAX_LENGTH = getattr(settings, \"ACCOUN"
},
{
"path": "allauth/account/migrations/0008_emailaddress_unique_primary_email_fixup.py",
"chars": 1649,
"preview": "from django.conf import settings\nfrom django.db import migrations\nfrom django.db.models import Count\n\n\ndef forwards(apps"
},
{
"path": "allauth/account/migrations/0009_emailaddress_unique_primary_email.py",
"chars": 545,
"preview": "# Generated by Django 4.2.11 on 2024-05-09 06:09\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations."
},
{
"path": "allauth/account/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/account/mixins.py",
"chars": 6585,
"preview": "from django.contrib.auth import REDIRECT_FIELD_NAME\nfrom django.core.exceptions import ImproperlyConfigured\nfrom django."
},
{
"path": "allauth/account/models.py",
"chars": 12006,
"preview": "from __future__ import annotations\n\nimport datetime\nimport time\nfrom typing import TYPE_CHECKING, Any, TypedDict\n\nfrom d"
},
{
"path": "allauth/account/reauthentication.py",
"chars": 308,
"preview": "import warnings\n\nfrom allauth.account.internal.flows.reauthentication import (\n did_recently_authenticate,\n raise_"
},
{
"path": "allauth/account/signals.py",
"chars": 1170,
"preview": "from django.contrib.auth.signals import user_logged_out # noqa\nfrom django.dispatch import Signal\n\n\n# Provides the argu"
},
{
"path": "allauth/account/stages.py",
"chars": 8520,
"preview": "import logging\n\nfrom allauth import app_settings as allauth_settings\nfrom allauth.account import app_settings\nfrom allau"
},
{
"path": "allauth/account/static/account/js/account.js",
"chars": 437,
"preview": "(function () {\n const allauth = window.allauth = window.allauth || {}\n\n function manageEmailForm (o) {\n const actio"
},
{
"path": "allauth/account/static/account/js/onload.js",
"chars": 495,
"preview": "(function () {\n document.addEventListener('DOMContentLoaded', function () {\n Array.from(document.querySelectorAll('s"
},
{
"path": "allauth/account/templatetags/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/account/templatetags/account.py",
"chars": 481,
"preview": "from django import template\n\nfrom allauth.account.utils import user_display\n\n\nregister = template.Library()\n\n\n@register."
},
{
"path": "allauth/account/urls.py",
"chars": 4149,
"preview": "from django.conf import settings\nfrom django.urls import path, re_path\n\nfrom allauth import app_settings as allauth_app_"
},
{
"path": "allauth/account/utils.py",
"chars": 10896,
"preview": "import unicodedata\nfrom collections import OrderedDict\n\nfrom django.contrib.auth import REDIRECT_FIELD_NAME, get_user_mo"
},
{
"path": "allauth/account/views.py",
"chars": 52211,
"preview": "from http import HTTPStatus\n\nfrom django.contrib import messages\nfrom django.contrib.auth.decorators import login_requir"
},
{
"path": "allauth/app_settings.py",
"chars": 2641,
"preview": "from django.apps import apps\n\nfrom allauth.core.internal.cryptokit import UserCodeFormat\n\n\nclass AppSettings:\n def __"
},
{
"path": "allauth/core/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/core/context.py",
"chars": 398,
"preview": "from contextlib import contextmanager\nfrom contextvars import ContextVar\n\n\n_request_var = ContextVar(\"request\", default="
},
{
"path": "allauth/core/exceptions.py",
"chars": 561,
"preview": "class ImmediateHttpResponse(Exception):\n \"\"\"\n This exception is used to interrupt the flow of processing to immedi"
},
{
"path": "allauth/core/internal/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/core/internal/adapter.py",
"chars": 502,
"preview": "from django.core.exceptions import ValidationError\n\nfrom allauth.core import context\n\n\nclass BaseAdapter:\n def __init"
},
{
"path": "allauth/core/internal/cryptokit.py",
"chars": 1584,
"preview": "import math\nimport string\nfrom typing import TypedDict\n\nfrom django.utils.crypto import get_random_string\n\n\nclass UserCo"
},
{
"path": "allauth/core/internal/httpkit.py",
"chars": 6406,
"preview": "import ipaddress\nimport json\nfrom urllib.parse import parse_qs, quote, urlencode, urlparse, urlunparse\n\nfrom django impo"
},
{
"path": "allauth/core/internal/jwkkit.py",
"chars": 1452,
"preview": "# https://github.com/jpadilla/pyjwt/issues/1032\nimport base64\nimport hashlib\nimport json\n\nimport jwt\nfrom cryptography.h"
},
{
"path": "allauth/core/internal/modelkit.py",
"chars": 3674,
"preview": "import base64\nimport json\n\nfrom django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured\nfrom django.core.f"
},
{
"path": "allauth/core/internal/ratelimit.py",
"chars": 6275,
"preview": "\"\"\"\nRate limiting in this implementation relies on a cache and uses non-atomic\noperations, making it vulnerable to race "
},
{
"path": "allauth/core/internal/sessionkit.py",
"chars": 346,
"preview": "from django.contrib.auth import get_user\nfrom django.contrib.sessions.backends.base import SessionBase\nfrom django.http "
},
{
"path": "allauth/core/internal/urlkit.py",
"chars": 405,
"preview": "from django.conf import settings\nfrom django.urls import resolve\n\n\ndef script_aware_resolve(path: str):\n \"\"\"\n Djan"
},
{
"path": "allauth/core/ratelimit.py",
"chars": 1936,
"preview": "from django.conf import settings\nfrom django.http import HttpResponse\n\nfrom allauth import app_settings\nfrom allauth.cor"
},
{
"path": "allauth/decorators.py",
"chars": 435,
"preview": "from functools import wraps\n\nfrom allauth.core import ratelimit\n\n\ndef rate_limit(*, action, **rl_kwargs):\n def decora"
},
{
"path": "allauth/exceptions.py",
"chars": 194,
"preview": "import warnings\n\nfrom allauth.core.exceptions import ImmediateHttpResponse\n\n\n__all__ = [\"ImmediateHttpResponse\"]\n\n\nwarni"
},
{
"path": "allauth/headless/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/account/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/account/inputs.py",
"chars": 9308,
"preview": "from django.core.exceptions import ValidationError\nfrom django.core.validators import validate_email\n\nfrom allauth.accou"
},
{
"path": "allauth/headless/account/response.py",
"chars": 1582,
"preview": "from http import HTTPStatus\n\nfrom allauth.headless.adapter import get_adapter\nfrom allauth.headless.base.response import"
},
{
"path": "allauth/headless/account/urls.py",
"chars": 4077,
"preview": "from django.urls import include, path\n\nfrom allauth import app_settings as allauth_settings\nfrom allauth.account import "
},
{
"path": "allauth/headless/account/views.py",
"chars": 19863,
"preview": "from http import HTTPStatus\n\nfrom django.http import HttpResponse\nfrom django.utils.decorators import method_decorator\n\n"
},
{
"path": "allauth/headless/adapter.py",
"chars": 5698,
"preview": "import dataclasses\nimport uuid\nfrom typing import Any, Optional\n\nfrom django.contrib.auth import get_user_model\nfrom dja"
},
{
"path": "allauth/headless/app_settings.py",
"chars": 2259,
"preview": "class AppSettings:\n def __init__(self, prefix: str) -> None:\n self.prefix = prefix\n\n def _setting(self, nam"
},
{
"path": "allauth/headless/apps.py",
"chars": 261,
"preview": "from django.apps import AppConfig\nfrom django.utils.translation import gettext_lazy as _\n\n\nclass HeadlessConfig(AppConfi"
},
{
"path": "allauth/headless/base/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/base/response.py",
"chars": 7539,
"preview": "from http import HTTPStatus\n\nfrom allauth import app_settings as allauth_settings\nfrom allauth.account import app_settin"
},
{
"path": "allauth/headless/base/urls.py",
"chars": 253,
"preview": "from django.urls import path\n\nfrom allauth.headless.base import views\n\n\ndef build_urlpatterns(client):\n return [\n "
},
{
"path": "allauth/headless/base/views.py",
"chars": 2156,
"preview": "from django.utils.decorators import classonlymethod\n\nfrom allauth.account.stages import LoginStage, LoginStageController"
},
{
"path": "allauth/headless/checks.py",
"chars": 498,
"preview": "from django.core.checks import Critical, register\n\n\n@register()\ndef settings_check(app_configs, **kwargs):\n from alla"
},
{
"path": "allauth/headless/constants.py",
"chars": 1003,
"preview": "from enum import Enum\n\nfrom allauth.account.internal.constants import LoginStageKey as AccountLoginStageKey\nfrom allauth"
},
{
"path": "allauth/headless/contrib/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/contrib/ninja/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/contrib/ninja/security.py",
"chars": 1735,
"preview": "from django.http import HttpRequest\n\nfrom ninja.security.base import AuthBase\n\nfrom allauth.core.internal.httpkit import"
},
{
"path": "allauth/headless/contrib/rest_framework/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/contrib/rest_framework/authentication.py",
"chars": 1682,
"preview": "from django.http import HttpRequest\n\nfrom rest_framework import authentication\nfrom rest_framework.exceptions import Aut"
},
{
"path": "allauth/headless/internal/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/internal/authkit.py",
"chars": 2950,
"preview": "from contextlib import contextmanager\nfrom typing import Any\n\nfrom django.utils.functional import SimpleLazyObject, empt"
},
{
"path": "allauth/headless/internal/decorators.py",
"chars": 1509,
"preview": "from functools import wraps\nfrom types import SimpleNamespace\n\nfrom django.middleware.csrf import get_token\nfrom django."
},
{
"path": "allauth/headless/internal/restkit/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/internal/restkit/inputs.py",
"chars": 388,
"preview": "from django.forms import (\n BooleanField,\n CharField,\n ChoiceField,\n Field,\n Form,\n ModelChoiceField,\n"
},
{
"path": "allauth/headless/internal/restkit/response.py",
"chars": 1944,
"preview": "from http import HTTPStatus\nfrom typing import Any\n\nfrom django.forms.utils import ErrorList\nfrom django.http import Jso"
},
{
"path": "allauth/headless/internal/restkit/views.py",
"chars": 1939,
"preview": "import json\n\nfrom django.http import HttpResponseBadRequest\nfrom django.views.generic import View\n\nfrom allauth.core.exc"
},
{
"path": "allauth/headless/internal/sessionkit.py",
"chars": 1623,
"preview": "from importlib import import_module\n\nfrom django.conf import settings\nfrom django.contrib.auth import SESSION_KEY, get_u"
},
{
"path": "allauth/headless/mfa/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/mfa/inputs.py",
"chars": 2104,
"preview": "from allauth.account.forms import BaseSignupForm\nfrom allauth.headless.internal.restkit import inputs\nfrom allauth.mfa.b"
},
{
"path": "allauth/headless/mfa/response.py",
"chars": 3251,
"preview": "from http import HTTPStatus\n\nfrom allauth.headless.base.response import APIResponse\nfrom allauth.mfa import app_settings"
},
{
"path": "allauth/headless/mfa/urls.py",
"chars": 3332,
"preview": "from django.urls import include, path\n\nfrom allauth.headless.constants import Client\nfrom allauth.headless.mfa import vi"
},
{
"path": "allauth/headless/mfa/views.py",
"chars": 10330,
"preview": "from http import HTTPStatus\n\nfrom django.core.exceptions import ValidationError\nfrom django.http import HttpResponse\n\nfr"
},
{
"path": "allauth/headless/socialaccount/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/socialaccount/forms.py",
"chars": 1252,
"preview": "from django import forms\nfrom django.core.exceptions import ObjectDoesNotExist\n\nfrom allauth.account.adapter import get_"
},
{
"path": "allauth/headless/socialaccount/inputs.py",
"chars": 4727,
"preview": "from django.core.exceptions import ValidationError\n\nfrom allauth.core import context\nfrom allauth.headless.adapter impor"
},
{
"path": "allauth/headless/socialaccount/internal.py",
"chars": 3211,
"preview": "from django.core.exceptions import PermissionDenied, ValidationError\nfrom django.http import HttpResponseRedirect\n\nfrom "
},
{
"path": "allauth/headless/socialaccount/response.py",
"chars": 3785,
"preview": "from allauth.headless.account.response import email_address_data\nfrom allauth.headless.adapter import get_adapter\nfrom a"
},
{
"path": "allauth/headless/socialaccount/urls.py",
"chars": 1687,
"preview": "from django.urls import include, path\n\nfrom allauth.headless.socialaccount import views\n\n\ndef build_urlpatterns(client):"
},
{
"path": "allauth/headless/socialaccount/views.py",
"chars": 3907,
"preview": "from django.core.exceptions import ValidationError\nfrom django.http import HttpResponse\n\nfrom allauth.core.exceptions im"
},
{
"path": "allauth/headless/spec/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/spec/doc/description.md",
"chars": 9069,
"preview": "# Introduction\n\nWelcome to the django-allauth API specification. This API is intended to be\nconsumed by two different ki"
},
{
"path": "allauth/headless/spec/doc/openapi.yaml",
"chars": 118879,
"preview": "openapi: 3.0.3\ninfo:\n version: \"1\"\n title: \"django-allauth: Headless API\"\n description:\n $ref: \"./description.md\"\n"
},
{
"path": "allauth/headless/spec/internal/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/spec/internal/openapikit.py",
"chars": 3229,
"preview": "import dataclasses\nimport datetime\nfrom typing import Any, Union, get_args, get_origin\n\nfrom django import forms\n\nfrom a"
},
{
"path": "allauth/headless/spec/internal/schema.py",
"chars": 6057,
"preview": "from pathlib import Path\n\nfrom django.urls import reverse\nfrom django.urls.exceptions import Resolver404\n\nfrom allauth.a"
},
{
"path": "allauth/headless/spec/urls.py",
"chars": 536,
"preview": "from django.urls import path\n\nfrom allauth.headless import app_settings\nfrom allauth.headless.spec import views\n\n\nurlpat"
},
{
"path": "allauth/headless/spec/views.py",
"chars": 1360,
"preview": "import json\n\nfrom django.http import HttpResponse\nfrom django.utils.decorators import method_decorator\nfrom django.views"
},
{
"path": "allauth/headless/templates/headless/spec/redoc_cdn.html",
"chars": 579,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta name=\"viewport\"\n content=\"width=device-width, ini"
},
{
"path": "allauth/headless/templates/headless/spec/swagger_cdn.html",
"chars": 1071,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <link type=\"text/css\"\n rel=\"stylesheet\"\n href=\"https"
},
{
"path": "allauth/headless/tokens/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/tokens/base.py",
"chars": 285,
"preview": "import warnings\n\nfrom allauth.headless.tokens.strategies.base import AbstractTokenStrategy\n\n\n__all__ = [\"AbstractTokenSt"
},
{
"path": "allauth/headless/tokens/inputs.py",
"chars": 133,
"preview": "from allauth.headless.internal.restkit import inputs\n\n\nclass RefreshTokenInput(inputs.Input):\n refresh_token = inputs"
},
{
"path": "allauth/headless/tokens/response.py",
"chars": 408,
"preview": "from django.http import HttpRequest\n\nfrom allauth.headless.base.response import APIResponse\n\n\nclass RefreshTokenResponse"
},
{
"path": "allauth/headless/tokens/sessions.py",
"chars": 293,
"preview": "import warnings\n\nfrom allauth.headless.tokens.strategies.sessions import SessionTokenStrategy\n\n\n__all__ = [\"SessionToken"
},
{
"path": "allauth/headless/tokens/strategies/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/tokens/strategies/base.py",
"chars": 2297,
"preview": "import abc\nfrom typing import Any\n\nfrom django.contrib.sessions.backends.base import SessionBase\nfrom django.http import"
},
{
"path": "allauth/headless/tokens/strategies/jwt/__init__.py",
"chars": 110,
"preview": "from allauth.headless.tokens.strategies.jwt.strategy import JWTTokenStrategy\n\n\n__all__ = [\"JWTTokenStrategy\"]\n"
},
{
"path": "allauth/headless/tokens/strategies/jwt/internal.py",
"chars": 7673,
"preview": "import base64\nimport binascii\nimport hashlib\nimport secrets\nimport time\nimport uuid\nfrom dataclasses import dataclass\nfr"
},
{
"path": "allauth/headless/tokens/strategies/jwt/strategy.py",
"chars": 3240,
"preview": "from typing import Any\n\nfrom django.contrib.sessions.backends.base import SessionBase\nfrom django.http import HttpReques"
},
{
"path": "allauth/headless/tokens/strategies/sessions.py",
"chars": 792,
"preview": "from django.contrib.sessions.backends.base import SessionBase\nfrom django.http import HttpRequest\n\nfrom allauth.headless"
},
{
"path": "allauth/headless/tokens/urls.py",
"chars": 270,
"preview": "from django.urls import path\n\nfrom allauth.headless.tokens import views\n\n\ndef build_urlpatterns(client):\n return [\n "
},
{
"path": "allauth/headless/tokens/views.py",
"chars": 1022,
"preview": "from django.http import HttpRequest\n\nfrom allauth.headless import app_settings\nfrom allauth.headless.base.views import A"
},
{
"path": "allauth/headless/urls.py",
"chars": 2768,
"preview": "from django.urls import include, path\n\nfrom allauth import app_settings as allauth_settings\nfrom allauth.headless import"
},
{
"path": "allauth/headless/usersessions/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/headless/usersessions/inputs.py",
"chars": 441,
"preview": "from allauth.headless.internal.restkit import inputs\nfrom allauth.usersessions.models import UserSession\n\n\nclass SelectS"
},
{
"path": "allauth/headless/usersessions/response.py",
"chars": 812,
"preview": "from allauth.headless.base.response import APIResponse\nfrom allauth.usersessions import app_settings\n\n\nclass SessionsRes"
},
{
"path": "allauth/headless/usersessions/urls.py",
"chars": 453,
"preview": "from django.urls import include, path\n\nfrom allauth.headless.usersessions import views\n\n\ndef build_urlpatterns(client):\n"
},
{
"path": "allauth/headless/usersessions/views.py",
"chars": 1154,
"preview": "from django.http import HttpResponse\n\nfrom allauth.headless.base.response import AuthenticationResponse\nfrom allauth.hea"
},
{
"path": "allauth/idp/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/adapter.py",
"chars": 4902,
"preview": "import hashlib\nimport uuid\nfrom collections.abc import Iterable\nfrom typing import Any, Literal\n\nfrom django.contrib.aut"
},
{
"path": "allauth/idp/oidc/admin.py",
"chars": 1415,
"preview": "from django.contrib import admin, messages\nfrom django.utils.html import escape\nfrom django.utils.safestring import mark"
},
{
"path": "allauth/idp/oidc/app_settings.py",
"chars": 2836,
"preview": "from allauth import app_settings as allauth_settings\nfrom allauth.core.internal.cryptokit import UserCodeFormat\n\n\nclass "
},
{
"path": "allauth/idp/oidc/apps.py",
"chars": 308,
"preview": "from django.apps import AppConfig\n\nfrom allauth import app_settings\n\n\nclass OIDCConfig(AppConfig):\n name = \"allauth.i"
},
{
"path": "allauth/idp/oidc/contrib/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/contrib/ninja/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/contrib/ninja/security.py",
"chars": 1530,
"preview": "from django.http import HttpRequest\n\nfrom ninja.security.base import AuthBase\n\nfrom allauth.idp.oidc.internal.oauthlib.s"
},
{
"path": "allauth/idp/oidc/contrib/rest_framework/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/contrib/rest_framework/authentication.py",
"chars": 583,
"preview": "from rest_framework.authentication import BaseAuthentication\n\nfrom allauth.idp.oidc.internal.oauthlib.server import get_"
},
{
"path": "allauth/idp/oidc/contrib/rest_framework/permissions.py",
"chars": 1597,
"preview": "from rest_framework.permissions import BasePermission\n\nfrom allauth.idp.oidc.internal.scope import is_scope_granted\nfrom"
},
{
"path": "allauth/idp/oidc/forms.py",
"chars": 7469,
"preview": "from typing import Any\n\nfrom django import forms\nfrom django.forms import widgets\nfrom django.utils.translation import g"
},
{
"path": "allauth/idp/oidc/internal/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/internal/clientkit.py",
"chars": 5110,
"preview": "import re\nfrom re import Pattern\nfrom urllib.parse import ParseResult, parse_qsl, urlparse\n\nfrom django.core.exceptions "
},
{
"path": "allauth/idp/oidc/internal/flows.py",
"chars": 695,
"preview": "from django.http import HttpRequest\n\nfrom allauth.account.internal.flows.logout import logout\nfrom allauth.idp.oidc.mode"
},
{
"path": "allauth/idp/oidc/internal/oauthlib/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/internal/oauthlib/authorization_codes.py",
"chars": 2238,
"preview": "from django.core.cache import cache\n\nfrom allauth.account.models import EmailAddress\nfrom allauth.idp.oidc import app_se"
},
{
"path": "allauth/idp/oidc/internal/oauthlib/device_codes.py",
"chars": 4094,
"preview": "import time\n\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.models import AbstractBaseUser\nfrom"
},
{
"path": "allauth/idp/oidc/internal/oauthlib/request_validator.py",
"chars": 16230,
"preview": "import uuid\nfrom datetime import timedelta\n\nfrom django.utils import timezone\n\nimport jwt\nfrom oauthlib.openid import Re"
},
{
"path": "allauth/idp/oidc/internal/oauthlib/server.py",
"chars": 3146,
"preview": "import secrets\nimport time\nimport uuid\n\nfrom django.urls import reverse\n\nimport jwt\nfrom oauthlib.oauth2.rfc8628.endpoin"
},
{
"path": "allauth/idp/oidc/internal/oauthlib/utils.py",
"chars": 2594,
"preview": "from urllib.parse import urlparse, urlunparse\n\nfrom django.forms import Form\nfrom django.http import HttpRequest, HttpRe"
},
{
"path": "allauth/idp/oidc/internal/scope.py",
"chars": 1212,
"preview": "from allauth.idp.oidc.models import Token\n\n\ndef _is_scope_granted(\n scope: str | list[str] | list[list[str]],\n gra"
},
{
"path": "allauth/idp/oidc/internal/tokens.py",
"chars": 1049,
"preview": "import jwt\n\nfrom allauth.core.internal import jwkkit\nfrom allauth.idp.oidc import app_settings\nfrom allauth.idp.oidc.ada"
},
{
"path": "allauth/idp/oidc/migrations/0001_initial.py",
"chars": 6106,
"preview": "import django.db.models.deletion\nimport django.utils.timezone\nfrom django.conf import settings\nfrom django.db import mig"
},
{
"path": "allauth/idp/oidc/migrations/0002_client_default_scopes.py",
"chars": 578,
"preview": "from django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n dependencies = [\n (\"allaut"
},
{
"path": "allauth/idp/oidc/migrations/0003_client_allow_uri_wildcards.py",
"chars": 600,
"preview": "from django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n dependencies = [\n (\"allaut"
},
{
"path": "allauth/idp/oidc/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "allauth/idp/oidc/models.py",
"chars": 8514,
"preview": "from django.conf import settings\nfrom django.contrib.auth.hashers import check_password, make_password\nfrom django.db im"
},
{
"path": "allauth/idp/oidc/urls.py",
"chars": 1968,
"preview": "from django.urls import include, path\n\nfrom allauth.idp.oidc import app_settings, views\n\n\napp_name = \"oidc\"\n\n\n_api_urlpa"
},
{
"path": "allauth/idp/oidc/views.py",
"chars": 19846,
"preview": "from http import HTTPStatus\n\nfrom django.contrib.auth import REDIRECT_FIELD_NAME\nfrom django.contrib.auth.decorators imp"
},
{
"path": "allauth/idp/urls.py",
"chars": 123,
"preview": "from django.urls import include, path\n\n\napp_name = \"idp\"\nurlpatterns = [\n path(\"\", include(\"allauth.idp.oidc.urls\")),"
},
{
"path": "allauth/locale/ar/LC_MESSAGES/django.po",
"chars": 62161,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "allauth/locale/az/LC_MESSAGES/django.po",
"chars": 61598,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
}
]
// ... and 1653 more files (download for full content)
About this extraction
This page contains the full source code of the pennersr/django-allauth GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1853 files (5.4 MB), approximately 1.5M tokens, and a symbol index with 4690 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.