From 958282749391a13dc6f03c1dd13a9554fb5db3ae Mon Sep 17 00:00:00 2001 From: Sam Wedgwood <28223854+swedgwood@users.noreply.github.com> Date: Thu, 20 Jul 2023 15:06:05 +0100 Subject: de-MSC-ifying space summaries (MSC2946) (#3134) - 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 --- federationapi/api/api.go | 3 +- federationapi/internal/federationclient.go | 8 ++-- federationapi/routing/query.go | 64 ++++++++++++++++++++++++++++++ federationapi/routing/routing.go | 7 ++++ 4 files changed, 77 insertions(+), 5 deletions(-) (limited to 'federationapi') diff --git a/federationapi/api/api.go b/federationapi/api/api.go index 756f9bc1..efe0547d 100644 --- a/federationapi/api/api.go +++ b/federationapi/api/api.go @@ -27,7 +27,6 @@ type FederationInternalAPI interface { QueryServerKeys(ctx context.Context, request *QueryServerKeysRequest, response *QueryServerKeysResponse) error LookupServerKeys(ctx context.Context, s spec.ServerName, keyRequests map[gomatrixserverlib.PublicKeyLookupRequest]spec.Timestamp) ([]gomatrixserverlib.ServerKeys, error) MSC2836EventRelationships(ctx context.Context, origin, dst spec.ServerName, r fclient.MSC2836EventRelationshipsRequest, roomVersion gomatrixserverlib.RoomVersion) (res fclient.MSC2836EventRelationshipsResponse, err error) - MSC2946Spaces(ctx context.Context, origin, dst spec.ServerName, roomID string, suggestedOnly bool) (res fclient.MSC2946SpacesResponse, err error) // Broadcasts an EDU to all servers in rooms we are joined to. Used in the yggdrasil demos. PerformBroadcastEDU( @@ -75,6 +74,8 @@ type RoomserverFederationAPI interface { GetEventAuth(ctx context.Context, origin, s spec.ServerName, roomVersion gomatrixserverlib.RoomVersion, roomID, eventID string) (res fclient.RespEventAuth, err error) GetEvent(ctx context.Context, origin, s spec.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error) LookupMissingEvents(ctx context.Context, origin, s spec.ServerName, roomID string, missing fclient.MissingEvents, roomVersion gomatrixserverlib.RoomVersion) (res fclient.RespMissingEvents, err error) + + RoomHierarchies(ctx context.Context, origin, dst spec.ServerName, roomID string, suggestedOnly bool) (res fclient.RoomHierarchyResponse, err error) } type P2PFederationAPI interface { diff --git a/federationapi/internal/federationclient.go b/federationapi/internal/federationclient.go index 98854d34..b6bc7a5e 100644 --- a/federationapi/internal/federationclient.go +++ b/federationapi/internal/federationclient.go @@ -194,16 +194,16 @@ func (a *FederationInternalAPI) MSC2836EventRelationships( return ires.(fclient.MSC2836EventRelationshipsResponse), nil } -func (a *FederationInternalAPI) MSC2946Spaces( +func (a *FederationInternalAPI) RoomHierarchies( ctx context.Context, origin, s spec.ServerName, roomID string, suggestedOnly bool, -) (res fclient.MSC2946SpacesResponse, err error) { +) (res fclient.RoomHierarchyResponse, err error) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) { - return a.federation.MSC2946Spaces(ctx, origin, s, roomID, suggestedOnly) + return a.federation.RoomHierarchy(ctx, origin, s, roomID, suggestedOnly) }) if err != nil { return res, err } - return ires.(fclient.MSC2946SpacesResponse), nil + return ires.(fclient.RoomHierarchyResponse), nil } diff --git a/federationapi/routing/query.go b/federationapi/routing/query.go index 2e845f32..327ba9b0 100644 --- a/federationapi/routing/query.go +++ b/federationapi/routing/query.go @@ -20,12 +20,14 @@ import ( federationAPI "github.com/matrix-org/dendrite/federationapi/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib/fclient" "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) // RoomAliasToID converts the queried alias into a room ID and returns it @@ -116,3 +118,65 @@ func RoomAliasToID( JSON: resp, } } + +// Query the immediate children of a room/space +// +// Implements /_matrix/federation/v1/hierarchy/{roomID} +func QueryRoomHierarchy(httpReq *http.Request, request *fclient.FederationRequest, roomIDStr string, rsAPI roomserverAPI.FederationRoomserverAPI) util.JSONResponse { + parsedRoomID, err := spec.NewRoomID(roomIDStr) + if err != nil { + return util.JSONResponse{ + Code: http.StatusNotFound, + JSON: spec.InvalidParam("room is unknown/forbidden"), + } + } + roomID := *parsedRoomID + + suggestedOnly := false // Defaults to false (spec-defined) + switch httpReq.URL.Query().Get("suggested_only") { + case "true": + suggestedOnly = true + case "false": + case "": // Empty string is returned when query param is not set + default: + return util.JSONResponse{ + Code: http.StatusBadRequest, + JSON: spec.InvalidParam("query parameter 'suggested_only', if set, must be 'true' or 'false'"), + } + } + + walker := roomserverAPI.NewRoomHierarchyWalker(types.NewServerNameNotDevice(request.Origin()), roomID, suggestedOnly, 1) + discoveredRooms, _, err := rsAPI.QueryNextRoomHierarchyPage(httpReq.Context(), walker, -1) + + if err != nil { + switch err.(type) { + case roomserverAPI.ErrRoomUnknownOrNotAllowed: + util.GetLogger(httpReq.Context()).WithError(err).Debugln("room unknown/forbidden when handling SS room hierarchy request") + return util.JSONResponse{ + Code: http.StatusNotFound, + JSON: spec.NotFound("room is unknown/forbidden"), + } + default: + log.WithError(err).Errorf("failed to fetch next page of room hierarchy (SS API)") + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.Unknown("internal server error"), + } + } + } + + if len(discoveredRooms) == 0 { + util.GetLogger(httpReq.Context()).Debugln("no rooms found when handling SS room hierarchy request") + return util.JSONResponse{ + Code: 404, + JSON: spec.NotFound("room is unknown/forbidden"), + } + } + return util.JSONResponse{ + Code: 200, + JSON: fclient.RoomHierarchyResponse{ + Room: discoveredRooms[0], + Children: discoveredRooms[1:], + }, + } +} diff --git a/federationapi/routing/routing.go b/federationapi/routing/routing.go index 4f998821..dc7a363e 100644 --- a/federationapi/routing/routing.go +++ b/federationapi/routing/routing.go @@ -596,6 +596,13 @@ func Setup( return GetOpenIDUserInfo(req, userAPI) }), ).Methods(http.MethodGet) + + v1fedmux.Handle("/hierarchy/{roomID}", MakeFedAPI( + "federation_room_hierarchy", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup, + func(httpReq *http.Request, request *fclient.FederationRequest, vars map[string]string) util.JSONResponse { + return QueryRoomHierarchy(httpReq, request, vars["roomID"], rsAPI) + }, + )).Methods(http.MethodGet) } func ErrorIfLocalServerNotInRoom( -- cgit v1.2.3