From 05e248df0822492c27e418c52fd3aa46df9ebb09 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Wed, 31 Jul 2024 14:06:13 +0200 Subject: [PATCH 1/7] =?UTF-8?q?feat(pro=5Fconnect):=C2=A0rename=20inclusio?= =?UTF-8?q?n=5Fconnect=20to=20openid=5Fconnect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.template | 6 +- README.md | 8 +- config/settings/base.py | 10 +- config/urls.py | 4 +- lacommunaute/event/tests/tests_views.py | 4 +- .../tests/__snapshots__/tests_views.ambr | 324 +++++++++--------- lacommunaute/inclusion_connect/constants.py | 26 -- .../migrations/0001_initial.py | 28 -- lacommunaute/inclusion_connect/urls.py | 12 - .../__init__.py | 0 lacommunaute/openid_connect/constants.py | 26 ++ .../openid_connect/migrations/0001_initial.py | 20 ++ .../migrations/__init__.py | 0 .../models.py | 4 +- .../tests/__init__.py | 0 .../tests/tests_model.py | 56 +-- .../tests/tests_views.py | 74 ++-- lacommunaute/openid_connect/urls.py | 12 + .../views.py | 74 ++-- lacommunaute/surveys/tests/test_views.py | 2 +- .../forum_conversation/topics_newsfeed.html | 2 +- .../forum_conversation/topics_public.html | 2 +- .../forum_member/join_forum_landing.html | 4 +- .../forum_member/seekers_profiles.html | 2 +- lacommunaute/templates/partials/upvotes.html | 2 +- lacommunaute/templates/surveys/dsp_form.html | 2 +- .../utils/templatetags/str_filters.py | 4 +- lacommunaute/utils/tests/tests_utils.py | 12 +- 28 files changed, 355 insertions(+), 365 deletions(-) delete mode 100644 lacommunaute/inclusion_connect/constants.py delete mode 100644 lacommunaute/inclusion_connect/migrations/0001_initial.py delete mode 100644 lacommunaute/inclusion_connect/urls.py rename lacommunaute/{inclusion_connect => openid_connect}/__init__.py (100%) create mode 100644 lacommunaute/openid_connect/constants.py create mode 100644 lacommunaute/openid_connect/migrations/0001_initial.py rename lacommunaute/{inclusion_connect => openid_connect}/migrations/__init__.py (100%) rename lacommunaute/{inclusion_connect => openid_connect}/models.py (97%) rename lacommunaute/{inclusion_connect => openid_connect}/tests/__init__.py (100%) rename lacommunaute/{inclusion_connect => openid_connect}/tests/tests_model.py (61%) rename lacommunaute/{inclusion_connect => openid_connect}/tests/tests_views.py (67%) create mode 100644 lacommunaute/openid_connect/urls.py rename lacommunaute/{inclusion_connect => openid_connect}/views.py (64%) diff --git a/.env.template b/.env.template index 0c651af12..73e8b1c31 100644 --- a/.env.template +++ b/.env.template @@ -18,9 +18,9 @@ SIB_API_KEY=__key_to_be_set__ #SENTRY_DSN=__url_to_be_set__ # for Inclusion Connect -INCLUSION_CONNECT_BASE_URL=http://127.0.0.1:8080 -INCLUSION_CONNECT_CLIENT_ID=local_inclusion_connect -INCLUSION_CONNECT_CLIENT_SECRET=password +OPENID_CONNECT_BASE_URL=http://127.0.0.1:8080 +OPENID_CONNECT_CLIENT_ID=local_openid_connect +OPENID_CONNECT_CLIENT_SECRET=password # Path to the itou-backup project repository. PATH_TO_BACKUPS=~/path/to/backups diff --git a/README.md b/README.md index 9eb6d0291..a794af13b 100644 --- a/README.md +++ b/README.md @@ -140,10 +140,10 @@ Créer les variables d'environnement suivantes dans le configuration provider - DJANGO_DEBUG - DJANGO_SECRET_KEY - DJANGO_SETTINGS_MODULE -- INCLUSION_CONNECT_BASE_URL -- INCLUSION_CONNECT_CLIENT_ID -- INCLUSION_CONNECT_CLIENT_SECRET -- INCLUSION_CONNECT_REALM +- OPENID_CONNECT_BASE_URL +- OPENID_CONNECT_CLIENT_ID +- OPENID_CONNECT_CLIENT_SECRET +- OPENID_CONNECT_REALM - PORT - PYTHONPATH - SENTRY_DSN diff --git a/config/settings/base.py b/config/settings/base.py index adba814a7..c1e18c54b 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -76,7 +76,7 @@ "lacommunaute.forum_moderation", "lacommunaute.notification", "lacommunaute.event", - "lacommunaute.inclusion_connect", + "lacommunaute.openid_connect", "lacommunaute.pages", "lacommunaute.forum_file", "lacommunaute.search", @@ -110,7 +110,7 @@ MIDDLEWARE = DJANGO_MIDDLEWARE + THIRD_PARTIES_MIDDLEWARE + LOCAL_MIDDLEWARE ROOT_URLCONF = "config.urls" -LOGIN_URL = "/inclusion_connect/authorize" +LOGIN_URL = "/openid_connect/authorize" LOGIN_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/" @@ -294,9 +294,9 @@ # Inclusion Connect # ------------------------------------------------------------------------------ -INCLUSION_CONNECT_BASE_URL = os.getenv("INCLUSION_CONNECT_BASE_URL") -INCLUSION_CONNECT_CLIENT_ID = os.getenv("INCLUSION_CONNECT_CLIENT_ID") -INCLUSION_CONNECT_CLIENT_SECRET = os.getenv("INCLUSION_CONNECT_CLIENT_SECRET") +OPENID_CONNECT_BASE_URL = os.getenv("OPENID_CONNECT_BASE_URL") +OPENID_CONNECT_CLIENT_ID = os.getenv("OPENID_CONNECT_CLIENT_ID") +OPENID_CONNECT_CLIENT_SECRET = os.getenv("OPENID_CONNECT_CLIENT_SECRET") # LOGGING # ------------------------------------------------------------------------------ diff --git a/config/urls.py b/config/urls.py index f31c0056d..f9e3c9a68 100644 --- a/config/urls.py +++ b/config/urls.py @@ -12,7 +12,7 @@ from lacommunaute.forum_member import urls as forum_member_urls from lacommunaute.forum_moderation import urls as forum_moderation_urls from lacommunaute.forum_upvote import urls as forum_upvote_urls -from lacommunaute.inclusion_connect import urls as inclusion_connect_urls +from lacommunaute.openid_connect import urls as openid_connect_urls from lacommunaute.pages import urls as pages_urls from lacommunaute.search import urls as search_urls from lacommunaute.stats import urls as stats_urls @@ -26,7 +26,7 @@ urlpatterns = [ path("admin/", admin.site.urls), # Inclusion Connect URLs. - path("inclusion_connect/", include(inclusion_connect_urls)), + path("openid_connect/", include(openid_connect_urls)), # www. path("", include(pages_urls)), path("members/", include(forum_member_urls)), diff --git a/lacommunaute/event/tests/tests_views.py b/lacommunaute/event/tests/tests_views.py index 0a33c95b1..b1b209e9b 100644 --- a/lacommunaute/event/tests/tests_views.py +++ b/lacommunaute/event/tests/tests_views.py @@ -75,7 +75,7 @@ def setUpTestData(cls): def test_login_is_required(self): response = self.client.get(self.url) self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, reverse("inclusion_connect:authorize") + "?next=" + self.url) + self.assertEqual(response.url, reverse("openid_connect:authorize") + "?next=" + self.url) def test_event_is_created(self): self.client.force_login(self.user) @@ -191,7 +191,7 @@ def setUpTestData(cls): def test_login_is_required(self): response = self.client.get(self.url) self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, reverse("inclusion_connect:authorize") + "?next=" + self.url) + self.assertEqual(response.url, reverse("openid_connect:authorize") + "?next=" + self.url) self.client.force_login(self.user) response = self.client.get(self.url) diff --git a/lacommunaute/forum/tests/__snapshots__/tests_views.ambr b/lacommunaute/forum/tests/__snapshots__/tests_views.ambr index ee7fff19e..6f51bcd79 100644 --- a/lacommunaute/forum/tests/__snapshots__/tests_views.ambr +++ b/lacommunaute/forum/tests/__snapshots__/tests_views.ambr @@ -5,12 +5,12 @@ ''' @@ -21,18 +21,18 @@ ''' @@ -43,12 +43,12 @@ ''' @@ -59,24 +59,24 @@ ''' @@ -87,12 +87,12 @@ ''' @@ -103,14 +103,14 @@ ''' @@ -121,18 +121,18 @@ ''' @@ -153,17 +153,17 @@ # name: TestDocumentationCategoryForumContent.test_documentation_category_subforum_list[documentation_category_subforum_list] '''
- +
- +
''' # --- # name: TestDocumentationCategoryForumContent.test_show_subforum_tags[documentation_category_subforum_tags] '''
- - - - - + + + + +
- - - - - + + + + +

Test Forum

- +

Test description

@@ -217,31 +217,31 @@
- - + +

Test description

- - + +
- +
- +
- +
- +
- +
- +
- - - - - - + + + + + +
''' # --- @@ -300,30 +300,30 @@ # name: TestDocumentationForumContent.test_documentation_forum_share_actions[template_documentation_upvotes] '''
- - - + + + 0 - - + +
''' # --- # name: TestForumDetailContent.test_forum_detail_foot_content[forum_detail_forum_actions_block] '''
- + - + Poser une question - + - - + +
''' # --- @@ -334,7 +334,7 @@

Test Forum

- +

Test description

@@ -345,23 +345,23 @@ # name: TestForumDetailContent.test_forum_detail_subforum_content_rendered[forum_detail_subforums] ''' ''' # --- @@ -369,34 +369,34 @@ '''

- +

Cette fiche vous a-t-elle été utile ?

- + - + - + - + - + - +
- +
''' # --- @@ -404,168 +404,168 @@ '''

- +

Merci d'avoir noté cette fiche !

- +
- + - +
- +
- + - +
- +
- + - +
- +
- + - +
- +
- + - +
- +
- +
''' # --- # name: TestForumViewContent.test_upvotes_counts[0-False][upvotes_counts_0] '''
- - + + 0 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[0-True][upvotes_counts_0] '''
- - + + 0 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[0-True][upvotes_counts_0_self_upvoted] '''
- - + +
- - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[1-False][upvotes_counts_1] '''
- - + + 1 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[1-True][upvotes_counts_1] '''
- - + + 1 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[1-True][upvotes_counts_1_self_upvoted] '''
- - + +
- - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[2-False][upvotes_counts_2] '''
- - + + 2 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[2-True][upvotes_counts_2] '''
- - + + 2 - - + +
''' # --- # name: TestForumViewContent.test_upvotes_counts[2-True][upvotes_counts_2_self_upvoted] '''
- - + +
- - + +
''' # --- diff --git a/lacommunaute/inclusion_connect/constants.py b/lacommunaute/inclusion_connect/constants.py deleted file mode 100644 index 98f83d92d..000000000 --- a/lacommunaute/inclusion_connect/constants.py +++ /dev/null @@ -1,26 +0,0 @@ -import datetime - -from django.conf import settings - - -INCLUSION_CONNECT_SCOPES = "openid profile email" - -INCLUSION_CONNECT_CLIENT_ID = settings.INCLUSION_CONNECT_CLIENT_ID -INCLUSION_CONNECT_CLIENT_SECRET = settings.INCLUSION_CONNECT_CLIENT_SECRET - -INCLUSION_CONNECT_ENDPOINT = "{base_url}/auth".format( - base_url=settings.INCLUSION_CONNECT_BASE_URL, -) -INCLUSION_CONNECT_ENDPOINT_AUTHORIZE = f"{INCLUSION_CONNECT_ENDPOINT}/authorize/" -INCLUSION_CONNECT_ENDPOINT_REGISTRATIONS = f"{INCLUSION_CONNECT_ENDPOINT}/register/" -INCLUSION_CONNECT_ENDPOINT_TOKEN = f"{INCLUSION_CONNECT_ENDPOINT}/token/" -INCLUSION_CONNECT_ENDPOINT_USERINFO = f"{INCLUSION_CONNECT_ENDPOINT}/userinfo/" -INCLUSION_CONNECT_ENDPOINT_LOGOUT = f"{INCLUSION_CONNECT_ENDPOINT}/logout/" - -# These expiration times have been chosen arbitrarily. -INCLUSION_CONNECT_TIMEOUT = 60 - -INCLUSION_CONNECT_SESSION_KEY = "inclusion_connect" - -# This expiration time has been chosen arbitrarily. -OIDC_STATE_EXPIRATION = datetime.timedelta(hours=1) diff --git a/lacommunaute/inclusion_connect/migrations/0001_initial.py b/lacommunaute/inclusion_connect/migrations/0001_initial.py deleted file mode 100644 index 44b1af405..000000000 --- a/lacommunaute/inclusion_connect/migrations/0001_initial.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 4.1.2 on 2022-10-20 09:09 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - initial = True - - dependencies = [] - - operations = [ - migrations.CreateModel( - name="InclusionConnectState", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("created_at", models.DateTimeField(auto_now_add=True)), - ("csrf", models.CharField(max_length=12, unique=True)), - ], - ), - ] diff --git a/lacommunaute/inclusion_connect/urls.py b/lacommunaute/inclusion_connect/urls.py deleted file mode 100644 index ce2183ba6..000000000 --- a/lacommunaute/inclusion_connect/urls.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.urls import path - -from lacommunaute.inclusion_connect import views - - -app_name = "inclusion_connect" - -urlpatterns = [ - path("authorize", views.inclusion_connect_authorize, name="authorize"), - path("callback", views.inclusion_connect_callback, name="callback"), - path("logout", views.inclusion_connect_logout, name="logout"), -] diff --git a/lacommunaute/inclusion_connect/__init__.py b/lacommunaute/openid_connect/__init__.py similarity index 100% rename from lacommunaute/inclusion_connect/__init__.py rename to lacommunaute/openid_connect/__init__.py diff --git a/lacommunaute/openid_connect/constants.py b/lacommunaute/openid_connect/constants.py new file mode 100644 index 000000000..5e7d496a7 --- /dev/null +++ b/lacommunaute/openid_connect/constants.py @@ -0,0 +1,26 @@ +import datetime + +from django.conf import settings + + +OPENID_CONNECT_SCOPES = "openid profile email" + +OPENID_CONNECT_CLIENT_ID = settings.OPENID_CONNECT_CLIENT_ID +OPENID_CONNECT_CLIENT_SECRET = settings.OPENID_CONNECT_CLIENT_SECRET + +OPENID_CONNECT_ENDPOINT = "{base_url}/auth".format( + base_url=settings.OPENID_CONNECT_BASE_URL, +) +OPENID_CONNECT_ENDPOINT_AUTHORIZE = f"{OPENID_CONNECT_ENDPOINT}/authorize/" +OPENID_CONNECT_ENDPOINT_REGISTRATIONS = f"{OPENID_CONNECT_ENDPOINT}/register/" +OPENID_CONNECT_ENDPOINT_TOKEN = f"{OPENID_CONNECT_ENDPOINT}/token/" +OPENID_CONNECT_ENDPOINT_USERINFO = f"{OPENID_CONNECT_ENDPOINT}/userinfo/" +OPENID_CONNECT_ENDPOINT_LOGOUT = f"{OPENID_CONNECT_ENDPOINT}/logout/" + +# These expiration times have been chosen arbitrarily. +OPENID_CONNECT_TIMEOUT = 60 + +OPENID_CONNECT_SESSION_KEY = "openid_connect" + +# This expiration time has been chosen arbitrarily. +OIDC_STATE_EXPIRATION = datetime.timedelta(hours=1) diff --git a/lacommunaute/openid_connect/migrations/0001_initial.py b/lacommunaute/openid_connect/migrations/0001_initial.py new file mode 100644 index 000000000..c1acd5537 --- /dev/null +++ b/lacommunaute/openid_connect/migrations/0001_initial.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.7 on 2024-07-31 13:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="OpenID_State", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("csrf", models.CharField(max_length=12, unique=True)), + ], + ), + ] diff --git a/lacommunaute/inclusion_connect/migrations/__init__.py b/lacommunaute/openid_connect/migrations/__init__.py similarity index 100% rename from lacommunaute/inclusion_connect/migrations/__init__.py rename to lacommunaute/openid_connect/migrations/__init__.py diff --git a/lacommunaute/inclusion_connect/models.py b/lacommunaute/openid_connect/models.py similarity index 97% rename from lacommunaute/inclusion_connect/models.py rename to lacommunaute/openid_connect/models.py index c52ebeda3..b9f09ba2b 100644 --- a/lacommunaute/inclusion_connect/models.py +++ b/lacommunaute/openid_connect/models.py @@ -6,7 +6,7 @@ from django.utils import crypto, timezone from lacommunaute.forum_member.models import ForumProfile -from lacommunaute.inclusion_connect.constants import OIDC_STATE_EXPIRATION +from lacommunaute.openid_connect.constants import OIDC_STATE_EXPIRATION from lacommunaute.users.models import User @@ -16,7 +16,7 @@ def cleanup(self, at=None): return self.filter(created_at__lte=at).delete() -class InclusionConnectState(models.Model): +class OpenID_State(models.Model): created_at = models.DateTimeField(auto_now_add=True) # Length used in call to get_random_string() csrf = models.CharField(max_length=12, unique=True) diff --git a/lacommunaute/inclusion_connect/tests/__init__.py b/lacommunaute/openid_connect/tests/__init__.py similarity index 100% rename from lacommunaute/inclusion_connect/tests/__init__.py rename to lacommunaute/openid_connect/tests/__init__.py diff --git a/lacommunaute/inclusion_connect/tests/tests_model.py b/lacommunaute/openid_connect/tests/tests_model.py similarity index 61% rename from lacommunaute/inclusion_connect/tests/tests_model.py rename to lacommunaute/openid_connect/tests/tests_model.py index 144dd1cad..1d2524621 100644 --- a/lacommunaute/inclusion_connect/tests/tests_model.py +++ b/lacommunaute/openid_connect/tests/tests_model.py @@ -4,8 +4,8 @@ from django.utils import timezone from lacommunaute.forum_member.models import ForumProfile -from lacommunaute.inclusion_connect import constants -from lacommunaute.inclusion_connect.models import InclusionConnectState, OIDConnectUserData +from lacommunaute.openid_connect import constants +from lacommunaute.openid_connect.models import OIDConnectUserData, OpenID_State from lacommunaute.users.factories import UserFactory from lacommunaute.users.models import User from lacommunaute.utils.testing import reload_module @@ -20,26 +20,26 @@ @override_settings( - INCLUSION_CONNECT_BASE_URL="https://inclusion.connect.fake", - INCLUSION_CONNECT_REALM="foobar", - INCLUSION_CONNECT_CLIENT_ID="IC_CLIENT_ID_123", - INCLUSION_CONNECT_CLIENT_SECRET="IC_CLIENT_SECRET_123", + OPENID_CONNECT_BASE_URL="https://openid.connect.fake", + OPENID_CONNECT_REALM="foobar", + OPENID_CONNECT_CLIENT_ID="IC_CLIENT_ID_123", + OPENID_CONNECT_CLIENT_SECRET="IC_CLIENT_SECRET_123", ) @reload_module(constants) -class InclusionConnectBaseTestCase(TestCase): +class OpenID_BaseTestCase(TestCase): pass -class InclusionConnectModelTest(InclusionConnectBaseTestCase): +class OpenID_ModelTest(OpenID_BaseTestCase): def test_state_is_valid(self): - csrf_signed = InclusionConnectState.create_signed_csrf_token() + csrf_signed = OpenID_State.create_signed_csrf_token() self.assertTrue(isinstance(csrf_signed, str)) - self.assertTrue(InclusionConnectState.is_valid(csrf_signed)) + self.assertTrue(OpenID_State.is_valid(csrf_signed)) def test_state_delete(self): - state = InclusionConnectState.objects.create(csrf="foo") + state = OpenID_State.objects.create(csrf="foo") - InclusionConnectState.objects.cleanup() + OpenID_State.objects.cleanup() state.refresh_from_db() self.assertIsNotNone(state) @@ -47,23 +47,23 @@ def test_state_delete(self): state.created_at = timezone.now() - constants.OIDC_STATE_EXPIRATION * 2 state.save() - InclusionConnectState.objects.cleanup() + OpenID_State.objects.cleanup() - with self.assertRaises(InclusionConnectState.DoesNotExist): + with self.assertRaises(OpenID_State.DoesNotExist): state.refresh_from_db() def test_create_user_from_user_info(self): """ - Nominal scenario: there is no user with InclusionConnect email + Nominal scenario: there is no user with OpenID_ email that is sent, so we create one. """ - ic_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) - self.assertFalse(User.objects.filter(username=ic_user_data.username).exists()) - self.assertFalse(User.objects.filter(email=ic_user_data.email).exists()) + proc_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) + self.assertFalse(User.objects.filter(username=proc_user_data.username).exists()) + self.assertFalse(User.objects.filter(email=proc_user_data.email).exists()) now = timezone.now() with mock.patch("django.utils.timezone.now", return_value=now): - user, created = ic_user_data.create_or_update_user() + user, created = proc_user_data.create_or_update_user() self.assertTrue(created) self.assertEqual(user.email, OIDC_USERINFO["email"]) self.assertEqual(user.last_name, OIDC_USERINFO["family_name"]) @@ -82,11 +82,11 @@ def test_update_user_from_user_info(self): user = UserFactory(**(USERINFO)) ForumProfile.objects.create(user=user) - ic_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) + proc_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) now = timezone.now() with mock.patch("django.utils.timezone.now", return_value=now): - _, created = ic_user_data.create_or_update_user() + _, created = proc_user_data.create_or_update_user() self.assertFalse(created) @@ -101,17 +101,17 @@ def test_update_user_from_user_info(self): def test_get_existing_user_with_existing_email(self): """ - If there already is an existing django user with email InclusionConnect sent us, we do not create it again, + If there already is an existing django user with email OpenID_ sent us, we do not create it again, We user it and we update it with the data form the identity_provider. """ - ic_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) + proc_user_data = OIDConnectUserData.from_user_info(OIDC_USERINFO) UserFactory( - first_name=ic_user_data.first_name, - last_name=ic_user_data.last_name, - email=ic_user_data.email, - username=ic_user_data.username, + first_name=proc_user_data.first_name, + last_name=proc_user_data.last_name, + email=proc_user_data.email, + username=proc_user_data.username, ) - user, created = ic_user_data.create_or_update_user() + user, created = proc_user_data.create_or_update_user() self.assertFalse(created) self.assertEqual(user.last_name, OIDC_USERINFO["family_name"]) self.assertEqual(user.first_name, OIDC_USERINFO["given_name"]) diff --git a/lacommunaute/inclusion_connect/tests/tests_views.py b/lacommunaute/openid_connect/tests/tests_views.py similarity index 67% rename from lacommunaute/inclusion_connect/tests/tests_views.py rename to lacommunaute/openid_connect/tests/tests_views.py index e82c9dc2b..f6ae5dac5 100644 --- a/lacommunaute/inclusion_connect/tests/tests_views.py +++ b/lacommunaute/openid_connect/tests/tests_views.py @@ -7,9 +7,9 @@ from django.test import RequestFactory, TestCase, override_settings from django.urls import reverse -from lacommunaute.inclusion_connect import constants -from lacommunaute.inclusion_connect.models import InclusionConnectState -from lacommunaute.inclusion_connect.views import InclusionConnectSession +from lacommunaute.openid_connect import constants +from lacommunaute.openid_connect.models import OpenID_State +from lacommunaute.openid_connect.views import OpenID_Session from lacommunaute.users.factories import UserFactory from lacommunaute.users.models import User from lacommunaute.utils.testing import reload_module @@ -24,13 +24,13 @@ @override_settings( - INCLUSION_CONNECT_BASE_URL="https://inclusion.connect.fake", - INCLUSION_CONNECT_REALM="foobar", - INCLUSION_CONNECT_CLIENT_ID="IC_CLIENT_ID_123", - INCLUSION_CONNECT_CLIENT_SECRET="IC_CLIENT_SECRET_123", + OPENID_CONNECT_BASE_URL="https://openid.connect.fake", + OPENID_CONNECT_REALM="foobar", + OPENID_CONNECT_CLIENT_ID="IC_CLIENT_ID_123", + OPENID_CONNECT_CLIENT_SECRET="IC_CLIENT_SECRET_123", ) @reload_module(constants) -class InclusionConnectBaseTestCase(TestCase): +class OpenID_BaseTestCase(TestCase): pass @@ -44,7 +44,7 @@ def mock_oauth_dance( expected_route="pages:home", user_info_email=None, ): - respx.get(constants.INCLUSION_CONNECT_ENDPOINT_AUTHORIZE).respond(302) + respx.get(constants.OPENID_CONNECT_ENDPOINT_AUTHORIZE).respond(302) authorize_params = { "previous_url": previous_url, "next": next_url, @@ -52,11 +52,11 @@ def mock_oauth_dance( authorize_params = {k: v for k, v in authorize_params.items() if v} # Calling this view is mandatory to start a new session. - authorize_url = f"{reverse('inclusion_connect:authorize')}?{urlencode(authorize_params)}" + authorize_url = f"{reverse('openid_connect:authorize')}?{urlencode(authorize_params)}" test_class.client.get(authorize_url) # User is logged out from IC when an error happens during the oauth dance. - respx.get(constants.INCLUSION_CONNECT_ENDPOINT_LOGOUT).respond(200) + respx.get(constants.OPENID_CONNECT_ENDPOINT_LOGOUT).respond(200) token_json = { "access_token": "7890123", @@ -64,15 +64,15 @@ def mock_oauth_dance( "expires_in": 60, "id_token": "123456", } - respx.post(constants.INCLUSION_CONNECT_ENDPOINT_TOKEN).mock(return_value=httpx.Response(200, json=token_json)) + respx.post(constants.OPENID_CONNECT_ENDPOINT_TOKEN).mock(return_value=httpx.Response(200, json=token_json)) user_info = OIDC_USERINFO.copy() if user_info_email: user_info["email"] = user_info_email - respx.get(constants.INCLUSION_CONNECT_ENDPOINT_USERINFO).mock(return_value=httpx.Response(200, json=user_info)) + respx.get(constants.PRO_CONNECT_ENDPOINT_USERINFO).mock(return_value=httpx.Response(200, json=user_info)) - csrf_signed = InclusionConnectState.create_signed_csrf_token() - url = reverse("inclusion_connect:callback") + csrf_signed = OpenID_State.create_signed_csrf_token() + url = reverse("openid_connect:callback") response = test_class.client.get(url, data={"code": "123", "state": csrf_signed}) if assert_redirects: test_class.assertRedirects(response, reverse(expected_route)) @@ -80,28 +80,28 @@ def mock_oauth_dance( return response -class InclusionConnectViewTest(InclusionConnectBaseTestCase): +class OpenID_ViewTest(OpenID_BaseTestCase): def test_callback_invalid_state(self): - url = reverse("inclusion_connect:callback") + url = reverse("openid_connect:callback") response = self.client.get(url, data={"code": "123", "state": "000"}) self.assertEqual(response.status_code, 302) def test_callback_no_state(self): - url = reverse("inclusion_connect:callback") + url = reverse("openid_connect:callback") response = self.client.get(url, data={"code": "123"}) self.assertEqual(response.status_code, 302) def test_callback_no_code(self): - url = reverse("inclusion_connect:callback") + url = reverse("openid_connect:callback") response = self.client.get(url) self.assertEqual(response.status_code, 302) def test_authorize_endpoint(self): - url = f"{reverse('inclusion_connect:authorize')}" + url = f"{reverse('openid_connect:authorize')}" # Don't use assertRedirects to avoid fetching the last URL. response = self.client.get(url, follow=False) - self.assertTrue(response.url.startswith(constants.INCLUSION_CONNECT_ENDPOINT_AUTHORIZE)) - self.assertIn(constants.INCLUSION_CONNECT_SESSION_KEY, self.client.session) + self.assertTrue(response.url.startswith(constants.OPENID_CONNECT_ENDPOINT_AUTHORIZE)) + self.assertIn(constants.OPENID_CONNECT_SESSION_KEY, self.client.session) #################################### ######### Callback tests ########### @@ -133,10 +133,10 @@ def test_callback_existing_user(self): self.assertEqual(user.username, OIDC_USERINFO["sub"]) -class InclusionConnectSessionTest(InclusionConnectBaseTestCase): +class OpenID_SessionTest(OpenID_BaseTestCase): def test_start_session(self): - ic_session = InclusionConnectSession() - self.assertEqual(ic_session.key, constants.INCLUSION_CONNECT_SESSION_KEY) + proc_session = OpenID_Session() + self.assertEqual(proc_session.key, constants.OPENID_CONNECT_SESSION_KEY) expected_keys = [ "token", @@ -146,21 +146,21 @@ def test_start_session(self): "user_email", "request", ] - ic_session_dict = ic_session.asdict() + proc_session_dict = proc_session.asdict() for key in expected_keys: with self.subTest(key): - self.assertIn(key, ic_session_dict.keys()) - self.assertEqual(ic_session_dict[key], None) + self.assertIn(key, proc_session_dict.keys()) + self.assertEqual(proc_session_dict[key], None) request = RequestFactory().get("/") middleware = SessionMiddleware(lambda x: x) middleware.process_request(request) request.session.save() - request = ic_session.bind_to_request(request=request) - self.assertTrue(request.session.get(constants.INCLUSION_CONNECT_SESSION_KEY)) + request = proc_session.bind_to_request(request=request) + self.assertTrue(request.session.get(constants.OPENID_CONNECT_SESSION_KEY)) -class InclusionConnectLoginTest(InclusionConnectBaseTestCase): +class OpenID_LoginTest(OpenID_BaseTestCase): @respx.mock def test_normal_signin(self): """ @@ -172,11 +172,11 @@ def test_normal_signin(self): mock_oauth_dance(self) # Then log out. - response = self.client.post(reverse("inclusion_connect:logout")) + response = self.client.post(reverse("openid_connect:logout")) # Then log in again. response = self.client.get(reverse("pages:home")) - self.assertContains(response, reverse("inclusion_connect:authorize")) + self.assertContains(response, reverse("openid_connect:authorize")) response = mock_oauth_dance(self, assert_redirects=False) expected_redirection = reverse("pages:home") @@ -187,7 +187,7 @@ def test_normal_signin(self): self.assertEqual(users_count, 1) -class InclusionConnectLogoutTest(InclusionConnectBaseTestCase): +class OpenID_LogoutTest(OpenID_BaseTestCase): @respx.mock def test_logout_with_redirection(self): mock_oauth_dance(self) @@ -195,9 +195,9 @@ def test_logout_with_redirection(self): "id_token_hint": 123456, "post_logout_redirect_uri": f'http://testserver{reverse("pages:home")}', } - expected_redirection = f"{constants.INCLUSION_CONNECT_ENDPOINT_LOGOUT}?{urlencode(params)}" - respx.get(constants.INCLUSION_CONNECT_ENDPOINT_LOGOUT).respond(200) - logout_url = reverse("inclusion_connect:logout") + expected_redirection = f"{constants.OPENID_CONNECT_ENDPOINT_LOGOUT}?{urlencode(params)}" + respx.get(constants.OPENID_CONNECT_ENDPOINT_LOGOUT).respond(200) + logout_url = reverse("openid_connect:logout") response = self.client.get(logout_url) self.assertFalse(auth.get_user(self.client).is_authenticated) self.assertRedirects(response, expected_redirection, fetch_redirect_response=False) diff --git a/lacommunaute/openid_connect/urls.py b/lacommunaute/openid_connect/urls.py new file mode 100644 index 000000000..590e502f6 --- /dev/null +++ b/lacommunaute/openid_connect/urls.py @@ -0,0 +1,12 @@ +from django.urls import path + +from lacommunaute.openid_connect import views + + +app_name = "openid_connect" + +urlpatterns = [ + path("authorize", views.openid_connect_authorize, name="authorize"), + path("callback", views.openid_connect_callback, name="callback"), + path("logout", views.openid_connect_logout, name="logout"), +] diff --git a/lacommunaute/inclusion_connect/views.py b/lacommunaute/openid_connect/views.py similarity index 64% rename from lacommunaute/inclusion_connect/views.py rename to lacommunaute/openid_connect/views.py index 70e62e763..548f925e3 100644 --- a/lacommunaute/inclusion_connect/views.py +++ b/lacommunaute/openid_connect/views.py @@ -10,22 +10,22 @@ from django.utils import crypto from django.utils.http import urlencode -from lacommunaute.inclusion_connect import constants -from lacommunaute.inclusion_connect.models import InclusionConnectState, OIDConnectUserData +from lacommunaute.openid_connect import constants +from lacommunaute.openid_connect.models import OIDConnectUserData, OpenID_State logger = logging.getLogger(__name__) @dataclasses.dataclass -class InclusionConnectSession: +class OpenID_Session: token: str = None state: str = None previous_url: str = None next_url: str = None user_email: str = None request: str = None - key: str = constants.INCLUSION_CONNECT_SESSION_KEY + key: str = constants.OPENID_CONNECT_SESSION_KEY channel: str = None # Tells us where did the user came from so that we can adapt # error messages in the callback view. @@ -46,60 +46,58 @@ def _redirect_to_login_page_on_error(error_msg, request=None): return HttpResponseRedirect(reverse("pages:home")) -def inclusion_connect_authorize(request): +def openid_connect_authorize(request): # Start a new session. previous_url = request.GET.get("previous_url", reverse("pages:home")) next_url = request.GET.get("next") sign_in = bool(request.GET.get("sign_in", False)) - ic_session = InclusionConnectSession(previous_url=previous_url, next_url=next_url) - request = ic_session.bind_to_request(request) - ic_session = request.session[constants.INCLUSION_CONNECT_SESSION_KEY] + proc_session = OpenID_Session(previous_url=previous_url, next_url=next_url) + request = proc_session.bind_to_request(request) + proc_session = request.session[constants.OPENID_CONNECT_SESSION_KEY] - redirect_uri = request.build_absolute_uri(reverse("inclusion_connect:callback")) - signed_csrf = InclusionConnectState.create_signed_csrf_token() + redirect_uri = request.build_absolute_uri(reverse("openid_connect:callback")) + signed_csrf = OpenID_State.create_signed_csrf_token() data = { "response_type": "code", - "client_id": constants.INCLUSION_CONNECT_CLIENT_ID, + "client_id": constants.OPENID_CONNECT_CLIENT_ID, "redirect_uri": redirect_uri, - "scope": constants.INCLUSION_CONNECT_SCOPES, + "scope": constants.OPENID_CONNECT_SCOPES, "state": signed_csrf, "nonce": crypto.get_random_string(length=12), "from": "communaute", # Display a "La communauté" logo on the connection page. } redirect_url = ( - constants.INCLUSION_CONNECT_ENDPOINT_AUTHORIZE - if not sign_in - else constants.INCLUSION_CONNECT_ENDPOINT_REGISTRATIONS + constants.OPENID_CONNECT_ENDPOINT_AUTHORIZE if not sign_in else constants.OPENID_CONNECT_ENDPOINT_REGISTRATIONS ) return HttpResponseRedirect(f"{redirect_url}?{urlencode(data)}") -def inclusion_connect_callback(request): # pylint: disable=too-many-return-statements +def openid_connect_callback(request): # pylint: disable=too-many-return-statements code = request.GET.get("code") state = request.GET.get("state") - if code is None or not InclusionConnectState.is_valid(state): + if code is None or not OpenID_State.is_valid(state): return _redirect_to_login_page_on_error(error_msg="Missing code or invalid state.", request=request) - ic_session = request.session[constants.INCLUSION_CONNECT_SESSION_KEY] - token_redirect_uri = request.build_absolute_uri(reverse("inclusion_connect:callback")) + proc_session = request.session[constants.OPENID_CONNECT_SESSION_KEY] + token_redirect_uri = request.build_absolute_uri(reverse("openid_connect:callback")) data = { - "client_id": constants.INCLUSION_CONNECT_CLIENT_ID, - "client_secret": constants.INCLUSION_CONNECT_CLIENT_SECRET, + "client_id": constants.OPENID_CONNECT_CLIENT_ID, + "client_secret": constants.OPENID_CONNECT_CLIENT_SECRET, "code": code, "grant_type": "authorization_code", "redirect_uri": token_redirect_uri, } response = httpx.post( - constants.INCLUSION_CONNECT_ENDPOINT_TOKEN, + constants.OPENID_CONNECT_ENDPOINT_TOKEN, data=data, - timeout=constants.INCLUSION_CONNECT_TIMEOUT, + timeout=constants.OPENID_CONNECT_TIMEOUT, ) if response.status_code != 200: - return _redirect_to_login_page_on_error(error_msg="Impossible to get IC token.", request=request) + return _redirect_to_login_page_on_error(error_msg="Impossible to get OpenID_ token.", request=request) # Contains access_token, token_type, expires_in, id_token token_data = response.json() @@ -109,17 +107,17 @@ def inclusion_connect_callback(request): # pylint: disable=too-many-return-stat # Keep token_data["id_token"] to logout from IC. # At this step, we can update the user's fields in DB and create a session if required. - ic_session["token"] = token_data["id_token"] - ic_session["state"] = state + proc_session["token"] = token_data["id_token"] + proc_session["state"] = state request.session.modified = True # A token has been provided so it's time to fetch associated user infos # because the token is only valid for 5 seconds. response = httpx.get( - constants.INCLUSION_CONNECT_ENDPOINT_USERINFO, + constants.OPENID_CONNECT_ENDPOINT_USERINFO, params={"schema": "openid"}, headers={"Authorization": "Bearer " + access_token}, - timeout=constants.INCLUSION_CONNECT_TIMEOUT, + timeout=constants.OPENID_CONNECT_TIMEOUT, ) if response.status_code != 200: return _redirect_to_login_page_on_error(error_msg="Impossible to get user infos.", request=request) @@ -133,38 +131,38 @@ def inclusion_connect_callback(request): # pylint: disable=too-many-return-stat # 'sub' is the unique identifier from Inclusion Connect, we need that to match a user later on. return _redirect_to_login_page_on_error(error_msg="Sub parameter missing.", request=request) - ic_user_data = OIDConnectUserData.from_user_info(user_data) - user, _ = ic_user_data.create_or_update_user() + proc_user_data = OIDConnectUserData.from_user_info(user_data) + user, _ = proc_user_data.create_or_update_user() if not user.is_active: logout_url_params = { - "redirect_url": ic_session["previous_url"], + "redirect_url": proc_session["previous_url"], } - next_url = f"{reverse('inclusion_connect:logout')}?{urlencode(logout_url_params)}" + next_url = f"{reverse('openid_connect:logout')}?{urlencode(logout_url_params)}" return HttpResponseRedirect(next_url) login(request, user) - next_url = ic_session["next_url"] or reverse("pages:home") + next_url = proc_session["next_url"] or reverse("pages:home") return HttpResponseRedirect(next_url) -def inclusion_connect_logout(request): +def openid_connect_logout(request): token = request.GET.get("token") post_logout_redirect_uri = request.GET.get("redirect_url", reverse("pages:home")) # Fallback on session data. if not token: - ic_session = request.session.get(constants.INCLUSION_CONNECT_SESSION_KEY) - if not ic_session: + proc_session = request.session.get(constants.OPENID_CONNECT_SESSION_KEY) + if not proc_session: raise KeyError("Missing session key.") - token = ic_session["token"] + token = proc_session["token"] params = { "id_token_hint": token, "post_logout_redirect_uri": request.build_absolute_uri(post_logout_redirect_uri), } - complete_url = f"{constants.INCLUSION_CONNECT_ENDPOINT_LOGOUT}?{urlencode(params)}" + complete_url = f"{constants.OPENID_CONNECT_ENDPOINT_LOGOUT}?{urlencode(params)}" logout(request) diff --git a/lacommunaute/surveys/tests/test_views.py b/lacommunaute/surveys/tests/test_views.py index 42a37c83f..a974223f0 100644 --- a/lacommunaute/surveys/tests/test_views.py +++ b/lacommunaute/surveys/tests/test_views.py @@ -23,7 +23,7 @@ location_field_list = ["location", "city_code"] form_html = '
' -login_with_next_url = reverse("inclusion_connect:authorize") + "?next=" + reverse("surveys:dsp_create") +login_with_next_url = reverse("openid_connect:authorize") + "?next=" + reverse("surveys:dsp_create") class TestDSPCreateView: diff --git a/lacommunaute/templates/forum_conversation/topics_newsfeed.html b/lacommunaute/templates/forum_conversation/topics_newsfeed.html index eadb93c5c..ec5dd281d 100644 --- a/lacommunaute/templates/forum_conversation/topics_newsfeed.html +++ b/lacommunaute/templates/forum_conversation/topics_newsfeed.html @@ -39,7 +39,7 @@

La veille informationnelle de l’inclusion (insertion et handi
- + Je me connecte pour accéder à toutes mes thématiques diff --git a/lacommunaute/templates/forum_conversation/topics_public.html b/lacommunaute/templates/forum_conversation/topics_public.html index bca2cf263..2dadb6592 100644 --- a/lacommunaute/templates/forum_conversation/topics_public.html +++ b/lacommunaute/templates/forum_conversation/topics_public.html @@ -47,7 +47,7 @@

- + Je me connecte pour accéder à toutes mes thématiques diff --git a/lacommunaute/templates/forum_member/join_forum_landing.html b/lacommunaute/templates/forum_member/join_forum_landing.html index b0c3b1f3f..3eaa12348 100644 --- a/lacommunaute/templates/forum_member/join_forum_landing.html +++ b/lacommunaute/templates/forum_member/join_forum_landing.html @@ -36,7 +36,7 @@

J'ai un compte Inclusion Connect

{% else %}
  • - - Se connecter | S'inscrire - + Se connecter | S'inscrire
  • {% endif %} @@ -280,16 +278,14 @@

  • - Déconnexion + Déconnexion
  • {% else %} {% endif %} diff --git a/lacommunaute/templates/surveys/dsp_form.html b/lacommunaute/templates/surveys/dsp_form.html index f3ae8c7c3..8add61e34 100644 --- a/lacommunaute/templates/surveys/dsp_form.html +++ b/lacommunaute/templates/surveys/dsp_form.html @@ -67,9 +67,7 @@

    Diagnostic Parcours IAE

    Je me connecte pour accéder à l'aide au diagnostic pour le parcours IAE
    From 76264b65a8b2f4943ae561fa1e8dc4891a1d2908 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 27 Aug 2024 14:59:25 +0200 Subject: [PATCH 6/7] add PyJWT --- poetry.lock | 2 +- pyproject.toml | 1 + requirements/base.txt | 3 +++ requirements/dev.txt | 3 +++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 349102646..0b77f790b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2564,4 +2564,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "4dd7e846255fa513acbbc5c986ca9937614c572b6c80863a8cf48978f5425ca4" +content-hash = "c93ee9ef093047b5bac4cc1f98d38d8b1cc20ab4d8700249f765fca808d675ea" diff --git a/pyproject.toml b/pyproject.toml index c2e8d0408..c1da623cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ django-csp = "^3.7" django-permissions-policy = "^4.15.0" langdetect = "^1.0.9" freezegun = "^1.5.1" +pyjwt = "^2.9.0" [tool.poetry.group.dev.dependencies] diff --git a/requirements/base.txt b/requirements/base.txt index dfb0f00a9..1e85aeb5f 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -242,6 +242,9 @@ psycopg2-binary==2.9.9 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 +pyjwt==2.9.0 ; python_version >= "3.11" and python_version < "4.0" \ + --hash=sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850 \ + --hash=sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c python-dateutil==2.9.0.post0 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 diff --git a/requirements/dev.txt b/requirements/dev.txt index 4c726733d..aa3a23573 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -730,6 +730,9 @@ pycparser==2.22 ; python_version >= "3.11" and python_version < "4.0" \ pygithub==1.59.1 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:3d87a822e6c868142f0c2c4bf16cce4696b5a7a4d142a7bd160e1bdf75bc54a9 \ --hash=sha256:c44e3a121c15bf9d3a5cc98d94c9a047a5132a9b01d22264627f58ade9ddc217 +pyjwt==2.9.0 ; python_version >= "3.11" and python_version < "4.0" \ + --hash=sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850 \ + --hash=sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c pyjwt[crypto]==2.9.0 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850 \ --hash=sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c From 985ebfe4f540b60a48efff3e77b0fdc8f3397f5f Mon Sep 17 00:00:00 2001 From: vincent porte Date: Wed, 28 Aug 2024 11:40:22 +0200 Subject: [PATCH 7/7] fix url and scope --- config/settings/base.py | 2 +- config/urls.py | 2 +- .../tests/__snapshots__/tests_views.ambr | 336 +++++++++--------- lacommunaute/openid_connect/constants.py | 16 +- lacommunaute/openid_connect/urls.py | 6 +- lacommunaute/openid_connect/views.py | 7 +- .../tests/__snapshots__/test_homepage.ambr | 4 +- 7 files changed, 186 insertions(+), 187 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index c1e18c54b..e19fc4cb4 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -110,7 +110,7 @@ MIDDLEWARE = DJANGO_MIDDLEWARE + THIRD_PARTIES_MIDDLEWARE + LOCAL_MIDDLEWARE ROOT_URLCONF = "config.urls" -LOGIN_URL = "/openid_connect/authorize" +LOGIN_URL = "/pro_connect/authorize" LOGIN_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/" diff --git a/config/urls.py b/config/urls.py index f9e3c9a68..2bccdb1cf 100644 --- a/config/urls.py +++ b/config/urls.py @@ -26,7 +26,7 @@ urlpatterns = [ path("admin/", admin.site.urls), # Inclusion Connect URLs. - path("openid_connect/", include(openid_connect_urls)), + path("", include(openid_connect_urls)), # www. path("", include(pages_urls)), path("members/", include(forum_member_urls)), diff --git a/lacommunaute/forum/tests/__snapshots__/tests_views.ambr b/lacommunaute/forum/tests/__snapshots__/tests_views.ambr index 6f51bcd79..2750aec2d 100644 --- a/lacommunaute/forum/tests/__snapshots__/tests_views.ambr +++ b/lacommunaute/forum/tests/__snapshots__/tests_views.ambr @@ -5,12 +5,12 @@ ''' @@ -21,18 +21,18 @@ ''' @@ -43,12 +43,12 @@ ''' @@ -59,24 +59,24 @@ ''' @@ -87,12 +87,12 @@ ''' @@ -103,14 +103,14 @@ ''' @@ -121,18 +121,18 @@ ''' @@ -153,17 +153,17 @@ # name: TestDocumentationCategoryForumContent.test_documentation_category_subforum_list[documentation_category_subforum_list] '''
    - +
    - +
    ''' # --- # name: TestDocumentationCategoryForumContent.test_show_subforum_tags[documentation_category_subforum_tags] '''
    - - - - - + + + + +
    - - - - - + + + + +

    Test Forum

    - +

    Test description

    @@ -217,31 +217,31 @@
    - - + +

    Test description

    - - + +
    - +
    - +
    - +
    - +
    - +
    - +
    - - - - - - + + + + + +
    ''' # --- @@ -300,30 +300,30 @@ # name: TestDocumentationForumContent.test_documentation_forum_share_actions[template_documentation_upvotes] '''
    - - - + + + 0 - - + +
    ''' # --- # name: TestForumDetailContent.test_forum_detail_foot_content[forum_detail_forum_actions_block] ''' ''' # --- @@ -334,7 +334,7 @@

    Test Forum

    - +

    Test description

    @@ -345,23 +345,23 @@ # name: TestForumDetailContent.test_forum_detail_subforum_content_rendered[forum_detail_subforums] '''
      - +
    • Test-Child - - + + 0 Sujet - + - - + 0 Message - +
    • - +
    ''' # --- @@ -369,34 +369,34 @@ '''

    - +

    Cette fiche vous a-t-elle été utile ?

    - + - + - + - + - + - +
    - +
    ''' # --- @@ -404,168 +404,168 @@ '''

    - +

    Merci d'avoir noté cette fiche !

    - +
    - + - +
    - +
    - + - +
    - +
    - + - +
    - +
    - + - +
    - +
    - + - +
    - +
    - +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[0-False][upvotes_counts_0] '''
    - - - + + + 0 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[0-True][upvotes_counts_0] '''
    - - - + + + 0 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[0-True][upvotes_counts_0_self_upvoted] '''
    - - + +
    - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[1-False][upvotes_counts_1] '''
    - - - + + + 1 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[1-True][upvotes_counts_1] '''
    - - - + + + 1 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[1-True][upvotes_counts_1_self_upvoted] '''
    - - + +
    - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[2-False][upvotes_counts_2] '''
    - - - + + + 2 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[2-True][upvotes_counts_2] '''
    - - - + + + 2 - - + +
    ''' # --- # name: TestForumViewContent.test_upvotes_counts[2-True][upvotes_counts_2_self_upvoted] '''
    - - + +
    - - + +
    ''' # --- diff --git a/lacommunaute/openid_connect/constants.py b/lacommunaute/openid_connect/constants.py index 5e7d496a7..6aaa9617b 100644 --- a/lacommunaute/openid_connect/constants.py +++ b/lacommunaute/openid_connect/constants.py @@ -3,24 +3,24 @@ from django.conf import settings -OPENID_CONNECT_SCOPES = "openid profile email" +OPENID_CONNECT_SCOPES = "openid email given_name usual_name" OPENID_CONNECT_CLIENT_ID = settings.OPENID_CONNECT_CLIENT_ID OPENID_CONNECT_CLIENT_SECRET = settings.OPENID_CONNECT_CLIENT_SECRET -OPENID_CONNECT_ENDPOINT = "{base_url}/auth".format( +OPENID_CONNECT_ENDPOINT = "{base_url}".format( base_url=settings.OPENID_CONNECT_BASE_URL, ) -OPENID_CONNECT_ENDPOINT_AUTHORIZE = f"{OPENID_CONNECT_ENDPOINT}/authorize/" -OPENID_CONNECT_ENDPOINT_REGISTRATIONS = f"{OPENID_CONNECT_ENDPOINT}/register/" -OPENID_CONNECT_ENDPOINT_TOKEN = f"{OPENID_CONNECT_ENDPOINT}/token/" -OPENID_CONNECT_ENDPOINT_USERINFO = f"{OPENID_CONNECT_ENDPOINT}/userinfo/" -OPENID_CONNECT_ENDPOINT_LOGOUT = f"{OPENID_CONNECT_ENDPOINT}/logout/" +OPENID_CONNECT_ENDPOINT_AUTHORIZE = f"{OPENID_CONNECT_ENDPOINT}/authorize" +OPENID_CONNECT_ENDPOINT_REGISTRATIONS = f"{OPENID_CONNECT_ENDPOINT}/register" +OPENID_CONNECT_ENDPOINT_TOKEN = f"{OPENID_CONNECT_ENDPOINT}/token" +OPENID_CONNECT_ENDPOINT_USERINFO = f"{OPENID_CONNECT_ENDPOINT}/userinfo" +OPENID_CONNECT_ENDPOINT_LOGOUT = f"{OPENID_CONNECT_ENDPOINT}/session/end" # These expiration times have been chosen arbitrarily. OPENID_CONNECT_TIMEOUT = 60 -OPENID_CONNECT_SESSION_KEY = "openid_connect" +OPENID_CONNECT_SESSION_KEY = "pro_connect" # This expiration time has been chosen arbitrarily. OIDC_STATE_EXPIRATION = datetime.timedelta(hours=1) diff --git a/lacommunaute/openid_connect/urls.py b/lacommunaute/openid_connect/urls.py index 590e502f6..1fd7e9c38 100644 --- a/lacommunaute/openid_connect/urls.py +++ b/lacommunaute/openid_connect/urls.py @@ -6,7 +6,7 @@ app_name = "openid_connect" urlpatterns = [ - path("authorize", views.openid_connect_authorize, name="authorize"), - path("callback", views.openid_connect_callback, name="callback"), - path("logout", views.openid_connect_logout, name="logout"), + path("pro_connect/authorize", views.pro_connect_authorize, name="authorize"), + path("pro_connect/callback", views.pro_connect_callback, name="callback"), + path("pro_connect/logout", views.pro_connect_logout, name="logout"), ] diff --git a/lacommunaute/openid_connect/views.py b/lacommunaute/openid_connect/views.py index 28ec4e827..fae71fb28 100644 --- a/lacommunaute/openid_connect/views.py +++ b/lacommunaute/openid_connect/views.py @@ -46,7 +46,7 @@ def _redirect_to_login_page_on_error(error_msg, request=None): return HttpResponseRedirect(reverse("pages:home")) -def openid_connect_authorize(request): +def pro_connect_authorize(request): # Start a new session. previous_url = request.GET.get("previous_url", reverse("pages:home")) next_url = request.GET.get("next") @@ -65,7 +65,6 @@ def openid_connect_authorize(request): "scope": constants.OPENID_CONNECT_SCOPES, "state": signed_csrf, "nonce": crypto.get_random_string(length=12), - "from": "communaute", # Display a "La communauté" logo on the connection page. "acr_values": "eidas1", # Force the eIDAS authentication. } redirect_url = ( @@ -74,7 +73,7 @@ def openid_connect_authorize(request): return HttpResponseRedirect(f"{redirect_url}?{urlencode(data)}") -def openid_connect_callback(request): # pylint: disable=too-many-return-statements +def pro_connect_callback(request): # pylint: disable=too-many-return-statements code = request.GET.get("code") state = request.GET.get("state") if code is None or not OpenID_State.is_valid(state): @@ -150,7 +149,7 @@ def openid_connect_callback(request): # pylint: disable=too-many-return-stateme return HttpResponseRedirect(next_url) -def openid_connect_logout(request): +def pro_connect_logout(request): token = request.GET.get("token") post_logout_redirect_uri = request.GET.get("redirect_url", reverse("pages:home")) diff --git a/lacommunaute/pages/tests/__snapshots__/test_homepage.ambr b/lacommunaute/pages/tests/__snapshots__/test_homepage.ambr index d0f3a5f3e..f86c4fe11 100644 --- a/lacommunaute/pages/tests/__snapshots__/test_homepage.ambr +++ b/lacommunaute/pages/tests/__snapshots__/test_homepage.ambr @@ -171,7 +171,7 @@
  • - Se connecter | S'inscrire + Se connecter | S'inscrire
  • @@ -262,7 +262,7 @@