Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit caa764b

Browse files
committed
Switch to pydantic.
1 parent b6359c2 commit caa764b

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

synapse/events/validator.py

+11-23
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import collections.abc
15-
from typing import Iterable, Type, Union, cast
15+
from typing import Iterable, List, Type, Union, cast
1616

1717
import jsonschema
18+
from pydantic import Field, StrictBool, StrictStr
1819

1920
from synapse.api.constants import (
2021
MAX_ALIAS_LENGTH,
@@ -33,6 +34,8 @@
3334
validate_canonicaljson,
3435
)
3536
from synapse.federation.federation_server import server_matches_acl_event
37+
from synapse.http.servlet import validate_json_object
38+
from synapse.rest.models import RequestBodyModel
3639
from synapse.types import EventID, JsonDict, RoomID, UserID
3740

3841

@@ -135,13 +138,9 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
135138
EventContentFields.MSC3952_MENTIONS in event.content
136139
and config.experimental.msc3952_intentional_mentions
137140
):
138-
mentions = event.content[EventContentFields.MSC3952_MENTIONS]
139-
try:
140-
jsonschema.validate(
141-
instance=mentions, schema=MENTIONS_SCHEMA, cls=MENTIONS_VALIDATOR
142-
)
143-
except jsonschema.ValidationError as e:
144-
raise SynapseError(400, e.message)
141+
validate_json_object(
142+
event.content[EventContentFields.MSC3952_MENTIONS], Mentions
143+
)
145144

146145
def _validate_retention(self, event: EventBase) -> None:
147146
"""Checks that an event that defines the retention policy for a room respects the
@@ -270,20 +269,10 @@ def _ensure_state_event(self, event: Union[EventBase, EventBuilder]) -> None:
270269
},
271270
}
272271

273-
MENTIONS_SCHEMA = {
274-
"type": "object",
275-
"properties": {
276-
"user_ids": {
277-
"type": "array",
278-
"items": {
279-
"type": "string",
280-
},
281-
},
282-
"room": {
283-
"type": "boolean",
284-
},
285-
},
286-
}
272+
273+
class Mentions(RequestBodyModel):
274+
user_ids: List[StrictStr] = Field(default_factory=list)
275+
room: StrictBool = False
287276

288277

289278
# This could return something newer than Draft 7, but that's the current "latest"
@@ -302,4 +291,3 @@ def _create_validator(schema: JsonDict) -> Type[jsonschema.Draft7Validator]:
302291

303292

304293
POWER_LEVELS_VALIDATOR = _create_validator(POWER_LEVELS_SCHEMA)
305-
MENTIONS_VALIDATOR = _create_validator(MENTIONS_SCHEMA)

synapse/http/servlet.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -778,17 +778,13 @@ def parse_json_object_from_request(
778778
Model = TypeVar("Model", bound=BaseModel)
779779

780780

781-
def parse_and_validate_json_object_from_request(
782-
request: Request, model_type: Type[Model]
783-
) -> Model:
784-
"""Parse a JSON object from the body of a twisted HTTP request, then deserialise and
785-
validate using the given pydantic model.
781+
def validate_json_object(content: JsonDict, model_type: Type[Model]) -> Model:
782+
"""Validate a deserialized JSON object using the given pydantic model.
786783
787784
Raises:
788785
SynapseError if the request body couldn't be decoded as JSON or
789786
if it wasn't a JSON object.
790787
"""
791-
content = parse_json_object_from_request(request, allow_empty_body=False)
792788
try:
793789
instance = model_type.parse_obj(content)
794790
except ValidationError as e:
@@ -811,6 +807,20 @@ def parse_and_validate_json_object_from_request(
811807
return instance
812808

813809

810+
def parse_and_validate_json_object_from_request(
811+
request: Request, model_type: Type[Model]
812+
) -> Model:
813+
"""Parse a JSON object from the body of a twisted HTTP request, then deserialise and
814+
validate using the given pydantic model.
815+
816+
Raises:
817+
SynapseError if the request body couldn't be decoded as JSON or
818+
if it wasn't a JSON object.
819+
"""
820+
content = parse_json_object_from_request(request, allow_empty_body=False)
821+
return validate_json_object(content, model_type)
822+
823+
814824
def assert_params_in_dict(body: JsonDict, required: Iterable[str]) -> None:
815825
absent = []
816826
for k in required:

0 commit comments

Comments
 (0)