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

Commit d642ce4

Browse files
author
David Robertson
authored
Use Pydantic to systematically validate a first batch of endpoints in synapse.rest.client.account. (#13188)
1 parent 73c83c6 commit d642ce4

File tree

10 files changed

+296
-92
lines changed

10 files changed

+296
-92
lines changed

changelog.d/13188.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve validation of request bodies for the following client-server API endpoints: [`/account/password`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountpassword), [`/account/password/email/requestToken`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountpasswordemailrequesttoken), [`/account/deactivate`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountdeactivate) and [`/account/3pid/email/requestToken`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3account3pidemailrequesttoken).

mypy.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[mypy]
22
namespace_packages = True
3-
plugins = mypy_zope:plugin, scripts-dev/mypy_synapse_plugin.py
3+
plugins = pydantic.mypy, mypy_zope:plugin, scripts-dev/mypy_synapse_plugin.py
44
follow_imports = normal
55
check_untyped_defs = True
66
show_error_codes = True

poetry.lock

Lines changed: 53 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ packaging = ">=16.1"
158158
# At the time of writing, we only use functions from the version `importlib.metadata`
159159
# which shipped in Python 3.8. This corresponds to version 1.4 of the backport.
160160
importlib_metadata = { version = ">=1.4", python = "<3.8" }
161+
# This is the most recent version of Pydantic with available on common distros.
162+
pydantic = ">=1.7.4"
163+
161164

162165

163166
# Optional Dependencies

synapse/http/servlet.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
Optional,
2424
Sequence,
2525
Tuple,
26+
Type,
27+
TypeVar,
2628
overload,
2729
)
2830

31+
from pydantic import BaseModel, ValidationError
2932
from typing_extensions import Literal
3033

3134
from twisted.web.server import Request
@@ -694,6 +697,28 @@ def parse_json_object_from_request(
694697
return content
695698

696699

700+
Model = TypeVar("Model", bound=BaseModel)
701+
702+
703+
def parse_and_validate_json_object_from_request(
704+
request: Request, model_type: Type[Model]
705+
) -> Model:
706+
"""Parse a JSON object from the body of a twisted HTTP request, then deserialise and
707+
validate using the given pydantic model.
708+
709+
Raises:
710+
SynapseError if the request body couldn't be decoded as JSON or
711+
if it wasn't a JSON object.
712+
"""
713+
content = parse_json_object_from_request(request, allow_empty_body=False)
714+
try:
715+
instance = model_type.parse_obj(content)
716+
except ValidationError as e:
717+
raise SynapseError(HTTPStatus.BAD_REQUEST, str(e), errcode=Codes.BAD_JSON)
718+
719+
return instance
720+
721+
697722
def assert_params_in_dict(body: JsonDict, required: Iterable[str]) -> None:
698723
absent = []
699724
for k in required:

0 commit comments

Comments
 (0)