Merge branch 'master' into travis/spec/is-unbind

pull/2282/head
Travis Ralston 5 years ago
commit 30a9de7e02

@ -112,7 +112,10 @@ paths:
description: The identity server to use.
id_access_token:
type: string
description: An access token previously registered with the identity server.
description: |-
An access token previously registered with the identity server. Servers
can treat this as optional to distinguish between r0.5-compatible clients
and this specification version.
sid:
type: string
description: The session identifier given by the identity server.

@ -141,7 +141,10 @@ paths:
description: The hostname+port of the identity server which should be used for third party identifier lookups.
id_access_token:
type: string
description: An access token previously registered with the identity server.
description: |-
An access token previously registered with the identity server. Servers
can treat this as optional to distinguish between r0.5-compatible clients
and this specification version.
medium:
type: string
# TODO: Link to Identity Service spec when it eixsts

@ -25,5 +25,8 @@ allOf:
example: "id.example.com"
id_access_token:
type: string
description: An access token previously registered with the identity server.
description: |-
An access token previously registered with the identity server. Servers
can treat this as optional to distinguish between r0.5-compatible clients
and this specification version.
required: ["id_server", "id_access_token"]

@ -25,5 +25,8 @@ allOf:
example: "id.example.com"
id_access_token:
type: string
description: An access token previously registered with the identity server.
description: |-
An access token previously registered with the identity server. Servers
can treat this as optional to distinguish between r0.5-compatible clients
and this specification version.
required: ["id_server", "id_access_token"]

@ -102,7 +102,10 @@ paths:
description: The hostname+port of the identity server which should be used for third party identifier lookups.
id_access_token:
type: string
description: An access token previously registered with the identity server.
description: |-
An access token previously registered with the identity server. Servers
can treat this as optional to distinguish between r0.5-compatible clients
and this specification version.
medium:
type: string
# TODO: Link to Identity Service spec when it eixsts

@ -165,7 +165,7 @@ paths:
description: The token generated by the ``requestToken`` call and emailed to the user.
x-example: atoken
responses:
"200":
200:
description: Email address is validated.
"3xx":
description: |-

@ -167,7 +167,7 @@ paths:
description: The token generated by the ``requestToken`` call and sent to the user.
x-example: atoken
responses:
"200":
200:
description: Phone number is validated.
"3xx":
description: |-

@ -95,6 +95,17 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/3pid/bind":
post:
summary: Publish an association between a session and a Matrix user ID.
@ -208,6 +219,17 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/3pid/unbind":
post:
summary: Remove an association between a session and a Matrix user ID.
@ -294,6 +316,9 @@ paths:
This may also be returned if the identity server does not support
the chosen authentication method (such as blocking homeservers from
unbinding identifiers).
Another common error code is ``M_TERMS_NOT_SIGNED`` where the user
needs to `agree to more terms`_ in order to continue.
examples:
application/json: {
"errcode": "M_FORBIDDEN",

@ -80,6 +80,17 @@ paths:
type: string
description: The user ID which registered the token.
required: ['user_id']
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/account/logout":
post:
summary: Logs out an access token, rendering it unusable.
@ -107,3 +118,14 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -74,6 +74,17 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/validate/email/submitToken":
post:
summary: Validate ownership of an email address.
@ -135,6 +146,17 @@ paths:
type: boolean
description: Whether the validation was successful or not.
required: ['success']
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
get:
summary: Validate ownership of an email address.
description: |-
@ -171,7 +193,7 @@ paths:
description: The token generated by the ``requestToken`` call and emailed to the user.
x-example: atoken
responses:
"200":
200:
description: Email address is validated.
"3xx":
description: |-
@ -181,3 +203,14 @@ paths:
"4xx":
description:
Validation failed.
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -99,3 +99,14 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -76,6 +76,17 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/validate/msisdn/submitToken":
post:
summary: Validate ownership of a phone number.
@ -137,6 +148,17 @@ paths:
type: boolean
description: Whether the validation was successful or not.
required: ['success']
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
get:
summary: Validate ownership of a phone number.
description: |-
@ -173,7 +195,7 @@ paths:
description: The token generated by the ``requestToken`` call and sent to the user.
x-example: atoken
responses:
"200":
200:
description: Phone number is validated.
"3xx":
description: |-
@ -183,3 +205,14 @@ paths:
"4xx":
description:
Validation failed.
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -163,3 +163,14 @@ paths:
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |
The user must do something in order to use this endpoint. One example
is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_.
examples:
application/json: {
"errcode": "M_TERMS_NOT_SIGNED",
"error": "Please accept our updated terms of service before continuing"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -0,0 +1,149 @@
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Terms of Service API"
version: "2.0.0"
host: localhost:8090
schemes:
- https
basePath: /_matrix/identity/v2
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/terms":
get:
summary: Gets the terms of service offered by the server.
description: |-
Gets all the terms of service offered by the server. The client is expected
to filter through the terms to determine which terms need acceptance from the
user. Note that this endpoint does not require authentication.
operationId: getTerms
parameters: []
responses:
200:
description: |-
The terms of service offered by the server.
examples:
application/json: {
"policies": {
"terms_of_service": {
"version": "2.0",
"en": {
"name": "Terms of Service",
"url": "https://example.org/somewhere/terms-2.0-en.html"
},
"fr": {
"name": "Conditions d'utilisation",
"url": "https://example.org/somewhere/terms-2.0-fr.html"
}
},
"privacy_policy": {
"version": "1.2",
"en": {
"name": "Privacy Policy",
"url": "https://example.org/somewhere/privacy-1.2-en.html"
},
"fr": {
"name": "Politique de confidentialité",
"url": "https://example.org/somewhere/privacy-1.2-fr.html"
}
}
}
}
schema:
type: object
properties:
policies:
type: object
title: Policy Map
description: |-
The policies the server offers. Mapped from arbitrary ID (unused in
this version of the specification) to a Policy Object.
additionalProperties:
type: object
title: Policy Object
description: |-
The policy. Includes a map of language (ISO 639-2) to language-specific
policy information.
properties:
version:
type: string
description: |-
The version for the policy. There are no requirements on what this
might be and could be "alpha", semantically versioned, or arbitrary.
required: ['version']
# TODO: TravisR - Make this render
additionalProperties:
type: object
title: Internationalised Policy
description: |-
The policy information for the specified language.
properties:
name:
type: string
description: The translated name of the policy.
url:
type: string
description: |-
The URL, which should include the policy ID, version, and language
in it, to be presented to the user as the policy. URLs should have
all three criteria to avoid conflicts when the policy is updated
in the future: for example, if this was "https://example.org/terms.html"
then the server would be unable to update it because the client would
have already added that URL to the ``m.accepted_terms`` collection.
required: ['name', 'url']
required: ['policies']
post:
summary: Indicates acceptance of terms to the server.
description: |-
Called by a client to indicate that the user has accepted/agreed to the included
set of URLs. Servers MUST NOT assume that the client will be sending all previously
accepted URLs and should therefore append the provided URLs to what the server
already knows has been accepted.
Clients MUST provide the URL of the policy in the language that was presented
to the user. Servers SHOULD consider acceptance of any one language's URL as
acceptance for all other languages of that policy.
The server should avoid returning ``M_TERMS_NOT_SIGNED`` because the client
may not be accepting all terms at once.
operationId: agreeToTerms
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
properties:
user_accepts:
type: array
items:
type: string
description: The URLs the user is accepting in this request.
example: "https://example.org/somewhere/terms-2.0-en.html"
required: ['user_accepts']
responses:
200:
description: |-
The server has considered the user as having accepted the provided URLs.
examples:
application/json: {}
schema:
type: object

@ -0,0 +1 @@
Add ``m.identity_server`` account data for tracking the user's preferred identity server.

@ -0,0 +1 @@
Add endpoints for accepting and handling terms of service.

@ -0,0 +1,10 @@
{
"$ref": "core/event.json",
"type": "m.accepted_terms",
"content": {
"accepted": [
"https://example.org/somewhere/terms-1.2-en.html",
"https://example.org/somewhere/privacy-1.2-en.html"
]
}
}

@ -0,0 +1,7 @@
{
"$ref": "core/event.json",
"type": "m.identity_server",
"content": {
"base_url": "https://example.org"
}
}

@ -0,0 +1,23 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
A list of terms URLs the user has previously accepted. Clients SHOULD use this
to avoid presenting the user with terms they have already agreed to.
properties:
content:
type: object
properties:
accepted:
type: array
items:
type: string
description: |-
The list of URLs the user has previously accepted. Should be appended to
when the user agrees to new terms.
type:
enum:
- m.accepted_terms
type: string
title: Accepted Terms of Service URLs
type: object

@ -0,0 +1,23 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
Persists the user's preferred identity server, or preference to not use
an identity server at all, in the user's account data.
properties:
content:
type: object
properties:
base_url:
type: string
description: |-
The URL of the identity server the user prefers to use, or ``null``
if the user does not want to use an identity server. This value is
similar in structure to the ``base_url`` for identity servers in the
``.well-known/matrix/client`` schema.
type:
enum:
- m.identity_server
type: string
title: Identity Server Preference
type: object

@ -586,7 +586,21 @@ class MatrixUnits(Units):
raise Exception("Error handling parameter %s" % param_name, e)
# endfor[param]
good_response = None
for code in sorted(endpoint_swagger.get("responses", {}).keys()):
endpoint_status_codes = endpoint_swagger.get("responses", {}).keys()
# Check to see if any of the status codes are strings ("4xx") and if
# so convert everything to a string to avoid comparing ints and strings.
has_string_status = False
for code in endpoint_status_codes:
if isinstance(code, str):
has_string_status = True
break
if has_string_status:
endpoint_status_codes = [str(i) for i in endpoint_status_codes]
for code in sorted(endpoint_status_codes):
# Convert numeric responses to ints, assuming they got converted
# above.
if isinstance(code, str) and code.isdigit():
code = int(code)
res = endpoint_swagger["responses"][code]
if not good_response and code == 200:
good_response = res

@ -1141,6 +1141,41 @@ Current account information
{{whoami_cs_http_api}}
Notes on identity servers
+++++++++++++++++++++++++
Identity servers in Matrix store bindings (relationships) between a user's third
party identifier, typically email or phone number, and their user ID. Once a user
has chosen an identity server, that identity server should be used by all clients.
Clients can see which identity server the user has chosen through the ``m.identity_server``
account data event, as described below. Clients SHOULD refrain from making requests
to any identity server until the presence of ``m.identity_server`` is confirmed as
(not) present. If present, the client SHOULD check for the presence of the ``base_url``
property in the event's content. If the ``base_url`` is present, the client SHOULD
use the identity server in that property as the identity server for the user. If the
``base_url`` is missing, or the account data event is not present, the client SHOULD
use whichever default value it normally would for an identity server, if applicable.
Clients SHOULD NOT update the account data with the default identity server when the
user is missing an identity server in their account data.
Clients SHOULD listen for changes to the ``m.identity_server`` account data event
and update the identity server they are contacting as a result.
If the client offers a way to set the identity server to use, it MUST update the
value of ``m.identity_server`` accordingly. A ``base_url`` of ``null`` MUST be
treated as though the user does not want to use an identity server, disabling all
related functionality as a result.
Clients SHOULD refrain from populating the account data as a migration step for users
who are lacking the account data, unless the user sets the identity server within
the client to a value. For example, a user which has no ``m.identity_server`` account
data event should not end up with the client's default identity server in their
account data, unless the user first visits their account settings to set the identity
server.
{{m_identity_server_event}}
Capabilities negotiation
------------------------

@ -198,6 +198,33 @@ status of 401 and the error code ``M_UNAUTHORIZED``.
{{v2_auth_is_http_api}}
.. _`agree to more terms`:
Terms of service
----------------
Identity Servers are encouraged to have terms of service (or similar policies) to
ensure that users have agreed to their data being processed by the server. To facilitate
this, an identity server can respond to almost any authenticated API endpoint with a
HTTP 403 and the error code ``M_TERMS_NOT_SIGNED``. The error code is used to indicate
that the user must accept new terms of service before being able to continue.
All endpoints which support authentication can return the ``M_TERMS_NOT_SIGNED`` error.
When clients receive the error, they are expected to make a call to ``GET /terms`` to
find out what terms the server offers. The client compares this to the ``m.accepted_terms``
account data for the user (described later) and presents the user with option to accept
the still-missing terms of service. After the user has made their selection, if applicable,
the client sends a request to ``POST /terms`` to indicate the user's acceptance. The
server cannot expect that the client will send acceptance for all pending terms, and the
client should not expect that the server will not respond with another ``M_TERMS_NOT_SIGNED``
on their next request. The terms the user has just accepted are appended to ``m.accepted_terms``.
{{m_accepted_terms_event}}
{{v2_terms_is_http_api}}
Status check
------------

@ -106,7 +106,7 @@ The principles that Matrix attempts to follow are:
- Empowering the end-user
+ The user should be able to choose the server and clients they use
+ The user should be control how private their communication is
+ The user should be able to control how private their communication is
+ The user should know precisely where their data is stored
- Fully decentralised - no single points of control over conversations or the

Loading…
Cancel
Save