summary refs log tree commit diff
path: root/synapse/rest
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/rest')
-rw-r--r--synapse/rest/client/account.py6
-rw-r--r--synapse/rest/client/devices.py4
-rw-r--r--synapse/rest/client/directory.py2
-rw-r--r--synapse/rest/client/models.py284
-rw-r--r--synapse/rest/client/sync.py2
-rw-r--r--synapse/rest/key/v2/remote_key_resource.py2
-rw-r--r--synapse/rest/models.py50
7 files changed, 8 insertions, 342 deletions
diff --git a/synapse/rest/client/account.py b/synapse/rest/client/account.py
index 6ac07d354c..8daa449f9e 100644
--- a/synapse/rest/client/account.py
+++ b/synapse/rest/client/account.py
@@ -56,14 +56,14 @@ from synapse.http.servlet import (
 from synapse.http.site import SynapseRequest
 from synapse.metrics import threepid_send_requests
 from synapse.push.mailer import Mailer
-from synapse.rest.client.models import (
+from synapse.types import JsonDict
+from synapse.types.rest import RequestBodyModel
+from synapse.types.rest.client import (
     AuthenticationData,
     ClientSecretStr,
     EmailRequestTokenBody,
     MsisdnRequestTokenBody,
 )
-from synapse.rest.models import RequestBodyModel
-from synapse.types import JsonDict
 from synapse.util.msisdn import phone_number_to_msisdn
 from synapse.util.stringutils import assert_valid_client_secret, random_string
 from synapse.util.threepids import check_3pid_allowed, validate_email
diff --git a/synapse/rest/client/devices.py b/synapse/rest/client/devices.py
index b1b803549e..8313d687b7 100644
--- a/synapse/rest/client/devices.py
+++ b/synapse/rest/client/devices.py
@@ -42,9 +42,9 @@ from synapse.http.servlet import (
 )
 from synapse.http.site import SynapseRequest
 from synapse.rest.client._base import client_patterns, interactive_auth_handler
-from synapse.rest.client.models import AuthenticationData
-from synapse.rest.models import RequestBodyModel
 from synapse.types import JsonDict
+from synapse.types.rest import RequestBodyModel
+from synapse.types.rest.client import AuthenticationData
 
 if TYPE_CHECKING:
     from synapse.server import HomeServer
diff --git a/synapse/rest/client/directory.py b/synapse/rest/client/directory.py
index 8099fdf3e4..11fdd0f7c6 100644
--- a/synapse/rest/client/directory.py
+++ b/synapse/rest/client/directory.py
@@ -41,8 +41,8 @@ from synapse.http.servlet import (
 )
 from synapse.http.site import SynapseRequest
 from synapse.rest.client._base import client_patterns
-from synapse.rest.models import RequestBodyModel
 from synapse.types import JsonDict, RoomAlias
+from synapse.types.rest import RequestBodyModel
 
 if TYPE_CHECKING:
     from synapse.server import HomeServer
diff --git a/synapse/rest/client/models.py b/synapse/rest/client/models.py
deleted file mode 100644
index 5433ed91ef..0000000000
--- a/synapse/rest/client/models.py
+++ /dev/null
@@ -1,284 +0,0 @@
-#
-# This file is licensed under the Affero General Public License (AGPL) version 3.
-#
-# Copyright 2022 The Matrix.org Foundation C.I.C.
-# Copyright (C) 2023 New Vector, Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# See the GNU Affero General Public License for more details:
-# <https://www.gnu.org/licenses/agpl-3.0.html>.
-#
-# Originally licensed under the Apache License, Version 2.0:
-# <http://www.apache.org/licenses/LICENSE-2.0>.
-#
-# [This file includes modifications made by New Vector Limited]
-#
-#
-from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
-
-from synapse._pydantic_compat import HAS_PYDANTIC_V2
-
-if TYPE_CHECKING or HAS_PYDANTIC_V2:
-    from pydantic.v1 import (
-        Extra,
-        StrictBool,
-        StrictInt,
-        StrictStr,
-        conint,
-        constr,
-        validator,
-    )
-else:
-    from pydantic import (
-        Extra,
-        StrictBool,
-        StrictInt,
-        StrictStr,
-        conint,
-        constr,
-        validator,
-    )
-
-from synapse.rest.models import RequestBodyModel
-from synapse.util.threepids import validate_email
-
-
-class AuthenticationData(RequestBodyModel):
-    """
-    Data used during user-interactive authentication.
-
-    (The name "Authentication Data" is taken directly from the spec.)
-
-    Additional keys will be present, depending on the `type` field. Use
-    `.dict(exclude_unset=True)` to access them.
-    """
-
-    class Config:
-        extra = Extra.allow
-
-    session: Optional[StrictStr] = None
-    type: Optional[StrictStr] = None
-
-
-if TYPE_CHECKING:
-    ClientSecretStr = StrictStr
-else:
-    # See also assert_valid_client_secret()
-    ClientSecretStr = constr(
-        regex="[0-9a-zA-Z.=_-]",  # noqa: F722
-        min_length=1,
-        max_length=255,
-        strict=True,
-    )
-
-
-class ThreepidRequestTokenBody(RequestBodyModel):
-    client_secret: ClientSecretStr
-    id_server: Optional[StrictStr]
-    id_access_token: Optional[StrictStr]
-    next_link: Optional[StrictStr]
-    send_attempt: StrictInt
-
-    @validator("id_access_token", always=True)
-    def token_required_for_identity_server(
-        cls, token: Optional[str], values: Dict[str, object]
-    ) -> Optional[str]:
-        if values.get("id_server") is not None and token is None:
-            raise ValueError("id_access_token is required if an id_server is supplied.")
-        return token
-
-
-class EmailRequestTokenBody(ThreepidRequestTokenBody):
-    email: StrictStr
-
-    # Canonicalise the email address. The addresses are all stored canonicalised
-    # in the database. This allows the user to reset his password without having to
-    # know the exact spelling (eg. upper and lower case) of address in the database.
-    # Without this, an email stored in the database as "foo@bar.com" would cause
-    # user requests for "FOO@bar.com" to raise a Not Found error.
-    _email_validator = validator("email", allow_reuse=True)(validate_email)
-
-
-if TYPE_CHECKING:
-    ISO3116_1_Alpha_2 = StrictStr
-else:
-    # Per spec: two-letter uppercase ISO-3166-1-alpha-2
-    ISO3116_1_Alpha_2 = constr(regex="[A-Z]{2}", strict=True)
-
-
-class MsisdnRequestTokenBody(ThreepidRequestTokenBody):
-    country: ISO3116_1_Alpha_2
-    phone_number: StrictStr
-
-
-class SlidingSyncBody(RequestBodyModel):
-    """
-    Sliding Sync API request body.
-
-    Attributes:
-        lists: Sliding window API. A map of list key to list information
-            (:class:`SlidingSyncList`). Max lists: 100. The list keys should be
-            arbitrary strings which the client is using to refer to the list. Keep this
-            small as it needs to be sent a lot. Max length: 64 bytes.
-        room_subscriptions: Room subscription API. A map of room ID to room subscription
-            information. Used to subscribe to a specific room. Sometimes clients know
-            exactly which room they want to get information about e.g by following a
-            permalink or by refreshing a webapp currently viewing a specific room. The
-            sliding window API alone is insufficient for this use case because there's
-            no way to say "please track this room explicitly".
-        extensions: Extensions API. A map of extension key to extension config.
-    """
-
-    class CommonRoomParameters(RequestBodyModel):
-        """
-        Common parameters shared between the sliding window and room subscription APIs.
-
-        Attributes:
-            required_state: Required state for each room returned. An array of event
-                type and state key tuples. Elements in this array are ORd together to
-                produce the final set of state events to return. One unique exception is
-                when you request all state events via `["*", "*"]`. When used, all state
-                events are returned by default, and additional entries FILTER OUT the
-                returned set of state events. These additional entries cannot use `*`
-                themselves. For example, `["*", "*"], ["m.room.member",
-                "@alice:example.com"]` will *exclude* every `m.room.member` event
-                *except* for `@alice:example.com`, and include every other state event.
-                In addition, `["*", "*"], ["m.space.child", "*"]` is an error, the
-                `m.space.child` filter is not required as it would have been returned
-                anyway.
-            timeline_limit: The maximum number of timeline events to return per response.
-                (Max 1000 messages)
-            include_old_rooms: Determines if `predecessor` rooms are included in the
-                `rooms` response. The user MUST be joined to old rooms for them to show up
-                in the response.
-        """
-
-        class IncludeOldRooms(RequestBodyModel):
-            timeline_limit: StrictInt
-            required_state: List[Tuple[StrictStr, StrictStr]]
-
-        required_state: List[Tuple[StrictStr, StrictStr]]
-        # mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884
-        if TYPE_CHECKING:
-            timeline_limit: int
-        else:
-            timeline_limit: conint(le=1000, strict=True)  # type: ignore[valid-type]
-        include_old_rooms: Optional[IncludeOldRooms] = None
-
-    class SlidingSyncList(CommonRoomParameters):
-        """
-        Attributes:
-            ranges: Sliding window ranges. If this field is missing, no sliding window
-                is used and all rooms are returned in this list. Integers are
-                *inclusive*.
-            sort: How the list should be sorted on the server. The first value is
-                applied first, then tiebreaks are performed with each subsequent sort
-                listed.
-
-                    FIXME: Furthermore, it's not currently defined how servers should behave
-                    if they encounter a filter or sort operation they do not recognise. If
-                    the server rejects the request with an HTTP 400 then that will break
-                    backwards compatibility with new clients vs old servers. However, the
-                    client would be otherwise unaware that only some of the sort/filter
-                    operations have taken effect. We may need to include a "warnings"
-                    section to indicate which sort/filter operations are unrecognised,
-                    allowing for some form of graceful degradation of service.
-                    -- https://github.com/matrix-org/matrix-spec-proposals/blob/kegan/sync-v3/proposals/3575-sync.md#filter-and-sort-extensions
-
-            slow_get_all_rooms: Just get all rooms (for clients that don't want to deal with
-                sliding windows). When true, the `ranges` and `sort` fields are ignored.
-            required_state: Required state for each room returned. An array of event
-                type and state key tuples. Elements in this array are ORd together to
-                produce the final set of state events to return.
-
-                One unique exception is when you request all state events via `["*",
-                "*"]`. When used, all state events are returned by default, and
-                additional entries FILTER OUT the returned set of state events. These
-                additional entries cannot use `*` themselves. For example, `["*", "*"],
-                ["m.room.member", "@alice:example.com"]` will *exclude* every
-                `m.room.member` event *except* for `@alice:example.com`, and include
-                every other state event. In addition, `["*", "*"], ["m.space.child",
-                "*"]` is an error, the `m.space.child` filter is not required as it
-                would have been returned anyway.
-
-                Room members can be lazily-loaded by using the special `$LAZY` state key
-                (`["m.room.member", "$LAZY"]`). Typically, when you view a room, you
-                want to retrieve all state events except for m.room.member events which
-                you want to lazily load. To get this behaviour, clients can send the
-                following::
-
-                    {
-                        "required_state": [
-                            // activate lazy loading
-                            ["m.room.member", "$LAZY"],
-                            // request all state events _except_ for m.room.member
-                            events which are lazily loaded
-                            ["*", "*"]
-                        ]
-                    }
-
-            timeline_limit: The maximum number of timeline events to return per response.
-            include_old_rooms: Determines if `predecessor` rooms are included in the
-                `rooms` response. The user MUST be joined to old rooms for them to show up
-                in the response.
-            include_heroes: Return a stripped variant of membership events (containing
-                `user_id` and optionally `avatar_url` and `displayname`) for the users used
-                to calculate the room name.
-            filters: Filters to apply to the list before sorting.
-            bump_event_types: Allowlist of event types which should be considered recent activity
-                when sorting `by_recency`. By omitting event types from this field,
-                clients can ensure that uninteresting events (e.g. a profile rename) do
-                not cause a room to jump to the top of its list(s). Empty or omitted
-                `bump_event_types` have no effect—all events in a room will be
-                considered recent activity.
-        """
-
-        class Filters(RequestBodyModel):
-            is_dm: Optional[StrictBool] = None
-            spaces: Optional[List[StrictStr]] = None
-            is_encrypted: Optional[StrictBool] = None
-            is_invite: Optional[StrictBool] = None
-            room_types: Optional[List[Union[StrictStr, None]]] = None
-            not_room_types: Optional[List[StrictStr]] = None
-            room_name_like: Optional[StrictStr] = None
-            tags: Optional[List[StrictStr]] = None
-            not_tags: Optional[List[StrictStr]] = None
-
-        # mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884
-        if TYPE_CHECKING:
-            ranges: Optional[List[Tuple[int, int]]] = None
-        else:
-            ranges: Optional[List[Tuple[conint(ge=0, strict=True), conint(ge=0, strict=True)]]] = None  # type: ignore[valid-type]
-        sort: Optional[List[StrictStr]] = None
-        slow_get_all_rooms: Optional[StrictBool] = False
-        include_heroes: Optional[StrictBool] = False
-        filters: Optional[Filters] = None
-        bump_event_types: Optional[List[StrictStr]] = None
-
-    class RoomSubscription(CommonRoomParameters):
-        pass
-
-    class Extension(RequestBodyModel):
-        enabled: Optional[StrictBool] = False
-        lists: Optional[List[StrictStr]] = None
-        rooms: Optional[List[StrictStr]] = None
-
-    # mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884
-    if TYPE_CHECKING:
-        lists: Optional[Dict[str, SlidingSyncList]] = None
-    else:
-        lists: Optional[Dict[constr(max_length=64, strict=True), SlidingSyncList]] = None  # type: ignore[valid-type]
-    room_subscriptions: Optional[Dict[StrictStr, RoomSubscription]] = None
-    extensions: Optional[Dict[StrictStr, Extension]] = None
-
-    @validator("lists")
-    def lists_length_check(
-        cls, value: Optional[Dict[str, SlidingSyncList]]
-    ) -> Optional[Dict[str, SlidingSyncList]]:
-        if value is not None:
-            assert len(value) <= 100, f"Max lists: 100 but saw {len(value)}"
-        return value
diff --git a/synapse/rest/client/sync.py b/synapse/rest/client/sync.py
index 385b102b3d..1b0ac20d94 100644
--- a/synapse/rest/client/sync.py
+++ b/synapse/rest/client/sync.py
@@ -53,8 +53,8 @@ from synapse.http.servlet import (
 )
 from synapse.http.site import SynapseRequest
 from synapse.logging.opentracing import trace_with_opname
-from synapse.rest.client.models import SlidingSyncBody
 from synapse.types import JsonDict, Requester, StreamToken
+from synapse.types.rest.client import SlidingSyncBody
 from synapse.util import json_decoder
 from synapse.util.caches.lrucache import LruCache
 
diff --git a/synapse/rest/key/v2/remote_key_resource.py b/synapse/rest/key/v2/remote_key_resource.py
index dc7325fc57..a411ed614e 100644
--- a/synapse/rest/key/v2/remote_key_resource.py
+++ b/synapse/rest/key/v2/remote_key_resource.py
@@ -41,9 +41,9 @@ from synapse.http.servlet import (
     parse_and_validate_json_object_from_request,
     parse_integer,
 )
-from synapse.rest.models import RequestBodyModel
 from synapse.storage.keys import FetchKeyResultForRemote
 from synapse.types import JsonDict
+from synapse.types.rest import RequestBodyModel
 from synapse.util import json_decoder
 from synapse.util.async_helpers import yieldable_gather_results
 
diff --git a/synapse/rest/models.py b/synapse/rest/models.py
deleted file mode 100644
index 2b6f5ed35a..0000000000
--- a/synapse/rest/models.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# This file is licensed under the Affero General Public License (AGPL) version 3.
-#
-# Copyright 2022 The Matrix.org Foundation C.I.C.
-# Copyright (C) 2023 New Vector, Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# See the GNU Affero General Public License for more details:
-# <https://www.gnu.org/licenses/agpl-3.0.html>.
-#
-# Originally licensed under the Apache License, Version 2.0:
-# <http://www.apache.org/licenses/LICENSE-2.0>.
-#
-# [This file includes modifications made by New Vector Limited]
-#
-#
-from typing import TYPE_CHECKING
-
-from synapse._pydantic_compat import HAS_PYDANTIC_V2
-
-if TYPE_CHECKING or HAS_PYDANTIC_V2:
-    from pydantic.v1 import BaseModel, Extra
-else:
-    from pydantic import BaseModel, Extra
-
-
-class RequestBodyModel(BaseModel):
-    """A custom version of Pydantic's BaseModel which
-
-     - ignores unknown fields and
-     - does not allow fields to be overwritten after construction,
-
-    but otherwise uses Pydantic's default behaviour.
-
-    Ignoring unknown fields is a useful default. It means that clients can provide
-    unstable field not known to the server without the request being refused outright.
-
-    Subclassing in this way is recommended by
-    https://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally
-    """
-
-    class Config:
-        # By default, ignore fields that we don't recognise.
-        extra = Extra.ignore
-        # By default, don't allow fields to be reassigned after parsing.
-        allow_mutation = False