From 9557ccada4efe50d0f370019ad0b9f017fc7ebcf Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 3 Mar 2021 17:00:31 +0000 Subject: [PATCH] Fix appsevice alias queries part 2 (#1684) * Check membership of room * Use QueryStateAfterEventsResponse * Fix complexity * Add field ShouldHitAppservice to GetRoomIDForAlias * Hit appservice when trying to join a non-existent alias * remove unused * Changes that I made a long time ago * Rename to appserviceJoinedAtEvent * Check membership in GetMemberships * Update QueryMembershipsForRoom * Tweaks in client API * Update appserviceJoinedAtEvent * Comments * Try QueryMembershipForUser instead * Undo some changes to client API that shouldn't be needed * More /event tweaks * Refactor /event bit * Go back to QueryMembershipsForRoom because appservices are hard * Fix bugs in onMessage * Add comments * More logical naming, clean up a bit Co-authored-by: Neil Alexander --- clientapi/routing/createroom.go | 3 +- clientapi/routing/directory.go | 9 +++-- federationapi/routing/query.go | 9 +++-- roomserver/api/alias.go | 3 ++ roomserver/internal/alias.go | 40 +++++++++++---------- roomserver/internal/api.go | 1 + roomserver/internal/perform/perform_join.go | 10 +++++- 7 files changed, 49 insertions(+), 26 deletions(-) diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go index 9be0b512..2d886746 100644 --- a/clientapi/routing/createroom.go +++ b/clientapi/routing/createroom.go @@ -217,7 +217,8 @@ func createRoom( roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, cfg.Matrix.ServerName) // check it's free TODO: This races but is better than nothing hasAliasReq := roomserverAPI.GetRoomIDForAliasRequest{ - Alias: roomAlias, + Alias: roomAlias, + IncludeAppservices: false, } var aliasResp roomserverAPI.GetRoomIDForAliasResponse diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index 1b844c4e..0e994b64 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -61,9 +61,12 @@ func DirectoryRoom( var res roomDirectoryResponse // Query the roomserver API to check if the alias exists locally. - queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias} - var queryRes roomserverAPI.GetRoomIDForAliasResponse - if err = rsAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil { + queryReq := &roomserverAPI.GetRoomIDForAliasRequest{ + Alias: roomAlias, + IncludeAppservices: true, + } + queryRes := &roomserverAPI.GetRoomIDForAliasResponse{} + if err = rsAPI.GetRoomIDForAlias(req.Context(), queryReq, queryRes); err != nil { util.GetLogger(req.Context()).WithError(err).Error("rsAPI.GetRoomIDForAlias failed") return jsonerror.InternalServerError() } diff --git a/federationapi/routing/query.go b/federationapi/routing/query.go index 6c25b4d3..b4158f0c 100644 --- a/federationapi/routing/query.go +++ b/federationapi/routing/query.go @@ -53,9 +53,12 @@ func RoomAliasToID( var resp gomatrixserverlib.RespDirectory if domain == cfg.Matrix.ServerName { - queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias} - var queryRes roomserverAPI.GetRoomIDForAliasResponse - if err = rsAPI.GetRoomIDForAlias(httpReq.Context(), &queryReq, &queryRes); err != nil { + queryReq := &roomserverAPI.GetRoomIDForAliasRequest{ + Alias: roomAlias, + IncludeAppservices: true, + } + queryRes := &roomserverAPI.GetRoomIDForAliasResponse{} + if err = rsAPI.GetRoomIDForAlias(httpReq.Context(), queryReq, queryRes); err != nil { util.GetLogger(httpReq.Context()).WithError(err).Error("aliasAPI.GetRoomIDForAlias failed") return jsonerror.InternalServerError() } diff --git a/roomserver/api/alias.go b/roomserver/api/alias.go index 61fdc611..2eb91129 100644 --- a/roomserver/api/alias.go +++ b/roomserver/api/alias.go @@ -34,6 +34,9 @@ type SetRoomAliasResponse struct { type GetRoomIDForAliasRequest struct { // Alias we want to lookup Alias string `json:"alias"` + // Should we ask appservices for their aliases as a part of + // the request? + IncludeAppservices bool `json:"include_appservices"` } // GetRoomIDForAliasResponse is a response to GetRoomIDForAlias diff --git a/roomserver/internal/alias.go b/roomserver/internal/alias.go index 843b0bcc..f15881d7 100644 --- a/roomserver/internal/alias.go +++ b/roomserver/internal/alias.go @@ -88,31 +88,35 @@ func (r *RoomserverInternalAPI) GetRoomIDForAlias( ) error { // Look up the room ID in the database roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias) - if err != nil { - return err + if err == nil && roomID != "" { + response.RoomID = roomID + return nil } - if r.asAPI != nil { // appservice component is wired in - if roomID == "" { - // No room found locally, try our application services by making a call to - // the appservice component - aliasReq := asAPI.RoomAliasExistsRequest{Alias: request.Alias} - var aliasResp asAPI.RoomAliasExistsResponse - if err = r.asAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil { + // Check appservice on err, but only if the appservice API is + // wired in and no room ID was found. + if r.asAPI != nil && request.IncludeAppservices && roomID == "" { + // No room found locally, try our application services by making a call to + // the appservice component + aliasReq := &asAPI.RoomAliasExistsRequest{ + Alias: request.Alias, + } + aliasRes := &asAPI.RoomAliasExistsResponse{} + if err = r.asAPI.RoomAliasExists(ctx, aliasReq, aliasRes); err != nil { + return err + } + + if aliasRes.AliasExists { + roomID, err = r.DB.GetRoomIDForAlias(ctx, request.Alias) + if err != nil { return err } - - if aliasResp.AliasExists { - roomID, err = r.DB.GetRoomIDForAlias(ctx, request.Alias) - if err != nil { - return err - } - } + response.RoomID = roomID + return nil } } - response.RoomID = roomID - return nil + return err } // GetAliasesForRoomID implements alias.RoomserverInternalAPI diff --git a/roomserver/internal/api.go b/roomserver/internal/api.go index e10bdb46..5b8959b0 100644 --- a/roomserver/internal/api.go +++ b/roomserver/internal/api.go @@ -89,6 +89,7 @@ func (r *RoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsAPI.FederationSen Cfg: r.Cfg, DB: r.DB, FSAPI: r.fsAPI, + RSAPI: r, Inputer: r.Inputer, } r.Peeker = &perform.Peeker{ diff --git a/roomserver/internal/perform/perform_join.go b/roomserver/internal/perform/perform_join.go index 453901fc..ada584a8 100644 --- a/roomserver/internal/perform/perform_join.go +++ b/roomserver/internal/perform/perform_join.go @@ -24,6 +24,7 @@ import ( fsAPI "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" + rsAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/internal/helpers" "github.com/matrix-org/dendrite/roomserver/internal/input" "github.com/matrix-org/dendrite/roomserver/storage" @@ -36,6 +37,7 @@ type Joiner struct { ServerName gomatrixserverlib.ServerName Cfg *config.RoomServer FSAPI fsAPI.FederationSenderInternalAPI + RSAPI rsAPI.RoomserverInternalAPI DB storage.Database Inputer *input.Inputer @@ -121,11 +123,17 @@ func (r *Joiner) performJoinRoomByAlias( roomID = dirRes.RoomID req.ServerNames = append(req.ServerNames, dirRes.ServerNames...) } else { + var getRoomReq = rsAPI.GetRoomIDForAliasRequest{ + Alias: req.RoomIDOrAlias, + IncludeAppservices: true, + } + var getRoomRes = rsAPI.GetRoomIDForAliasResponse{} // Otherwise, look up if we know this room alias locally. - roomID, err = r.DB.GetRoomIDForAlias(ctx, req.RoomIDOrAlias) + err = r.RSAPI.GetRoomIDForAlias(ctx, &getRoomReq, &getRoomRes) if err != nil { return "", "", fmt.Errorf("Lookup room alias %q failed: %w", req.RoomIDOrAlias, err) } + roomID = getRoomRes.RoomID } // If the room ID is empty then we failed to look up the alias.