Merge branch 'master' into anoa/hs_3pid_tokens

* master:
  Update example
  Fix 404s in links from room v1 spec
  Provide a more complete example of a "minimally-sized event"
  Revert signature change for redactable event test
  Clarify how many PDUs are in a given transaction object
  Clarify that the server shouldn't process retries for UIA
  Clarify when authorization and rate-limiting are not applicable
  Skip over partial event definitions in examples
  Rename example to invite_room_state
  Shorten references to StrippedState in s2s spec
  Fix examples of StrippedState in s2s spec
  Clarify exactly what StrippedState is
  Clarify that UIA stages cannot be attempted twice
  Fix test vectors with invalid JSON and signature
  Spec 3PID unbind API
  Spec MSISDN UIA support
anoa/hs_3pid_tokens
Andrew Morgan 5 years ago
commit 62910a28cc

@ -182,6 +182,14 @@ paths:
schema:
type: object
properties:
id_server:
type: string
description: |-
The identity server to unbind from. If not provided, the homeserver
MUST use the ``id_server`` the identifier was added through. If the
homeserver does not know the original ``id_server``, it MUST return
a ``id_server_unbind_result`` of ``no-support``.
example: "example.org"
medium:
type: string
description: The medium of the third party identifier being removed.
@ -199,7 +207,24 @@ paths:
user.
schema:
type: object
properties: {}
properties:
id_server_unbind_result:
type: string
enum:
# XXX: I don't know why, but the order matters here so that "no-support"
# doesn't become "no- support" by the renderer.
- "no-support"
- "success"
description: |-
An indicator as to whether or not the homeserver was able to unbind
the 3PID from the identity server. ``success`` indicates that the
indentity server has unbound the identifier whereas ``no-support``
indicates that the identity server refuses to support the request
or the homeserver was not able to determine an identity server to
unbind from.
example: "success"
required:
- id_server_unbind_result
tags:
- User data
"/account/3pid/email/requestToken":

@ -94,6 +94,12 @@ paths:
If true, the server binds the email used for authentication to
the Matrix ID with the identity server.
example: false
bind_msisdn:
type: boolean
description: |-
If true, the server binds the phone number used for authentication
to the Matrix ID with the identity server.
example: false
username:
type: string
description: |-
@ -622,13 +628,39 @@ paths:
description: |-
Additional authentication information for the user-interactive authentication API.
"$ref": "definitions/auth_data.yaml"
id_server:
type: string
description: |-
The identity server to unbind all of the user's 3PIDs from.
If not provided, the homeserver MUST use the ``id_server``
that was originally use to bind each identifier. If the
homeserver does not know which ``id_server`` that was,
it must return an ``id_server_unbind_result`` of
``no-support``.
example: "example.org"
responses:
200:
description: The account has been deactivated.
examples:
application/json: {}
schema:
type: object
properties:
id_server_unbind_result:
type: string
enum:
- "success"
- "no-support"
description: |-
An indicator as to whether or not the homeserver was able to unbind
the user's 3PIDs from the identity server(s). ``success`` indicates
that all identifiers have been unbound from the identity server while
``no-support`` indicates that one or more identifiers failed to unbind
due to the identity server refusing the request or the homeserver
being unable to determine an identity server to unbind from. This
must be ``success`` if the homeserver has no identifiers to unbind
for the user.
example: "success"
required:
- id_server_unbind_result
401:
description: |-
The homeserver requires additional authentication information.

@ -212,30 +212,7 @@ paths:
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
$ref: "definitions/event-schemas/schema/stripped_state.yaml"
type: array
leave:
title: Left rooms

@ -201,3 +201,86 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/3pid/unbind":
post:
summary: Remove an association between a session and a Matrix user ID.
description: |-
Remove an association between a session and a Matrix user ID.
Future calls to ``/lookup`` for any of the session's 3pids will not
return the removed association.
The identity server should authenticate the request in one of two
ways:
1. The request is signed by the homeserver which controls the ``user_id``.
2. The request includes the ``sid`` and ``client_secret`` parameters,
as per ``/3pid/bind``, which proves ownership of the 3PID.
If this endpoint returns a JSON Matrix error, that error should be passed
through to the client requesting an unbind through a homeserver, if the
homeserver is acting on behalf of a client.
operationId: unbind
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:example.org",
"threepid": {
"medium": "email",
"address": "monkeys_have_ears@example.org"
}
}
properties:
sid:
type: string
description: The Session ID generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret passed to the ``requestToken`` call.
mxid:
type: string
description: The Matrix user ID to remove from the 3pids.
threepid:
type: object
title: 3PID
description: |-
The 3PID to remove. Must match the 3PID used to generate the session
if using ``sid`` and ``client_secret`` to authenticate this request.
properties:
medium:
type: string
description: |-
A medium from the `3PID Types`_ Appendix, matching the medium
of the identifier to unbind.
address:
type: string
description: The 3PID address to remove.
required: ['medium', 'address']
required: ["threepid", "mxid"]
responses:
200:
description: The association was successfully removed.
examples:
application/json: {}
schema:
type: object
400:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.
404:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.
501:
description: |-
If the response body is not a JSON Matrix error, the identity server
does not support unbinds. If a JSON Matrix error is in the response
body, the requesting party should respect the error.

@ -64,7 +64,7 @@ paths:
A transaction containing the PDUs that preceded the given event(s), including the given
event(s), up to the given limit.
schema:
$ref: "definitions/transaction.yaml"
$ref: "definitions/unlimited_pdu_transaction.yaml"
"/get_missing_events/{roomId}":
post:
summary: Retrieves events that the sender is missing

@ -0,0 +1,32 @@
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
allOf:
- $ref: "transaction.yaml"
properties:
pdus:
type: array
description: |-
A single PDU. Note that events have a different format depending on the room
version - check the `room version specification`_ for precise event formats.
items:
type: object
title: PDU
description: |-
The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending
on the room version - check the `room version specification`_ for precise event formats.
properties: []
example:
$ref: "../examples/minimal_pdu.json"
required: ['origin', 'origin_server_ts', 'pdus']

@ -0,0 +1,33 @@
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
allOf:
- $ref: "transaction.yaml"
properties:
pdus:
type: array
description: |-
List of persistent updates to rooms. Note that events have a different format
depending on the room version - check the `room version specification`_ for
precise event formats.
items:
type: object
title: PDU
description: |-
The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending
on the room version - check the `room version specification`_ for precise event formats.
properties: []
example:
$ref: "../examples/minimal_pdu.json"
required: ['origin', 'origin_server_ts', 'pdus']

@ -156,4 +156,4 @@ paths:
200:
description: A transaction containing a single PDU which is the event requested.
schema:
$ref: "definitions/transaction.yaml"
$ref: "definitions/single_pdu_transaction.yaml"

@ -82,35 +82,9 @@ paths:
identify the room. The recommended events to include are the join rules,
canonical alias, avatar, and name of the room.
items:
type: object
title: Invite Room State Event
properties:
type:
type: string
description: The type of event.
example: "m.room.join_rules"
state_key:
type: string
description: The state key for the event. May be an empty string.
example: ""
content:
type: object
description: The content for the event.
sender:
type: string
description: The sender of the event.
example: "@someone:matrix.org"
required: ['type', 'state_key', 'content', 'sender']
example: [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
}
]
$ref: "../../event-schemas/schema/stripped_state.yaml"
example:
$ref: "../../event-schemas/examples/invite_room_state.json"
example: {
"$ref": "examples/minimal_pdu.json",
"type": "m.room.member",
@ -118,26 +92,6 @@ paths:
"origin": "example.org",
"origin_server_ts": 1549041175876,
"sender": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
},
"content": {
"membership": "invite"
},
@ -180,24 +134,9 @@ paths:
"origin_server_ts": 1549041175876,
"sender": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
"invite_room_state": {
"$ref": "../../../event-schemas/examples/invite_room_state.json"
}
},
"content": {
"membership": "invite"

@ -83,35 +83,9 @@ paths:
identify the room. The recommended events to include are the join rules,
canonical alias, avatar, and name of the room.
items:
type: object
title: Invite Room State Event
properties:
type:
type: string
description: The type of event.
example: "m.room.join_rules"
state_key:
type: string
description: The state key for the event. May be an empty string.
example: ""
content:
type: object
description: The content for the event.
sender:
type: string
description: The sender of the event.
example: "@someone:matrix.org"
required: ['type', 'state_key', 'content', 'sender']
example: [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
}
]
$ref: "../../event-schemas/schema/stripped_state.yaml"
example:
$ref: "../../event-schemas/examples/invite_room_state.json"
required: ['room_version', 'event']
example: {
"room_version": "2",
@ -130,25 +104,7 @@ paths:
"ed25519:key_version": "SomeSignatureHere"
},
}
},
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
}
}
responses:
200:
@ -174,24 +130,9 @@ paths:
"origin_server_ts": 1549041175876,
"sender": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
"invite_room_state": {
"$ref": "../../../event-schemas/examples/invite_room_state.json"
}
},
"content": {
"membership": "invite"

@ -0,0 +1 @@
Add MSISDN (phone number) support to User-Interactive Authentication.

@ -0,0 +1 @@
Add ``id_server`` to ``/deactivate`` and ``/3pid/delete`` endpoints to unbind from a specific identity server.

@ -0,0 +1 @@
Clarify that User-Interactive Authentication stages cannot be attempted more than once.

@ -0,0 +1 @@
Clarify exactly what invite_room_state consists of.

@ -0,0 +1 @@
Clarify when authorization and rate-limiting are not applicable.

@ -0,0 +1 @@
Add ``/3pid/unbind`` for removing 3PIDs.

@ -0,0 +1 @@
Clarify exactly what invite_room_state consists of.

@ -0,0 +1 @@
Clarify how many PDUs are contained in transaction objects for various endpoints.

@ -106,6 +106,9 @@ def check_example_dir(exampledir, schemadir):
if filename.startswith("."):
# Skip over any vim .swp files.
continue
if filename.endswith(".json"):
# Skip over any explicit examples (partial event definitions)
continue
cwd = os.path.basename(os.path.dirname(os.path.join(root, filename)))
if cwd == "core":
# Skip checking the underlying definitions

@ -0,0 +1,18 @@
[
{
"type": "m.room.name",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"name": "Example Room"
}
},
{
"type": "m.room.join_rules",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
]

@ -7,21 +7,8 @@
},
"unsigned": {
"age": 1234,
"invite_room_state": [
{
"type": "m.room.name",
"state_key": "",
"content": {
"name": "Forest of Magic"
}
},
{
"type": "m.room.join_rules",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
]
"invite_room_state": {
"$ref": "invite_room_state.json"
}
}
}

@ -104,24 +104,7 @@ properties:
invite_room_state:
description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.'
items:
description: 'A stripped down state event, with only the ``type``, ``state_key`` 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
required:
- type
- state_key
- content
title: StrippedState
type: object
$ref: "stripped_state.yaml"
type: array
required:
- membership

@ -0,0 +1,44 @@
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# 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, and the example, are in the `event-schemas` directory because
# the CS API uses a symlink. In order for the `m.room.member` event to
# reference this, we'd need to use relative pathing. The symlink makes this
# difficult because the schema would be at two different locations, with
# different relative pathing.
title: StrippedState
type: object
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

@ -27,7 +27,9 @@ known by the homeserver).
The 200 response is a JSON object with an `id_server_unbind_result` field whose
value is either `success` or `no-support`, where the latter indicates that the
identity server (IS) does not support unbinding 3PIDs directly. If the identity
server returns an error then that should be returned to the client.
server returns an error then that should be returned to the client. If the homeserver
is unable to determine an `id_server` to use, it should return `no-support` for
the `id_server_unbind_result`.
Example:

@ -10,13 +10,13 @@
{{endpoint.desc}}
{{":Rate-limited: Yes." if endpoint.rate_limited else "" }}
{{":Requires auth: Yes." if endpoint.requires_auth else "" }}
{{":Rate-limited: Yes." if endpoint.rate_limited else ":Rate-limited: No." }}
{{":Requires auth: Yes." if endpoint.requires_auth else ":Requires auth: No." }}
.. class:: httpheaders
Request format:
{% if (endpoint.req_param_by_loc | length) %}
{{ tables.split_paramtable(endpoint.req_param_by_loc) }}
{% if (endpoint.req_body_tables) %}
@ -33,7 +33,7 @@
{% if endpoint.res_headers is not none -%}
.. class:: httpheaders
Response headers:
{{ tables.paramtable(endpoint.res_headers.rows) }}
@ -42,7 +42,7 @@
{% if endpoint.res_tables|length > 0 -%}
.. class:: httpheaders
Response format:
{% for table in endpoint.res_tables -%}
@ -54,7 +54,7 @@
{% endif -%}
.. class:: httpheaders
Example request:
.. code:: http
@ -64,7 +64,7 @@
{% if endpoint.responses|length > 0 -%}
.. class:: httpheaders
Response{{"s" if endpoint.responses|length > 1 else "" }}:
{% endif -%}
@ -78,7 +78,7 @@
{% if res["example"] -%}
.. class:: httpheaders
Example
.. code:: json

@ -91,11 +91,17 @@ Given the following minimally-sized event:
.. code:: json
{
"event_id": "$0:domain",
"room_id": "!x:domain",
"sender": "@a:domain",
"origin": "domain",
"origin_server_ts": 1000000,
"signatures": {},
"hashes": {},
"type": "X",
"content": {},
"prev_events": [],
"auth_events": [],
"depth": 3,
"unsigned": {
"age_ts": 1000000
}
@ -106,15 +112,20 @@ The event signing algorithm should emit the following signed event:
.. code:: json
{
"event_id": "$0:domain",
"auth_events": [],
"content": {},
"depth": 3,
"hashes": {
"sha256": "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI"
"sha256": "5jM4wQpv6lnBo7CLIghJuHdW+s2CMBJPUOGOC89ncos"
},
"origin": "domain",
"origin_server_ts": 1000000,
"prev_events": [],
"room_id": "!x:domain",
"sender": "@a:domain",
"signatures": {
"domain": {
"ed25519:1": "2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA"
"ed25519:1": "KxwGjPSDEtvnFgU00fwFz+l6d2pJM6XBIaMEn81SXPTRl16AqLAYqfIReFGZlHi5KLjAWbOoMszkwsQma+lYAg"
}
},
"type": "X",
@ -129,7 +140,7 @@ Given the following event containing redactable content:
{
"content": {
"body": "Here is the message content",
"body": "Here is the message content"
},
"event_id": "$0:domain",
"origin": "domain",
@ -149,7 +160,7 @@ The event signing algorithm should emit the following signed event:
{
"content": {
"body": "Here is the message content",
"body": "Here is the message content"
},
"event_id": "$0:domain",
"hashes": {

@ -453,11 +453,10 @@ params
presented, that type may be present as a key in this dictionary. For example,
the public part of an OAuth client ID could be given here.
session
This is a session identifier that the client must pass back to the home
server, if one is provided, in subsequent attempts to authenticate in the same
API call.
This is a session identifier that the client must pass back to the homeserver,
if one is provided, in subsequent attempts to authenticate in the same API call.
The client then chooses a flow and attempts to complete one of the stages. It
The client then chooses a flow and attempts to complete the first stage. It
does this by resubmitting the same request with the addition of an ``auth``
key in the object that it submits. This dictionary contains a ``type`` key whose
value is the name of the authentication type that the client is attempting to complete.
@ -558,7 +557,10 @@ message in the standard format. For example:
}
If the client has completed all stages of a flow, the homeserver performs the
API call and returns the result as normal.
API call and returns the result as normal. Completed stages cannot be retried
by clients, therefore servers must return either a 401 response with the completed
stages, or the result of the API call if all stages were completed when a client
retries a stage.
Some authentication types may be completed by means other than through the
Matrix client, for example, an email confirmation may be completed when the user
@ -623,6 +625,7 @@ This specification defines the following auth types:
- ``m.login.recaptcha``
- ``m.login.oauth2``
- ``m.login.email.identity``
- ``m.login.msisdn``
- ``m.login.token``
- ``m.login.dummy``
@ -787,6 +790,34 @@ To use this authentication type, clients should submit an auth dict as follows:
"session": "<session ID>"
}
Phone number/MSISDN-based (identity server)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
:Type:
``m.login.msisdn``
:Description:
Authentication is supported by authorising a phone number with an identity
server.
Prior to submitting this, the client should authenticate with an identity
server. After authenticating, the session information should be submitted to
the homeserver.
To use this authentication type, clients should submit an auth dict as follows:
.. code:: json
{
"type": "m.login.msisdn",
"threepidCreds": [
{
"sid": "<identity server session id>",
"client_secret": "<identity server client secret>",
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>"
}
],
"session": "<session ID>"
}
Dummy Auth
<<<<<<<<<<
:Type:

@ -293,5 +293,5 @@ Events in version 1 rooms have the following structure:
{{definition_ss_pdu}}
.. _`auth events selection`: ../../server_server/r0.1.1.html#auth-events-selection
.. _`Signing Events`: ../../server_server/r0.1.1.html#signing-events
.. _`auth events selection`: ../server_server/r0.1.1.html#auth-events-selection
.. _`Signing Events`: ../server_server/r0.1.1.html#signing-events

Loading…
Cancel
Save