mirror of
https://github.com/suitenumerique/meet.git
synced 2026-09-07 16:05:39 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80dfaf43dc | |||
| 2a59b55128 |
+2
-1
@@ -17,6 +17,7 @@ and this project adheres to
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- ⬆️(dev) pin LiveKit server to v1.13.6
|
- ⬆️(dev) pin LiveKit server to v1.13.6
|
||||||
|
- 🔒(frontend) upgrade base image to 1.30.4-alpine3.24
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ and this project adheres to
|
|||||||
- 🐛(frontend) keep the sending resolution picked while the camera is off #1667
|
- 🐛(frontend) keep the sending resolution picked while the camera is off #1667
|
||||||
- 🐛(frontend) restore automatic lower-hand on speaking
|
- 🐛(frontend) restore automatic lower-hand on speaking
|
||||||
- 🐛(frontend) center Avatar initials with a font-aware cap-height ratio
|
- 🐛(frontend) center Avatar initials with a font-aware cap-height ratio
|
||||||
- 🔒️(backend) reject inactive users in resource server backend
|
- 🐛(frontend) keep feedback buttons on one line for fr/es/en
|
||||||
|
|
||||||
## [1.30.0] - 2026-09-01
|
## [1.30.0] - 2026-09-01
|
||||||
|
|
||||||
|
|||||||
@@ -54,19 +54,11 @@ RUN npx webpack --mode production
|
|||||||
|
|
||||||
|
|
||||||
# ---- Front-end image ----
|
# ---- Front-end image ----
|
||||||
FROM nginxinc/nginx-unprivileged:1.30.3-alpine3.23 AS frontend-production
|
FROM nginxinc/nginx-unprivileged:1.30.4-alpine3.24 AS frontend-production
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
RUN apk del curl
|
||||||
# Security patches for known CVEs
|
USER nginx
|
||||||
RUN apk update && apk upgrade \
|
|
||||||
libcrypto3>=3.5.7-r0 \
|
|
||||||
libssl3>=3.5.7-r0 \
|
|
||||||
musl \
|
|
||||||
musl-utils \
|
|
||||||
zlib>=1.3.2-r0 \
|
|
||||||
libexpat>=2.8.4-r0 \
|
|
||||||
&& apk del curl
|
|
||||||
|
|
||||||
USER nginx
|
USER nginx
|
||||||
|
|
||||||
|
|||||||
@@ -286,10 +286,6 @@ class ResourceServerBackend(LaSuiteBackend):
|
|||||||
if user is None and settings.OIDC_CREATE_USER:
|
if user is None and settings.OIDC_CREATE_USER:
|
||||||
user = self.create_user(sub)
|
user = self.create_user(sub)
|
||||||
|
|
||||||
if user is not None and not user.is_active:
|
|
||||||
logger.warning("Inactive user attempted authentication: %s", user.pk)
|
|
||||||
raise SuspiciousOperation("User account is disabled.")
|
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def create_user(self, sub):
|
def create_user(self, sub):
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
"""Tests for the external API ResourceServerBackend."""
|
|
||||||
|
|
||||||
from django.core.exceptions import SuspiciousOperation
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
import responses
|
|
||||||
from rest_framework.test import APIClient
|
|
||||||
|
|
||||||
from core.external_api.authentication import ResourceServerBackend
|
|
||||||
from core.factories import UserFactory
|
|
||||||
from core.models import User
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
|
||||||
|
|
||||||
|
|
||||||
def _payload(sub):
|
|
||||||
return {"sub": sub, "active": True, "scope": "lasuite_meet", "client_id": "app"}
|
|
||||||
|
|
||||||
|
|
||||||
def test_resource_server_backend_get_or_create_user_active():
|
|
||||||
"""An existing active user matching the sub should be returned."""
|
|
||||||
|
|
||||||
user = UserFactory()
|
|
||||||
|
|
||||||
result = ResourceServerBackend().get_or_create_user(
|
|
||||||
access_token="token", id_token=None, payload=_payload(user.sub)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result == user
|
|
||||||
|
|
||||||
|
|
||||||
def test_resource_server_backend_get_or_create_user_inactive():
|
|
||||||
"""An inactive user should be rejected even with a valid token."""
|
|
||||||
|
|
||||||
user = UserFactory(is_active=False)
|
|
||||||
|
|
||||||
with pytest.raises(SuspiciousOperation, match="User account is disabled."):
|
|
||||||
ResourceServerBackend().get_or_create_user(
|
|
||||||
access_token="token", id_token=None, payload=_payload(user.sub)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_resource_server_backend_get_or_create_user_creates(settings):
|
|
||||||
"""An unknown sub should create an active user when OIDC_CREATE_USER is set."""
|
|
||||||
|
|
||||||
settings.OIDC_CREATE_USER = True
|
|
||||||
|
|
||||||
result = ResourceServerBackend().get_or_create_user(
|
|
||||||
access_token="token", id_token=None, payload=_payload("new-sub")
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result.sub == "new-sub"
|
|
||||||
assert result.is_active is True
|
|
||||||
assert User.objects.filter(sub="new-sub").exists()
|
|
||||||
|
|
||||||
|
|
||||||
def test_resource_server_backend_get_or_create_user_no_creation(settings):
|
|
||||||
"""An unknown sub should return None when OIDC_CREATE_USER is unset."""
|
|
||||||
|
|
||||||
settings.OIDC_CREATE_USER = False
|
|
||||||
|
|
||||||
result = ResourceServerBackend().get_or_create_user(
|
|
||||||
access_token="token", id_token=None, payload=_payload("new-sub")
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result is None
|
|
||||||
assert not User.objects.filter(sub="new-sub").exists()
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_api_rooms_list_resource_server_inactive_user(settings):
|
|
||||||
"""End to end: a valid introspected token for an inactive user should get 401."""
|
|
||||||
|
|
||||||
settings.OIDC_OP_INTROSPECTION_ENDPOINT = "https://oidc.example.com/introspect"
|
|
||||||
settings.OIDC_OP_URL = "https://oidc.example.com"
|
|
||||||
|
|
||||||
user = UserFactory(is_active=False)
|
|
||||||
|
|
||||||
responses.add(
|
|
||||||
responses.POST,
|
|
||||||
"https://oidc.example.com/introspect",
|
|
||||||
json={
|
|
||||||
"iss": "https://oidc.example.com",
|
|
||||||
"active": True,
|
|
||||||
"sub": user.sub,
|
|
||||||
"scope": "lasuite_meet",
|
|
||||||
"client_id": "app",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
client = APIClient()
|
|
||||||
client.credentials(HTTP_AUTHORIZATION="Bearer rs-token")
|
|
||||||
response = client.get("/external-api/v1.0/rooms/")
|
|
||||||
|
|
||||||
assert response.status_code == 401
|
|
||||||
assert "login failed" in str(response.data).lower()
|
|
||||||
+2
-12
@@ -42,20 +42,10 @@ ENV VITE_APP_TITLE=${VITE_APP_TITLE}
|
|||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# ---- Front-end image ----
|
# ---- Front-end image ----
|
||||||
FROM nginxinc/nginx-unprivileged:1.30.3-alpine3.23 AS frontend-production
|
FROM nginxinc/nginx-unprivileged:1.30.4-alpine3.24 AS frontend-production
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
RUN apk del curl
|
||||||
# Security patches for known CVEs
|
|
||||||
RUN apk update && apk upgrade \
|
|
||||||
libcrypto3>=3.5.7-r0 \
|
|
||||||
libssl3>=3.5.7-r0 \
|
|
||||||
musl \
|
|
||||||
musl-utils \
|
|
||||||
zlib>=1.3.2-r0 \
|
|
||||||
libexpat>=2.8.4-r0 \
|
|
||||||
&& apk del curl
|
|
||||||
|
|
||||||
USER nginx
|
USER nginx
|
||||||
|
|
||||||
# Un-privileged user running the application
|
# Un-privileged user running the application
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const FeedbackRoute = () => {
|
|||||||
<Stack
|
<Stack
|
||||||
direction={{ base: 'column', xsm: 'row' }}
|
direction={{ base: 'column', xsm: 'row' }}
|
||||||
width={{ base: '100%', xsm: 'auto' }}
|
width={{ base: '100%', xsm: 'auto' }}
|
||||||
maxWidth="380px"
|
maxWidth="410px"
|
||||||
>
|
>
|
||||||
{showBackButton && (
|
{showBackButton && (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
Reference in New Issue
Block a user