Update 3pid invite spec

This takes into account:
 1) That finding the existing servers of a room is hard
 2) Federation
pull/977/head
Daniel Wagner-Hall 9 years ago
parent d2c56fb7a3
commit af7d2ca9fc

@ -159,26 +159,29 @@ paths:
If the identity server does not know a Matrix user identifier for the If the identity server does not know a Matrix user identifier for the
passed third party identifier, the homeserver will issue an invitation passed third party identifier, the homeserver will issue an invitation
which can be accepted upon providing proof of ownership of the third which can be accepted upon providing proof of ownership of the third
party identifier. This is achieved by requesting a nonce and digest from party identifier. This is achieved by the identity server generating a
the identity server. When a user binds the invited third party token, which it gives to the inviting homeserver. The homeserver will
identifier to a Matrix user ID, the identity server will give the user a add an ``m.room.third_party_invite`` event into the graph for the room,
list of pending invitations, each containing: containing that token.
When a user binds the invited third party identifier to a Matrix user ID,
the identity server will give the user a list of pending invitations,
each containing:
- The room ID to which they were invited - The room ID to which they were invited
- The digest given to the homeserver - The token given to the homeserver
- A secret which, when appended to the nonce, digests to the above digest, - A signature of the token, signed with the identity server's private key
i.e. digest = sha256(nonce + secret)
The digest algorithm to be used is SHA256. - The matrix user ID who invited them to the room
If the identity server did know the Matrix user identifier for the If the identity server did know the Matrix user identifier for the
third party identifier, the home server will append a ``m.room.member`` third party identifier, the home server will append a ``m.room.member``
event to the room. event to the room.
If a digest and nonce are requested from the identity server, the home If a token is requested from the identity server, the home server will
server will append a ``m.room.token_based_invite`` event to the room. append a ``m.room.third_party_invite`` event to the room.
security: security:
- accessToken: [] - accessToken: []
parameters: parameters:
@ -195,13 +198,13 @@ paths:
type: object type: object
example: |- example: |-
{ {
"identity_server": "matrix.org", "id_server": "matrix.org",
"medium": "email", "medium": "email",
"address": "cheeky@monkey.com", "address": "cheeky@monkey.com",
"display_name": "A very cheeky monkey" "display_name": "A very cheeky monkey"
} }
properties: properties:
identity_server: id_server:
type: string type: string
description: The hostname+port of the identity server which should be used for third party identifier lookups. description: The hostname+port of the identity server which should be used for third party identifier lookups.
medium: medium:
@ -213,7 +216,7 @@ paths:
display_name: display_name:
type: string type: string
description: A user-friendly string describing who has been invited. It should not contain the address of the invitee, to avoid leaking mappings between third party identities and matrix user IDs. description: A user-friendly string describing who has been invited. It should not contain the address of the invitee, to avoid leaking mappings between third party identities and matrix user IDs.
required: ["identity_server", "medium", "address", "display_name"] required: ["id_server", "medium", "address", "display_name"]
responses: responses:
200: 200:
description: The user has been invited to join the room. description: The user has been invited to join the room.

@ -3,7 +3,12 @@
"content": { "content": {
"membership": "join", "membership": "join",
"avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto",
"displayname": "Alice Margatroid" "displayname": "Alice Margatroid",
"token": "pc98",
"public_key": "abc123",
"key_validity_url": "https://magic.forest/verifykey",
"signature": "q1w2e3",
"sender": "@zun:zun.soft"
}, },
"state_key": "@alice:localhost", "state_key": "@alice:localhost",
"origin_server_ts": 1431961217939, "origin_server_ts": 1431961217939,

@ -0,0 +1,14 @@
{
"age": 242352,
"content": {
"display_name": "Alice Margatroid",
"key_validity_url": "https://magic.forest/verifykey",
"public_key": "abc123"
},
"state_key": "pc98",
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",
"type": "m.room.third_party_invite",
"room_id": "!Cuyf34gef24t:localhost",
"sender": "@example:localhost"
}

@ -1,7 +1,7 @@
{ {
"type": "object", "type": "object",
"title": "The current membership state of a user in the room.", "title": "The current membership state of a user in the room.",
"description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.", "description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. The token, public_key, key_validity_url, signature, and sender properties either must all or none be set - they are set if the invite was an ``m.room.third_party_invite`` event, and absent if the invite was an ``m.room.member`` event.",
"allOf": [{ "allOf": [{
"$ref": "core-event-schema/state_event.json" "$ref": "core-event-schema/state_event.json"
}], }],
@ -21,6 +21,26 @@
"displayname": { "displayname": {
"type": ["string", "null"], "type": ["string", "null"],
"description": "The display name for this user, if any. This is added by the homeserver." "description": "The display name for this user, if any. This is added by the homeserver."
},
"token": {
"type": "string",
"description": "A token which must be correctly signed, in order to join the room."
},
"key_validity_url": {
"type": "string",
"description": "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'."
},
"public_key": {
"type": "string",
"description": "A base64-encoded ed25519 key with which token must be signed."
},
"signature": {
"type": "string",
"description": "A base64-encoded signature of token with public_key."
},
"sender": {
"type": "string",
"description": "The matrix user ID of the user who send the invite which is being used."
} }
}, },
"required": ["membership"] "required": ["membership"]

@ -0,0 +1,37 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "An invitation to a room issued to a third party identifier, rather than a matrix user ID.",
"description": "Acts as an ``m.room.member`` invite event, where there isn't a target user_id to invite. This event contains a token and a public key whose private key must be used to sign the token. Any user who can present that signature may use this invitation to join the target room.",
"allOf": [{
"$ref": "core#/definitions/state_event"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"display_name": {
"type": "string",
"description": "A user-readable string which represents the user who has been invited. This should not contain the user's third party ID, as otherwise when the invite is accepted it would leak the association between the matrix ID and the third party ID."
},
"key_validity_url": {
"type": "string",
"description": "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'."
},
"public_key": {
"type": "string",
"description": "A base64-encoded ed25519 key with which token must be signed."
}
},
"required": ["display_name", "key_validity_url", "public_key"]
},
"state_key": {
"type": "string",
"description": "The token, of which a signature must be produced in order to join the room."
},
"type": {
"type": "string",
"enum": ["m.room.third_party_invite"]
}
}
}

@ -0,0 +1,39 @@
Third party invites
===================
.. _module:third_party_invites:
This module adds in support for inviting new members to a room where their
Matrix user ID is not known, instead addressing them by a third party identifier
such as an email address.
Events
------
{{m_room_third_party_invite_event}}
Client behaviour
----------------
A client asks a server to invite a user by their third party identifier.
See the documentation for /invite for more information.
Server behaviour
----------------
All homeservers MUST verify that sign(``token``, ``public_key``) = ``signature``.
If a client of the current homeserver is joining by an
``m.room.third_party_invite``, that homesever MUST validate that the public
key used for signing is still valid, by checking ``key_validity_url``.
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
room MUST validate that the public key used for signing is still valid, by
checking ``key_validity_url``.
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.

@ -22,6 +22,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/content_repo.rst - modules/content_repo.rst
- modules/end_to_end_encryption.rst - modules/end_to_end_encryption.rst
- modules/history_visibility.rst - modules/history_visibility.rst
- modules/third_party_invites.rst
- modules/push_overview.rst - modules/push_overview.rst
# relative depth # relative depth
- { 1: [modules/push_cs_api.rst , modules/push_push_gw_api.rst] } - { 1: [modules/push_cs_api.rst , modules/push_push_gw_api.rst] }

Loading…
Cancel
Save