From b05072bccec622b2a41db066b8ced0eea4abe844 Mon Sep 17 00:00:00 2001 From: Harris Tzovanakis Date: Tue, 17 Sep 2024 09:58:29 +0200 Subject: [PATCH] backoffice: Addition of headless `allauth` for ORCID login * ref: cern-sis/issues-inspire/issues/509 Co-authored-by: Harris Tzovanakis --- backoffice/.envs/local/.django | 3 ++ backoffice/config/settings/base.py | 5 ++- backoffice/config/urls.py | 5 +++ backoffice/poetry.lock | 66 ++++-------------------------- backoffice/pyproject.toml | 2 +- ruff.toml | 2 +- 6 files changed, 21 insertions(+), 62 deletions(-) diff --git a/backoffice/.envs/local/.django b/backoffice/.envs/local/.django index a0fd784e..fd5afd91 100644 --- a/backoffice/.envs/local/.django +++ b/backoffice/.envs/local/.django @@ -24,3 +24,6 @@ AIRFLOW_BASE_URL=http://airflow-webserver:8080 AIRFLOW_TOKEN=YWlyZmxvdzphaXJmbG93 SERVICENOW_URL=https://cerntraining.service-now.com + +# Frontend +FRONTEND_LOGIN_SUCCESS=http://127.0.0.1:5000/success diff --git a/backoffice/config/settings/base.py b/backoffice/config/settings/base.py index e8fa6288..ba06396d 100644 --- a/backoffice/config/settings/base.py +++ b/backoffice/config/settings/base.py @@ -95,6 +95,7 @@ "allauth", "allauth.account", "allauth.socialaccount", + "allauth.headless", "django_celery_beat", "rest_framework", "rest_framework.authtoken", @@ -127,7 +128,7 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model AUTH_USER_MODEL = "users.User" # https://docs.djangoproject.com/en/dev/ref/settings/#login-redirect-url -LOGIN_REDIRECT_URL = "users:redirect" +LOGIN_REDIRECT_URL = env("FRONTEND_LOGIN_SUCCESS", default="users:redirect") # https://docs.djangoproject.com/en/dev/ref/settings/#login-url LOGIN_URL = "account_login" @@ -331,7 +332,7 @@ # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_USER_MODEL_USERNAME_FIELD = None # https://django-allauth.readthedocs.io/en/latest/configuration.html -ACCOUNT_EMAIL_VERIFICATION = "mandatory" +ACCOUNT_EMAIL_VERIFICATION = False # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_ADAPTER = "backoffice.users.adapters.AccountAdapter" # https://django-allauth.readthedocs.io/en/latest/forms.html diff --git a/backoffice/config/urls.py b/backoffice/config/urls.py index 045b7976..fdb5ee4f 100644 --- a/backoffice/config/urls.py +++ b/backoffice/config/urls.py @@ -1,3 +1,4 @@ +from allauth.socialaccount.providers.orcid.views import oauth2_login from django.conf import settings from django.conf.urls.static import static from django.contrib import admin @@ -8,6 +9,8 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView from rest_framework.authtoken.views import obtain_auth_token from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView +from django.views.decorators.csrf import csrf_exempt + urlpatterns = [ path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), @@ -18,6 +21,7 @@ path(settings.ADMIN_URL, admin.site.urls), # User management path("users/", include("backoffice.users.urls", namespace="users")), + path("accounts/orcid/login/", csrf_exempt(oauth2_login), name="orcid_login"), path("accounts/", include("allauth.urls")), path("", include("django_prometheus.urls")), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) @@ -40,6 +44,7 @@ ), path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"), path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), + path("api/_allauth/", include("allauth.headless.urls")), ] diff --git a/backoffice/poetry.lock b/backoffice/poetry.lock index c4aea059..740e5c77 100644 --- a/backoffice/poetry.lock +++ b/backoffice/poetry.lock @@ -870,17 +870,6 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - [[package]] name = "dill" version = "0.3.7" @@ -943,24 +932,23 @@ bcrypt = ["bcrypt"] [[package]] name = "django-allauth" -version = "0.57.0" +version = "65.0.1" description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "django-allauth-0.57.0.tar.gz", hash = "sha256:a095ef0db7de305d9175772c78e765ebd5fceb004ae61c1383d7fc1af0f7c5b1"}, + {file = "django_allauth-65.0.1.tar.gz", hash = "sha256:1f8281e2dc17d3b977bcd95b99538f128c5cd2fb2551346a7f8ad31aa76f17cc"}, ] [package.dependencies] -Django = ">=3.2" -pyjwt = {version = ">=1.7", extras = ["crypto"]} -python3-openid = ">=3.0.8" -requests = ">=2.0.0" -requests-oauthlib = ">=0.3.0" +Django = ">=4.2" [package.extras] -mfa = ["qrcode (>=7.0.0)"] +mfa = ["fido2 (>=1.1.2)", "qrcode (>=7.0.0)"] +openid = ["python3-openid (>=3.0.8)"] saml = ["python3-saml (>=1.15.0,<2.0.0)"] +socialaccount = ["pyjwt[crypto] (>=1.7)", "requests (>=2.0.0)", "requests-oauthlib (>=0.3.0)"] +steam = ["python3-openid (>=3.0.8)"] [[package]] name = "django-anymail" @@ -2568,22 +2556,6 @@ files = [ [package.dependencies] setuptools = "*" -[[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.6" -files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - [[package]] name = "opensearch" version = "0.9.2" @@ -3042,9 +3014,6 @@ files = [ {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, ] -[package.dependencies] -cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} - [package.extras] crypto = ["cryptography (>=3.4.0)"] dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] @@ -3296,24 +3265,6 @@ text-unidecode = ">=1.3" [package.extras] unidecode = ["Unidecode (>=1.1.1)"] -[[package]] -name = "python3-openid" -version = "3.2.0" -description = "OpenID support for modern servers and consumers." -optional = false -python-versions = "*" -files = [ - {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"}, - {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"}, -] - -[package.dependencies] -defusedxml = "*" - -[package.extras] -mysql = ["mysql-connector-python"] -postgresql = ["psycopg2"] - [[package]] name = "pytz" version = "2023.3.post1" @@ -4092,7 +4043,6 @@ description = "Automatically mock your HTTP interactions to simplify and speed u optional = false python-versions = ">=3.8" files = [ - {file = "vcrpy-6.0.1-py2.py3-none-any.whl", hash = "sha256:621c3fb2d6bd8aa9f87532c688e4575bcbbde0c0afeb5ebdb7e14cac409edfdd"}, {file = "vcrpy-6.0.1.tar.gz", hash = "sha256:9e023fee7f892baa0bbda2f7da7c8ac51165c1c6e38ff8688683a12a4bde9278"}, ] diff --git a/backoffice/pyproject.toml b/backoffice/pyproject.toml index 40d4c1c1..35939651 100644 --- a/backoffice/pyproject.toml +++ b/backoffice/pyproject.toml @@ -125,7 +125,6 @@ uvicorn = {version = "0.23.2", extras = ["standard"]} django = "4.2.6" django-environ = "0.11.2" django-model-utils = "4.3.1" -django-allauth = "0.57.0" django-crispy-forms = "2.1" crispy-bootstrap5 = "0.7" django-redis = "5.4.0" @@ -151,6 +150,7 @@ opensearch-py = "2.6.0" djangorestframework-simplejwt = "^5.3.1" django-json-widget = "^2.0.1" sentry-sdk = "1.19.1" +django-allauth = {version = "65.0.1", extras = ["headless"]} [tool.poetry.dev-dependencies] factory-boy = "3.3.0" diff --git a/ruff.toml b/ruff.toml index d849b4ae..00a551a8 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,5 +1,5 @@ target-version = "py311" -ignore = ["PT009"] +lint.ignore = ["PT009"] [lint.flake8-tidy-imports] ban-relative-imports = "all"