From 8348a55f7e4f29cdd704095199c0221ac255c098 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Mon, 15 Dec 2025 22:39:43 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(backend)=20enable=20user=20creation?= =?UTF-8?q?=20via=20email=20for=20external=20integrations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow external platforms using the public API to create provisional users with email-only identification when the user doesn't yet exist in our system. This removes a key friction point blocking third-party integrations from fully provisioning access on behalf of new users. Provisional users are created with email as the primary identifier. Full identity reconciliation (sub assignment) occurs on first login, ensuring reliable user identification is eventually established. While email-only user creation is not ideal from an identity perspective, it provides a pragmatic path to unlock integrations and accelerate adoption through external platforms that are increasingly driving our videoconference tool's growth. --- CHANGELOG.md | 4 +++ docs/openapi.yaml | 1 - src/backend/core/external_api/viewsets.py | 28 +++++++++++++++---- .../locale/de_DE/LC_MESSAGES/django.po | 10 +++---- .../locale/en_US/LC_MESSAGES/django.po | 10 +++---- .../locale/fr_FR/LC_MESSAGES/django.po | 10 +++---- .../locale/nl_NL/LC_MESSAGES/django.po | 10 +++---- src/backend/meet/settings.py | 8 ++++++ 8 files changed, 55 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81007629..b49c15d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [Unreleased] +### Added + +- ✨(backend) enable user creation via email for external integrations + ## [1.0.1] - 2025-12-17 ### Changed diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 617cde50..fc23ffdf 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -21,7 +21,6 @@ info: #### Upcoming Features - * **Create rooms for unknown users from the web app:** Support for generating rooms for users who are not yet registered in the system. * **Add attendees to a room:** You will be able to update a room to include a list of attendees, allowing them to bypass the lobby system automatically. * **Delete application-generated rooms:** Rooms created via the application can be deleted when no longer needed. diff --git a/src/backend/core/external_api/viewsets.py b/src/backend/core/external_api/viewsets.py index ebe3dec7..2c663902 100644 --- a/src/backend/core/external_api/viewsets.py +++ b/src/backend/core/external_api/viewsets.py @@ -95,11 +95,29 @@ class ApplicationViewSet(viewsets.GenericViewSet): try: user = models.User.objects.get(email=email) except models.User.DoesNotExist as e: - raise drf_exceptions.NotFound( - { - "error": "User not found.", - } - ) from e + if ( + settings.APPLICATION_ALLOW_USER_CREATION + and settings.OIDC_FALLBACK_TO_EMAIL_FOR_IDENTIFICATION + ): + # Create a pending user without sub, but with an email. + user = models.User( + sub=None, + email=email, + ) + user.set_unusable_password() + user.save() + logger.info( + "Provisional user created via application: user_id=%s, email=%s, client_id=%s", + user.id, + email, + application.client_id, + ) + else: + raise drf_exceptions.NotFound( + { + "error": "User not found.", + } + ) from e now = datetime.now(timezone.utc) scope = " ".join(application.scopes or []) diff --git a/src/backend/locale/de_DE/LC_MESSAGES/django.po b/src/backend/locale/de_DE/LC_MESSAGES/django.po index 2c5d332e..a647357e 100644 --- a/src/backend/locale/de_DE/LC_MESSAGES/django.po +++ b/src/backend/locale/de_DE/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-13 16:21+0000\n" +"POT-Creation-Date: 2025-12-17 15:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -531,18 +531,18 @@ msgstr "" " Wenn Sie Fragen haben oder Unterstützung benötigen, wenden Sie sich bitte " "an unser Support-Team unter %(support_email)s. " -#: meet/settings.py:167 +#: meet/settings.py:169 msgid "English" msgstr "Englisch" -#: meet/settings.py:168 +#: meet/settings.py:170 msgid "French" msgstr "Französisch" -#: meet/settings.py:169 +#: meet/settings.py:171 msgid "Dutch" msgstr "Niederländisch" -#: meet/settings.py:170 +#: meet/settings.py:172 msgid "German" msgstr "Deutsch" diff --git a/src/backend/locale/en_US/LC_MESSAGES/django.po b/src/backend/locale/en_US/LC_MESSAGES/django.po index 12f1f2d6..4e369881 100644 --- a/src/backend/locale/en_US/LC_MESSAGES/django.po +++ b/src/backend/locale/en_US/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-13 16:21+0000\n" +"POT-Creation-Date: 2025-12-17 15:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -529,18 +529,18 @@ msgstr "" " If you have any questions or need assistance, please contact our support " "team at %(support_email)s. " -#: meet/settings.py:167 +#: meet/settings.py:169 msgid "English" msgstr "English" -#: meet/settings.py:168 +#: meet/settings.py:170 msgid "French" msgstr "French" -#: meet/settings.py:169 +#: meet/settings.py:171 msgid "Dutch" msgstr "Dutch" -#: meet/settings.py:170 +#: meet/settings.py:172 msgid "German" msgstr "German" diff --git a/src/backend/locale/fr_FR/LC_MESSAGES/django.po b/src/backend/locale/fr_FR/LC_MESSAGES/django.po index 7c6be7b1..efa8e4dd 100644 --- a/src/backend/locale/fr_FR/LC_MESSAGES/django.po +++ b/src/backend/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-13 16:21+0000\n" +"POT-Creation-Date: 2025-12-17 15:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: antoine.lebaud@mail.numerique.gouv.fr\n" "Language-Team: LANGUAGE \n" @@ -531,18 +531,18 @@ msgstr "" " Si vous avez des questions ou besoin d'assistance, veuillez contacter notre " "équipe d'assistance à %(support_email)s. " -#: meet/settings.py:167 +#: meet/settings.py:169 msgid "English" msgstr "Anglais" -#: meet/settings.py:168 +#: meet/settings.py:170 msgid "French" msgstr "Français" -#: meet/settings.py:169 +#: meet/settings.py:171 msgid "Dutch" msgstr "Néerlandais" -#: meet/settings.py:170 +#: meet/settings.py:172 msgid "German" msgstr "Allemand" diff --git a/src/backend/locale/nl_NL/LC_MESSAGES/django.po b/src/backend/locale/nl_NL/LC_MESSAGES/django.po index e2810b1c..32a5067f 100644 --- a/src/backend/locale/nl_NL/LC_MESSAGES/django.po +++ b/src/backend/locale/nl_NL/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-13 16:21+0000\n" +"POT-Creation-Date: 2025-12-17 15:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -526,18 +526,18 @@ msgstr "" " Als je vragen hebt of hulp nodig hebt, neem dan contact op met ons support " "team via %(support_email)s. " -#: meet/settings.py:167 +#: meet/settings.py:169 msgid "English" msgstr "Engels" -#: meet/settings.py:168 +#: meet/settings.py:170 msgid "French" msgstr "Frans" -#: meet/settings.py:169 +#: meet/settings.py:171 msgid "Dutch" msgstr "Nederlands" -#: meet/settings.py:170 +#: meet/settings.py:172 msgid "German" msgstr "Duits" diff --git a/src/backend/meet/settings.py b/src/backend/meet/settings.py index 2a2e7f49..bf9bbdba 100755 --- a/src/backend/meet/settings.py +++ b/src/backend/meet/settings.py @@ -770,6 +770,14 @@ class Base(Configuration): environ_name="APPLICATION_BASE_URL", environ_prefix=None, ) + # Allows third-party platforms to create users with email-only identification. + # Required for external integrations, but fragile due to deferred user reconciliation + # on sub. Enable it with care /!\ + APPLICATION_ALLOW_USER_CREATION = values.BooleanValue( + False, + environ_name="APPLICATION_ALLOW_USER_CREATION", + environ_prefix=None, + ) # pylint: disable=invalid-name @property