From b386525e0ca62491b4e40485b33b7875415d0170 Mon Sep 17 00:00:00 2001
From: krek0
Date: Sat, 16 May 2026 20:09:23 +0200
Subject: [PATCH] fix alloauth
---
.env.example | 3 ++-
allauth_oauth/provider.py | 6 ++----
allauth_oauth/signals.py | 12 +++++++++++-
allauth_oauth/views.py | 16 ++++++++++++----
photo21/settings.py | 5 +++++
photo21/templates/account/login.html | 6 +++++-
photo21/templates/base.html | 7 ++++---
.../socialaccount/snippets/provider_list.html | 2 +-
photo21/urls.py | 2 ++
photo21/views.py | 7 +++++++
10 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/.env.example b/.env.example
index 930af5b..14e0f17 100644
--- a/.env.example
+++ b/.env.example
@@ -39,7 +39,8 @@ OAUTH_ONLY=False
#OAUTH_BUTTON_TEXT=Login with OAuth
#OAUTH_BUTTON_IMAGE=
# Space-separated OAuth2 scopes
-#OAUTH_SCOPE=openid profile email
+#OAUTH_SCOPE=openid profile email groups
+#OAUTH_ADMIN_GROUP=Admins
# Database engine: 'sqlite' or 'postgres'
DB_ENGINE=sqlite
diff --git a/allauth_oauth/provider.py b/allauth_oauth/provider.py
index 6a6430c..2a9035e 100644
--- a/allauth_oauth/provider.py
+++ b/allauth_oauth/provider.py
@@ -18,14 +18,12 @@ class OAuthProvider(OAuth2Provider):
account_class = OAuthAccount
def extract_uid(self, data):
- return str(data["username"])
+ return str(data["preferred_username"])
def extract_common_fields(self, data):
return dict(
email=data.get("email"),
- username=data.get("username"),
- last_name=data.get("last_name"),
- first_name=data.get("first_name"),
+ username=data.get("preferred_username"),
)
def get_default_scope(self):
diff --git a/allauth_oauth/signals.py b/allauth_oauth/signals.py
index d7f1cf6..8a7c9a2 100644
--- a/allauth_oauth/signals.py
+++ b/allauth_oauth/signals.py
@@ -2,7 +2,9 @@
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
+from allauth.account.models import EmailAddress
from allauth.socialaccount.signals import pre_social_login
+from django.conf import settings
from django.dispatch import receiver
@@ -19,11 +21,19 @@ def sync_user_fields(sender, request, sociallogin, **kwargs):
if email and user.email != email:
user.email = email
changed = True
+ EmailAddress.objects.filter(user=user).update(email=email)
- username = data.get("username")
+ username = data.get("preferred_username")
if username and user.username != username:
user.username = username
changed = True
+ admin_group = settings.OAUTH_ADMIN_GROUP
+ if admin_group:
+ is_staff = admin_group in data.get("groups", [])
+ if user.is_staff != is_staff:
+ user.is_staff = is_staff
+ changed = True
+
if changed:
user.save()
diff --git a/allauth_oauth/views.py b/allauth_oauth/views.py
index 7a568a5..f247412 100644
--- a/allauth_oauth/views.py
+++ b/allauth_oauth/views.py
@@ -4,6 +4,7 @@
import requests
from allauth.socialaccount import app_settings
+from django.core.exceptions import ImproperlyConfigured
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
OAuth2CallbackView,
@@ -31,20 +32,27 @@ class OAuthAdapter(OAuth2Adapter):
@property
def domain(self):
- return self.settings.get("DOMAIN", "")
+ domain = self.settings.get("DOMAIN", "")
+ if not domain:
+ raise ImproperlyConfigured(
+ "OAUTH_SERVER_URL is not configured. Set it in your .env file."
+ )
+ return domain
@property
def access_token_url(self):
- return f"https://{self.domain}/o/token/"
+ return f"https://{self.domain}/application/o/token/"
@property
def authorize_url(self):
- return f"https://{self.domain}/o/authorize/"
+ return f"https://{self.domain}/application/o/authorize/"
@property
def profile_url(self):
- return f"https://{self.domain}/api/me/"
+ return f"https://{self.domain}/application/o/userinfo/"
+OAuthProvider.oauth2_adapter_class = OAuthAdapter
+
oauth2_login = OAuth2LoginView.adapter_view(OAuthAdapter)
oauth2_callback = OAuth2CallbackView.adapter_view(OAuthAdapter)
diff --git a/photo21/settings.py b/photo21/settings.py
index 422f2c7..c41d520 100644
--- a/photo21/settings.py
+++ b/photo21/settings.py
@@ -64,6 +64,7 @@ OAUTH_SERVER_URL = config("OAUTH_SERVER_URL", default="")
OAUTH_BUTTON_TEXT = config("OAUTH_BUTTON_TEXT", default="Login with OAuth")
OAUTH_BUTTON_IMAGE = config("OAUTH_BUTTON_IMAGE", default="")
OAUTH_SCOPE = config("OAUTH_SCOPE", default="openid profile email", cast=Csv(delimiter=" "))
+OAUTH_ADMIN_GROUP = config("OAUTH_ADMIN_GROUP", default="")
INSTALLED_APPS = [
"django.contrib.admin",
@@ -118,6 +119,7 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
+ "photo21.views.oauth_context",
],
},
},
@@ -282,6 +284,9 @@ ACCOUNT_FORMS = {"signup": "photo21.forms.CustomSignupForm"}
if OAUTH_ENABLED:
SOCIALACCOUNT_ONLY = OAUTH_ONLY
+ if OAUTH_ONLY:
+ ACCOUNT_EMAIL_VERIFICATION = 'none'
+ SOCIALACCOUNT_LOGIN_ON_GET = True
SOCIALACCOUNT_PROVIDERS = {
"oauth": {
"SCOPE": OAUTH_SCOPE,
diff --git a/photo21/templates/account/login.html b/photo21/templates/account/login.html
index a2bc666..b1c48b3 100644
--- a/photo21/templates/account/login.html
+++ b/photo21/templates/account/login.html
@@ -15,10 +15,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% include "socialaccount/snippets/provider_list.html" with process="login" %}
+ {% if not SOCIALACCOUNT_ONLY %}
{% blocktrans trimmed with site.name as site_name %}Please sign in with one
of your existing third party accounts. Or, sign up
for a {{ site_name }} account and sign in below:{% endblocktrans %}
+ {% endif %}
{% include "socialaccount/snippets/login_extra.html" %}
@@ -27,6 +29,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
sign up first.{% endblocktrans %}
{% endif %}
+ {% if not SOCIALACCOUNT_ONLY %}
- {% trans "Forgot Password?" %}
+ {% url 'account_reset_password' as reset_url %}{% if reset_url %}{% trans "Forgot Password?" %} {% endif %}
+ {% endif %}
diff --git a/photo21/templates/base.html b/photo21/templates/base.html
index ccd17c2..ce771a1 100644
--- a/photo21/templates/base.html
+++ b/photo21/templates/base.html
@@ -100,15 +100,16 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% trans "Log in" %}
-
-
+ {% url 'account_signup' as signup_url %}
+ {% if signup_url %}
+
{% trans "Sign up" %}
-
+ {% endif %}
{% endif %}
diff --git a/photo21/templates/socialaccount/snippets/provider_list.html b/photo21/templates/socialaccount/snippets/provider_list.html
index 71a8ec0..dc6aad7 100644
--- a/photo21/templates/socialaccount/snippets/provider_list.html
+++ b/photo21/templates/socialaccount/snippets/provider_list.html
@@ -17,5 +17,5 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endfor %}
{% endif %}
{% trans "Sign in with" %} {{provider.name}}
+ href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}">{{ OAUTH_BUTTON_TEXT|default:provider.name }}
{% endfor %}
diff --git a/photo21/urls.py b/photo21/urls.py
index 2884442..5b4df26 100644
--- a/photo21/urls.py
+++ b/photo21/urls.py
@@ -24,6 +24,8 @@ urlpatterns = [
path("", IndexView.as_view(), name="index"),
path("", include("photologue.urls", namespace="photologue")),
path("accounts/", include("allauth.urls")),
+ path("accounts/", include("allauth_oauth.urls")),
+
path("i18n/", include("django.conf.urls.i18n")),
path("jsi18n/", JavaScriptCatalog.as_view(), name="javascript-catalog"),
path("admin/doc/", include("django.contrib.admindocs.urls")),
diff --git a/photo21/views.py b/photo21/views.py
index 65f0b11..075f249 100644
--- a/photo21/views.py
+++ b/photo21/views.py
@@ -69,3 +69,10 @@ class IndexView(LoginRequiredMixin, ListView):
context["superusers"] = superusers
return context
+
+
+def oauth_context(request):
+ return {
+ "OAUTH_BUTTON_TEXT": getattr(settings, "OAUTH_BUTTON_TEXT", ""),
+ "OAUTH_BUTTON_IMAGE": getattr(settings, "OAUTH_BUTTON_IMAGE", ""),
+ }