From 81a60a25ccd78b413d5fc0a25e6267dcf05db23d Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 28 Oct 2015 14:46:10 +0000 Subject: [PATCH 1/7] Update 3pid spec based on new implementation --- event-schemas/examples/v1/m.room.member | 15 ---------- event-schemas/schema/v1/m.room.member | 20 ++----------- specification/modules/third_party_invites.rst | 29 ++++++++++--------- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/event-schemas/examples/v1/m.room.member b/event-schemas/examples/v1/m.room.member index 2c174e8a6..d7605dcd1 100644 --- a/event-schemas/examples/v1/m.room.member +++ b/event-schemas/examples/v1/m.room.member @@ -4,21 +4,6 @@ "membership": "join", "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", "displayname": "Alice Margatroid", - "third_party_invite": { - "token": "pc98", - "public_key": "abc123", - "key_validity_url": "https://magic.forest/verifykey", - "signed": { - "mxid": "@alice:localhost", - "token": "pc98", - "signatures": { - "magic.forest": { - "ed25519:0": "poi098" - } - } - }, - "sender": "@zun:zun.soft" - } }, "invite_room_state": [ { diff --git a/event-schemas/schema/v1/m.room.member b/event-schemas/schema/v1/m.room.member index 45f2ad705..1d09a0dd8 100644 --- a/event-schemas/schema/v1/m.room.member +++ b/event-schemas/schema/v1/m.room.member @@ -1,7 +1,7 @@ { "type": "object", "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//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. \n\nThe ``third_party_invite`` property will be set if the invite was an ``m.room.third_party_invite`` event, and absent if the invite was an ``m.room.member`` event.\n\nThis event also includes an ``invite_room_state`` key **outside the** ``content`` **key**. This contains an array of ``StrippedState`` Events. These events provide information on a few select state events such as the room name.", + "description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms//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. \n\nThe ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.\n\nThis event also includes an ``invite_room_state`` key **outside the** ``content`` **key**. This contains an array of ``StrippedState`` Events. These events provide information on a few select state events such as the room name.", "allOf": [{ "$ref": "core-event-schema/state_event.json" }], @@ -26,18 +26,6 @@ "type": "object", "title": "Invite", "properties": { - "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." - }, "signed": { "type": "object", "title": "signed", @@ -57,13 +45,9 @@ } }, "required": ["mxid", "signatures", "token"] - }, - "sender": { - "type": "string", - "description": "The matrix user ID of the user who send the invite which is being used." } }, - "required": ["token", "key_validity_url", "public_key", "sender", "signed"] + "required": ["signed"] } }, "required": ["membership"] diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index 85538c314..140bab86d 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -15,13 +15,15 @@ The homeserver asks the identity server whether a Matrix user ID is known for that identifier. If it is, an invite is simply issued for that user. If it is not, the homeserver asks the identity server to record the details of -the invitation, and to notify the client of this pending invitation if it gets +the invitation, and to notify the invitee's homeserver of this pending invitation if it gets a binding for this identifier in the future. The identity server returns a token -and public key to the homeserver. +and public key to the inviting homeserver. -If a client then tries to join the room in the future, it will be allowed to if -it presents both the token, and a signature of that token from the identity -server which can be verified with the public key. +When the invitee's homeserver receives the notification of the binding, it +should insert an ``m.room.member`` event into the room's graph for that user, +with ``content.membership`` = ``invite``, as well as a +``content.third_party_invite`` property whichi contains proof that the invitee +does indeed own that third party identifier. Events ------ @@ -39,9 +41,10 @@ Server behaviour All homeservers MUST verify the signature in the event's ``content.third_party_invite.signed`` object. -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``. It does +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 @@ -91,16 +94,16 @@ For example: 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, they are told about the - invite, and ask their homeserver, H3, to join 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. - H3 validates the signature in the event's - ``content.third_party_invite.signed`` object. + 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 join event to the room, and H3 + Having validated these things, H1 writes the invite event to the room, and H3 begins participating in the room. H2 *must* accept this event. The reason that no other homeserver may reject the event based on checking From b92a0f2b4de47093b229e9f0521aec2bb008435c Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 28 Oct 2015 14:49:22 +0000 Subject: [PATCH 2/7] Remove extra trailing comma --- event-schemas/examples/v1/m.room.member | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/examples/v1/m.room.member b/event-schemas/examples/v1/m.room.member index d7605dcd1..e2ca56685 100644 --- a/event-schemas/examples/v1/m.room.member +++ b/event-schemas/examples/v1/m.room.member @@ -3,7 +3,7 @@ "content": { "membership": "join", "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", - "displayname": "Alice Margatroid", + "displayname": "Alice Margatroid" }, "invite_room_state": [ { From 176f919fc89f5d01669aea17003aef8da903ce4e Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 28 Oct 2015 15:00:53 +0000 Subject: [PATCH 3/7] Show multiple examples where present --- .../v1/m.room.member#third_party_invite | 41 +++++++++++++++++++ templating/matrix_templates/sections.py | 2 +- .../matrix_templates/templates/events.tmpl | 4 +- templating/matrix_templates/units.py | 11 +++-- 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 event-schemas/examples/v1/m.room.member#third_party_invite diff --git a/event-schemas/examples/v1/m.room.member#third_party_invite b/event-schemas/examples/v1/m.room.member#third_party_invite new file mode 100644 index 000000000..4ef571ec5 --- /dev/null +++ b/event-schemas/examples/v1/m.room.member#third_party_invite @@ -0,0 +1,41 @@ +{ + "age": 242352, + "content": { + "membership": "join", + "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", + "displayname": "Alice Margatroid", + "third_party_invite": { + "signed": { + "mxid": "@alice:localhost", + "signatures": { + "magic.forest": { + "ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" + } + }, + "token": "abc123" + } + } + }, + "invite_room_state": [ + { + "type": "m.room.name", + "state_key": "", + "content": { + "name": "Forest of Magic" + } + }, + { + "type": "m.room.join_rules", + "state_key": "", + "content": { + "join_rules": "invite" + } + } + ], + "state_key": "@alice:localhost", + "origin_server_ts": 1431961217939, + "event_id": "$WLGTSEFSEF:localhost", + "type": "m.room.member", + "room_id": "!Cuyf34gef24t:localhost", + "user_id": "@example:localhost" +} diff --git a/templating/matrix_templates/sections.py b/templating/matrix_templates/sections.py index e75a75af8..81b2bb3cc 100644 --- a/templating/matrix_templates/sections.py +++ b/templating/matrix_templates/sections.py @@ -35,7 +35,7 @@ class MatrixSections(Sections): if not filterFn(event_name): continue sections.append(template.render( - example=examples[event_name], + examples=examples[event_name], event=schemas[event_name], title_kind=subtitle_title_char )) diff --git a/templating/matrix_templates/templates/events.tmpl b/templating/matrix_templates/templates/events.tmpl index fb876440c..fbefe17f3 100644 --- a/templating/matrix_templates/templates/events.tmpl +++ b/templating/matrix_templates/templates/events.tmpl @@ -21,8 +21,10 @@ ======================= ================= =========================================== {% endfor %} -Example: +Example{% if examples | length > 1 %}s{% endif %}: +{% for example in examples %} .. code:: json {{example | jsonify(4, 4)}} +{% endfor %} diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index c43421411..d33ba81df 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -495,9 +495,14 @@ class MatrixUnits(Units): if not filename.startswith("m."): continue with open(os.path.join(path, filename), "r") as f: - examples[filename] = json.loads(f.read()) - if filename == "m.room.message#m.text": - examples["m.room.message"] = examples[filename] + event_name = filename.split("#")[0] + example = json.loads(f.read()) + + examples[filename] = examples.get(event_name, []) + examples[filename].append(example) + if filename != event_name: + examples[event_name] = examples.get(event_name, []) + examples[event_name].append(example) return examples def load_event_schemas(self): From 810922bb381a0f7162941605ec631f00927071ef Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 28 Oct 2015 15:06:44 +0000 Subject: [PATCH 4/7] Fix schema validator for multiple examples --- event-schemas/check_examples.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/event-schemas/check_examples.py b/event-schemas/check_examples.py index e54d3a1ca..b10b2d0ef 100755 --- a/event-schemas/check_examples.py +++ b/event-schemas/check_examples.py @@ -60,6 +60,8 @@ def check_example_dir(exampledir, schemadir): continue examplepath = os.path.join(root, filename) schemapath = examplepath.replace(exampledir, schemadir) + if schemapath.find("#") >= 0: + schemapath = schemapath[:schemapath.find("#")] try: check_example_file(examplepath, schemapath) except Exception as e: From cddfc110edc9018e44ce1a3690f3f6431a0ea9b7 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 29 Oct 2015 12:48:04 +0000 Subject: [PATCH 5/7] Review comments --- specification/modules/third_party_invites.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index 140bab86d..6d3f8f6a5 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -22,7 +22,7 @@ and public key to the inviting homeserver. When the invitee's homeserver receives the notification of the binding, it should insert an ``m.room.member`` event into the room's graph for that user, with ``content.membership`` = ``invite``, as well as a -``content.third_party_invite`` property whichi contains proof that the invitee +``content.third_party_invite`` property which contains proof that the invitee does indeed own that third party identifier. Events @@ -94,8 +94,8 @@ For example: 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 + 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. H3 validates the signature given to it by the identity server. From 9f4d81308d3eca3870f54c196335d2bb5176bd44 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 30 Oct 2015 16:21:50 +0000 Subject: [PATCH 6/7] Pull out separate invite_room_state example --- .../v1/m.room.member#invite_room_state | 30 +++++++++++++++++++ .../v1/m.room.member#third_party_invite | 16 ---------- 2 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 event-schemas/examples/v1/m.room.member#invite_room_state diff --git a/event-schemas/examples/v1/m.room.member#invite_room_state b/event-schemas/examples/v1/m.room.member#invite_room_state new file mode 100644 index 000000000..e2ca56685 --- /dev/null +++ b/event-schemas/examples/v1/m.room.member#invite_room_state @@ -0,0 +1,30 @@ +{ + "age": 242352, + "content": { + "membership": "join", + "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", + "displayname": "Alice Margatroid" + }, + "invite_room_state": [ + { + "type": "m.room.name", + "state_key": "", + "content": { + "name": "Forest of Magic" + } + }, + { + "type": "m.room.join_rules", + "state_key": "", + "content": { + "join_rules": "invite" + } + } + ], + "state_key": "@alice:localhost", + "origin_server_ts": 1431961217939, + "event_id": "$WLGTSEFSEF:localhost", + "type": "m.room.member", + "room_id": "!Cuyf34gef24t:localhost", + "user_id": "@example:localhost" +} diff --git a/event-schemas/examples/v1/m.room.member#third_party_invite b/event-schemas/examples/v1/m.room.member#third_party_invite index 4ef571ec5..2457302ac 100644 --- a/event-schemas/examples/v1/m.room.member#third_party_invite +++ b/event-schemas/examples/v1/m.room.member#third_party_invite @@ -16,22 +16,6 @@ } } }, - "invite_room_state": [ - { - "type": "m.room.name", - "state_key": "", - "content": { - "name": "Forest of Magic" - } - }, - { - "type": "m.room.join_rules", - "state_key": "", - "content": { - "join_rules": "invite" - } - } - ], "state_key": "@alice:localhost", "origin_server_ts": 1431961217939, "event_id": "$WLGTSEFSEF:localhost", From c00abe9f2faa80f6cfcf7fba028de870eca676ac Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Tue, 10 Nov 2015 15:26:51 +0000 Subject: [PATCH 7/7] Fix msgtype display --- templating/matrix_templates/sections.py | 2 +- templating/matrix_templates/units.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templating/matrix_templates/sections.py b/templating/matrix_templates/sections.py index 81b2bb3cc..78aabca76 100644 --- a/templating/matrix_templates/sections.py +++ b/templating/matrix_templates/sections.py @@ -136,7 +136,7 @@ class MatrixSections(Sections): if not event_name.startswith("m.room.message#m."): continue sections.append(template.render( - example=examples[event_name], + example=examples[event_name][0], event=schemas[event_name], title_kind=subtitle_title_char )) diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 5ae117ca4..94435c52e 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -562,7 +562,7 @@ class MatrixUnits(Units): event_name = filename.split("#")[0] example = json.loads(f.read()) - examples[filename] = examples.get(event_name, []) + examples[filename] = examples.get(filename, []) examples[filename].append(example) if filename != event_name: examples[event_name] = examples.get(event_name, [])