aboutsummaryrefslogtreecommitdiff
path: root/roomserver/api
diff options
context:
space:
mode:
authorSam Wedgwood <28223854+swedgwood@users.noreply.github.com>2023-07-20 15:06:05 +0100
committerGitHub <noreply@github.com>2023-07-20 15:06:05 +0100
commit958282749391a13dc6f03c1dd13a9554fb5db3ae (patch)
tree1f370ac9cf956667923756bf851b9329c2c67b98 /roomserver/api
parent297479ea4993f00a60600232485275d2c57462fe (diff)
de-MSC-ifying space summaries (MSC2946) (#3134)helm-dendrite-0.13.1
- This PR moves and refactors the [code](https://github.com/matrix-org/dendrite/blob/main/setup/mscs/msc2946/msc2946.go) for [MSC2946](https://github.com/matrix-org/matrix-spec-proposals/pull/2946) ('Space Summaries') to integrate it into the rest of the codebase. - Means space summaries are no longer hidden behind an MSC flag - Solves #3096 Signed-off-by: Sam Wedgwood <sam@wedgwood.dev>
Diffstat (limited to 'roomserver/api')
-rw-r--r--roomserver/api/api.go24
-rw-r--r--roomserver/api/query.go76
2 files changed, 100 insertions, 0 deletions
diff --git a/roomserver/api/api.go b/roomserver/api/api.go
index c29406a1..28b381d3 100644
--- a/roomserver/api/api.go
+++ b/roomserver/api/api.go
@@ -34,6 +34,17 @@ func (e ErrNotAllowed) Error() string {
return e.Err.Error()
}
+// ErrRoomUnknownOrNotAllowed is an error return if either the provided
+// room ID does not exist, or points to a room that the requester does
+// not have access to.
+type ErrRoomUnknownOrNotAllowed struct {
+ Err error
+}
+
+func (e ErrRoomUnknownOrNotAllowed) Error() string {
+ return e.Err.Error()
+}
+
type RestrictedJoinAPI interface {
CurrentStateEvent(ctx context.Context, roomID spec.RoomID, eventType string, stateKey string) (gomatrixserverlib.PDU, error)
InvitePending(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (bool, error)
@@ -113,6 +124,17 @@ type QueryEventsAPI interface {
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
}
+type QueryRoomHierarchyAPI interface {
+ // Traverse the room hierarchy using the provided walker up to the provided limit,
+ // returning a new walker which can be used to fetch the next page.
+ //
+ // If limit is -1, this is treated as no limit, and the entire hierarchy will be traversed.
+ //
+ // If returned walker is nil, then there are no more rooms left to traverse. This method does not modify the provided walker, so it
+ // can be cached.
+ QueryNextRoomHierarchyPage(ctx context.Context, walker RoomHierarchyWalker, limit int) ([]fclient.RoomHierarchyRoom, *RoomHierarchyWalker, error)
+}
+
// API functions required by the syncapi
type SyncRoomserverAPI interface {
QueryLatestEventsAndStateAPI
@@ -187,6 +209,7 @@ type ClientRoomserverAPI interface {
QueryEventsAPI
QuerySenderIDAPI
UserRoomPrivateKeyCreator
+ QueryRoomHierarchyAPI
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
@@ -236,6 +259,7 @@ type FederationRoomserverAPI interface {
QueryLatestEventsAndStateAPI
QueryBulkStateContentAPI
QuerySenderIDAPI
+ QueryRoomHierarchyAPI
UserRoomPrivateKeyCreator
AssignRoomNID(ctx context.Context, roomID spec.RoomID, roomVersion gomatrixserverlib.RoomVersion) (roomNID types.RoomNID, err error)
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
diff --git a/roomserver/api/query.go b/roomserver/api/query.go
index b6140afd..57bac2df 100644
--- a/roomserver/api/query.go
+++ b/roomserver/api/query.go
@@ -503,3 +503,79 @@ func (mq *MembershipQuerier) CurrentMembership(ctx context.Context, roomID spec.
}
return membership, err
}
+
+type QueryRoomHierarchyRequest struct {
+ SuggestedOnly bool `json:"suggested_only"`
+ Limit int `json:"limit"`
+ MaxDepth int `json:"max_depth"`
+ From int `json:"json"`
+}
+
+// A struct storing the intermediate state of a room hierarchy query for pagination purposes.
+//
+// Used for implementing space summaries / room hierarchies
+//
+// Use NewRoomHierarchyWalker to construct this, and QueryNextRoomHierarchyPage on the roomserver API
+// to traverse the room hierarchy.
+type RoomHierarchyWalker struct {
+ RootRoomID spec.RoomID
+ Caller types.DeviceOrServerName
+ SuggestedOnly bool
+ MaxDepth int
+ Processed RoomSet
+ Unvisited []RoomHierarchyWalkerQueuedRoom
+}
+
+type RoomHierarchyWalkerQueuedRoom struct {
+ RoomID spec.RoomID
+ ParentRoomID *spec.RoomID
+ Depth int
+ Vias []string // vias to query this room by
+}
+
+// Create a new room hierarchy walker, starting from the provided root room ID.
+//
+// Use the resulting struct with QueryNextRoomHierarchyPage on the roomserver API to traverse the room hierarchy.
+func NewRoomHierarchyWalker(caller types.DeviceOrServerName, roomID spec.RoomID, suggestedOnly bool, maxDepth int) RoomHierarchyWalker {
+ walker := RoomHierarchyWalker{
+ RootRoomID: roomID,
+ Caller: caller,
+ SuggestedOnly: suggestedOnly,
+ MaxDepth: maxDepth,
+ Unvisited: []RoomHierarchyWalkerQueuedRoom{{
+ RoomID: roomID,
+ ParentRoomID: nil,
+ Depth: 0,
+ }},
+ Processed: NewRoomSet(),
+ }
+
+ return walker
+}
+
+// A set of room IDs.
+type RoomSet map[spec.RoomID]struct{}
+
+// Create a new empty room set.
+func NewRoomSet() RoomSet {
+ return RoomSet{}
+}
+
+// Check if a room ID is in a room set.
+func (s RoomSet) Contains(val spec.RoomID) bool {
+ _, ok := s[val]
+ return ok
+}
+
+// Add a room ID to a room set.
+func (s RoomSet) Add(val spec.RoomID) {
+ s[val] = struct{}{}
+}
+
+func (s RoomSet) Copy() RoomSet {
+ copied := make(RoomSet, len(s))
+ for k := range s {
+ copied.Add(k)
+ }
+ return copied
+}