From 7eb8b4fde275834496580cf642de6dd5eca8c377 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 15 Sep 2015 15:52:36 +0100 Subject: [PATCH 01/10] Add new-style docs for the APIs for getting events for a room --- api/client-server/v1/rooms.yaml | 433 ++++++++++++++++++++++++ specification/10_client_server_api.rst | 44 +-- templating/matrix_templates/sections.py | 6 + templating/matrix_templates/units.py | 4 +- 4 files changed, 442 insertions(+), 45 deletions(-) create mode 100644 api/client-server/v1/rooms.yaml diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml new file mode 100644 index 00000000..9a73bb05 --- /dev/null +++ b/api/client-server/v1/rooms.yaml @@ -0,0 +1,433 @@ +swagger: '2.0' +info: + title: "Matrix Client-Server v1 Rooms API" + version: "1.0.0" +host: example.com:8008 +schemes: + - https + - http +basePath: /_matrix/client/api/v1 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + accessToken: + type: apiKey + description: The user_id or application service access_token + name: access_token + in: query +paths: + "/rooms/{roomId}/state/{eventType}/{stateKey}": + get: + summary: Get the state identified by the type and key. + description: |- + Looks up the contents of a state event in a room. If the user is + joined to the room then the state is taken from the current + state of the room. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room to look up the state in. + required: true + x-example: "!room:example.com" + - in: path + type: string + name: eventType + description: The type of state to look up. + required: true + x-example: "m.room.name" + - in: path + type: string + name: stateKey + description: |- + The key of the state to look up. Defaults to the empty string. + required: false + x-example: "" + responses: + 200: + description: The content of the state event. + examples: + application/json: |- + {"name": "Example room name"} + schema: + type: object + 404: + description: The room has no state with the given type or key. + 403: + description: You are not joined to the room. + + "/rooms/{roomId}/state": + get: + summary: Get all state events in the current state of a room. + description: |- + Get the state events for the current state of a room. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room to look up the state for. + required: true + x-example: "!room:example.com" + responses: + 200: + description: The current state of the room + examples: + application/json: |- + [ + { + "age": 7148266897, + "content": { + "join_rule": "public" + }, + "event_id": "$14259997323TLwtb:example.com", + "origin_server_ts": 1425999732392, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.join_rules", + "user_id": "@alice:example.com" + }, + { + "age": 6547561012, + "content": { + "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", + "displayname": null, + "membership": "join" + }, + "event_id": "$1426600438280zExKY:example.com", + "membership": "join", + "origin_server_ts": 1426600438277, + "room_id": "!room:example.com", + "state_key": "@alice:example.com", + "type": "m.room.member", + "user_id": "@alice:example.com" + }, + { + "age": 7148267200, + "content": { + "creator": "@alice:example.com" + }, + "event_id": "$14259997320KhbwJ:example.com", + "origin_server_ts": 1425999732089, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.create", + "user_id": "@alice:example.com" + }, + { + "age": 1622568720, + "content": { + "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", + "displayname": "Bob", + "membership": "join" + }, + "event_id": "$1431525430134MxlLX:example.com", + "origin_server_ts": 1431525430569, + "replaces_state": "$142652023736BSXcM:example.com", + "room_id": "!room:example.com", + "state_key": "@bob:example.com", + "type": "m.room.member", + "user_id": "@bob:example.com" + }, + { + "age": 7148267004, + "content": { + "ban": 50, + "events": { + "m.room.name": 100, + "m.room.power_levels": 100 + }, + "events_default": 0, + "kick": 50, + "redact": 50, + "state_default": 50, + "users": { + "@alice:example.com": 100 + }, + "users_default": 0 + }, + "event_id": "$14259997322mqfaq:example.com", + "origin_server_ts": 1425999732285, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.power_levels", + "user_id": "@alice:example.com" + } + ] + schema: + type: array + title: RoomState + description: |- + If the user is a member of the room this will be the + current state of the room as a list of events. + items: + title: StateEvent + type: object + allOf: + - "$ref": "definitions/state_event.yaml" + 403: + description: You are not joined to the room. + + "/rooms/{roomId}/initialSync": + get: + summary: Snapshot the current state of a room and its most recent messages. + description: |- + Get a copy of the current state and the most recent messages in a room. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room to get the data. + required: true + x-example: "!room:example.com" + responses: + 200: + description: The current state of the room + examples: + application/json: |- + { + "membership": "join", + "messages": { + "chunk": [ + { + "age": 343513403, + "content": { + "body": "foo", + "msgtype": "m.text" + }, + "event_id": "$14328044851tzTJS:example.com", + "origin_server_ts": 1432804485886, + "room_id": "!room:example.com", + "type": "m.room.message", + "user_id": "@alice:example.com" + }, + { + "age": 343511809, + "content": { + "body": "bar", + "msgtype": "m.text" + }, + "event_id": "$14328044872spjFg:example.com", + "origin_server_ts": 1432804487480, + "room_id": "!room:example.com", + "type": "m.room.message", + "user_id": "@bob:example.com" + } + ], + "end": "s3456_9_0", + "start": "t44-3453_9_0" + }, + "room_id": "!room:example.com", + "state": [ + { + "age": 7148266897, + "content": { + "join_rule": "public" + }, + "event_id": "$14259997323TLwtb:example.com", + "origin_server_ts": 1425999732392, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.join_rules", + "user_id": "@alice:example.com" + }, + { + "age": 6547561012, + "content": { + "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", + "displayname": null, + "membership": "join" + }, + "event_id": "$1426600438280zExKY:example.com", + "membership": "join", + "origin_server_ts": 1426600438277, + "room_id": "!room:example.com", + "state_key": "@alice:example.com", + "type": "m.room.member", + "user_id": "@alice:example.com" + }, + { + "age": 7148267200, + "content": { + "creator": "@alice:example.com" + }, + "event_id": "$14259997320KhbwJ:example.com", + "origin_server_ts": 1425999732089, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.create", + "user_id": "@alice:example.com" + }, + { + "age": 1622568720, + "content": { + "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", + "displayname": "Bob", + "membership": "join" + }, + "event_id": "$1431525430134MxlLX:example.com", + "origin_server_ts": 1431525430569, + "replaces_state": "$142652023736BSXcM:example.com", + "room_id": "!room:example.com", + "state_key": "@bob:example.com", + "type": "m.room.member", + "user_id": "@bob:example.com" + }, + { + "age": 7148267004, + "content": { + "ban": 50, + "events": { + "m.room.name": 100, + "m.room.power_levels": 100 + }, + "events_default": 0, + "kick": 50, + "redact": 50, + "state_default": 50, + "users": { + "@alice:example.com": 100 + }, + "users_default": 0 + }, + "event_id": "$14259997322mqfaq:example.com", + "origin_server_ts": 1425999732285, + "room_id": "!room:example.com", + "state_key": "", + "type": "m.room.power_levels", + "user_id": "@alice:example.com" + } + ], + "visibility": "private" + } + schema: + title: RoomInfo + type: object + properties: + room_id: + type: string + description: "The ID of this room." + membership: + type: string + description: "The user's membership state in this room." + enum: ["invite", "join", "leave", "ban"] + messages: + type: object + title: PaginationChunk + description: "The pagination chunk for this room." + properties: + start: + type: string + description: |- + A token which correlates to the first value in ``chunk``. + Used for pagination. + end: + type: string + description: |- + A token which correlates to the last value in ``chunk``. + Used for pagination. + chunk: + type: array + description: |- + If the user is a member of the room this will be a + list of the most recent messages for this room. If + the user has left the room this will be the + messages that preceeded them leaving. This array + will consist of at most ``limit`` elements. + items: + type: object + title: RoomEvent + allOf: + - "$ref": "definitions/room_event.yaml" + required: ["start", "end", "chunk"] + state: + type: array + description: |- + If the user is a member of the room this will be the + current state of the room as a list of events. If the + user has left the room this will be the state of the + room when they left it. + items: + title: StateEvent + type: object + allOf: + - "$ref": "definitions/state_event.yaml" + visibility: + type: string + enum: ["private", "public"] + description: |- + Whether this room is visible to the ``/publicRooms`` API + or not." + required: ["room_id", "membership"] + + "/rooms/{roomId}/members": + get: + summary: Get the m.room.member events for the room. + description: + Get the list of members of the room. + parameters: + - in: path + type: string + name: roomId + description: The room to get the member events for. + required: true, + x-example: "!room:example.com" + responses: + 200: + description: The members of the room. + examples: + application/json: |- + { + "chunk": [ + { + "age": 6547561012, + "content": { + "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", + "displayname": null, + "membership": "join" + }, + "event_id": "$1426600438280zExKY:example.com", + "membership": "join", + "origin_server_ts": 1426600438277, + "room_id": "!room:example.com", + "state_key": "@alice:example.com", + "type": "m.room.member", + "user_id": "@alice:example.com" + }, + { + "age": 1622568720, + "content": { + "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", + "displayname": "Bob", + "membership": "join" + }, + "event_id": "$1431525430134MxlLX:example.com", + "origin_server_ts": 1431525430569, + "replaces_state": "$142652023736BSXcM:example.com", + "room_id": "!room:example.com", + "state_key": "@bob:example.com", + "type": "m.room.member", + "user_id": "@bob:example.com" + }, + ] + } + schema: + object: + properities: + chunk: + type: array + items: + title: MemberEvent + type: object + allOf: + - "$ref": "../../event-schemas/schema/v1/m.room.member" + visibility: + type: string + diff --git a/specification/10_client_server_api.rst b/specification/10_client_server_api.rst index fe11d199..2c85a4c2 100644 --- a/specification/10_client_server_api.rst +++ b/specification/10_client_server_api.rst @@ -631,49 +631,7 @@ Getting events for a room There are several APIs provided to ``GET`` events for a room: -``/rooms//state//`` - Description: - Get the state event identified. - Response format: - A JSON object representing the state event **content**. - Example: - ``/rooms/!room:domain.com/state/m.room.name`` returns ``{ "name": "Room name" }`` - -|/rooms//state|_ - Description: - Get all state events for a room. - Response format: - ``[ { state event }, { state event }, ... ]`` - Example: - TODO-doc - -|/rooms//members|_ - Description: - Get all ``m.room.member`` state events. - Response format: - ``{ "start": "", "end": "", "chunk": [ { m.room.member event }, ... ] }`` - Example: - TODO-doc - -|/rooms//messages|_ - Description: - Get all events from the room's timeline. This API supports - pagination using ``from`` and ``to`` query parameters, coupled with the - ``start`` and ``end`` tokens from an |initialSync|_ API. - - Response format: - ``{ "start": "", "end": "" }`` - Example: - TODO-doc - -|/rooms//initialSync|_ - Description: - Get all relevant events for a room. This includes state events, paginated - non-state events and presence events. - Response format: - `` { TODO-doc } `` - Example: - TODO-doc +{{rooms_http_api}} Redactions ~~~~~~~~~~ diff --git a/templating/matrix_templates/sections.py b/templating/matrix_templates/sections.py index 729157bb..2a591c11 100644 --- a/templating/matrix_templates/sections.py +++ b/templating/matrix_templates/sections.py @@ -102,6 +102,12 @@ class MatrixSections(Sections): title_kind="~" ) + def render_rooms_http_api(self): + return self._render_http_api_group( + "rooms", + title_kind="+" + ) + def render_room_events(self): def filterFn(eventType): return ( diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 0c072df3..98f0f3a9 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -149,8 +149,8 @@ class MatrixUnits(Units): # object with some keys; we'll add entries f.e one) if "schema" not in param: raise Exception( - "API endpoint group=%s path=%s method=%s param=%s"+ - " has no valid parameter value." % ( + ("API endpoint group=%s path=%s method=%s param=%s"+ + " has no valid parameter value.") % ( group_name, path, method, param ) ) From 654ed9b99e7dfae5cd227e192c5a5ace111dacf0 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 17 Sep 2015 16:00:06 +0100 Subject: [PATCH 02/10] Remove keys from the m.room.* schema files so that they may be used in the node swagger validator --- event-schemas/schema/v1/m.call.answer | 1 - event-schemas/schema/v1/m.call.candidates | 1 - event-schemas/schema/v1/m.call.hangup | 1 - event-schemas/schema/v1/m.call.invite | 1 - event-schemas/schema/v1/m.presence | 1 - event-schemas/schema/v1/m.receipt | 1 - event-schemas/schema/v1/m.room.aliases | 1 - event-schemas/schema/v1/m.room.canonical_alias | 1 - event-schemas/schema/v1/m.room.create | 1 - event-schemas/schema/v1/m.room.history_visibility | 1 - event-schemas/schema/v1/m.room.join_rules | 1 - event-schemas/schema/v1/m.room.member | 1 - event-schemas/schema/v1/m.room.message | 1 - event-schemas/schema/v1/m.room.message#m.audio | 1 - event-schemas/schema/v1/m.room.message#m.emote | 1 - event-schemas/schema/v1/m.room.message#m.file | 1 - event-schemas/schema/v1/m.room.message#m.image | 1 - event-schemas/schema/v1/m.room.message#m.location | 1 - event-schemas/schema/v1/m.room.message#m.notice | 1 - event-schemas/schema/v1/m.room.message#m.text | 1 - event-schemas/schema/v1/m.room.message#m.video | 1 - event-schemas/schema/v1/m.room.message.feedback | 1 - event-schemas/schema/v1/m.room.name | 1 - event-schemas/schema/v1/m.room.power_levels | 1 - event-schemas/schema/v1/m.room.redaction | 1 - event-schemas/schema/v1/m.room.topic | 1 - 26 files changed, 26 deletions(-) diff --git a/event-schemas/schema/v1/m.call.answer b/event-schemas/schema/v1/m.call.answer index abdf4a9b..3b2c48d4 100644 --- a/event-schemas/schema/v1/m.call.answer +++ b/event-schemas/schema/v1/m.call.answer @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "description": "This event is sent by the callee when they wish to answer the call.", "allOf": [{ diff --git a/event-schemas/schema/v1/m.call.candidates b/event-schemas/schema/v1/m.call.candidates index 052ead0b..f3c86296 100644 --- a/event-schemas/schema/v1/m.call.candidates +++ b/event-schemas/schema/v1/m.call.candidates @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "description": "This event is sent by callers after sending an invite and by the callee after answering. Its purpose is to give the other party additional ICE candidates to try using to communicate.", "allOf": [{ diff --git a/event-schemas/schema/v1/m.call.hangup b/event-schemas/schema/v1/m.call.hangup index 383952d8..0f253ef9 100644 --- a/event-schemas/schema/v1/m.call.hangup +++ b/event-schemas/schema/v1/m.call.hangup @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call.", "allOf": [{ diff --git a/event-schemas/schema/v1/m.call.invite b/event-schemas/schema/v1/m.call.invite index a852ff43..393e2455 100644 --- a/event-schemas/schema/v1/m.call.invite +++ b/event-schemas/schema/v1/m.call.invite @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "description": "This event is sent by the caller when they wish to establish a call.", "allOf": [{ diff --git a/event-schemas/schema/v1/m.presence b/event-schemas/schema/v1/m.presence index bb69ce40..79852ac6 100644 --- a/event-schemas/schema/v1/m.presence +++ b/event-schemas/schema/v1/m.presence @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Presence Event", "description": "Informs the client of a user's presence state change.", diff --git a/event-schemas/schema/v1/m.receipt b/event-schemas/schema/v1/m.receipt index 4bd9f17b..0f365eed 100644 --- a/event-schemas/schema/v1/m.receipt +++ b/event-schemas/schema/v1/m.receipt @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Receipt Event", "description": "Informs the client of new receipts.", diff --git a/event-schemas/schema/v1/m.room.aliases b/event-schemas/schema/v1/m.room.aliases index 79fd259b..38fd7d18 100644 --- a/event-schemas/schema/v1/m.room.aliases +++ b/event-schemas/schema/v1/m.room.aliases @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Informs the room about what room aliases it has been given.", "description": "This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.", diff --git a/event-schemas/schema/v1/m.room.canonical_alias b/event-schemas/schema/v1/m.room.canonical_alias index 17caa321..f79ce234 100644 --- a/event-schemas/schema/v1/m.room.canonical_alias +++ b/event-schemas/schema/v1/m.room.canonical_alias @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Informs the room as to which alias is the canonical one.", "description": "This event is used to inform the room about which alias should be considered the canonical one. This could be for display purposes or as suggestion to users which alias to use to advertise the room.", diff --git a/event-schemas/schema/v1/m.room.create b/event-schemas/schema/v1/m.room.create index ecc2ed63..9561f19b 100644 --- a/event-schemas/schema/v1/m.room.create +++ b/event-schemas/schema/v1/m.room.create @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "The first event in the room.", "description": "This is the first event in a room and cannot be changed. It acts as the root of all other events.", diff --git a/event-schemas/schema/v1/m.room.history_visibility b/event-schemas/schema/v1/m.room.history_visibility index 48b0a5c4..22b39623 100644 --- a/event-schemas/schema/v1/m.room.history_visibility +++ b/event-schemas/schema/v1/m.room.history_visibility @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Controls visibility of history.", "description": "This event controls whether a member of a room can see the events that happened in a room from before they joined.", diff --git a/event-schemas/schema/v1/m.room.join_rules b/event-schemas/schema/v1/m.room.join_rules index 567247eb..095ccfa7 100644 --- a/event-schemas/schema/v1/m.room.join_rules +++ b/event-schemas/schema/v1/m.room.join_rules @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Describes how users are allowed to join the room.", "description": "A room may be ``public`` meaning anyone can join the room without any prior action. Alternatively, it can be ``invite`` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, ``knock`` and ``private`` are reserved keywords which are not implemented.", diff --git a/event-schemas/schema/v1/m.room.member b/event-schemas/schema/v1/m.room.member index 67e10d51..5acc5f7c 100644 --- a/event-schemas/schema/v1/m.room.member +++ b/event-schemas/schema/v1/m.room.member @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "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.", diff --git a/event-schemas/schema/v1/m.room.message b/event-schemas/schema/v1/m.room.message index 61b6256f..c8c5931e 100644 --- a/event-schemas/schema/v1/m.room.message +++ b/event-schemas/schema/v1/m.room.message @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Message", "description": "This event is used when sending messages in a room. Messages are not limited to be text. The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc. The ``body`` key is text and MUST be used with every kind of ``msgtype`` as a fallback mechanism for when a client cannot render a message.", diff --git a/event-schemas/schema/v1/m.room.message#m.audio b/event-schemas/schema/v1/m.room.message#m.audio index b236e5b0..f943fc7f 100644 --- a/event-schemas/schema/v1/m.room.message#m.audio +++ b/event-schemas/schema/v1/m.room.message#m.audio @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "AudioMessage", "description": "This message represents a single audio clip.", diff --git a/event-schemas/schema/v1/m.room.message#m.emote b/event-schemas/schema/v1/m.room.message#m.emote index 9f17180c..3379d635 100644 --- a/event-schemas/schema/v1/m.room.message#m.emote +++ b/event-schemas/schema/v1/m.room.message#m.emote @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "EmoteMessage", "description": "This message is similar to ``m.text`` except that the sender is 'performing' the action contained in the ``body`` key, similar to ``/me`` in IRC. This message should be prefixed by the name of the sender. This message could also be represented in a different colour to distinguish it from regular ``m.text`` messages.", diff --git a/event-schemas/schema/v1/m.room.message#m.file b/event-schemas/schema/v1/m.room.message#m.file index d8c63b33..b1cdff22 100644 --- a/event-schemas/schema/v1/m.room.message#m.file +++ b/event-schemas/schema/v1/m.room.message#m.file @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "FileMessage", "description": "This message represents a generic file.", diff --git a/event-schemas/schema/v1/m.room.message#m.image b/event-schemas/schema/v1/m.room.message#m.image index ca22654f..5d4f811b 100644 --- a/event-schemas/schema/v1/m.room.message#m.image +++ b/event-schemas/schema/v1/m.room.message#m.image @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "ImageMessage", "description": "This message represents a single image and an optional thumbnail.", diff --git a/event-schemas/schema/v1/m.room.message#m.location b/event-schemas/schema/v1/m.room.message#m.location index 919c3325..f02bea78 100644 --- a/event-schemas/schema/v1/m.room.message#m.location +++ b/event-schemas/schema/v1/m.room.message#m.location @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "LocationMessage", "description": "This message represents a real-world location.", diff --git a/event-schemas/schema/v1/m.room.message#m.notice b/event-schemas/schema/v1/m.room.message#m.notice index e6ce6f89..972eb45e 100644 --- a/event-schemas/schema/v1/m.room.message#m.notice +++ b/event-schemas/schema/v1/m.room.message#m.notice @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "NoticeMessage", "description": "A m.notice message should be considered similar to a plain m.text message except that clients should visually distinguish it in some way. It is intended to be used by automated clients, such as bots, bridges, and other entities, rather than humans. Additionally, such automated agents which watch a room for messages and respond to them ought to ignore m.notice messages. This helps to prevent infinite-loop situations where two automated clients continuously exchange messages, as each responds to the other.", diff --git a/event-schemas/schema/v1/m.room.message#m.text b/event-schemas/schema/v1/m.room.message#m.text index ceadbcd0..00aa1818 100644 --- a/event-schemas/schema/v1/m.room.message#m.text +++ b/event-schemas/schema/v1/m.room.message#m.text @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "TextMessage", "description": "This message is the most basic message and is used to represent text.", diff --git a/event-schemas/schema/v1/m.room.message#m.video b/event-schemas/schema/v1/m.room.message#m.video index 667832ff..b91fd48a 100644 --- a/event-schemas/schema/v1/m.room.message#m.video +++ b/event-schemas/schema/v1/m.room.message#m.video @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "VideoMessage", "description": "This message represents a single video clip.", diff --git a/event-schemas/schema/v1/m.room.message.feedback b/event-schemas/schema/v1/m.room.message.feedback index b662e9e6..3a069654 100644 --- a/event-schemas/schema/v1/m.room.message.feedback +++ b/event-schemas/schema/v1/m.room.message.feedback @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "MessageFeedback", "description": "Feedback events are events sent to acknowledge a message in some way. There are two supported acknowledgements: ``delivered`` (sent when the event has been received) and ``read`` (sent when the event has been observed by the end-user). The ``target_event_id`` should reference the ``m.room.message`` event being acknowledged. N.B. not implemented in Synapse, and superceded in v2 CS API by the ``relates_to`` event field.", diff --git a/event-schemas/schema/v1/m.room.name b/event-schemas/schema/v1/m.room.name index 5565147c..2a72feeb 100644 --- a/event-schemas/schema/v1/m.room.name +++ b/event-schemas/schema/v1/m.room.name @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "title": "RoomName", "description": "A room has an opaque room ID which is not human-friendly to read. A room alias is human-friendly, but not all rooms have room aliases. The room name is a human-friendly string designed to be displayed to the end-user. The room name is not unique, as multiple rooms can have the same room name set. The room name can also be set when creating a room using ``/createRoom`` with the ``name`` key.", "type": "object", diff --git a/event-schemas/schema/v1/m.room.power_levels b/event-schemas/schema/v1/m.room.power_levels index 95850fcb..b5cb1049 100644 --- a/event-schemas/schema/v1/m.room.power_levels +++ b/event-schemas/schema/v1/m.room.power_levels @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Defines the power levels (privileges) of users in the room.", "description": "This event specifies the minimum level a user must have in order to perform a certain action. It also specifies the levels of each user in the room. If a ``user_id`` is in the ``users`` list, then that ``user_id`` has the associated power level. Otherwise they have the default level ``users_default``. If ``users_default`` is not supplied, it is assumed to be 0. The level required to send a certain event is governed by ``events``, ``state_default`` and ``events_default``. If an event type is specified in ``events``, then the user must have at least the level specified in order to send that event. If the event type is not supplied, it defaults to ``events_default`` for Message Events and ``state_default`` for State Events.", diff --git a/event-schemas/schema/v1/m.room.redaction b/event-schemas/schema/v1/m.room.redaction index b095b17d..970679c7 100644 --- a/event-schemas/schema/v1/m.room.redaction +++ b/event-schemas/schema/v1/m.room.redaction @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Redaction", "description": "Events can be redacted by either room or server admins. Redacting an event means that all keys not required by the protocol are stripped off, allowing admins to remove offensive or illegal content that may have been attached to any event. This cannot be undone, allowing server owners to physically delete the offending data. There is also a concept of a moderator hiding a message event, which can be undone, but cannot be applied to state events. The event that has been redacted is specified in the ``redacts`` event level key.", diff --git a/event-schemas/schema/v1/m.room.topic b/event-schemas/schema/v1/m.room.topic index 32319c38..a9956228 100644 --- a/event-schemas/schema/v1/m.room.topic +++ b/event-schemas/schema/v1/m.room.topic @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "title": "Topic", "description": "A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using ``/createRoom`` with the ``topic`` key.", From 46d29e9eea31d32e4865554e0c36badcd4006091 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 17 Sep 2015 16:48:07 +0100 Subject: [PATCH 03/10] fix the room api swagger to be valid swagger --- api/client-server/v1/rooms.yaml | 41 +++++++++++++++------------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 9a73bb05..c038dba5 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -43,9 +43,8 @@ paths: - in: path type: string name: stateKey - description: |- - The key of the state to look up. Defaults to the empty string. - required: false + description: The key of the state to look up. Defaults to the empty string. + required: true x-example: "" responses: 200: @@ -159,17 +158,17 @@ paths: "user_id": "@alice:example.com" } ] - schema: - type: array - title: RoomState - description: |- - If the user is a member of the room this will be the - current state of the room as a list of events. - items: - title: StateEvent - type: object - allOf: - - "$ref": "definitions/state_event.yaml" + schema: + type: array + title: RoomState + description: |- + If the user is a member of the room this will be the + current state of the room as a list of events. + items: + title: StateEvent + type: object + allOf: + - "$ref": "events/core/state_event.json" 403: description: You are not joined to the room. @@ -345,7 +344,7 @@ paths: type: object title: RoomEvent allOf: - - "$ref": "definitions/room_event.yaml" + - "$ref": "events/core/room_event.json" required: ["start", "end", "chunk"] state: type: array @@ -358,7 +357,7 @@ paths: title: StateEvent type: object allOf: - - "$ref": "definitions/state_event.yaml" + - "$ref": "events/core/state_event.json" visibility: type: string enum: ["private", "public"] @@ -377,7 +376,7 @@ paths: type: string name: roomId description: The room to get the member events for. - required: true, + required: true x-example: "!room:example.com" responses: 200: @@ -419,15 +418,13 @@ paths: ] } schema: - object: - properities: + type: object + properties: chunk: type: array items: title: MemberEvent type: object allOf: - - "$ref": "../../event-schemas/schema/v1/m.room.member" - visibility: - type: string + - "$ref": "events/m.room.member" From 6a2c4d27fc187d6efb755705be9eca7a07dec26f Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 18 Sep 2015 17:58:44 +0100 Subject: [PATCH 04/10] Update the docs for room v1 api --- api/client-server/v1/rooms.yaml | 10 +++++----- event-schemas/schema/v1/m.room.member | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index c038dba5..4902560b 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -168,7 +168,7 @@ paths: title: StateEvent type: object allOf: - - "$ref": "events/core/state_event.json" + - "$ref": "core-event-schema/state_event.json" 403: description: You are not joined to the room. @@ -344,7 +344,7 @@ paths: type: object title: RoomEvent allOf: - - "$ref": "events/core/room_event.json" + - "$ref": "core-event-schema/room_event.json" required: ["start", "end", "chunk"] state: type: array @@ -357,7 +357,7 @@ paths: title: StateEvent type: object allOf: - - "$ref": "events/core/state_event.json" + - "$ref": "core-event-schema/state_event.json" visibility: type: string enum: ["private", "public"] @@ -414,7 +414,7 @@ paths: "state_key": "@bob:example.com", "type": "m.room.member", "user_id": "@bob:example.com" - }, + } ] } schema: @@ -426,5 +426,5 @@ paths: title: MemberEvent type: object allOf: - - "$ref": "events/m.room.member" + - "$ref": "v1-event-schema/m.room.member" diff --git a/event-schemas/schema/v1/m.room.member b/event-schemas/schema/v1/m.room.member index 48f1b034..49b9f5b8 100644 --- a/event-schemas/schema/v1/m.room.member +++ b/event-schemas/schema/v1/m.room.member @@ -19,7 +19,7 @@ "description": "The avatar URL for this user, if any. This is added by the homeserver." }, "displayname": { - "type": "string", + "type": ["string", "null"], "description": "The display name for this user, if any. This is added by the homeserver." } }, From cb41adee707a04591c93726f5002855febf2543f Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 21 Sep 2015 17:10:23 +0100 Subject: [PATCH 05/10] Fix the swagger host to be "localhost:8008" so that it can be used in a "Try it now" setup against localhost --- api/client-server/v1/rooms.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 4902560b..4494d357 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -2,7 +2,7 @@ swagger: '2.0' info: title: "Matrix Client-Server v1 Rooms API" version: "1.0.0" -host: example.com:8008 +host: localhost:8008 schemes: - https - http From 615a9575cbad5401997e89c292cc741e0bf5ff23 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 21 Sep 2015 17:12:29 +0100 Subject: [PATCH 06/10] SPEC-216: Clarify when the room getters will return 403 --- api/client-server/v1/rooms.yaml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 4494d357..3bd23c4a 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -57,7 +57,9 @@ paths: 404: description: The room has no state with the given type or key. 403: - description: You are not joined to the room. + description: > + You aren't a member of the room and weren't previously a + member of the room. "/rooms/{roomId}/state": get: @@ -170,7 +172,9 @@ paths: allOf: - "$ref": "core-event-schema/state_event.json" 403: - description: You are not joined to the room. + description: > + You aren't a member of the room and weren't previously a + member of the room. "/rooms/{roomId}/initialSync": get: @@ -365,6 +369,10 @@ paths: Whether this room is visible to the ``/publicRooms`` API or not." required: ["room_id", "membership"] + 403: + description: > + You aren't a member of the room and weren't previously a + member of the room. "/rooms/{roomId}/members": get: @@ -427,4 +435,8 @@ paths: type: object allOf: - "$ref": "v1-event-schema/m.room.member" + 403: + description: > + You aren't a member of the room and weren't previously a + member of the room. From ba6c7d267ca4b5265d2eb1ba19933fe6f790090a Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 21 Sep 2015 17:17:40 +0100 Subject: [PATCH 07/10] SPEC-216: Document the behaviour of the room getters when the user has left the room --- api/client-server/v1/rooms.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 3bd23c4a..7550c5fe 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -24,7 +24,8 @@ paths: description: |- Looks up the contents of a state event in a room. If the user is joined to the room then the state is taken from the current - state of the room. + state of the room. If the user has left the room then the state is + taken from the state of the room when they left. security: - accessToken: [] parameters: @@ -165,7 +166,9 @@ paths: title: RoomState description: |- If the user is a member of the room this will be the - current state of the room as a list of events. + current state of the room as a list of events. If the user + has left the room then this will be the state of the room + when they left as a list of events. items: title: StateEvent type: object @@ -378,7 +381,7 @@ paths: get: summary: Get the m.room.member events for the room. description: - Get the list of members of the room. + Get the list of members for this room. parameters: - in: path type: string From f60190086a41579d35a7d42caaaee7e69fe27b00 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 21 Sep 2015 17:30:10 +0100 Subject: [PATCH 08/10] Describe the behaviour of /rooms/{roomId}/member when the user has left the room --- api/client-server/v1/rooms.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 7550c5fe..e02c75c6 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -391,7 +391,10 @@ paths: x-example: "!room:example.com" responses: 200: - description: The members of the room. + description: |- + A list of members of the room. If you are joined to the room then + this will be the current members of the room. If you have left te + room then this will be the members of the room when you left. examples: application/json: |- { From 98d91d0c2b3b098618bc91f70079a1a9c64bb546 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 21 Sep 2015 17:31:35 +0100 Subject: [PATCH 09/10] Make the example room id more "random" so that people are less likely to think that it is supposed to be human readable --- api/client-server/v1/rooms.yaml | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index e02c75c6..9300d7d1 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -34,7 +34,7 @@ paths: name: roomId description: The room to look up the state in. required: true - x-example: "!room:example.com" + x-example: "!636q39766251:example.com" - in: path type: string name: eventType @@ -75,7 +75,7 @@ paths: name: roomId description: The room to look up the state for. required: true - x-example: "!room:example.com" + x-example: "!636q39766251:example.com" responses: 200: description: The current state of the room @@ -89,7 +89,7 @@ paths: }, "event_id": "$14259997323TLwtb:example.com", "origin_server_ts": 1425999732392, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.join_rules", "user_id": "@alice:example.com" @@ -104,7 +104,7 @@ paths: "event_id": "$1426600438280zExKY:example.com", "membership": "join", "origin_server_ts": 1426600438277, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@alice:example.com", "type": "m.room.member", "user_id": "@alice:example.com" @@ -116,7 +116,7 @@ paths: }, "event_id": "$14259997320KhbwJ:example.com", "origin_server_ts": 1425999732089, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.create", "user_id": "@alice:example.com" @@ -131,7 +131,7 @@ paths: "event_id": "$1431525430134MxlLX:example.com", "origin_server_ts": 1431525430569, "replaces_state": "$142652023736BSXcM:example.com", - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@bob:example.com", "type": "m.room.member", "user_id": "@bob:example.com" @@ -155,7 +155,7 @@ paths: }, "event_id": "$14259997322mqfaq:example.com", "origin_server_ts": 1425999732285, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.power_levels", "user_id": "@alice:example.com" @@ -192,7 +192,7 @@ paths: name: roomId description: The room to get the data. required: true - x-example: "!room:example.com" + x-example: "!636q39766251:example.com" responses: 200: description: The current state of the room @@ -210,7 +210,7 @@ paths: }, "event_id": "$14328044851tzTJS:example.com", "origin_server_ts": 1432804485886, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "type": "m.room.message", "user_id": "@alice:example.com" }, @@ -222,7 +222,7 @@ paths: }, "event_id": "$14328044872spjFg:example.com", "origin_server_ts": 1432804487480, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "type": "m.room.message", "user_id": "@bob:example.com" } @@ -230,7 +230,7 @@ paths: "end": "s3456_9_0", "start": "t44-3453_9_0" }, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state": [ { "age": 7148266897, @@ -239,7 +239,7 @@ paths: }, "event_id": "$14259997323TLwtb:example.com", "origin_server_ts": 1425999732392, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.join_rules", "user_id": "@alice:example.com" @@ -254,7 +254,7 @@ paths: "event_id": "$1426600438280zExKY:example.com", "membership": "join", "origin_server_ts": 1426600438277, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@alice:example.com", "type": "m.room.member", "user_id": "@alice:example.com" @@ -266,7 +266,7 @@ paths: }, "event_id": "$14259997320KhbwJ:example.com", "origin_server_ts": 1425999732089, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.create", "user_id": "@alice:example.com" @@ -281,7 +281,7 @@ paths: "event_id": "$1431525430134MxlLX:example.com", "origin_server_ts": 1431525430569, "replaces_state": "$142652023736BSXcM:example.com", - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@bob:example.com", "type": "m.room.member", "user_id": "@bob:example.com" @@ -305,7 +305,7 @@ paths: }, "event_id": "$14259997322mqfaq:example.com", "origin_server_ts": 1425999732285, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "", "type": "m.room.power_levels", "user_id": "@alice:example.com" @@ -388,7 +388,7 @@ paths: name: roomId description: The room to get the member events for. required: true - x-example: "!room:example.com" + x-example: "!636q39766251:example.com" responses: 200: description: |- @@ -409,7 +409,7 @@ paths: "event_id": "$1426600438280zExKY:example.com", "membership": "join", "origin_server_ts": 1426600438277, - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@alice:example.com", "type": "m.room.member", "user_id": "@alice:example.com" @@ -424,7 +424,7 @@ paths: "event_id": "$1431525430134MxlLX:example.com", "origin_server_ts": 1431525430569, "replaces_state": "$142652023736BSXcM:example.com", - "room_id": "!room:example.com", + "room_id": "!636q39766251:example.com", "state_key": "@bob:example.com", "type": "m.room.member", "user_id": "@bob:example.com" From 056b5eba22e94b613c50b6255b23152553bced2e Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Tue, 22 Sep 2015 16:01:22 +0100 Subject: [PATCH 10/10] Partially handle representing top-level array responses If an HTTP API returned a top-level array response, the templating system would fail to create a table for it. This is now partially fixed by pulling out the type of the elements (no recursion is done to populate nested tables) --- templating/matrix_templates/units.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 84c96ce3..975f7c80 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -247,7 +247,8 @@ class MatrixUnits(Units): "rows": [{ "key": good_response["schema"].get("name", ""), "type": res_type, - "desc": res.get("description", "") + "desc": res.get("description", ""), + "req_str": "" }] }) elif res_type and Units.prop(good_response, "schema/properties"): @@ -257,6 +258,24 @@ class MatrixUnits(Units): for table in res_tables: if "no-table" not in table: endpoint["res_tables"].append(table) + elif res_type and Units.prop(good_response, "schema/items"): + # response is an array: + # FIXME: Doesn't recurse at all. + schema = good_response["schema"] + array_type = Units.prop(schema, "items/type") + if Units.prop(schema, "items/allOf"): + array_type = ( + Units.prop(schema, "items/title") + ) + endpoint["res_tables"].append({ + "title": schema.get("title", ""), + "rows": [{ + "key": "N/A", + "type": ("[%s]" % array_type), + "desc": schema.get("description", ""), + "req_str": "" + }] + }) endpoints.append(endpoint)