diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a0b6032..f79449f3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,9 +23,29 @@ buildswaggerui: &buildswaggerui wget https://raw.githubusercontent.com/matrix-org/matrix.org/master/scripts/swagger-ui.patch patch api/client-server/index.html swagger-ui.patch +checkexamples: &checkexamples + name: Check Event Examples + command: | + source /env/bin/activate + cd event-schemas + ./check_examples.py + +genmatrixassets: &genmatrixassets + name: Generate/Verify matrix.org assets + command: | + source /env/bin/activate + ./scripts/generate-matrix-org-assets + version: 2 jobs: + check-docs: + docker: + - image: uhoreg/matrix-doc-build + steps: + - checkout + - run: *checkexamples + - run: *genmatrixassets # We don't actually use the assets, but we do want to make sure they build build-docs: docker: - image: uhoreg/matrix-doc-build diff --git a/api/application-service/application_service.yaml b/api/application-service/application_service.yaml index 8fcfa006..67b5b1b5 100644 --- a/api/application-service/application_service.yaml +++ b/api/application-service/application_service.yaml @@ -26,243 +26,3 @@ consumes: produces: - application/json paths: - "/_matrix/app/unstable/thirdparty/protocol/{protocol}": - get: - summary: Retrieve metadata about a specific protocol that the application service supports. - description: |- - This API is called by the homeserver when it wants to present clients - with specific information about the various third party networks that - an application service supports. - operationId: getProtocolMetadata - parameters: - - in: path - name: protocol - type: string - description: The protocol ID. - required: true - x-example: "irc" - responses: - 200: - description: The protocol was found and metadata returned. - schema: - $ref: definitions/protocol_metadata.yaml - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: No protocol was found with the given path. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - "/_matrix/app/unstable/thirdparty/user/{protocol}": - get: - summary: Retrieve the Matrix User ID of a corresponding third party user. - description: |- - This API is called by the homeserver in order to retrieve a Matrix - User ID linked to a user on the third party network, given a set of - user parameters. - operationId: queryUserByProtocol - parameters: - - in: path - name: protocol - type: string - description: The protocol ID. - required: true - x-example: irc - - in: query - name: fields... - type: string - description: |- - One or more custom fields that are passed to the application - service to help identify the user. - responses: - 200: - description: The Matrix User IDs found with the given parameters. - schema: - $ref: definitions/user_batch.yaml - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: No users were found with the given parameters. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - "/_matrix/app/unstable/thirdparty/location/{protocol}": - get: - summary: Retreive Matrix-side portal rooms leading to a third party location. - description: |- - Retrieve a list of Matrix portal rooms that lead to the matched third party location. - operationId: queryLocationByProtocol - parameters: - - in: path - name: protocol - type: string - description: The protocol ID. - required: true - x-example: irc - - in: query - name: fields... - type: string - description: |- - One or more custom fields that are passed to the application - service to help identify the third party location. - responses: - 200: - description: At least one portal room was found. - schema: - $ref: definitions/location_batch.yaml - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: No mappings were found with the given parameters. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - "/_matrix/app/unstable/thirdparty/location": - get: - summary: Reverse-lookup third party locations given a Matrix room alias. - description: |- - Retreive an array of third party network locations from a Matrix room - alias. - operationId: queryLocationByAlias - parameters: - - in: query - name: alias - type: string - description: The Matrix room alias to look up. - responses: - 200: - description: |- - All found third party locations. - schema: - $ref: definitions/location_batch.yaml - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: No mappings were found with the given parameters. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - "/_matrix/app/unstable/thirdparty/user": - get: - summary: Reverse-lookup third party users given a Matrix User ID. - description: |- - Retreive an array of third party users from a Matrix User ID. - operationId: queryUserByID - parameters: - - in: query - name: userid - type: string - description: The Matrix User ID to look up. - responses: - 200: - description: |- - An array of third party users. - schema: - $ref: definitions/user_batch.yaml - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: No mappings were found with the given parameters. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml diff --git a/api/application-service/definitions/location.yaml b/api/application-service/definitions/location.yaml index 4967ef61..5a0f92c8 100644 --- a/api/application-service/definitions/location.yaml +++ b/api/application-service/definitions/location.yaml @@ -19,12 +19,14 @@ properties: protocol: description: The protocol ID that the third party location is a part of. type: string - example: irc + example: "irc" fields: description: Information used to identify this third party location. type: object - example: - "network": "freenode" + example: { + "network": "freenode", "channel": "#matrix" + } +required: ['alias', 'protocol', 'fields'] title: Location type: object \ No newline at end of file diff --git a/api/application-service/definitions/protocol.yaml b/api/application-service/definitions/protocol.yaml index 231e8288..851091d6 100644 --- a/api/application-service/definitions/protocol.yaml +++ b/api/application-service/definitions/protocol.yaml @@ -11,41 +11,60 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +title: Protocol +type: object properties: user_fields: - description: Fields used to identify a third party user. + description: |- + Fields which may be used to identify a third party user. These should be + ordered to suggest the way that entities may be grouped, where higher + groupings are ordered first. For example, the name of a network should be + searched before the nickname of a user. type: array items: type: string description: Field used to identify a third party user. example: ["network", "nickname"] location_fields: - description: Fields used to identify a third party location. + description: |- + Fields which may be used to identify a third party location. These should be + ordered to suggest the way that entities may be grouped, where higher + groupings are ordered first. For example, the name of a network should be + searched before the name of a channel. type: array items: type: string description: Field used to identify a third party location. example: ["network", "channel"] icon: - description: An icon representing the third party protocol. + description: A content URI representing an icon for the third party protocol. type: string example: "mxc://example.org/aBcDeFgH" field_types: title: Field Types - description: All location or user fields should have an entry here. + description: |- + The type definitions for the fields defined in the ``user_fields`` and + ``location_fields``. Each entry in those arrays MUST have an entry here. The + ``string`` key for this object is field name itself. + + May be an empty object if no fields are defined. type: object - properties: - fieldname: - title: Field Type - description: Definition of valid values for a field. - type: object - properties: - regexp: - description: A regular expression for validation of a field's value. - type: string - placeholder: - description: An placeholder serving as a valid example of the field value. - type: string + additionalProperties: + title: Field Type + description: Definition of valid values for a field. + type: object + properties: + regexp: + description: |- + A regular expression for validation of a field's value. This may be relatively + coarse to verify the value as the application service providing this protocol + may apply additional validation or filtering. + type: string + placeholder: + description: An placeholder serving as a valid example of the field value. + type: string + required: ['regexp', 'placeholder'] + required: ['fieldname'] example: { "network": { "regexp": "([a-z0-9]+\\.)*[a-z0-9]+", @@ -63,17 +82,32 @@ properties: instances: description: |- A list of objects representing independent instances of configuration. - For instance multiple networks on IRC if multiple are bridged by the - same bridge. + For example, multiple networks on IRC if multiple are provided by the + same application service. type: array items: type: object - example: { - "desc": "Freenode", - "icon": "mxc://example.org/JkLmNoPq", - "fields": { - "network": "freenode.net", - } - } -title: Protocol -type: object \ No newline at end of file + title: Protocol Instance + properties: + desc: + type: string + description: A human-readable description for the protocol, such as the name. + example: "Freenode" + icon: + type: string + description: |- + An optional content URI representing the protocol. Overrides the one provided + at the higher level Protocol object. + example: "mxc://example.org/JkLmNoPq" + fields: + type: object + description: Preset values for ``fields`` the client may use to search by. + example: { + "network": "freenode" + } + network_id: + type: string + description: A unique identifier across all instances. + example: "freenode" + required: ['desc', 'fields', 'network_id'] +required: ['user_fields', 'location_fields', 'icon', 'field_types', 'instances'] diff --git a/api/application-service/definitions/protocol_metadata.yaml b/api/application-service/definitions/protocol_metadata.yaml index 2b2c8f4e..e7bf45da 100644 --- a/api/application-service/definitions/protocol_metadata.yaml +++ b/api/application-service/definitions/protocol_metadata.yaml @@ -36,6 +36,7 @@ example: { }, "instances": [ { + "network_id": "freenode", "desc": "Freenode", "icon": "mxc://example.org/JkLmNoPq", "fields": { @@ -59,6 +60,7 @@ example: { }, "instances": [ { + "network_id": "gitter", "desc": "Gitter", "icon": "mxc://example.org/zXyWvUt", "fields": {} diff --git a/api/application-service/definitions/user.yaml b/api/application-service/definitions/user.yaml index a7b2287e..258e7c13 100644 --- a/api/application-service/definitions/user.yaml +++ b/api/application-service/definitions/user.yaml @@ -21,11 +21,13 @@ properties: protocol: description: The protocol ID that the third party location is a part of. type: string - example: gitter + example: "gitter" fields: description: Information used to identify this third party location. type: object - example: + example: { "user": "jim" + } +required: ['userid', 'protocol', 'fields'] title: User type: object \ No newline at end of file diff --git a/api/application-service/protocols.yaml b/api/application-service/protocols.yaml new file mode 100644 index 00000000..e6489cc5 --- /dev/null +++ b/api/application-service/protocols.yaml @@ -0,0 +1,267 @@ +# Copyright 2018 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Application Service API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: "/" +consumes: + - application/json +produces: + - application/json +paths: + "/_matrix/app/unstable/thirdparty/protocol/{protocol}": + get: + summary: Retrieve metadata about a specific protocol that the application service supports. + description: |- + This API is called by the homeserver when it wants to present clients + with specific information about the various third party networks that + an application service supports. + operationId: getProtocolMetadata + parameters: + - in: path + name: protocol + type: string + description: The protocol ID. + required: true + x-example: "irc" + responses: + 200: + description: The protocol was found and metadata returned. + schema: + $ref: definitions/protocol_metadata.yaml + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: No protocol was found with the given path. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + "/_matrix/app/unstable/thirdparty/user/{protocol}": + get: + summary: Retrieve the Matrix User ID of a corresponding third party user. + description: |- + This API is called by the homeserver in order to retrieve a Matrix + User ID linked to a user on the third party network, given a set of + user parameters. + operationId: queryUserByProtocol + parameters: + - in: path + name: protocol + type: string + description: The protocol ID. + required: true + x-example: irc + - in: query + name: fields... + type: string + description: |- + One or more custom fields that are passed to the application + service to help identify the user. + responses: + 200: + description: The Matrix User IDs found with the given parameters. + schema: + $ref: definitions/user_batch.yaml + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: No users were found with the given parameters. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + "/_matrix/app/unstable/thirdparty/location/{protocol}": + get: + summary: Retrieve Matrix-side portal rooms leading to a third party location. + description: |- + Retrieve a list of Matrix portal rooms that lead to the matched third party location. + operationId: queryLocationByProtocol + parameters: + - in: path + name: protocol + type: string + description: The protocol ID. + required: true + x-example: irc + - in: query + name: fields... + type: string + description: |- + One or more custom fields that are passed to the application + service to help identify the third party location. + responses: + 200: + description: At least one portal room was found. + schema: + $ref: definitions/location_batch.yaml + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: No mappings were found with the given parameters. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + "/_matrix/app/unstable/thirdparty/location": + get: + summary: Reverse-lookup third party locations given a Matrix room alias. + description: |- + Retrieve an array of third party network locations from a Matrix room + alias. + operationId: queryLocationByAlias + parameters: + - in: query + name: alias + type: string + description: The Matrix room alias to look up. + responses: + 200: + description: |- + All found third party locations. + schema: + $ref: definitions/location_batch.yaml + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: No mappings were found with the given parameters. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + "/_matrix/app/unstable/thirdparty/user": + get: + summary: Reverse-lookup third party users given a Matrix User ID. + description: |- + Retrieve an array of third party users from a Matrix User ID. + operationId: queryUserByID + parameters: + - in: query + name: userid + type: string + description: The Matrix User ID to look up. + responses: + 200: + description: |- + An array of third party users. + schema: + $ref: definitions/user_batch.yaml + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: No mappings were found with the given parameters. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml diff --git a/api/client-server/appservice_room_directory.yaml b/api/client-server/appservice_room_directory.yaml new file mode 100644 index 00000000..0225ecd8 --- /dev/null +++ b/api/client-server/appservice_room_directory.yaml @@ -0,0 +1,87 @@ +# Copyright 2018 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Client-Server Application Service Room Directory API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +consumes: + - application/json +produces: + - application/json +securityDefinitions: + # Note: this is the same access_token definition used elsewhere in the client + # server API, however this expects an access token for an application service. + $ref: definitions/security.yaml +paths: + "/directory/list/appservice/{networkId}/{roomId}": + put: + summary: |- + Updates a room's visibility in the application service's room directory. + description: |- + Updates the visibility of a given room on the application service's room + directory. + + This API is similar to the room directory visibility API used by clients + to update the homeserver's more general room directory. + + This API requires the use of an application service access token (``as_token``) + instead of a typical client's access_token. This API cannot be invoked by + users who are not identified as application services. + operationId: updateAppserviceRoomDirectoryVsibility + parameters: + - in: path + type: string + name: networkId + description: |- + The protocol (network) ID to update the room list for. This would + have been provided by the application service as being listed as + a supported protocol. + required: true + x-example: "irc" + - in: path + type: string + name: roomId + description: The room ID to add to the directory. + required: true + x-example: "!somewhere:domain.com" + - in: body + name: body + schema: + type: object + properties: + visibility: + type: enum + enum: ["public", "private"] + description: |- + Whether the room should be visible (public) in the directory + or not (private). + example: "public" + required: ['visibility'] + security: + # again, this is the appservice's token - not a typical client's + - accessToken: [] + responses: + 200: + description: The room's directory visibility has been updated. + schema: + type: object + examples: + application/json: {} + tags: + - Application service room directory management diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index f9aec519..ac0c3b16 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -147,14 +147,22 @@ paths: type: string description: The invitee's third party identifier. required: ["id_server", "medium", "address"] + room_version: + type: string + description: |- + The room version to set for the room. If not provided, the homeserver is + to use its configured default. If provided, the homeserver will return a + 400 error with the errcode ``M_UNSUPPORTED_ROOM_VERSION`` if it does not + support the room version. + example: "1" creation_content: title: CreationContent type: object description: |- Extra keys, such as ``m.federate``, to be added to the content of the `m.room.create`_ event. The server will clobber the following - keys: ``creator``. Future versions of the specification may allow - the server to clobber other keys. + keys: ``creator``, ``room_version``. Future versions of the specification + may allow the server to clobber other keys. initial_state: type: array description: |- diff --git a/api/client-server/directory.yaml b/api/client-server/directory.yaml index ee42cf84..78ddfa29 100644 --- a/api/client-server/directory.yaml +++ b/api/client-server/directory.yaml @@ -41,7 +41,7 @@ paths: required: true x-example: "#monkeys:matrix.org" - in: body - name: roomInfo + name: body description: Information about this room alias. required: true schema: @@ -50,24 +50,24 @@ paths: room_id: type: string description: The room ID to set. + required: ['room_id'] example: { - "room_id": "!abnjk1jdasj98:capuchins.com" - } + "room_id": "!abnjk1jdasj98:capuchins.com" + } responses: 200: description: The mapping was created. examples: - application/json: { - } + application/json: {} schema: type: object 409: description: A room alias with that name already exists. examples: application/json: { - "errcode": "M_UNKNOWN", - "error": "Room alias #monkeys:matrix.org already exists." - } + "errcode": "M_UNKNOWN", + "error": "Room alias #monkeys:matrix.org already exists." + } schema: "$ref": "definitions/errors/error.yaml" tags: diff --git a/api/client-server/list_public_rooms.yaml b/api/client-server/list_public_rooms.yaml index 72a12060..d1abc68e 100644 --- a/api/client-server/list_public_rooms.yaml +++ b/api/client-server/list_public_rooms.yaml @@ -194,8 +194,26 @@ paths: description: |- A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional). + include_all_networks: + type: boolean + description: |- + Whether or not to include all known networks/protocols from + application services on the homeserver. Defaults to false. + example: false + third_party_instance_id: + type: string + description: |- + The specific third party network/protocol to request from the + homeserver. Can only be used if ``include_all_networks`` is false. + example: "irc" example: { - "limit": 10, "filter": {"generic_search_term": "foo"}} + "limit": 10, + "filter": { + "generic_search_term": "foo" + }, + "include_all_networks": false, + "third_party_instance_id": "irc" + } responses: 200: description: A list of the rooms on the server. diff --git a/api/client-server/openid.yaml b/api/client-server/openid.yaml index 4b89232e..cb982fb3 100644 --- a/api/client-server/openid.yaml +++ b/api/client-server/openid.yaml @@ -90,7 +90,7 @@ paths: The homeserver domain the consumer should use when attempting to verify the user's identity. expires_in: - type: int + type: integer description: |- The number of seconds before this token expires and a new one must be generated. diff --git a/api/client-server/pushrules.yaml b/api/client-server/pushrules.yaml index ceb9954b..e23c9189 100644 --- a/api/client-server/pushrules.yaml +++ b/api/client-server/pushrules.yaml @@ -343,6 +343,8 @@ paths: This endpoint allows the creation, modification and deletion of pushers for this user ID. The behaviour of this endpoint varies depending on the values in the JSON body. + + When creating push rules, they MUST be enabled by default. operationId: setPushRule security: - accessToken: [] @@ -424,7 +426,7 @@ paths: required: ["actions"] responses: 200: - description: The pusher was set. + description: The push rule was created/updated. examples: application/json: { } diff --git a/api/client-server/third_party_lookup.yaml b/api/client-server/third_party_lookup.yaml index cba9ce22..3d348df2 100644 --- a/api/client-server/third_party_lookup.yaml +++ b/api/client-server/third_party_lookup.yaml @@ -73,7 +73,7 @@ paths: $ref: definitions/errors/error.yaml "/thirdparty/location/{protocol}": get: - summary: Retreive Matrix-side portals rooms leading to a third party location. + summary: Retrieve Matrix-side portals rooms leading to a third party location. description: |- Requesting this endpoint with a valid protocol name results in a list of successful mapping results in a JSON array. Each result contains @@ -151,7 +151,7 @@ paths: get: summary: Reverse-lookup third party locations given a Matrix room alias. description: |- - Retreive an array of third party network locations from a Matrix room + Retrieve an array of third party network locations from a Matrix room alias. operationId: queryLocationByAlias security: @@ -181,7 +181,7 @@ paths: get: summary: Reverse-lookup third party users given a Matrix User ID. description: |- - Retreive an array of third party users from a Matrix User ID. + Retrieve an array of third party users from a Matrix User ID. operationId: queryUserByID security: - accessToken: [] diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index e76a0aa6..4902ea9e 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -49,6 +49,15 @@ paths: description: The user ID the join event will be for. required: true x-example: "@someone:example.org" + - in: query + type: array + items: + type: string + name: ver + description: |- + The room versions the sending server has support for. Defaults + to ``[1]``. + x-example: ["1", "2"] responses: 200: description: |- @@ -142,6 +151,30 @@ paths: ["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}] ] } + 400: + description: |- + The request is invalid or the room the server is attempting + to join has a version that is not listed in the ``ver`` + parameters. + + The error should be passed through to clients so that they + may give better feedback to users. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + - type: object + properties: + room_version: + type: string + description: |- + The version of the room. Required if the ``errcode`` + is ``M_INCOMPATIBLE_ROOM_VERSION``. + examples: + application/json: { + "errcode": "M_INCOMPATIBLE_ROOM_VERSION", + "error": "Your homeserver does not support the features required to join this room", + "room_version": "3" + } "/send_join/{roomId}/{eventId}": put: summary: Submit a signed join event to a resident server diff --git a/api/server-server/public_rooms.yaml b/api/server-server/public_rooms.yaml index d162568f..b7691023 100644 --- a/api/server-server/public_rooms.yaml +++ b/api/server-server/public_rooms.yaml @@ -49,6 +49,20 @@ paths: A pagination token from a previous call to this endpoint to fetch more rooms. x-example: "GetMoreRoomsTokenHere" + - in: query + name: include_all_networks + type: boolean + description: |- + Whether or not to include all networks/protocols defined by application + services on the homeserver. Defaults to false. + x-example: false + - in: query + name: third_party_instance_id + type: string + description: |- + The specific third party network/protocol to request from the homeserver. + Can only be used if ``include_all_networks`` is false. + x-example: "irc" responses: 200: description: The public room list for the homeserver. diff --git a/changelogs/client_server/newsfragments/1516.feature b/changelogs/client_server/newsfragments/1516.feature new file mode 100644 index 00000000..8e9b26df --- /dev/null +++ b/changelogs/client_server/newsfragments/1516.feature @@ -0,0 +1 @@ +Add support for Room Versions. diff --git a/changelogs/client_server/newsfragments/1550.feature b/changelogs/client_server/newsfragments/1550.feature new file mode 100644 index 00000000..f04fa9ae --- /dev/null +++ b/changelogs/client_server/newsfragments/1550.feature @@ -0,0 +1 @@ +Add server ACLs as an option for controlling federation in a room. diff --git a/changelogs/client_server/newsfragments/1551.clarification b/changelogs/client_server/newsfragments/1551.clarification new file mode 100644 index 00000000..06eac4da --- /dev/null +++ b/changelogs/client_server/newsfragments/1551.clarification @@ -0,0 +1 @@ +Clarify that new push rules should be enabled by default, and that unrecognised conditions should not match. diff --git a/changelogs/client_server/newsfragments/1551.feature b/changelogs/client_server/newsfragments/1551.feature new file mode 100644 index 00000000..dfce0f0a --- /dev/null +++ b/changelogs/client_server/newsfragments/1551.feature @@ -0,0 +1 @@ +Add new push rules for encrypted events and ``@room`` notifications. diff --git a/changelogs/client_server/newsfragments/1554.feature b/changelogs/client_server/newsfragments/1554.feature new file mode 100644 index 00000000..ec7ffe71 --- /dev/null +++ b/changelogs/client_server/newsfragments/1554.feature @@ -0,0 +1 @@ +Add third party network room directories, as provided by application services. diff --git a/changelogs/client_server/newsfragments/1574.clarification b/changelogs/client_server/newsfragments/1574.clarification new file mode 100644 index 00000000..8d07ef56 --- /dev/null +++ b/changelogs/client_server/newsfragments/1574.clarification @@ -0,0 +1 @@ +Fix naming of the body field in ``PUT /directory/room``. diff --git a/event-schemas/examples/m.room.server_acl b/event-schemas/examples/m.room.server_acl new file mode 100644 index 00000000..86da2093 --- /dev/null +++ b/event-schemas/examples/m.room.server_acl @@ -0,0 +1,14 @@ +{ + "age": 242352, + "content": { + "allow_ip_literals": false, + "allow": ["*"], + "deny": ["*.evil.com", "evil.com"] + }, + "state_key": "", + "origin_server_ts": 1431961217939, + "event_id": "$WLGTSEFSEF:localhost", + "type": "m.room.server_acl", + "room_id": "!Cuyf34gef24t:localhost", + "sender": "@example:localhost" +} diff --git a/event-schemas/schema/m.room.create b/event-schemas/schema/m.room.create index a07ab90f..d12b9ccd 100644 --- a/event-schemas/schema/m.room.create +++ b/event-schemas/schema/m.room.create @@ -11,6 +11,9 @@ properties: m.federate: description: Whether users on other servers can join this room. Defaults to ``true`` if key does not exist. type: boolean + room_version: + description: The version of the room. Defaults to ``"1"`` if the key does not exist. + type: string required: - creator type: object diff --git a/event-schemas/schema/m.room.encrypted b/event-schemas/schema/m.room.encrypted index 6825be1d..44b09c3f 100644 --- a/event-schemas/schema/m.room.encrypted +++ b/event-schemas/schema/m.room.encrypted @@ -13,8 +13,8 @@ properties: algorithm: type: string enum: - - m.olm.curve25519-aes-sha256 - - m.megolm.v1.aes-sha + - m.olm.v1.curve25519-aes-sha2 + - m.megolm.v1.aes-sha2 description: |- The encryption algorithm used to encrypt this event. The value of this field determines which other properties will be diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl new file mode 100644 index 00000000..c6adaf05 --- /dev/null +++ b/event-schemas/schema/m.room.server_acl @@ -0,0 +1,88 @@ +--- +title: Server ACL +description: |- + An event to indicate which servers are permitted to participate in the + room. Server ACLs may allow or deny groups of hosts. All servers participating + in the room, including those that are denied, are expected to uphold the + server ACL. Servers that do not uphold the ACLs MUST be added to the denied hosts + list in order for the ACLs to remain effective. + + The ``allow`` and ``deny`` lists are lists of globs supporting ``?`` and ``*`` + as wildcards. When comparing against the server ACLs, the suspect server's port + number must not be considered. Therefore ``evil.com``, ``evil.com:8448``, and + ``evil.com:1234`` would all match rules that apply to ``evil.com``, for example. + + The ACLs are applied to servers when they make requests, and are applied in + the following order: + + 1. If there is no ``m.room.server_acl`` event in the room state, allow. + #. If the server name is an IP address (v4 or v6) literal, and ``allow_ip_literals`` + is present and ``false``, deny. + #. If the server name matches an entry in the ``deny`` list, deny. + #. If the server name matches an entry in the ``allow`` list, allow. + #. Otherwise, deny. + + .. Note:: + Server ACLs do not restrict the events relative to the room DAG via authorisation + rules, but instead act purely at the network layer to determine which servers are + allowed to connect and interact with a given room. + + .. WARNING:: + Failing to provide an ``allow`` rule of some kind will prevent **all** + servers from participating in the room, including the sender. This renders + the room unusable. A common allow rule is ``[ "*" ]`` which would still + permit the use of the ``deny`` list without losing the room. + + .. WARNING:: + All compliant servers must implement server ACLs. However, legacy or noncompliant + servers exist which do not uphold ACLs, and these MUST be manually appended to + the denied hosts list when setting an ACL to prevent them from leaking events from + banned servers into a room. Currently, the only way to determine noncompliant hosts is + to check the ``prev_events`` of leaked events, therefore detecting servers which + are not upholding the ACLs. Server versions can also be used to try to detect hosts that + will not uphold the ACLs, although this is not comprehensive. Server ACLs were added + in Synapse v0.32.0, although other server implementations and versions exist in the world. +allOf: + - $ref: core-event-schema/state_event.yaml +type: object +properties: + content: + properties: + allow_ip_literals: + type: boolean + description: |- + True to allow server names that are IP address literals. False to + deny. Defaults to true if missing or otherwise not a boolean. + + This is strongly recommended to be set to ``false`` as servers running + with IP literal names are strongly discouraged in order to require + legitimate homeservers to be backed by a valid registered domain name. + allow: + type: array + description: |- + The server names to allow in the room, excluding any port information. + Wildcards may be used to cover a wider range of hosts, where ``*`` + matches zero or more characters and ``?`` matches exactly one character. + + **This defaults to an empty list when not provided, effectively disallowing + every server.** + items: + type: string + deny: + type: array + description: |- + The server names to disallow in the room, excluding any port information. + Wildcards may be used to cover a wider range of hosts, where ``*`` + matches zero or more characters and ``?`` matches exactly one character. + + This defaults to an empty list when not provided. + items: + type: string + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: ['m.room.server_acl'] + type: enum diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 7156c7d5..fc89f031 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -41,6 +41,37 @@ Examples of valid server names are: * ``[1234:5678::abcd]:5678`` (IPv6 literal with explicit port) +Room Versions +~~~~~~~~~~~~~ + +Room versions are used to change properties of rooms that may not be compatible +with other servers. For example, changing the rules for event authorization would +cause older servers to potentially end up in a split-brain situation due to them +not understanding the new rules. + +A room version is defined as a string of characters which MUST NOT exceed 32 +codepoints in length. Room versions MUST NOT be empty and SHOULD contain only +the characters ``a-z``, ``0-9``, ``.``, and ``-``. + +Room versions are not intended to be parsed and should be treated as opaque +identifiers. Room versions consisting only of the characters ``0-9`` and ``.`` +are reserved for future versions of the Matrix protocol. + +The complete grammar for a legal room version is:: + + room_version = 1*room_version_char + room_version_char = DIGIT + / %x61-7A ; a-z + / "-" / "." + +Examples of valid room versions are: + +* ``1`` (would be reserved by the Matrix protocol) +* ``1.2`` (would be reserved by the Matrix protocol) +* ``1.2-beta`` +* ``com.example.version`` + + Common Identifier Format ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 09e38e91..48e6896d 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -75,8 +75,7 @@ said to be interested in a given event if one of the application service's names users is the target of the event, or is a joined member of the room where the event occurred. -An application -service can also state whether they should be the only ones who +An application service can also state whether they should be the only ones who can manage a specified namespace. This is referred to as an "exclusive" namespace. An exclusive namespace prevents humans and other application services from creating/deleting entities in that namespace. Typically, @@ -90,27 +89,29 @@ regular expressions and look like: users: - exclusive: true - regex: @_irc.freenode.net_.* + regex: "@_irc.freenode.net_.*" +Application services may define the following namespaces (with none being explicitly required): -The registration is represented by a series of key-value pairs, which this -specification will present as YAML. An example HS configuration required to pass -traffic to the AS is: ++------------------+-----------------------------------------------------------+ +| Name | Description | ++==================+===========================================================+ +| users | Events which are sent from certain users. | ++------------------+-----------------------------------------------------------+ +| aliases | Events which are sent in rooms with certain room aliases. | ++------------------+-----------------------------------------------------------+ +| rooms | Events which are sent in rooms with certain room IDs. | ++------------------+-----------------------------------------------------------+ -.. code-block:: yaml +Each individual namespace MUST declare the following fields: - id: - url: - as_token: - hs_token: - sender_localpart: - namespaces: - users: # Namespaces of users which should be delegated to the AS - - exclusive: - regex: - - ... - aliases: [] # Namespaces of room aliases which should be delegated to the AS - rooms: [] # Namespaces of room ids which should be delegated to the AS ++------------------+-----------------------------------------------------------------------------------------------------------------------------------+ +| Name | Description | ++==================+===================================================================================================================================+ +| exclusive | **Required** A true or false value stating whether this application service has exclusive access to events within this namespace. | ++------------------+-----------------------------------------------------------------------------------------------------------------------------------+ +| regex | **Required** A regular expression defining which values this namespace includes. | ++------------------+-----------------------------------------------------------------------------------------------------------------------------------+ Exclusive user and alias namespaces should begin with an underscore after the sigil to avoid collisions with other users on the homeserver. Application @@ -118,6 +119,48 @@ services should additionally attempt to identify the service they represent in the reserved namespace. For example, ``@_irc_.*`` would be a good namespace to register for an application service which deals with IRC. +The registration is represented by a series of key-value pairs, which this +specification will present as YAML. See below for the possible options along +with their explanation: + ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Description | ++==================+====================================================================================================================================================+ +| id | **Required.** A unique, user-defined ID of the application service which will never change. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| url | **Required.** The URL for the application service. May include a path after the domain name. Optionally set to ``null`` if no traffic is required. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| as_token | **Required.** A unique token for application services to use to authenticate requests to Homeservers. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| hs_token | **Required.** A unique token for Homeservers to use to authenticate requests to application services. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| sender_localpart | **Required.** The localpart of the user associated with the application service. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| namespaces | **Required.** A list of ``users``, ``aliases`` and ``rooms`` namespaces that the application service controls. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| rate_limited | Whether requests from masqueraded users are rate-limited. The sender is excluded. | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| protocols | The external protocols which the application service provides (e.g. IRC). | ++------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +An example registration file for an IRC-bridging application service is below: + +.. code-block:: yaml + + id: "IRC Bridge" + url: "http://127.0.0.1:1234" + as_token: "30c05ae90a248a4188e620216fa72e349803310ec83e2a77b34fe90be6081f46" + hs_token: "312df522183efd404ec1cd22d2ffa4bbc76a8c1ccf541dd692eef281356bb74e" + sender_localpart: "_irc_bot" # Will result in @_irc_bot:domain.com + namespaces: + users: + - exclusive: true + regex: "@_irc_bridge_.*" + aliases: + - exclusive: false + regex: "#_irc_bridge_.*" + rooms: [] + .. WARNING:: If the homeserver in question has multiple application services, each ``as_token`` and ``id`` MUST be unique per application service as these are @@ -182,6 +225,27 @@ this request (e.g. to join a room alias). {{query_room_as_http_api}} +Third party networks +++++++++++++++++++++ + +Application services may declare which protocols they support via their registration +configuration for the homeserver. These networks are generally for third party services +such as IRC that the application service is managing. Application services may populate +a Matrix room directory for their registered protocols, as defined in the Client-Server +API Extensions. + +Each protocol may have several "locations" (also known as "third party locations" or "3PLs"). +A location within a protocol is a place in the third party network, such as an IRC channel. +Users of the third party network may also be represented by the application service. + +Locations and users can be searched by fields defined by the application service, such +as by display name or other attribute. When clients request the homeserver to search +in a particular "network" (protocol), the search fields will be passed along to the +application service for filtering. + +{{protocols_as_http_api}} + + HTTP APIs +++++++++ @@ -200,6 +264,9 @@ Application services can use a more powerful version of the client-server API by identifying itself as an application service to the homeserver. +Endpoints defined in this section MUST be supported by homeservers in the +client-server API as accessible only by application services. + Identity assertion ++++++++++++++++++ The client-server API infers the user ID from the ``access_token`` provided in @@ -296,6 +363,15 @@ API MUST do so with a virtual user (provide a ``user_id`` via the query string). is expected that the application service use the transactions pushed to it to handle events rather than syncing with the user implied by ``sender_localpart``. +Application service room directories +++++++++++++++++++++++++++++++++++++ + +Application services can maintain their own room directories for their defined +third party protocols. These room directories may be accessed by clients through +additional parameters on the ``/publicRooms`` client-server endpoint. + +{{appservice_room_directory_cs_http_api}} + Event fields ~~~~~~~~~~~~ diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 7cd14f7f..71c60097 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -148,6 +148,13 @@ Some requests have unique error codes: :``M_SERVER_NOT_TRUSTED``: The client's request used a third party server, eg. ID server, that this server does not trust. +:``M_UNSUPPORTED_ROOM_VERSION``: + The client's request to create a room used a room version that the server does not support. + +:``M_INCOMPATIBLE_ROOM_VERSION``: + The client attempted to join a room that has a version the server does not support. Inspect the + ``room_version`` property of the error response for the room's version. + .. _sect:txn_ids: The client-server API typically uses ``HTTP PUT`` to submit requests with a diff --git a/specification/modules/push.rst b/specification/modules/push.rst index e9ee8c90..1972fa17 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -124,7 +124,7 @@ There are different "kinds" of push rules and each rule has an associated priority. Every push rule MUST have a ``kind`` and ``rule_id``. The ``rule_id`` is a unique string within the kind of rule and its' scope: ``rule_ids`` do not need to be unique between rules of the same kind on different devices. Rules may -have extra keys depending on the value of ``kind``.The different kinds of rule +have extra keys depending on the value of ``kind``. The different kinds of rule in descending order of priority are: Override Rules ``override`` @@ -369,6 +369,41 @@ Definition: } +``.m.rule.roomnotif`` +````````````````````` +Matches any message whose content is unencrypted and contains the +text ``@room``, signifying the whole room should be notified of +the event. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.roomnotif", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "event_match", + "key": "content.body", + "pattern": "@room" + }, + { + "kind": "sender_notification_permission", + "key": "room" + } + ], + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": true + } + ] + } + + Default Content Rules ^^^^^^^^^^^^^^^^^^^^^ @@ -428,7 +463,47 @@ Definition: "value": false } ] - }, + } + +``.m.rule.encrypted_room_one_to_one`` +````````````````````````````````````` +Matches any encrypted event sent in a room with exactly two members. +Unlike other push rules, this rule cannot be matched against the content +of the event by nature of it being encrypted. This causes the rule to +be an "all or nothing" match where it either matches *all* events that +are encrypted (in 1:1 rooms) or none. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.encrypted_room_one_to_one", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "room_member_count", + "is": "2" + } + ], + "actions": [ + "notify", + { + "set_tweak": "sound", + "value": "default" + }, + { + "set_tweak": "highlight", + "value": false + }, + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.encrypted" + } + ] + } ``.m.rule.room_one_to_one`` ``````````````````````````` @@ -489,6 +564,37 @@ Definition: ] } +``.m.rule.encrypted`` +````````````````````` +Matches all encrypted events. Unlike other push rules, this rule cannot +be matched against the content of the event by nature of it being encrypted. +This causes the rule to be an "all or nothing" match where it either +matches *all* events that are encrypted (in 1:1 rooms) or none. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.encrypted", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.encrypted" + } + ], + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": false + } + ] + } + Conditions ++++++++++ @@ -523,6 +629,21 @@ rule determines its behaviour. The following conditions are defined: count is strictly less than the given number and so forth. If no prefix is present, this parameter defaults to ``==``. +``sender_notification_permission`` + This takes into account the current power levels in the room, ensuring the + sender of the event has high enough power to trigger the notification. + + Parameters: + + * ``key``: A string that determines the power level the sender must have to trigger + notifications of a given type, such as ``room``. Refer to the `m.room.power_levels`_ + event schema for information about what the defaults are and how to interpret the event. + The ``key`` is used to look up the power level required to send a notification type + from the ``notifications`` object in the power level event content. + +Unrecognised conditions MUST NOT match any events, effectively making the push +rule disabled. + Push Rules: API ~~~~~~~~~~~~~~~ diff --git a/specification/modules/server_acls.rst b/specification/modules/server_acls.rst new file mode 100644 index 00000000..2b2d8f35 --- /dev/null +++ b/specification/modules/server_acls.rst @@ -0,0 +1,70 @@ +.. Copyright 2018 New Vector Ltd +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Server Access Control Lists (ACLs) for rooms +============================================ + +.. _module:server-acls: + +In some scenarios room operators may wish to prevent a malicious or untrusted +server from participating in their room. Sending an `m.room.server_acl`_ state +event into a room is an effective way to prevent the server from participating +in the room at the federation level. + +Server ACLs can also be used to make rooms only federate with a limited set of +servers, or retroactively make the room no longer federate with any other server, +similar to setting the ``m.federate`` value on the `m.room.create`_ event. + +{{m_room_server_acl_event}} + +.. Note:: + Port numbers are not supported because it is unclear to parsers whether a + port number should be matched or an IP address literal. Additionally, it + is unlikely that one would trust a server running on a particular domain's + port but not a different port, especially considering the server host can + easily change ports. + +.. Note:: + CIDR notation is not supported for IP addresses because Matrix does not + encourage the use of IPs for identifying servers. Instead, a blanket + ``allow_ip_literals`` is provided to cover banning them. + +Client behaviour +---------------- +Clients are not expected to perform any additional duties beyond sending the +event. Clients should describe changes to the server ACLs to the user in the +user interface, such as in the timeline. + +Clients may wish to kick affected users from the room prior to denying a server +access to the room to help prevent those servers from participating and to +provide feedback to the users that they have been excluded from the room. + +Server behaviour +---------------- +Servers MUST prevent blacklisted servers from sending events or participating +in the room when an `m.room.server_acl`_ event is present in the room state. +Which APIs are specifically affected are described in the Server-Server API +specification. + +Servers should still send events to denied servers if they are still residents +of the room. + + +Security considerations +----------------------- +Server ACLs are only effective if every server in the room honours them. Servers +that do not honour the ACLs may still permit events sent by denied servers into +the room, leaking them to other servers in the room. To effectively enforce an +ACL in a room, the servers that do not honour the ACLs should be denied in the +room as well. \ No newline at end of file diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index dbde8b10..439b35f9 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -929,6 +929,32 @@ described in the `Client-Server API`_, being sure to use the ``allow_remote`` parameter (set to ``false``). +Server Access Control Lists (ACLs) +---------------------------------- + +Server ACLs and their purpose are described in the `Server ACLs`_ section of the +Client-Server API. + +When a remote server makes a request, it MUST be verified to be allowed by the +server ACLs. If the server is denied access to a room, the receiving server +MUST reply with a 403 HTTP status code and an ``errcode`` of ``M_FORBIDDEN``. + +The following endpoint prefixes MUST be protected: + +* ``/_matrix/federation/v1/send`` (on a per-PDU basis) +* ``/_matrix/federation/v1/make_join`` +* ``/_matrix/federation/v1/make_leave`` +* ``/_matrix/federation/v1/send_join`` +* ``/_matrix/federation/v1/send_leave`` +* ``/_matrix/federation/v1/invite`` +* ``/_matrix/federation/v1/state`` +* ``/_matrix/federation/v1/state_ids`` +* ``/_matrix/federation/v1/backfill`` +* ``/_matrix/federation/v1/event_auth`` +* ``/_matrix/federation/v1/query_auth`` +* ``/_matrix/federation/v1/get_missing_events`` + + Signing Events -------------- diff --git a/specification/targets.yaml b/specification/targets.yaml index 5480bbc5..acf4b6ac 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -67,6 +67,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/report_content.rst - modules/third_party_networks.rst - modules/openid.rst + - modules/server_acls.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]