Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5c9dc1fa8 |
+3
-2
@@ -19,12 +19,13 @@ and this project adheres to
|
||||
- ♿️(frontend) sync html lang attribute with i18n for screen readers #1111
|
||||
- ♿️(frontend) improve MoreLink a11y and UX on home page #1112
|
||||
- ♿(frontend) improve chat toast a11y for screen readers #1109
|
||||
- ♿(frontend) improve ui and qria labels for help article links #1108
|
||||
- ♿(frontend) improve ui and aria labels for help article links #1108
|
||||
- 🌐(frontend) improve German translation #1125
|
||||
- 🦺(backend) optionally validate room names using a regex #1132
|
||||
|
||||
### Fixed
|
||||
|
||||
- 🐛(frontend) fix hand icon and queue position aligment and position #1119
|
||||
- 🐛(frontend) fix hand icon and queue position alignment and position #1119
|
||||
|
||||
## [1.10.0] - 2026-03-05
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
# pylint: disable=abstract-method,no-name-in-module
|
||||
import logging
|
||||
import re
|
||||
from os.path import splitext
|
||||
from typing import Literal
|
||||
from urllib.parse import quote
|
||||
@@ -131,6 +132,21 @@ class RoomSerializer(serializers.ModelSerializer):
|
||||
fields = ["id", "name", "slug", "configuration", "access_level", "pin_code"]
|
||||
read_only_fields = ["id", "slug", "pin_code"]
|
||||
|
||||
def validate_name(self, value):
|
||||
"""Validate the name matches the optionally configured ROOM_NAME_REGEX"""
|
||||
|
||||
if not value:
|
||||
raise serializers.ValidationError("Name cannot be empty.")
|
||||
|
||||
room_name_regex = settings.ROOM_NAME_REGEX
|
||||
if room_name_regex is None:
|
||||
return value
|
||||
|
||||
if not re.fullmatch(room_name_regex, value):
|
||||
raise SuspiciousOperation("Name does not match the expected format.")
|
||||
|
||||
return value
|
||||
|
||||
def to_representation(self, instance):
|
||||
"""
|
||||
Add users only for administrator users.
|
||||
|
||||
@@ -3,7 +3,10 @@ Test rooms API endpoints in the Meet core app: create.
|
||||
"""
|
||||
|
||||
# pylint: disable=redefined-outer-name,unused-argument
|
||||
from unittest import mock
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
@@ -109,3 +112,47 @@ def test_api_rooms_create_authenticated_existing_slug():
|
||||
|
||||
assert response.status_code == 400
|
||||
assert response.json() == {"slug": ["Room with this Slug already exists."]}
|
||||
|
||||
|
||||
@mock.patch("core.api.serializers.SuspiciousOperation", side_effect=SuspiciousOperation)
|
||||
def test_api_rooms_create_invalid_regex(mock_suspicious, settings):
|
||||
"""A room can not be created when its name doesn't match the configured pattern."""
|
||||
|
||||
settings.ROOM_NAME_REGEX = r"[a-z]{3}-[a-z]{4}-[a-z]{3}"
|
||||
user = UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
"/api/v1.0/rooms/",
|
||||
{
|
||||
"name": "my room",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert Room.objects.exists() is False
|
||||
|
||||
mock_suspicious.assert_called_once_with("Name does not match the expected format.")
|
||||
|
||||
|
||||
def test_api_rooms_create_valid_regex(settings):
|
||||
"""A room can be created when its name matches the configured pattern."""
|
||||
|
||||
settings.ROOM_NAME_REGEX = r"[a-z]{3}-[a-z]{4}-[a-z]{3}"
|
||||
user = UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
"/api/v1.0/rooms/",
|
||||
{
|
||||
"name": "foo-barn-baz",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
assert Room.objects.count() == 1
|
||||
assert Room.objects.filter(name="foo-barn-baz").exists()
|
||||
|
||||
@@ -752,6 +752,13 @@ class Base(Configuration):
|
||||
environ_prefix=None,
|
||||
)
|
||||
|
||||
# Room validation
|
||||
ROOM_NAME_REGEX = values.RegexValue(
|
||||
None,
|
||||
environ_name="ROOM_NAME_REGEX",
|
||||
environ_prefix=None,
|
||||
)
|
||||
|
||||
# Calendar integrations
|
||||
ROOM_CREATION_CALLBACK_CACHE_TIMEOUT = values.PositiveIntegerValue(
|
||||
600, # 10 minutes
|
||||
|
||||
Reference in New Issue
Block a user