Commit Graph

406 Commits

Author SHA1 Message Date
lebaudantoine dcb788b57b 🔒️(backend) avoid information exposure through exception messages
Sanitize error handling to prevent leaking internal details when
invalid or malicious requests are sent to the API.

Return generic error responses to reduce the risk of information
disclosure during probing attempts.
2026-03-13 17:33:55 +01:00
lebaudantoine 73bcb9d598 🐛(backend) fix unescaped dot in regex pattern
The dot before (?P<extension>...) was not escaped and matched any
character instead of a literal period.

Escape it to align with MEDIA_STORAGE_URL_PATTERN, which correctly
uses \. for the file extension separator.
2026-03-13 16:19:36 +01:00
lebaudantoine f3e90c3999 ♻️(backend) clarify storage hook message for intentionally ignored req
Update the response message to explicitly state that certain
notifications are ignored on purpose, avoiding confusion
during debugging or log inspection.
2026-03-13 15:42:30 +01:00
lebaudantoine cb4ed3c9d7 🩹(backend) ignore non-recording uploads in storage webhook handler
With the introduction of background file uploads, a misconfigured
MinIO webhook could trigger the storage hook endpoint for unrelated
files.

While the dev setup now filters events via the MinIO lifecycle
configuration, add a safeguard at the application level.

Enforce a stricter filepath regex when parsing storage hook events
and ignore files outside the recording output directory.

Return a clean 200 response to acknowledge the webhook while
avoiding unnecessary processing.
2026-03-13 15:34:02 +01:00
lebaudantoine f8b0746e73 ♻️(backend) factorize regex used in the S3 event parser
Avoid duplicating patterns that match the same logical unit by
sharing common parts between the two regexes.

This logical factorization improves maintainability and ensures
consistent parsing behavior across S3 event handlers.
2026-03-13 15:34:02 +01:00
lebaudantoine d8ad7a743e ♻️(backend) align recording file regex with MEDIA_URL-based pattern
Initially I avoided coupling the recording path regex with the
setting that provides the Django static URL. However the new
file viewset already relies on it, and Drive does as well.

For consistency, update the recording regex to use the same
STATIC_URL-based approach.

While the coupling may not feel ideal, having two different
regex strategies for similar file paths would be worse.
2026-03-13 15:34:02 +01:00
lebaudantoine 0ba445895c ♻️(backend) merge room name regex and centralize patterns in enums
Combine the regex used in Drive with the one from the recording
feature and centralize them in the enums module.

Although the module name suggests only enums, it also hosts
shared constants used across the codebase.
2026-03-13 15:34:02 +01:00
Florent Chehab 3b719ab9ba (settings) disable file upload by default & max count
Add FILE_UPLOAD_ENABLED setting (default to False, to avoid
a breaking change). Also adds a max_count_by_user sub setting
to restrict the number of uploaded files per user.
2026-03-12 14:55:33 +01:00
lebaudantoine 7da99f2116 🔐(backend) avoids revealing the inactive status of an application
Authenticate the application secret before checking whether the
application is inactive.

This avoids revealing the inactive status of an application when
an incorrect secret is provided, preventing an authentication
state oracle and client_id enumeration.
2026-03-12 13:40:11 +01:00
lebaudantoine b0af5e7f35 🧪(backend) add failing test for client_id enumeration issue
Currently the inactive status is revealed before verifying the
secret, creating an authentication state oracle.

Introduce a failing test to capture the issue before
applying the fix.
2026-03-12 13:39:44 +01:00
lebaudantoine 1306f0bcfe (backend) expose is_active field for Application in Django admin
Add minimal admin support to allow administrators to mark an
application account as inactive if it becomes rogue or compromised.

This capability was missing when the application concept was
initially introduced in the backend.
2026-03-12 13:27:08 +01:00
lebaudantoine ca4494c09e ♻️(backend) align Application model field with is_active convention
Most models in the project use `is_active` rather than `active`.
The Application model was not aligned with this convention.

Rename the field and add a migration to standardize the naming.
Update related tests accordingly.

This change should not introduce breaking changes for external
applications.
2026-03-12 13:26:37 +01:00
lebaudantoine f57db0acc8 ♻️(backend) refactor uploaded file's key format
Remove the user-provided filename while preserving the extension,
and switch to the format `uuid.extension`.

This is more natural than the previous `uuid/.extension` format
and avoids confusion.

Update related tests accordingly.
2026-03-12 10:39:59 +01:00
Florent Chehab 342f992556 🔨(python-env) migrate meet main app to UV
Migrate main meet app to use UV for dependancy management.
Also optimized the backend image build sequence for faster rebuilds
when dependencies don't change.
Also removed compiled django translations files are they are done in the build
process now.

Changes inspired by drive repo.
2026-03-12 10:25:35 +01:00
lebaudantoine 0f3eb35c83 🩹(backend) add Django admin action to update recording status manually
Making the status read-only improved security and enforced least
privilege, but in production some recordings could not be properly
stopped, leaving them in an active state.

Introduce an admin action to allow support staff to mark recordings
as "failed to stop" or update their status when necessary.
2026-03-11 19:41:45 +01:00
lebaudantoine 051f33bb1e (backend) add tests for request-entry throttling in the lobby system
Cover throttling behavior for both authenticated users and
anonymous participants identified via the lobby cookie.
2026-03-11 18:07:39 +01:00
lebaudantoine 566eacc8fe (backend) add authenticated user rate throttling on request-entry
Throttle the request-entry endpoint for authenticated users also
to guard against accidental hammering from buggy clients.

Authenticated users are throttled via RequestEntryUserRateThrottle.
Anonymous users are throttled using the lobby participant cookie
through RequestEntryAnonRateThrottle.
2026-03-11 18:07:39 +01:00
lebaudantoine d19023a1ba 🐛(backend) refactor lobby throttling to use participant id instead of IP
use the lobby participant cookie ID as the throttle cache key
rather than the client IP address.

This avoids penalising multiple users behind the same NAT or proxy
and aligns throttling with how LobbyService identifies participants.

This bug was spotted in production where users from ministries behind
NAT was blocked by throttling while using visio.

If no cookie is present yet, skip throttling for the request. The
cookie will be set on the first response and throttling will apply
from subsequent requests.

This throttle is intended to protect against accidental hammering
from buggy clients, not as a security control against DoS attacks.

This is not a security measure, we should use a WAF.
2026-03-11 18:07:39 +01:00
lebaudantoine c3fd1a89ef 🩹(backend) add page_size to pagination for room endpoints
Align room endpoints with the pagination behavior used across
other API endpoints and resolve issue #1055.
2026-03-11 16:27:02 +01:00
Hadrien Blanc 6b08b8da1b 📝 Fix documentation and comment typos 2026-03-10 22:56:08 +01:00
Florent Chehab 77105001e0 (settings) configure celery & run task in dedicated queue
Improve celery configuration from env variables and set
meet backend related tasks to run in the `meet-backend` queue
to ease sharing a single redis instance for multiple celery.
2026-03-10 18:36:04 +01:00
Florent Chehab dc278a6064 (backend) add file upload feature & tests
For the coming features we will need to store files on the meet side.
(for instance user backgrounds).

This commits adds a new Model to manage files, and the associated
serializers & viewsets. All are tested.

This work was heavily inspired by the work done by our friends at
https://github.com/suitenumerique/drive
It build on the same architecture design (upload directly to S3 but
download goes through our proxy), but model is much much simplier
(no folders, no file sharing, etc.).
2026-03-06 11:31:39 +01:00
Florent Chehab 047da94494 (backend) add mimetype detection logic from drive
Reused the logic developed by the team working on drive.
This is usefull for our own upload file backend (that will
come in later commits).

Dockefile was updated to add a required system dependency.

We might want to put this shared logic in a lib.
2026-03-06 11:31:39 +01:00
lebaudantoine b564044e70 🔖(minor) bump release to 1.10.0 2026-03-05 14:19:25 +01:00
renovate[bot] 4717143251 ⬆️(dependencies) update django to v5.2.12 [SECURITY] 2026-03-05 12:19:47 +01:00
lebaudantoine 42647d6d25 🦺(backend) strengthen API validation for recording options
Improve validation of parameters accepted when starting a
recording to prevent unsupported or unexpected values.

Language validation will be further tightened to only accept
languages supported by the transcribe microservice.

Add extensive API validation tests to cover these scenarios.
2026-03-03 19:05:15 +01:00
Florent Chehab 25167495cc 🐛(migrations) use settings in migrations
Use settings directly in migrations to avoid noop
migrations. This might have undisered side effects
if we change the config over time 'invalid' data will be
in the database.

It's a simple quick fix.
Keeping some migrations that are no useless to avoid changing
too much the migration history for users.

Similar to https://github.com/suitenumerique/people/commit/
469014ac415b25be0ceed08b31a87d2d40d743cd
2026-03-03 14:48:06 +01:00
lebaudantoine 720eb6a93e ♻️(backend) extract forbidden permission fields from the serializer
These fields previously triggered a suspicious operation exception
when passed to the API.

Make the list configurable so the serializer behavior can be
adjusted without requiring a new release.
2026-03-03 13:30:10 +01:00
lebaudantoine bfbf253033 🔒️(backend) enhance API input validation to strengthen security
During the bug bounty, attempts were made to pass unexpected hidden
fields to manipulate room behavior and join as a ghost.

Treat these parameters as suspicious. They are not sent by the
frontend, so their presence likely indicates tampering.

Explicitly allow the parameters but emit warning logs to help detect
and investigate suspicious activity.
2026-03-03 13:30:10 +01:00
lebaudantoine 692e0e359e (backend) install pydantic and django-pydantic-field to strengthen API
Super useful for validation when handling unstructured dictionaries.

Follow qbey's recommendation and align with the
suitenumerique/conversation project approach to improve schema
validation and data integrity.
2026-03-03 13:30:10 +01:00
lebaudantoine b2ad423886 🔖(minor) bump release to 1.9.0 2026-03-02 14:33:25 +01:00
Florent Chehab 4b76e9571f ⬆️ (python) bump minimal required python version to 3.13
We are going to use features only available in python 3.13.
We already ship docker images based on python 3.13.

For https://github.com/suitenumerique/meet/pull/1030
2026-02-27 12:37:14 +01:00
leo f5e0ddf692 (summary) add localization support for transcription context text
Transcription and summarization results were always generated
using a French text structure (e.g. "Réunion du..."), regardless
of user preference or meeting language. Introduced basic localization
support to adapt generated string languages.
2026-02-25 18:07:19 +01:00
lebaudantoine f625df6508 ♻️(backend) refactor external API tests
Refactor tests to avoid duplicating JWT secret key configuration.

Introduce configuration of the JWT audience, which previously had no
default value.
2026-02-24 16:07:23 +01:00
lebaudantoine ac87980a27 ♻️(backend) refactor external API authentication classes
Refactor external API authentication classes to inherit from a
common base authentication backend.

Prepare the introduction of a new authentication class responsible
for verifying tokens provided to calendar integrations.

Move token decoding responsibility to the new token service so it
can both generate and validate tokens.

Encapsulate external exceptions and expose a clear interface by
defining custom Python exceptions raised during token validation.

Taken from #897.
2026-02-24 16:07:23 +01:00
lebaudantoine 7cab46dc29 ♻️(backend) encapsulate token generation in a service
Encapsulate token generation logic for authenticating to the
external API in a well-scoped service.

This service can later be reused in other parts of the codebase,
especially for providing tokens required by calendar integrations.

Commit was cherry picked from #897
2026-02-24 16:07:23 +01:00
lebaudantoine 6f77559633 ⬆️(backend) update python dependencies
Updating ruff led me to refactor an unnecessary lambda
2026-02-24 12:23:22 +01:00
lebaudantoine 9916ab7d7e 🔖(minor) bump release to 1.8.0 2026-02-20 13:44:19 +01:00
lebaudantoine ce9f812a7e 🔖(minor) bump release to 1.7.0 2026-02-19 12:37:26 +01:00
lebaudantoine 89031abb63 🔖(minor) bump release to 1.6.0 2026-02-10 15:31:29 +01:00
Bastien Ogier 2c65cc061e 🚀(settings) standardize DATABASE_URL environment retrieval
(settings) standardize DATABASE_URL environment retrieval
2026-02-10 10:44:13 +01:00
Sylvain Zimmer 117677bd14 🚀(paas) add PaaS deployment scripts, tested on Scalingo
add PaaS deployment scripts, tested on Scalingo
2026-02-10 10:44:13 +01:00
lebaudantoine 69c6e58017 🔒️(backend) add application validation when consuming external JWT
Token generation already verifies that the application is active, but this
guarantee was not enforced when the token was used. This change adds a
runtime check to ensure the client_id claim matches an existing and active
application when evaluating permissions.

This also introduces an emergency revocation mechanism, allowing all previously
issued tokens for a given application to be invalidated if the application is
disabled.
2026-02-09 22:18:09 +01:00
lebaudantoine 6742f5d19d (backend) monitor throttling rate failure through sentry
Use a mixin, introduced by @lunika in the shared
backend library to monitor throttling behavior.

The mixin tracks when throttling limits are reached, sending errors to Sentry
to trigger alerts when configured. This helps detect misconfigurations,
fine-tune throttling settings, and identify suspicious operations.

This enables safely increasing API throttling limits while ensuring stability,
providing confidence that higher limits won’t break the system.
2026-02-09 15:50:53 +01:00
lebaudantoine 23de7e52bc ♻️(backend) extract throttling classes into a module
Extract throttling classes into a dedicated Python module, following the
structure of suitenumerique/docs.

This is a preparatory refactor to ease upcoming changes to the throttling
implementation. No functional behavior change is introduced in this commit.
2026-02-09 15:50:53 +01:00
lebaudantoine 3887255e9c ♻️(backend) rework permission to better align with DRF responsibilities
If a viewset action is not implemented, the permission layer no longer returns
a 403. Instead, it lets DRF handle the request and return the appropriate 405
Method Not Allowed response, ensuring cleaner and more standard API error
handling.
2026-02-09 12:16:12 +01:00
lebaudantoine 5d6ad3f3f6 🔒️(backend) enhance scope manipulation
Enhance scope manipulation by normalizing and sanitizing
scope values before processing.

Scopes are now converted to lowercase to ensure consistent behavior,
deduplicated while preserving their original order, and handled in a
deterministic way aligned with the intended authorization model.
2026-02-09 12:16:12 +01:00
lebaudantoine 44d68a9c80 (backend) strengthen external API viewset test coverage
Reinforce the test suite around the external API viewset to better
prevent regressions, permission leaks, and unexpected failures.

Adds additional scenarios covering permission enforcement, edge cases,
and error handling to ensure the external API behavior remains stable
and secure as it evolves.
2026-02-09 12:16:12 +01:00
lebaudantoine ed5c1bbd84 ♻️(backend) improve scope prefix removal logic
The previous replace usage was too broad and could remove multiple
occurrences, which was not the original intention.

Replace the replace call with removeprefix, which more accurately
matches the expected behavior by only removing the prefix when present
at the start of the string.
2026-02-09 12:16:12 +01:00
lebaudantoine f8c6da8021 🔐(backend) enforce object-level permission checks on room endpoint
Apply strict permission validation on the external API room endpoint to
enforce the principle of least privilege. Unlike the default API (which allows
unauthenticated room retrieval and filters access in the serializer), the
external API now only exposes rooms to users with explicit permissions.

This change fixes a security issue. Slug-based room retrieval, as supported
by the default API, is not introduced here but could be added later if needed.
Retrieving rooms by UUID is retained, as guessing a UUID is significantly harder
than a slug.

A dedicated permission class was created to avoid coupling permissions between
the default and external APIs. The external API enforces stricter access rules.

Access policies may be revisited based on user and integrator feedback. The
external API currently has no production usage.
2026-02-09 12:16:12 +01:00