(backend) enable user creation via email for external integrations

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.
This commit is contained in:
lebaudantoine
2025-12-15 22:39:43 +01:00
committed by aleb_the_flash
parent a4b76433ab
commit 8348a55f7e
8 changed files with 55 additions and 26 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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 [])

View File

@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

View File

@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

View File

@@ -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 <LL@li.org>\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"

View File

@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

View File

@@ -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