Merge pull request #1413 from turt2live/travis/s2s/join-swagger

Convert joins/invites to swagger
This commit is contained in:
Travis Ralston 2018-07-26 08:39:26 -06:00 committed by GitHub
commit b0744aa1e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 504 additions and 71 deletions

View file

@ -56,7 +56,8 @@ def check_parameter(filepath, request, parameter):
# Setting the 'id' tells jsonschema where the file is so that it
# can correctly resolve relative $ref references in the schema
schema['id'] = fileurl
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_yaml})
example = resolve_references(filepath, example)
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_file})
jsonschema.validate(example, schema, resolver=resolver)
except Exception as e:
raise ValueError("Error validating JSON schema for %r" % (
@ -76,7 +77,8 @@ def check_response(filepath, request, code, response):
# Setting the 'id' tells jsonschema where the file is so that it
# can correctly resolve relative $ref references in the schema
schema['id'] = fileurl
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_yaml})
example = resolve_references(filepath, example)
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_file})
jsonschema.validate(example, schema, resolver=resolver)
except Exception as e:
raise ValueError("Error validating JSON schema for %r %r" % (
@ -104,6 +106,27 @@ def check_swagger_file(filepath):
check_response(filepath, request, code, response)
def resolve_references(path, schema):
if isinstance(schema, dict):
# do $ref first
if '$ref' in schema:
value = schema['$ref']
path = os.path.abspath(os.path.join(os.path.dirname(path), value))
ref = load_file("file://" + path)
result = resolve_references(path, ref)
del schema['$ref']
else:
result = {}
for key, value in schema.items():
result[key] = resolve_references(path, value)
return result
elif isinstance(schema, list):
return [resolve_references(path, value) for value in schema]
else:
return schema
def load_yaml(path):
if not path.startswith("file:///"):
raise Exception("Bad ref: %s" % (path,))
@ -112,6 +135,24 @@ def load_yaml(path):
return yaml.load(f)
def load_json(path):
if not path.startswith("file:///"):
raise Exception("Bad ref: %s" % (path,))
path = path[len("file://"):]
with open(path, "r") as f:
return json.load(f)
def load_file(path):
print("Loading reference: %s" % path)
if path.endswith(".json"):
return load_json(path)
else:
# We have to assume it's YAML because some of the YAML examples
# do not have file extensions.
return load_yaml(path)
if __name__ == '__main__':
paths = sys.argv[1:]
if not paths:

View file

@ -0,0 +1,88 @@
# 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.
type: object
title: Invite Event
description: An invite event
allOf:
- $ref: "pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
# TODO: Verify/clarify this - it doesn't seem right, given this is a 'regular' invite
description: |-
The matrix ID of the user who sent the original ``m.room.third_party_invite``.
example: "@someone:example.org"
origin:
type: string
description: The name of the inviting homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the inviting homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the invited member.
example: "@joe:elsewhere.com"
content:
type: object
title: Membership Event Content
description: |-
The content of the event, matching what is available in the
`Client-Server API`_.
example: {"membership": "invite"}
properties:
membership:
type: string
description: The value ``invite``.
example: "invite"
required: ['membership']
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to be invited to the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
- unsigned # TODO: apparently this is required? Verify.

View file

@ -4,6 +4,13 @@
"origin": "example.com",
"event_id": "$a4ecee13e2accdadf56c1025:example.com",
"origin_server_ts": 1404838188000,
"depth": 12,
"auth_events": [
[
"$af232176:example.org",
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
]
],
"type": "m.room.message",
"prev_events": [
[

View file

@ -0,0 +1,88 @@
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Invite User To Room API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
paths:
"/invite/{roomId}/{eventId}":
put:
summary: Invites a user to a room
description: |-
Invites a remote user to a room. Once the event has been
signed by both the inviting homeserver and the invited
homeserver, it can be sent to all of the users in the room.
operationId: sendInvite
parameters:
- in: path
name: roomId
type: string
description: The room ID that the user is being invited to.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID for the invite event.
required: true
x-example: "$abc123:example.org"
- in: body
name: body
type: object
required: true
schema:
$ref: "definitions/invite_event.yaml"
example: {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "invite"
},
"unsigned": {}
}
responses:
200:
description: |-
The event with the invited server's signature added. All other fields of the events
should remain untouched.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- $ref: "definitions/invite_event.yaml"
examples:
application/json: [
200,
{
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "invite"
},
"unsigned": {}
}
]

View file

@ -0,0 +1,276 @@
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Join Room API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
paths:
"/make_join/{roomId}/{userId}":
get:
summary: Get information required to make a join event for a room
description: |-
Asks the receiving server to return information that the sending
server will need to prepare a join event to get into the room.
This is part of the `Joining Rooms`_ handshake.
operationId: makeJoin
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be joined.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: userId
type: string
description: The user ID the join event will be for.
required: true
x-example: "@someone:example.org"
responses:
200:
description: |-
An unsigned event that the server may now use as a template
for the rest of the `Joining Rooms`_ handshake.
schema:
allOf:
- $ref: "definitions/unsigned_pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
origin:
type: string
description: The name of the resident homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the resident homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "join"}
properties:
membership:
type: string
description: The value ``join``.
example: "join"
required: ['membership']
depth:
type: integer
description: This field must be present but is ignored; it may be 0.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to join the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
examples:
application/json: {
"$ref": "examples/unsigned_pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "join"
}
}
"/send_join/{roomId}/{eventId}":
put:
summary: Submit a signed join event to a resident server
description: |-
Submits a signed join event to the resident server for it
to accept it into the room's graph.
operationId: sendJoin
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be joined.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID for the join event.
required: true
x-example: "$abc123:example.org"
- in: body
name: body
type: object
required: true
schema:
allOf:
- $ref: "definitions/pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
origin:
type: string
description: The name of the joining homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the joining homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "join"}
properties:
membership:
type: string
description: The value ``join``.
example: "join"
required: ['membership']
depth:
type: integer
description: This field must be present but is ignored; it may be 0.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to join the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
example: {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "join"
}
}
responses:
200:
description: |-
The full state for the room, having accepted the join event.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- type: object
title: Room State
description: The state for the room.
properties:
auth_chain:
type: array
description: The auth chain.
items:
type: object
properties: {}
# TODO: Verify schema
state:
type: array
description: The room state.
items:
type: object
properties: {}
# TODO: Verify schema
required: ["auth_chain", "state"]
examples:
application/json: [
200,
{
# TODO: Use the appropriate refs (see TODOs in schema)
"auth_chain": [],
"state": []
}
]