Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC2946: Spaces Summary #2946

Merged
merged 77 commits into from
Oct 31, 2021
Merged
Changes from 27 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
059f324
Spaces Summary
kegsay Jan 7, 2021
14eb56c
MSC2946
kegsay Jan 7, 2021
aea5336
Clarity
kegsay Jan 7, 2021
7618ed6
More clarity
kegsay Jan 7, 2021
6e051d5
Clarify what no room data means for clients
kegsay Jan 7, 2021
619c100
Federation API
kegsay Jan 13, 2021
104cf78
Update 2946-spaces-summary.md
kegsay Jan 13, 2021
8f6fb9d
auto_join filter
kegsay Jan 13, 2021
200147c
Blurb on auth for fed api
kegsay Jan 13, 2021
f2457cf
Update to reflect MSC1772 changes
kegsay Jan 15, 2021
1430661
Mention auth chain on federation api
kegsay Jan 15, 2021
09b0848
Add 'version' field
kegsay Jan 18, 2021
7b2f3dc
Stripped state; remove room versions
kegsay Jan 19, 2021
6224859
Update 2946-spaces-summary.md
kegsay Feb 25, 2021
211e5e6
Update proposals/2946-spaces-summary.md
kegsay Mar 15, 2021
725277e
Replace with link to draft doc.
richvdh Mar 23, 2021
0fd8d8d
Add a preamble and copy the current draft API.
clokep Apr 13, 2021
dee9040
Switch to using stable identifiers (and add an unstable identifiers s…
clokep Apr 13, 2021
a3b62a8
Updates / clarifications.
clokep Apr 13, 2021
f28ad9b
Fix typo.
clokep Apr 14, 2021
d911c82
Clean-ups.
clokep Apr 14, 2021
74f12d5
Update proposals/2946-spaces-summary.md
ara4n Apr 30, 2021
8b1fe00
Drop unstable identifiers from MSC1772.
clokep May 3, 2021
8fdbfb1
Various updates and clarifications.
clokep May 4, 2021
f145fa3
Include the origin_server_ts in the response, as needed by MSC1772.
clokep May 5, 2021
f9c00a5
Rename a parameter for clarity.
clokep May 5, 2021
9c2e85a
Fix typo.
clokep May 5, 2021
760cda8
Various clarifications based on feedback.
clokep May 5, 2021
a5ad9a4
Add auth / rate-limiting info.
clokep May 6, 2021
4c10e02
Combine some double spaces.
clokep May 6, 2021
ad5af4d
Use only GET endpoints.
clokep May 6, 2021
dba41f9
Add notes about DoS potential.
clokep May 6, 2021
8a968eb
Tweaks from review.
clokep May 6, 2021
b379c42
Add context about why stripped events are returned.
clokep May 6, 2021
27f526c
Remove some implementation details.
clokep May 6, 2021
c142433
Add notes on ordering.
clokep May 10, 2021
af8c7b0
Remove unnecessary data.
clokep May 10, 2021
bcde9e0
Clarify the server-server API.
clokep May 10, 2021
328ae81
More clarifications.
clokep May 10, 2021
518db51
Remove obsolete note.
clokep May 11, 2021
3b0051f
Some clarifications to what accessible means.
clokep May 19, 2021
5cd8270
Update notes about sorting to include the origin_server_ts of the m.s…
clokep May 19, 2021
797dda4
Only consider `m.space` rooms and do not return links to nowhere.
clokep Jun 11, 2021
105fd93
Updates based on MSC3173 merging and updates to MSC3083.
clokep Jun 25, 2021
a7a08eb
Updates per MSC2403.
clokep Jul 2, 2021
094de30
Remove field which is not part of the C-S API.
clokep Jul 27, 2021
c0a63ab
Rewrite the proposal.
clokep Jul 28, 2021
3d7769f
Handle todo comments.
clokep Jul 28, 2021
5627721
Update URLs.
clokep Jul 29, 2021
7d0c8f6
Rename field.
clokep Jul 29, 2021
420d698
Updates based on implementation.
clokep Aug 9, 2021
5cd0db4
Clarify the state which is persisted.
clokep Aug 10, 2021
14bdc42
Expand notes about errors.
clokep Aug 10, 2021
00d3d67
Update MSC with pagination parameter.
clokep Aug 11, 2021
e39eac3
Fix wrong endpoint.
clokep Aug 13, 2021
6823998
Clarifications based on implementation.
clokep Aug 27, 2021
5a5a404
Remove empty section.
clokep Sep 7, 2021
0174348
Fix typo.
clokep Sep 10, 2021
545ff90
Rename field in example.
clokep Sep 21, 2021
42ba46e
Clarify error code.
clokep Sep 21, 2021
dee3b2d
Clarify ordering changes.
clokep Sep 21, 2021
a9803c3
Clarify wording.
clokep Sep 28, 2021
e9592ff
Fix typos.
clokep Sep 29, 2021
8978562
Clarify that rooms do not belong to servers.
clokep Sep 29, 2021
622f8ed
Fix example to use correct URL.
clokep Sep 29, 2021
6ad9ead
Clarify using local vs. remote data.
clokep Sep 29, 2021
482597e
Clarify bits aboud stripped state.
clokep Sep 29, 2021
41bfaa5
Clarify access control of federation responses.
clokep Sep 29, 2021
f6f41b1
Clarify error code.
clokep Sep 29, 2021
828c076
Be less prescriptive about expiring data.
clokep Oct 5, 2021
7fd45e5
Limit must be non-zero.
clokep Oct 6, 2021
902a124
Rate limiting.
clokep Oct 6, 2021
bf5f84d
Add a note about room upgrades.
clokep Oct 6, 2021
b43333a
Update stable URLs per MSC2844.
clokep Oct 12, 2021
c74adf7
Clarify federation return values.
clokep Oct 12, 2021
fe5a9a7
Clarify `origin_server_ts`.
clokep Oct 26, 2021
a9f6cf6
Tweak wording around `inaccessible_children`.
clokep Oct 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 215 additions & 0 deletions proposals/2946-spaces-summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
## MSC2946: Spaces Summary

This MSC depends on [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772), which
describes why a Space is useful:

> Collecting rooms together into groups is useful for a number of purposes. Examples include:
>
> * Allowing users to discover different rooms related to a particular topic: for example "official matrix.org rooms".
> * Allowing administrators to manage permissions across a number of rooms: for example "a new employee has joined my company and needs access to all of our rooms".
> * Letting users classify their rooms: for example, separating "work" from "personal" rooms.
>
> We refer to such collections of rooms as "spaces".

This MSC attempts to solve how a member of a space discovers rooms in that space. This
is useful for quickly exposing a user to many aspects of an entire community, using the
examples above, joining the "official matrix.org rooms" space might suggest joining a few
rooms:

* A room to discuss development of the Matrix Spec.
* An announcements room for news related to matrix.org.
* An off-topic room for members of the space.

## Proposal
turt2live marked this conversation as resolved.
Show resolved Hide resolved

A new client-server API (and corresponding server-server API) is added which allows
for querying for the rooms and spaces contained within a space. This allows a client
to efficiently display a hierarchy of rooms to a user (i.e. without having
to walk the full state of the space).

### Client-server API

An endpoint is provided to walk the space tree, starting at the provided room ID
("the root room"), and visiting other rooms/spaces found via `m.space.child`
events. It recurses into the children and into their children, etc.

Example request:

```jsonc
POST /_matrix/client/r0/rooms/{roomID}/spaces
richvdh marked this conversation as resolved.
Show resolved Hide resolved
clokep marked this conversation as resolved.
Show resolved Hide resolved
clokep marked this conversation as resolved.
Show resolved Hide resolved

clokep marked this conversation as resolved.
Show resolved Hide resolved
{
"max_rooms_per_space": 5,
"suggested_only": true
}
```

or:

```text
GET /_matrix/client/r0/rooms/{roomID}/spaces?
max_rooms_per_space=5&
suggested_only=true
```

Example response:
clokep marked this conversation as resolved.
Show resolved Hide resolved

```jsonc
{
"rooms": [
{
"room_id": "!ol19s:bleecker.street",
"avatar_url": "mxc://bleecker.street/CHEDDARandBRIE",
"guest_can_join": false,
"name": "CHEESE",
"num_joined_members": 37,
"topic": "Tasty tasty cheese",
"world_readable": true,
"creation_ts": 1432735824653,
"room_type": "m.space"
},
{ ... }
],
"events": [
richvdh marked this conversation as resolved.
Show resolved Hide resolved
{
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": ["example.com"],
"suggested": true
},
"room_id": "!ol19s:bleecker.street",
"sender": "@alice:bleecker.street"
},
{ ... }
]
}
```

Request params:

* **`suggested_only`**: Optional. If `true`, return only child events and rooms where the
`m.space.child` event has `suggested: true`. Defaults to `false`.

For the POST request, must be a boolean. For GET, must be either `true` or `false`,
case-sensitive.
clokep marked this conversation as resolved.
Show resolved Hide resolved
* **`max_rooms_per_space`**: Optional: a client-defined limit to the maximum
number of children to return per space. Doesn't apply to the root space (ie,
the `room_id` in the request).

Server implementations may also have an internal limit (recommended as 50)
(which *does* apply to the root room); attempts to exceed this limit are
clokep marked this conversation as resolved.
Show resolved Hide resolved
ignored. Must be a non-negative integer.

Response fields:

* **`rooms`**: for each room/space, starting with the root room, a
summary of that room. The fields are the same as those returned by
`/publicRooms` (see
[spec](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms)),
with the addition of:
* **`room_type`**: the value of the `m.type` field from the
room's `m.room.create` event, if any.
clokep marked this conversation as resolved.
Show resolved Hide resolved
* **`creation_ts`**: the value of the `origin_server_ts` field from the
room's `m.room.create` event. This is required for sorting of rooms as specified
in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772).
* **`events`**: `m.space.child` events of the returned rooms. For each event, only the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be best to call this stripped_state, space_state, or similar to line up with terminology already established in the spec for this data structure. Specifically, these look like StrippedState events with the addition of a room_id

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed below these are stripped state events. We can explore renaming the field.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few words as to why this is not under the relevant room would be appreciated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure there's a particular reason, I believe the child events could be added under the room.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kegsay / @richvdh Any idea why these were not added under the rooms themselves? I'm guessing this was due to the original implementation going up and down the tree or something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kegsay might know better, but I think the idea is that it's possible under certain circumstances - particularly with pagination? - to return events without their parent rooms.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this was due to the original implementation going up and down the tree or something?

This is the main reason. The previous impl had children and parents, so it wasn't clear where each event should live. The new impl just has children which are events in the room, so it could in theory live under there. However, this wouldn't play nicely with any kind of pagination as vdh points out: if you have a room (so you know the name, topic, etc) you don't want to have to return that data again when returning the next page of results for the room.

following fields are returned: `type`, `state_key`, `content`, `room_id`,
`sender`.
clokep marked this conversation as resolved.
Show resolved Hide resolved

clokep marked this conversation as resolved.
Show resolved Hide resolved
#### Algorithm

1. Start at the "root" room (the provided room ID).
2. Generate a summary and add it to `rooms`.
3. Add any `m.space.child` events in the room to `events`.
4. Recurse into the targets of the `m.space.child` events, generate a summary for
each room and add it to `rooms`, also add any `m.space.child` events of the room
to `events`.
5. Recurse into grandchildren, etc. until either all discovered rooms have been
inspected, or the server-side limit on the number of rooms is reached.
clokep marked this conversation as resolved.
Show resolved Hide resolved

Other notes:

* If the user doesn't have permission to view/peek the root room (including if
that room does not exist), a 403 error is returned with `M_FORBIDDEN`. Any
inaccessible children are simply omitted from the result (though the `m.space.child`
events that point to them are still returned).
* There could be loops in the returned child events - clients should handle this
gracefully.
* Similarly, note that a child room might appear multiple times (e.g. also be a
grandchild).
* `suggested_only` applies transitively.

For example, if a space A has child space B which is *not* suggested, and space
B has suggested child room C, and the client makes a summary request for A with
`suggested_only=true`, neither B **nor** C will be returned.

Similarly, if a space A has child space B which is suggested, and space B has
suggested child room C which is suggested, and the client makes a summary request
for A with `suggested_only=true`, both B and C will be returned.
* The current implementation doesn't honour `order` fields in child events, as
suggested in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772).
clokep marked this conversation as resolved.
Show resolved Hide resolved
* `m.space.child` with an invalid `via` (invalid is defined as missing, not an
array or an empty array) are ignored.

### Server-server API
clokep marked this conversation as resolved.
Show resolved Hide resolved

Much the same interface as the Client-Server API.

Example request:

```jsonc
POST /_matrix/federation/v1/spaces/{roomID}
clokep marked this conversation as resolved.
Show resolved Hide resolved
{
"exclude_rooms": ["!a:b", "!b:c"],
"max_rooms_per_space": 5,
"suggested_only": true
}
```

The response has the same shape as the Client-Server API.
clokep marked this conversation as resolved.
Show resolved Hide resolved

Request params are the same as the Client-Server API, with the addition of:

* **`exclude_rooms`**: Optional. A list of room IDs that can be omitted
from the response.

This is largely the same as the Client-Server API, but differences are:

* The calling server can specify a list of spaces/rooms to omit from the
response (via `exclude_rooms`).
* `max_rooms_per_space` applies to the root room as well as any returned
children.
* If the target server is not a member of any discovered children (so
would have to send another request over federation to inspect them), no
attempt is made to recurse into them - they are simply omitted from the
response.
* If the target server is not a member of the root room, an empty
response is returned.
* Currently, no consideration is given to room membership: the spaces/rooms
must be world-readable (ie, peekable) for them to appear in the results.

## Potential issues

To reduce complexity, only a limited number of rooms are returned for a room,
no effort is made to paginate the results. Proper pagination is left to a future
MSC.
clokep marked this conversation as resolved.
Show resolved Hide resolved

## Alternatives

An initial version of this followed both `m.space.child` and `m.space.parent` events,
but this is unnecessary to provide the expected user experience.

## Security considerations

None.
clokep marked this conversation as resolved.
Show resolved Hide resolved

## Unstable prefix

During development of this feature it will be available at unstable endpoints.

The client-server API will be:
`/_matrix/client/unstable/org.matrix.msc2946/rooms/{roomID}/spaces`

The server-server API will be:
`/_matrix/federation/unstable/org.matrix.msc2946/spaces/{roomID}`