Merge remote-tracking branch 'matrix-org/master' into travis/c2s/id-server
This commit is contained in:
commit
7f1b94c211
37 changed files with 795 additions and 229 deletions
|
@ -1,4 +1,5 @@
|
|||
# Copyright 2016 OpenMarket Ltd
|
||||
# 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.
|
||||
|
@ -13,10 +14,10 @@
|
|||
# limitations under the License.
|
||||
properties:
|
||||
events:
|
||||
description: List of events
|
||||
description: List of events.
|
||||
items:
|
||||
allOf:
|
||||
- $ref: event.yaml
|
||||
- $ref: event-schemas/schema/core-event-schema/event.yaml
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
|
|
27
api/client-server/definitions/room_event_batch.yaml
Normal file
27
api/client-server/definitions/room_event_batch.yaml
Normal file
|
@ -0,0 +1,27 @@
|
|||
# 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.
|
||||
properties:
|
||||
events:
|
||||
description: List of events.
|
||||
items:
|
||||
allOf:
|
||||
- $ref: event-schemas/schema/core-event-schema/sync_room_event.yaml
|
||||
type: object
|
||||
required:
|
||||
- event_id
|
||||
#- room_id - Not in /sync
|
||||
- sender
|
||||
- origin_server_ts
|
||||
type: array
|
||||
type: object
|
28
api/client-server/definitions/state_event_batch.yaml
Normal file
28
api/client-server/definitions/state_event_batch.yaml
Normal file
|
@ -0,0 +1,28 @@
|
|||
# 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.
|
||||
properties:
|
||||
events:
|
||||
description: List of events.
|
||||
items:
|
||||
allOf:
|
||||
- $ref: event-schemas/schema/core-event-schema/sync_state_event.yaml
|
||||
type: object
|
||||
required:
|
||||
- event_id
|
||||
#- room_id - Not in /sync
|
||||
- sender
|
||||
- origin_server_ts
|
||||
- state_key
|
||||
type: array
|
||||
type: object
|
|
@ -1,4 +1,5 @@
|
|||
# Copyright 2016 OpenMarket Ltd
|
||||
# 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.
|
||||
|
@ -12,14 +13,14 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
allOf:
|
||||
- $ref: event_batch.yaml
|
||||
- $ref: room_event_batch.yaml
|
||||
properties:
|
||||
limited:
|
||||
description: True if the number of events returned was limited by the ``limit``
|
||||
on the filter
|
||||
on the filter.
|
||||
type: boolean
|
||||
prev_batch:
|
||||
description: A token that can be supplied to the ``from`` parameter of the
|
||||
rooms/{roomId}/messages endpoint
|
||||
rooms/{roomId}/messages endpoint.
|
||||
type: string
|
||||
type: object
|
||||
|
|
|
@ -117,6 +117,13 @@ paths:
|
|||
A display name to assign to the newly-created device. Ignored
|
||||
if ``device_id`` corresponds to a known device.
|
||||
example: Jungle Phone
|
||||
inhibit_login:
|
||||
type: boolean
|
||||
description: |-
|
||||
If true, an ``access_token`` and ``device_id`` should not be
|
||||
returned from this call, therefore preventing an automatic
|
||||
login. Defaults to false.
|
||||
example: false
|
||||
responses:
|
||||
200:
|
||||
description: The account has been registered.
|
||||
|
@ -141,6 +148,7 @@ paths:
|
|||
description: |-
|
||||
An access token for the account.
|
||||
This access token can then be used to authorize other requests.
|
||||
Required if the ``inhibit_login`` option is false.
|
||||
home_server:
|
||||
type: string
|
||||
description: |-
|
||||
|
@ -155,6 +163,8 @@ paths:
|
|||
description: |-
|
||||
ID of the registered device. Will be the same as the
|
||||
corresponding parameter in the request, if one was specified.
|
||||
Required if the ``inhibit_login`` option is false.
|
||||
required: ['user_id']
|
||||
400:
|
||||
description: |-
|
||||
Part of the request was invalid. This may include one of the following error codes:
|
||||
|
|
|
@ -135,7 +135,7 @@ paths:
|
|||
``timeline``, if ``since`` is not given, or
|
||||
``full_state`` is true).
|
||||
allOf:
|
||||
- $ref: "definitions/event_batch.yaml"
|
||||
- $ref: "definitions/state_event_batch.yaml"
|
||||
timeline:
|
||||
title: Timeline
|
||||
type: object
|
||||
|
@ -202,8 +202,35 @@ paths:
|
|||
the room then the current state will be given as a
|
||||
delta against the archived ``state`` not the
|
||||
``invite_state``.
|
||||
allOf:
|
||||
- $ref: "definitions/event_batch.yaml"
|
||||
properties:
|
||||
events:
|
||||
description: The StrippedState events that form the invite state.
|
||||
items:
|
||||
description: |-
|
||||
A stripped down state event, with only the ``type``, ``state_key``,
|
||||
``sender``, and ``content`` keys.
|
||||
properties:
|
||||
content:
|
||||
description: The ``content`` for the event.
|
||||
title: EventContent
|
||||
type: object
|
||||
state_key:
|
||||
description: The ``state_key`` for the event.
|
||||
type: string
|
||||
type:
|
||||
description: The ``type`` for the event.
|
||||
type: string
|
||||
sender:
|
||||
description: The ``sender`` for the event.
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- state_key
|
||||
- content
|
||||
- sender
|
||||
title: StrippedState
|
||||
type: object
|
||||
type: array
|
||||
leave:
|
||||
title: Left rooms
|
||||
type: object
|
||||
|
@ -219,7 +246,7 @@ paths:
|
|||
description: |-
|
||||
The state updates for the room up to the start of the timeline.
|
||||
allOf:
|
||||
- $ref: "definitions/event_batch.yaml"
|
||||
- $ref: "definitions/state_event_batch.yaml"
|
||||
timeline:
|
||||
title: Timeline
|
||||
type: object
|
||||
|
@ -270,6 +297,8 @@ paths:
|
|||
description: |-
|
||||
Information on end-to-end encryption keys, as specified
|
||||
in |device_lists_sync|_.
|
||||
required:
|
||||
- next_batch
|
||||
examples:
|
||||
application/json: {
|
||||
"next_batch": "s72595_4483_1934",
|
||||
|
@ -321,7 +350,6 @@ paths:
|
|||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.message",
|
||||
"age": 124524,
|
||||
"txn_id": "1234",
|
||||
"content": {
|
||||
"body": "I am a fish",
|
||||
|
|
|
@ -43,14 +43,14 @@ paths:
|
|||
required: true
|
||||
description: |-
|
||||
The id of the user to get tags for. The access token must be
|
||||
authorized to make requests for this user id.
|
||||
authorized to make requests for this user ID.
|
||||
x-example: "@alice:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
name: roomId
|
||||
required: true
|
||||
description: |-
|
||||
The id of the room to get tags for.
|
||||
The ID of the room to get tags for.
|
||||
x-example: "!726s6s6q:example.com"
|
||||
responses:
|
||||
200:
|
||||
|
@ -60,16 +60,26 @@ paths:
|
|||
type: object
|
||||
properties:
|
||||
tags:
|
||||
title: Tags
|
||||
type: object
|
||||
additionalProperties:
|
||||
title: Tag
|
||||
type: object
|
||||
properties:
|
||||
order:
|
||||
type: number
|
||||
format: float
|
||||
description: |-
|
||||
A number in a range ``[0,1]`` describing a relative
|
||||
position of the room under the given tag.
|
||||
additionalProperties: true
|
||||
examples:
|
||||
application/json: {
|
||||
"tags": {
|
||||
"m.favourite": {},
|
||||
"u.Work": {"order": "1"},
|
||||
"u.Customers": {}
|
||||
}
|
||||
"tags": {
|
||||
"m.favourite": {"order": 0.1},
|
||||
"u.Work": {"order": 0.7},
|
||||
"u.Customers": {}
|
||||
}
|
||||
}
|
||||
tags:
|
||||
- User data
|
||||
"/user/{userId}/rooms/{roomId}/tags/{tag}":
|
||||
|
@ -87,14 +97,14 @@ paths:
|
|||
required: true
|
||||
description: |-
|
||||
The id of the user to add a tag for. The access token must be
|
||||
authorized to make requests for this user id.
|
||||
authorized to make requests for this user ID.
|
||||
x-example: "@alice:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
name: roomId
|
||||
required: true
|
||||
description: |-
|
||||
The id of the room to add a tag to.
|
||||
The ID of the room to add a tag to.
|
||||
x-example: "!726s6s6q:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
|
@ -102,7 +112,7 @@ paths:
|
|||
required: true
|
||||
description: |-
|
||||
The tag to add.
|
||||
x-example: "work"
|
||||
x-example: "u.work"
|
||||
- in: body
|
||||
name: body
|
||||
required: true
|
||||
|
@ -110,8 +120,17 @@ paths:
|
|||
Extra data for the tag, e.g. ordering.
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
order:
|
||||
type: number
|
||||
format: float
|
||||
description: |-
|
||||
A number in a range ``[0,1]`` describing a relative
|
||||
position of the room under the given tag.
|
||||
additionalProperties: true
|
||||
example: {
|
||||
"order": "1"}
|
||||
"order": 0.25
|
||||
}
|
||||
responses:
|
||||
200:
|
||||
description:
|
||||
|
@ -119,8 +138,7 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
examples:
|
||||
application/json: {
|
||||
}
|
||||
application/json: {}
|
||||
tags:
|
||||
- User data
|
||||
delete:
|
||||
|
@ -137,14 +155,14 @@ paths:
|
|||
required: true
|
||||
description: |-
|
||||
The id of the user to remove a tag for. The access token must be
|
||||
authorized to make requests for this user id.
|
||||
authorized to make requests for this user ID.
|
||||
x-example: "@alice:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
name: roomId
|
||||
required: true
|
||||
description: |-
|
||||
The id of the room to remove a tag from.
|
||||
The ID of the room to remove a tag from.
|
||||
x-example: "!726s6s6q:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
|
@ -152,15 +170,14 @@ paths:
|
|||
required: true
|
||||
description: |-
|
||||
The tag to remove.
|
||||
x-example: "work"
|
||||
x-example: "u.work"
|
||||
responses:
|
||||
200:
|
||||
description:
|
||||
The tag was successfully removed
|
||||
The tag was successfully removed.
|
||||
schema:
|
||||
type: object
|
||||
examples:
|
||||
application/json: {
|
||||
}
|
||||
application/json: {}
|
||||
tags:
|
||||
- User data
|
||||
|
|
|
@ -31,8 +31,16 @@ paths:
|
|||
post:
|
||||
summary: Searches the user directory.
|
||||
description: |-
|
||||
This API performs a server-side search over all users registered on the server.
|
||||
It searches user ID and displayname case-insensitively for users that you share a room with or that are in public rooms.
|
||||
Performs a search for users on the homeserver. The homeserver may
|
||||
determine which subset of users are searched, however the homeserver
|
||||
MUST at a minimum consider the users the requesting user shares a
|
||||
room with and those who reside in public rooms (known to the homeserver).
|
||||
The search MUST consider local users to the homeserver, and SHOULD
|
||||
query remote users as part of the search.
|
||||
|
||||
The search is performed case-insensitively on user IDs and display
|
||||
names preferably using a collation determined based upon the
|
||||
``Accept-Language`` header provided in the request, if present.
|
||||
operationId: searchUserDirectory
|
||||
security:
|
||||
- accessToken: []
|
||||
|
@ -48,7 +56,7 @@ paths:
|
|||
example: "foo"
|
||||
limit:
|
||||
type: integer
|
||||
description: The maximum number of results to return (Defaults to 10).
|
||||
description: The maximum number of results to return. Defaults to 10.
|
||||
example: 10
|
||||
required: ["search_term"]
|
||||
responses:
|
||||
|
@ -56,15 +64,15 @@ paths:
|
|||
description: The results of the search.
|
||||
examples:
|
||||
application/json: {
|
||||
"results": [
|
||||
{
|
||||
"user_id": "@foo:bar.com",
|
||||
"display_name": "Foo",
|
||||
"avatar_url": "mxc://bar.com/foo"
|
||||
}
|
||||
],
|
||||
"limited": false
|
||||
}
|
||||
"results": [
|
||||
{
|
||||
"user_id": "@foo:bar.com",
|
||||
"display_name": "Foo",
|
||||
"avatar_url": "mxc://bar.com/foo"
|
||||
}
|
||||
],
|
||||
"limited": false
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
required: ["results", "limited"]
|
||||
|
|
|
@ -69,7 +69,8 @@ paths:
|
|||
get:
|
||||
summary: Check whether a long-term public key is valid.
|
||||
description: |-
|
||||
Check whether a long-term public key is valid.
|
||||
Check whether a long-term public key is valid. The response should always
|
||||
be the same, provided the key exists.
|
||||
operationId: isPubKeyValid
|
||||
parameters:
|
||||
- in: query
|
||||
|
|
|
@ -194,3 +194,126 @@ paths:
|
|||
type: object
|
||||
description: An empty object
|
||||
example: {}
|
||||
"/3pid/onbind":
|
||||
put:
|
||||
summary: |-
|
||||
Notifies the server that a third party identifier has been bound to one
|
||||
of its users.
|
||||
description: |-
|
||||
Used by Identity Servers to notify the homeserver that one of its users
|
||||
has bound a third party identifier successfully, including any pending
|
||||
room invites the Identity Server has been made aware of.
|
||||
operationId: onBindThirdPartyIdentifier
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
type: object
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
medium:
|
||||
type: string
|
||||
description: |-
|
||||
The type of third party identifier. Currently only "email" is
|
||||
a possible value.
|
||||
example: "email"
|
||||
address:
|
||||
type: string
|
||||
description: |-
|
||||
The third party identifier itself. For example, an email address.
|
||||
example: "alice@domain.com"
|
||||
mxid:
|
||||
type: string
|
||||
description: The user that is now bound to the third party identifier.
|
||||
example: "@alice:matrix.org"
|
||||
invites:
|
||||
type: array
|
||||
description: |-
|
||||
A list of pending invites that the third party identifier has received.
|
||||
items:
|
||||
type: object
|
||||
title: Third Party Invite
|
||||
properties:
|
||||
medium:
|
||||
type: string
|
||||
description: |-
|
||||
The type of third party invite issues. Currently only
|
||||
"email" is used.
|
||||
example: "email"
|
||||
address:
|
||||
type: string
|
||||
description: |-
|
||||
The third party identifier that received the invite.
|
||||
example: "alice@domain.com"
|
||||
mxid:
|
||||
type: string
|
||||
description: The now-bound user ID that received the invite.
|
||||
example: "@alice:matrix.org"
|
||||
room_id:
|
||||
type: string
|
||||
description: The room ID the invite is valid for.
|
||||
example: "!somewhere:example.org"
|
||||
sender:
|
||||
type: string
|
||||
description: The user ID that sent the invite.
|
||||
example: "@bob:matrix.org"
|
||||
# TODO (TravisR): Make this reusable when doing IS spec changes
|
||||
# also make sure it isn't lying about anything, like the key version
|
||||
signed:
|
||||
type: object
|
||||
title: Identity Server Signatures
|
||||
description: |-
|
||||
Signature from the Identity Server using a long-term private
|
||||
key.
|
||||
properties:
|
||||
mxid:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that has been bound to the third party
|
||||
identifier.
|
||||
example: "@alice:matrix.org"
|
||||
token:
|
||||
type: string
|
||||
# TODO: What is this actually?
|
||||
description: A token.
|
||||
example: "Hello World"
|
||||
signatures:
|
||||
type: object
|
||||
title: Identity Server Signature
|
||||
description: |-
|
||||
The signature from the identity server. The ``string`` key
|
||||
is the identity server's domain name, such as vector.im
|
||||
additionalProperties:
|
||||
type: object
|
||||
title: Identity Server Domain Signature
|
||||
description: The signature for the identity server.
|
||||
properties:
|
||||
"ed25519:0":
|
||||
type: string
|
||||
description: The signature.
|
||||
example: "SomeSignatureGoesHere"
|
||||
required: ['ed25519:0']
|
||||
example: {
|
||||
"vector.im": {
|
||||
"ed25519:0": "SomeSignatureGoesHere"
|
||||
}
|
||||
}
|
||||
required: ['mxid', 'token', 'signatures']
|
||||
required:
|
||||
- medium
|
||||
- address
|
||||
- mxid
|
||||
- room_id
|
||||
- sender
|
||||
- signed
|
||||
required: ['medium', 'address', 'mxid', 'invites']
|
||||
responses:
|
||||
200:
|
||||
description: The homeserver has processed the notification.
|
||||
examples:
|
||||
application/json: {}
|
||||
schema:
|
||||
type: object
|
||||
description: An empty object
|
||||
example: {}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
r0.1.0
|
||||
======
|
||||
|
||||
This is the first release of the Application Service specification. It
|
||||
includes support for application services being able to interact with
|
||||
homeservers and bridge third party networks, such as IRC, over to Matrix
|
||||
in a standard and accessible way.
|
|
@ -0,0 +1 @@
|
|||
Clarify the homeserver's behaviour for searching users.
|
|
@ -0,0 +1 @@
|
|||
Clarify the event fields used in the ``/sync`` response.
|
1
changelogs/client_server/newsfragments/1589.feature
Normal file
1
changelogs/client_server/newsfragments/1589.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Add an ``inhibit_login`` registration option.
|
1
changelogs/client_server/newsfragments/1600.feature
Normal file
1
changelogs/client_server/newsfragments/1600.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Recommend that servers set a Content Security Policy for the content repository.
|
|
@ -0,0 +1 @@
|
|||
Add the other keys that redactions are expected to preserve.
|
|
@ -0,0 +1 @@
|
|||
Clarify that clients should not be generating invalid HTML for formatted events.
|
|
@ -0,0 +1 @@
|
|||
Clarify the room tag structure (thanks @KitsuneRal!)
|
|
@ -0,0 +1 @@
|
|||
Add a note that clients may use the transaction ID to avoid flickering when doing local echo.
|
|
@ -3,7 +3,7 @@
|
|||
"type": "m.tag",
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {"order": 1}
|
||||
"u.work": {"order": 0.9}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,5 +10,6 @@ properties:
|
|||
type: string
|
||||
required:
|
||||
- type
|
||||
- content
|
||||
title: Event
|
||||
type: object
|
||||
|
|
|
@ -1,46 +1,14 @@
|
|||
allOf:
|
||||
- $ref: event.yaml
|
||||
- $ref: sync_room_event.yaml
|
||||
description: In addition to the Event fields, Room Events have the following additional
|
||||
fields.
|
||||
properties:
|
||||
event_id:
|
||||
description: The globally unique event identifier.
|
||||
type: string
|
||||
room_id:
|
||||
description: The ID of the room associated with this event.
|
||||
description: |-
|
||||
The ID of the room associated with this event. Will not be present on events
|
||||
that arrive through ``/sync``, despite being required everywhere else.
|
||||
type: string
|
||||
sender:
|
||||
description: Contains the fully-qualified ID of the user who *sent*
|
||||
this event.
|
||||
type: string
|
||||
origin_server_ts:
|
||||
description: Timestamp in milliseconds on originating homeserver
|
||||
when this event was sent.
|
||||
type: integer
|
||||
format: int64
|
||||
unsigned:
|
||||
description: Contains optional extra information about the event.
|
||||
properties:
|
||||
age:
|
||||
description: The time in milliseconds that has elapsed since the event was
|
||||
sent. This field is generated by the local homeserver, and may be incorrect
|
||||
if the local time on at least one of the two servers is out of sync, which can
|
||||
cause the age to either be negative or greater than it actually is.
|
||||
type: integer
|
||||
redacted_because:
|
||||
description: Optional. The event that redacted this event, if any.
|
||||
title: Event
|
||||
type: object
|
||||
transaction_id:
|
||||
description: The client-supplied transaction ID, if the client being given
|
||||
the event is the same one which sent it.
|
||||
type: string
|
||||
title: UnsignedData
|
||||
type: object
|
||||
required:
|
||||
- event_id
|
||||
- room_id
|
||||
- sender
|
||||
- origin_server_ts
|
||||
title: Room Event
|
||||
type: object
|
||||
|
|
|
@ -1,23 +1,7 @@
|
|||
allOf:
|
||||
- $ref: room_event.yaml
|
||||
- $ref: sync_state_event.yaml
|
||||
description: In addition to the Room Event fields, State Events have the following
|
||||
additional fields.
|
||||
properties:
|
||||
prev_content:
|
||||
description: Optional. The previous ``content`` for this event. If there is no
|
||||
previous content, this key will be missing.
|
||||
title: EventContent
|
||||
type: object
|
||||
state_key:
|
||||
description: A unique key which defines the overwriting semantics for this piece
|
||||
of room state. This value is often a zero-length string. The presence of this
|
||||
key makes this event a State Event.
|
||||
|
||||
State keys starting with an ``@`` are reserved for referencing user IDs, such
|
||||
as room members. With the exception of a few events, state events set with a
|
||||
given user's ID as the state key MUST only be set by that user.
|
||||
type: string
|
||||
required:
|
||||
- state_key
|
||||
title: State Event
|
||||
type: object
|
||||
|
|
60
event-schemas/schema/core-event-schema/sync_room_event.yaml
Normal file
60
event-schemas/schema/core-event-schema/sync_room_event.yaml
Normal file
|
@ -0,0 +1,60 @@
|
|||
# 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.
|
||||
|
||||
# Note: this is technically not a core event schema, however it is included here
|
||||
# to keep things sane. The short story is that /sync doesn't require a room_id to
|
||||
# be on events, so we give it a whole event structure as a base for room_event.
|
||||
# This base doesn't declare a room_id, which instead appears in the room_event.
|
||||
|
||||
allOf:
|
||||
- $ref: event.yaml
|
||||
description: In addition to the Event fields, Room Events have the following additional
|
||||
fields.
|
||||
properties:
|
||||
event_id:
|
||||
description: The globally unique event identifier.
|
||||
type: string
|
||||
sender:
|
||||
description: Contains the fully-qualified ID of the user who sent this event.
|
||||
type: string
|
||||
origin_server_ts:
|
||||
description: Timestamp in milliseconds on originating homeserver
|
||||
when this event was sent.
|
||||
type: integer
|
||||
format: int64
|
||||
unsigned:
|
||||
description: Contains optional extra information about the event.
|
||||
properties:
|
||||
age:
|
||||
description: The time in milliseconds that has elapsed since the event was
|
||||
sent. This field is generated by the local homeserver, and may be incorrect
|
||||
if the local time on at least one of the two servers is out of sync, which can
|
||||
cause the age to either be negative or greater than it actually is.
|
||||
type: integer
|
||||
redacted_because:
|
||||
description: Optional. The event that redacted this event, if any.
|
||||
title: Event
|
||||
type: object
|
||||
transaction_id:
|
||||
description: The client-supplied transaction ID, if the client being given
|
||||
the event is the same one which sent it.
|
||||
type: string
|
||||
title: UnsignedData
|
||||
type: object
|
||||
required:
|
||||
- event_id
|
||||
- sender
|
||||
- origin_server_ts
|
||||
title: Room Event
|
||||
type: object
|
39
event-schemas/schema/core-event-schema/sync_state_event.yaml
Normal file
39
event-schemas/schema/core-event-schema/sync_state_event.yaml
Normal file
|
@ -0,0 +1,39 @@
|
|||
# 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.
|
||||
|
||||
# See sync_room_event.yaml for why this file is here.
|
||||
|
||||
allOf:
|
||||
- $ref: sync_room_event.yaml
|
||||
description: In addition to the Room Event fields, State Events have the following
|
||||
additional fields.
|
||||
properties:
|
||||
prev_content:
|
||||
description: Optional. The previous ``content`` for this event. If there is no
|
||||
previous content, this key will be missing.
|
||||
title: EventContent
|
||||
type: object
|
||||
state_key:
|
||||
description: A unique key which defines the overwriting semantics for this piece
|
||||
of room state. This value is often a zero-length string. The presence of this
|
||||
key makes this event a State Event.
|
||||
|
||||
State keys starting with an ``@`` are reserved for referencing user IDs, such
|
||||
as room members. With the exception of a few events, state events set with a
|
||||
given user's ID as the state key MUST only be set by that user.
|
||||
type: string
|
||||
required:
|
||||
- state_key
|
||||
title: State Event
|
||||
type: object
|
|
@ -18,7 +18,15 @@
|
|||
"description": "The tags on the room and their contents.",
|
||||
"additionalProperties": {
|
||||
"title": "Tag",
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"description":
|
||||
"A number in a range ``[0,1]`` describing a relative position of the room under the given tag."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,6 +207,13 @@ class MatrixSections(Sections):
|
|||
apis = self.units.get("apis")
|
||||
return template.render(apis=apis)
|
||||
|
||||
def render_unstable_warnings(self):
|
||||
rendered = {}
|
||||
blocks = self.units.get("unstable_warnings")
|
||||
for var, text in blocks.items():
|
||||
rendered["unstable_warning_block_" + var] = text
|
||||
return rendered
|
||||
|
||||
def render_swagger_definition(self):
|
||||
rendered = {}
|
||||
template = self.env.get_template("schema-definition.tmpl")
|
||||
|
|
|
@ -971,6 +971,22 @@ class MatrixUnits(Units):
|
|||
|
||||
return changelogs
|
||||
|
||||
def load_unstable_warnings(self, substitutions):
|
||||
warning = """
|
||||
.. WARNING::
|
||||
You are viewing an unstable version of this specification. Unstable
|
||||
specifications may change at any time without notice. To view the
|
||||
current specification, please `click here <latest.html>`_.
|
||||
"""
|
||||
warnings = {}
|
||||
for var in substitutions.keys():
|
||||
key = var[1:-1] # take off the surrounding %-signs
|
||||
if substitutions.get(var, "unstable") == "unstable":
|
||||
warnings[key] = warning
|
||||
else:
|
||||
warnings[key] = ""
|
||||
return warnings
|
||||
|
||||
|
||||
def load_spec_targets(self):
|
||||
with open(TARGETS, "r") as f:
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
Application Service API
|
||||
=======================
|
||||
|
||||
{{unstable_warning_block_APPSERVICE_RELEASE_LABEL}}
|
||||
|
||||
The Matrix client-server API and server-server APIs provide the means to
|
||||
implement a consistent self-contained federated messaging fabric. However, they
|
||||
provide limited means of implementing custom server-side behaviour in Matrix
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
Client-Server API
|
||||
=================
|
||||
|
||||
{{unstable_warning_block_CLIENT_RELEASE_LABEL}}
|
||||
|
||||
The client-server API provides a simple lightweight API to let clients send
|
||||
messages, control rooms and synchronise conversation history. It is designed to
|
||||
support both lightweight clients which store no state and lazy-load data from
|
||||
|
@ -1328,16 +1330,30 @@ the following list:
|
|||
- ``state_key``
|
||||
- ``prev_content``
|
||||
- ``content``
|
||||
- ``hashes``
|
||||
- ``signatures``
|
||||
- ``depth``
|
||||
- ``prev_events``
|
||||
- ``prev_state``
|
||||
- ``auth_events``
|
||||
- ``origin``
|
||||
- ``origin_server_ts``
|
||||
- ``membership``
|
||||
|
||||
.. Note:
|
||||
Some of the keys, such as ``hashes``, will appear on the federation-formatted
|
||||
event and therefore the client may not be aware of them.
|
||||
|
||||
The content object should also be stripped of all keys, unless it is one of
|
||||
one of the following event types:
|
||||
|
||||
- ``m.room.member`` allows key ``membership``
|
||||
- ``m.room.create`` allows key ``creator``
|
||||
- ``m.room.join_rules`` allows key ``join_rule``
|
||||
- ``m.room.member`` allows key ``membership``.
|
||||
- ``m.room.create`` allows key ``creator``.
|
||||
- ``m.room.join_rules`` allows key ``join_rule``.
|
||||
- ``m.room.power_levels`` allows keys ``ban``, ``events``, ``events_default``,
|
||||
``kick``, ``redact``, ``state_default``, ``users``, ``users_default``.
|
||||
- ``m.room.aliases`` allows key ``aliases``
|
||||
- ``m.room.aliases`` allows key ``aliases``.
|
||||
- ``m.room.history_visibility`` allows key ``history_visibility``.
|
||||
|
||||
The server should add the event causing the redaction to the ``unsigned``
|
||||
property of the redacted event, under the ``redacted_because`` key. When a
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
Identity Service API
|
||||
====================
|
||||
|
||||
{{unstable_warning_block_IDENTITY_RELEASE_LABEL}}
|
||||
|
||||
The Matrix client-server and server-server APIs are largely expressed in Matrix
|
||||
user identifiers. From time to time, it is useful to refer to users by other
|
||||
("third-party") identifiers, or "3pid"s, e.g. their email address or phone
|
||||
|
@ -179,9 +181,11 @@ An identity service has some long-term public-private keypairs. These are named
|
|||
in a scheme ``algorithm:identifier``, e.g. ``ed25519:0``. When signing an
|
||||
association, the standard `Signing JSON`_ algorithm applies.
|
||||
|
||||
In the event of key compromise, the identity service may revoke any of its keys.
|
||||
An HTTP API is offered to get public keys, and check whether a particular key is
|
||||
valid.
|
||||
.. TODO: Actually allow identity services to revoke all keys
|
||||
See: https://github.com/matrix-org/matrix-doc/issues/1633
|
||||
.. In the event of key compromise, the identity service may revoke any of its keys.
|
||||
An HTTP API is offered to get public keys, and check whether a particular key is
|
||||
valid.
|
||||
|
||||
The identity service may also keep track of some short-term public-private
|
||||
keypairs, which may have different usage and lifetime characteristics than the
|
||||
|
|
|
@ -33,6 +33,10 @@ recipient's local homeserver, which must first transfer the content from the
|
|||
origin homeserver using the same API (unless the origin and destination
|
||||
homeservers are the same).
|
||||
|
||||
When serving content, the server SHOULD provide a ``Content-Security-Policy``
|
||||
header. The recommended policy is ``default-src 'none'; script-src 'none';
|
||||
plugin-types application/pdf; style-src 'unsafe-inline'; object-src 'self';``.
|
||||
|
||||
Client behaviour
|
||||
----------------
|
||||
|
||||
|
|
|
@ -106,6 +106,12 @@ of tags they can render, falling back to other representations of the tags where
|
|||
For example, a client may not be able to render tables correctly and instead could fall
|
||||
back to rendering tab-delimited text.
|
||||
|
||||
In addition to not rendering unsafe HTML, clients should not emit unsafe HTML in events.
|
||||
Likewise, clients should not generate HTML that is not needed, such as extra paragraph tags
|
||||
surrounding text due to Rich Text Editors. HTML included in events should otherwise be valid,
|
||||
such as having appropriate closing tags, appropriate attributes (considering the custom ones
|
||||
defined in this specification), and generally valid structure.
|
||||
|
||||
.. Note::
|
||||
A future iteration of the specification will support more powerful and extensible
|
||||
message formatting options, such as the proposal `MSC1225 <https://github.com/matrix-org/matrix-doc/issues/1225>`_.
|
||||
|
@ -167,9 +173,14 @@ message which they receive from the event stream. The echo of the same message
|
|||
from the event stream is referred to as "remote echo". Both echoes need to be
|
||||
identified as the same message in order to prevent duplicate messages being
|
||||
displayed. Ideally this pairing would occur transparently to the user: the UI
|
||||
would not flicker as it transitions from local to remote. Flickering cannot be
|
||||
fully avoided in the current client-server API. Two scenarios need to be
|
||||
considered:
|
||||
would not flicker as it transitions from local to remote. Flickering can be
|
||||
reduced through clients making use of the transaction ID they used to send
|
||||
a particular event. The transaction ID used will be included in the event's
|
||||
``unsigned`` data as ``transaction_id`` when it arrives through the event stream.
|
||||
|
||||
Clients unable to make use of the transaction ID are more likely to experience
|
||||
flickering due to the following two scenarios, however the effect can be mitigated
|
||||
to a degree:
|
||||
|
||||
- The client sends a message and the remote echo arrives on the event stream
|
||||
*after* the request to send the message completes.
|
||||
|
|
|
@ -39,7 +39,7 @@ with an ``order`` of ``0.2`` would be displayed before a room with an ``order``
|
|||
of ``0.7``. If a room has a tag without an ``order`` key then it should appear
|
||||
after the rooms with that tag that have an ``order`` key.
|
||||
|
||||
The name of a tag MUST not exceed 255 bytes.
|
||||
The name of a tag MUST NOT exceed 255 bytes.
|
||||
|
||||
The tag namespace is defined as follows:
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ with ``content.membership`` = ``invite``, as well as a
|
|||
``content.third_party_invite`` property which contains proof that the invitee
|
||||
does indeed own that third party identifier.
|
||||
|
||||
|
||||
Events
|
||||
------
|
||||
|
||||
|
@ -55,41 +56,79 @@ A client asks a server to invite a user by their third party identifier.
|
|||
Server behaviour
|
||||
----------------
|
||||
|
||||
Upon receipt of an ``/invite``, the server is expected to look up the third party
|
||||
identifier with the provided identity server. If the lookup yields a result for
|
||||
a Matrix User ID then the normal invite process can be initiated. This process
|
||||
ends up looking like this:
|
||||
|
||||
::
|
||||
|
||||
+---------+ +-------------+ +-----------------+
|
||||
| Client | | Homeserver | | IdentityServer |
|
||||
+---------+ +-------------+ +-----------------+
|
||||
| | |
|
||||
| POST /invite | |
|
||||
|------------------------------------>| |
|
||||
| | |
|
||||
| | GET /lookup |
|
||||
| |--------------------------------------------------->|
|
||||
| | |
|
||||
| | User ID result |
|
||||
| |<---------------------------------------------------|
|
||||
| | |
|
||||
| | Invite process for the discovered User ID |
|
||||
| |------------------------------------------ |
|
||||
| | | |
|
||||
| |<----------------------------------------- |
|
||||
| | |
|
||||
| Complete the /invite request | |
|
||||
|<------------------------------------| |
|
||||
| | |
|
||||
|
||||
|
||||
However, if the lookup does not yield a bound User ID, the homeserver must store
|
||||
the invite on the identity server and emit a valid ``m.room.third_party_invite``
|
||||
event to the room. This process ends up looking like this:
|
||||
|
||||
::
|
||||
|
||||
+---------+ +-------------+ +-----------------+
|
||||
| Client | | Homeserver | | IdentityServer |
|
||||
+---------+ +-------------+ +-----------------+
|
||||
| | |
|
||||
| POST /invite | |
|
||||
|------------------------------------>| |
|
||||
| | |
|
||||
| | GET /lookup |
|
||||
| |-------------------------------------------------------------->|
|
||||
| | |
|
||||
| | "no users" result |
|
||||
| |<--------------------------------------------------------------|
|
||||
| | |
|
||||
| | POST /store-invite |
|
||||
| |-------------------------------------------------------------->|
|
||||
| | |
|
||||
| | Information needed for the m.room.third_party_invite |
|
||||
| |<--------------------------------------------------------------|
|
||||
| | |
|
||||
| | Emit m.room.third_party_invite to the room |
|
||||
| |------------------------------------------- |
|
||||
| | | |
|
||||
| |<------------------------------------------ |
|
||||
| | |
|
||||
| Complete the /invite request | |
|
||||
|<------------------------------------| |
|
||||
| | |
|
||||
|
||||
|
||||
All homeservers MUST verify the signature in the event's
|
||||
``content.third_party_invite.signed`` object.
|
||||
|
||||
When a homeserver inserts an ``m.room.member`` ``invite`` event into the graph
|
||||
because of an ``m.room.third_party_invite`` event,
|
||||
that homesever MUST validate that the public
|
||||
key used for signing is still valid, by checking ``key_validity_url`` from the ``m.room.third_party_invite``. It does
|
||||
this by making an HTTP GET request to ``key_validity_url``:
|
||||
|
||||
.. TODO: Link to identity server spec when it exists
|
||||
|
||||
Schema::
|
||||
|
||||
=> GET $key_validity_url?public_key=$public_key
|
||||
<= HTTP/1.1 200 OK
|
||||
{
|
||||
"valid": true|false
|
||||
}
|
||||
|
||||
|
||||
Example::
|
||||
|
||||
key_validity_url = https://identity.server/is_valid
|
||||
public_key = ALJWLAFQfqffQHFqFfeqFUOEHf4AIHfefh4
|
||||
=> GET https://identity.server/is_valid?public_key=ALJWLAFQfqffQHFqFfeqFUOEHf4AIHfefh4
|
||||
<= HTTP/1.1 200 OK
|
||||
{
|
||||
"valid": true
|
||||
}
|
||||
|
||||
with the querystring
|
||||
?public_key=``public_key``. A JSON object will be returned.
|
||||
The invitation is valid if the object contains a key named ``valid`` which is
|
||||
``true``. Otherwise, the invitation MUST be rejected. This request is
|
||||
idempotent and may be retried by the homeserver.
|
||||
The third party user will then need to verify their identity, which results in
|
||||
a call from the Identity Server to the homeserver that bound the third party
|
||||
identifier to a user. The homeserver then exchanges the ``m.room.third_party_invite``
|
||||
event in the room for a complete ``m.room.member`` event for ``membership: invite``
|
||||
for the user that has bound the third party identifier.
|
||||
|
||||
If a homeserver is joining a room for the first time because of an
|
||||
``m.room.third_party_invite``, the server which is already participating in the
|
||||
|
@ -99,29 +138,84 @@ validate that the public key used for signing is still valid, by checking
|
|||
|
||||
No other homeservers may reject the joining of the room on the basis of
|
||||
``key_validity_url``, this is so that all homeservers have a consistent view of
|
||||
the room. They may, however, indicate to their clients that a member's'
|
||||
the room. They may, however, indicate to their clients that a member's
|
||||
membership is questionable.
|
||||
|
||||
For example:
|
||||
For example, given H1, H2, and H3 as homeservers, UserA as a user of H1, and an
|
||||
identity server IS, the full sequence for a third party invite would look like
|
||||
the following. This diagram assumes H1 and H2 are residents of the room while
|
||||
H3 is attempting to join.
|
||||
|
||||
#. Room R has two participating homeservers, H1, H2
|
||||
::
|
||||
|
||||
#. User A on H1 invites a third party identifier to room R
|
||||
+-------+ +-----------------+ +-----+ +-----+ +-----+ +-----+
|
||||
| UserA | | ThirdPartyUser | | H1 | | H2 | | H3 | | IS |
|
||||
+-------+ +-----------------+ +-----+ +-----+ +-----+ +-----+
|
||||
| | | | | |
|
||||
| POST /invite for ThirdPartyUser | | | |
|
||||
|----------------------------------->| | | |
|
||||
| | | | | |
|
||||
| | | GET /lookup | | |
|
||||
| | |---------------------------------------------------------------------------------------------->|
|
||||
| | | | | |
|
||||
| | | | Lookup results (empty object) |
|
||||
| | |<----------------------------------------------------------------------------------------------|
|
||||
| | | | | |
|
||||
| | | POST /store-invite | | |
|
||||
| | |---------------------------------------------------------------------------------------------->|
|
||||
| | | | | |
|
||||
| | | | Token, keys, etc for third party invite |
|
||||
| | |<----------------------------------------------------------------------------------------------|
|
||||
| | | | | |
|
||||
| | | (Federation) Emit m.room.third_party_invite | | |
|
||||
| | |----------------------------------------------->| | |
|
||||
| | | | | |
|
||||
| Complete /invite request | | | |
|
||||
|<-----------------------------------| | | |
|
||||
| | | | | |
|
||||
| | Verify identity | | | |
|
||||
| |-------------------------------------------------------------------------------------------------------------------->|
|
||||
| | | | | |
|
||||
| | | | | POST /3pid/onbind |
|
||||
| | | | |<---------------------------|
|
||||
| | | | | |
|
||||
| | | PUT /exchange_third_party_invite/:roomId | |
|
||||
| | |<-----------------------------------------------------------------| |
|
||||
| | | | | |
|
||||
| | | Verify the request | | |
|
||||
| | |------------------- | | |
|
||||
| | | | | | |
|
||||
| | |<------------------ | | |
|
||||
| | | | | |
|
||||
| | | (Federation) Emit m.room.member for invite | | |
|
||||
| | |----------------------------------------------->| | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | (Federation) Emit the m.room.member event sent to H2 | |
|
||||
| | |----------------------------------------------------------------->| |
|
||||
| | | | | |
|
||||
| | | Complete /exchange_third_party_invite/:roomId request | |
|
||||
| | |----------------------------------------------------------------->| |
|
||||
| | | | | |
|
||||
| | | | | Participate in the room |
|
||||
| | | | |------------------------ |
|
||||
| | | | | | |
|
||||
| | | | |<----------------------- |
|
||||
| | | | | |
|
||||
|
||||
#. H1 asks the identity server for a binding to a Matrix user ID, and has none,
|
||||
so issues an ``m.room.third_party_invite`` event to the room.
|
||||
|
||||
#. When the third party user validates their identity, their homeserver H3
|
||||
is notified and attempts to issue an ``m.room.member`` event to participate
|
||||
in the room.
|
||||
Note that when H1 sends the ``m.room.member`` event to H2 and H3 it does not
|
||||
have to block on either server's receipt of the event. Likewise, H1 may complete
|
||||
the ``/exchange_third_party_invite/:roomId`` request at the same time as sending
|
||||
the ``m.room.member`` event to H2 and H3. Additionally, H3 may complete the
|
||||
``/3pid/onbind`` request it got from IS at any time - the completion is not shown
|
||||
in the diagram.
|
||||
|
||||
#. H3 validates the signature given to it by the identity server.
|
||||
|
||||
#. H3 then asks H1 to join it to the room. H1 *must* validate the ``signed``
|
||||
property *and* check ``key_validity_url``.
|
||||
|
||||
#. Having validated these things, H1 writes the invite event to the room, and H3
|
||||
begins participating in the room. H2 *must* accept this event.
|
||||
H1 MUST verify the request from H3 to ensure the ``signed`` property is correct
|
||||
as well as the ``key_validity_url`` as still being valid. This is done by making
|
||||
a request to the `Identity Server /isvalid`_ endpoint, using the provided URL
|
||||
rather than constructing a new one. The query string and response for the provided
|
||||
URL must match the Identity Server specification.
|
||||
|
||||
The reason that no other homeserver may reject the event based on checking
|
||||
``key_validity_url`` is that we must ensure event acceptance is deterministic.
|
||||
|
@ -158,3 +252,6 @@ There is some risk of denial of service attacks by flooding homeservers or
|
|||
identity servers with many requests, or much state to store. Defending against
|
||||
these is left to the implementer's discretion.
|
||||
|
||||
|
||||
|
||||
.. _`Identity Server /isvalid`: ../identity_service/unstable.html#get-matrix-identity-api-v1-pubkey-isvalid
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
Push Gateway API
|
||||
================
|
||||
|
||||
{{unstable_warning_block_PUSH_GATEWAY_RELEASE_LABEL}}
|
||||
|
||||
Clients may want to receive push notifications when events are received at
|
||||
the homeserver. This is managed by a distinct entity called the Push Gateway.
|
||||
|
||||
|
|
|
@ -308,6 +308,8 @@ creating a new event in this room should populate the new event's
|
|||
|
|
||||
E4
|
||||
|
||||
.. _`auth events selection`:
|
||||
|
||||
The ``auth_events`` field of a PDU identifies the set of events which give the
|
||||
sender permission to send the event. The ``auth_events`` for the
|
||||
``m.room.create`` event in a room is empty; for other events, it should be the
|
||||
|
@ -315,8 +317,16 @@ following subset of the room state:
|
|||
|
||||
- The ``m.room.create`` event.
|
||||
- The current ``m.room.power_levels`` event, if any.
|
||||
- The current ``m.room.join_rules`` event, if any.
|
||||
- The sender's current ``m.room.member`` event, if any.
|
||||
- If type is ``m.room.member``:
|
||||
|
||||
- The target's current ``m.room.member`` event, if any.
|
||||
- If ``membership`` is ``join`` or ``invite``, the current
|
||||
``m.room.join_rules`` event, if any.
|
||||
- If membership is ``invite`` and ``content`` contains a
|
||||
``third_party_invite`` property, the current
|
||||
``m.room.third_party_invite`` event with ``state_key`` matching
|
||||
``content.third_party_invite.signed.token``, if any.
|
||||
|
||||
{{definition_ss_pdu}}
|
||||
|
||||
|
@ -358,117 +368,170 @@ be inserted. The types of state events that affect authorization are:
|
|||
- ``m.room.member``
|
||||
- ``m.room.join_rules``
|
||||
- ``m.room.power_levels``
|
||||
|
||||
Servers should not create new events that reference unauthorized events.
|
||||
However, any event that does reference an unauthorized event is not itself
|
||||
automatically considered unauthorized.
|
||||
|
||||
Unauthorized events that appear in the event graph do *not* have any effect on
|
||||
the state of the room.
|
||||
|
||||
.. Note:: This is in contrast to redacted events which can still affect the
|
||||
state of the room. For example, a redacted ``join`` event will still
|
||||
result in the user being considered joined.
|
||||
- ``m.room.third_party_invite``
|
||||
|
||||
The rules are as follows:
|
||||
|
||||
1. If type is ``m.room.create``, allow if and only if it has no
|
||||
previous events - *i.e.* it is the first event in the room.
|
||||
1. If type is ``m.room.create``:
|
||||
|
||||
2. If type is ``m.room.member``:
|
||||
a. If it has any previous events, reject.
|
||||
b. If the domain of the ``room_id`` does not match the domain of the
|
||||
``sender``, reject.
|
||||
c. If ``content.room_version`` is present and is not a recognised version,
|
||||
reject.
|
||||
d. If ``content`` has no ``creator`` field, reject.
|
||||
e. Otherwise, allow.
|
||||
|
||||
a. If ``membership`` is ``join``:
|
||||
#. Reject if event has ``auth_events`` that:
|
||||
|
||||
i. If the only previous event is an ``m.room.create``
|
||||
and the ``state_key`` is the creator, allow.
|
||||
a. have duplicate entries for a given ``type`` and ``state_key`` pair
|
||||
#. have entries whose ``type`` and ``state_key`` don't match those
|
||||
specified by the `auth events selection`_ algorithm described above.
|
||||
|
||||
#. If the ``sender`` does not match ``state_key``, reject.
|
||||
#. If event does not have a ``m.room.create`` in its ``auth_events``, reject.
|
||||
|
||||
#. If the user's current membership state is ``invite`` or ``join``,
|
||||
allow.
|
||||
#. If type is ``m.room.aliases``:
|
||||
|
||||
#. If the ``join_rule`` is ``public``, allow.
|
||||
a. If event has no ``state_key``, reject.
|
||||
b. If sender's domain doesn't matches ``state_key``, reject.
|
||||
c. Otherwise, allow.
|
||||
|
||||
#. Otherwise, reject.
|
||||
#. If type is ``m.room.member``:
|
||||
|
||||
b. If ``membership`` is ``invite``:
|
||||
a. If no ``state_key`` key or ``membership`` key in ``content``, reject.
|
||||
|
||||
i. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
#. If ``membership`` is ``join``:
|
||||
|
||||
#. If *target user*'s current membership state is ``join`` or ``ban``,
|
||||
reject.
|
||||
i. If the only previous event is an ``m.room.create``
|
||||
and the ``state_key`` is the creator, allow.
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *invite
|
||||
level*, allow.
|
||||
#. If the ``sender`` does not match ``state_key``, reject.
|
||||
|
||||
#. Otherwise, reject.
|
||||
#. If the ``sender`` is banned, reject.
|
||||
|
||||
c. If ``membership`` is ``leave``:
|
||||
#. If the ``join_rule`` is ``invite`` then allow if membership state
|
||||
is ``invite`` or ``join``.
|
||||
|
||||
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
|
||||
current membership state is ``invite`` or ``join``.
|
||||
#. If the ``join_rule`` is ``public``, allow.
|
||||
|
||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. If the *target user*'s current membership state is ``ban``, and the
|
||||
``sender``'s power level is less than the *ban level*, reject.
|
||||
#. If ``membership`` is ``invite``:
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *kick
|
||||
level*, and the *target user*'s power level is less than the
|
||||
``sender``'s power level, allow.
|
||||
i. If ``content`` has ``third_party_invite`` key:
|
||||
|
||||
#. Otherwise, reject.
|
||||
#. If *target user* is banned, reject.
|
||||
|
||||
d. If ``membership`` is ``ban``:
|
||||
#. If ``content.third_party_invite`` does not have a
|
||||
``signed`` key, reject.
|
||||
|
||||
i. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
#. If ``signed`` does not have ``mxid`` and ``token`` keys, reject.
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *ban
|
||||
level*, and the *target user*'s power level is less than the
|
||||
``sender``'s power level, allow.
|
||||
#. If ``mxid`` does not match ``state_key``, reject.
|
||||
|
||||
#. Otherwise, reject.
|
||||
#. If there is no ``m.room.third_party_invite`` event in the
|
||||
current room state with ``state_key`` matching ``token``, reject.
|
||||
|
||||
e. Otherwise, the membership is unknown. Reject.
|
||||
#. If ``sender`` does not match ``sender`` of the
|
||||
``m.room.third_party_invite``, reject.
|
||||
|
||||
3. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
#. If any signature in ``signed`` matches any public key in the
|
||||
``m.room.third_party_invite`` event, allow. The public keys are
|
||||
in ``content`` of ``m.room.third_party_invite`` as:
|
||||
|
||||
4. If the event type's *required power level* is greater than the ``sender``'s power
|
||||
#. A single public key in the ``public_key`` field.
|
||||
#. A list of public keys in the ``public_keys`` field.
|
||||
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
|
||||
#. If *target user*'s current membership state is ``join`` or ``ban``,
|
||||
reject.
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *invite
|
||||
level*, allow.
|
||||
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. If ``membership`` is ``leave``:
|
||||
|
||||
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
|
||||
current membership state is ``invite`` or ``join``.
|
||||
|
||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
|
||||
#. If the *target user*'s current membership state is ``ban``, and the
|
||||
``sender``'s power level is less than the *ban level*, reject.
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *kick
|
||||
level*, and the *target user*'s power level is less than the
|
||||
``sender``'s power level, allow.
|
||||
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. If ``membership`` is ``ban``:
|
||||
|
||||
i. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
|
||||
#. If the ``sender``'s power level is greater than or equal to the *ban
|
||||
level*, and the *target user*'s power level is less than the
|
||||
``sender``'s power level, allow.
|
||||
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. Otherwise, the membership is unknown. Reject.
|
||||
|
||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||
|
||||
#. If type is ``m.room.third_party_invite``:
|
||||
|
||||
a. Allow if and only if ``sender``'s current power level is greater than
|
||||
or equal to the *invite level*.
|
||||
|
||||
#. If the event type's *required power level* is greater than the ``sender``'s power
|
||||
level, reject.
|
||||
|
||||
5. If type is ``m.room.power_levels``:
|
||||
#. If the event has a ``state_key`` that starts with an ``@`` and does not match
|
||||
the ``sender``, reject.
|
||||
|
||||
a. If there is no previous ``m.room.power_levels`` event in the room, allow.
|
||||
#. If type is ``m.room.power_levels``:
|
||||
|
||||
b. For each of the keys ``users_default``, ``events_default``,
|
||||
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
|
||||
each entry being changed under the ``events`` or ``users`` keys:
|
||||
a. If ``users`` key in ``content`` is not a dictionary with keys that are
|
||||
valid user IDs with values that are integers (or a string that is an
|
||||
integer), reject.
|
||||
|
||||
i. If the current value is higher than the ``sender``'s current power level,
|
||||
reject.
|
||||
#. If there is no previous ``m.room.power_levels`` event in the room, allow.
|
||||
|
||||
#. If the new value is higher than the ``sender``'s current power level,
|
||||
reject.
|
||||
#. For each of the keys ``users_default``, ``events_default``,
|
||||
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
|
||||
each entry being changed under the ``events`` or ``users`` keys:
|
||||
|
||||
c. For each entry being changed under the ``users`` key, other than the
|
||||
``sender``'s own entry:
|
||||
i. If the current value is higher than the ``sender``'s current power level,
|
||||
reject.
|
||||
|
||||
i. If the current value is equal to the ``sender``'s current power level,
|
||||
reject.
|
||||
#. If the new value is higher than the ``sender``'s current power level,
|
||||
reject.
|
||||
|
||||
d. Otherwise, allow.
|
||||
#. For each entry being changed under the ``users`` key, other than the
|
||||
``sender``'s own entry:
|
||||
|
||||
6. If type is ``m.room.redaction``:
|
||||
i. If the current value is equal to the ``sender``'s current power level,
|
||||
reject.
|
||||
|
||||
a. If the ``sender``'s power level is greater than or equal to the *redact
|
||||
level*, allow.
|
||||
#. Otherwise, allow.
|
||||
|
||||
#. If the ``sender`` of the event being redacted is the same as the
|
||||
``sender`` of the ``m.room.redaction``, allow.
|
||||
#. If type is ``m.room.redaction``:
|
||||
|
||||
#. Otherwise, reject.
|
||||
a. If the ``sender``'s power level is greater than or equal to the *redact
|
||||
level*, allow.
|
||||
|
||||
7. Otherwise, allow.
|
||||
#. If the domain of the ``event_id`` of the event being redacted is the same
|
||||
as the domain of the ``event_id`` of the ``m.room.redaction``, allow.
|
||||
|
||||
#. Otherwise, reject.
|
||||
|
||||
#. Otherwise, allow.
|
||||
|
||||
.. NOTE::
|
||||
|
||||
|
@ -482,9 +545,30 @@ The rules are as follows:
|
|||
the kick *and* ban levels, *and* greater than the target user's power
|
||||
level.
|
||||
|
||||
.. TODO-spec
|
||||
|
||||
I think there is some magic about 3pid invites too.
|
||||
Rejection
|
||||
+++++++++
|
||||
|
||||
If an event is rejected it should neither be relayed to clients nor be included
|
||||
as a prev event in any new events generated by the server. Subsequent events
|
||||
from other servers that reference rejected events should be allowed if they
|
||||
still pass the auth rules. The state used in the checks should be calculated as
|
||||
normal, except not updating with the rejected event where it is a state event.
|
||||
|
||||
If an event in an incoming transaction is rejected, this should not cause the
|
||||
transaction request to be responded to with an error response.
|
||||
|
||||
.. NOTE::
|
||||
|
||||
This means that events may be included in the room DAG even though they
|
||||
should be rejected.
|
||||
|
||||
.. NOTE::
|
||||
|
||||
This is in contrast to redacted events which can still affect the
|
||||
state of the room. For example, a redacted ``join`` event will still
|
||||
result in the user being considered joined.
|
||||
|
||||
|
||||
Retrieving event authorization information
|
||||
++++++++++++++++++++++++++++++++++++++++++
|
||||
|
@ -752,6 +836,10 @@ event to other servers in the room.
|
|||
Third-party invites
|
||||
-------------------
|
||||
|
||||
.. NOTE::
|
||||
More information about third party invites is available in the `Client-Server API`_
|
||||
under the Third Party Invites module.
|
||||
|
||||
When an user wants to invite another user in a room but doesn't know the Matrix
|
||||
ID to invite, they can do so using a third-party identifier (e.g. an e-mail or a
|
||||
phone number).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue