From a930c0d0b1534f3bb885011fb16d36c7a91cd8a4 Mon Sep 17 00:00:00 2001 From: Cnly Date: Sat, 24 Aug 2019 01:35:01 +0800 Subject: [PATCH] Actually add servers in the servers field Signed-off-by: Alex Chen --- clientapi/clientapi.go | 4 +- clientapi/routing/directory.go | 78 +++++++++++++++----------- clientapi/routing/routing.go | 4 +- cmd/dendrite-client-api-server/main.go | 3 +- cmd/dendrite-monolith-server/main.go | 4 +- common/basecomponent/base.go | 7 +++ common/config/config.go | 9 +++ testfile | 3 + 8 files changed, 73 insertions(+), 39 deletions(-) diff --git a/clientapi/clientapi.go b/clientapi/clientapi.go index 5b6e21c80..f3f3e08cf 100644 --- a/clientapi/clientapi.go +++ b/clientapi/clientapi.go @@ -23,6 +23,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/routing" "github.com/matrix-org/dendrite/common/basecomponent" "github.com/matrix-org/dendrite/common/transactions" + federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" typingServerAPI "github.com/matrix-org/dendrite/typingserver/api" "github.com/matrix-org/gomatrixserverlib" @@ -43,6 +44,7 @@ func SetupClientAPIComponent( typingInputAPI typingServerAPI.TypingServerInputAPI, asAPI appserviceAPI.AppServiceQueryAPI, transactionsCache *transactions.Cache, + fedSenderAPI federationSenderAPI.FederationSenderQueryAPI, ) { roomserverProducer := producers.NewRoomserverProducer(inputAPI) typingProducer := producers.NewTypingServerProducer(typingInputAPI) @@ -67,6 +69,6 @@ func SetupClientAPIComponent( routing.Setup( base.APIMux, *base.Cfg, roomserverProducer, queryAPI, aliasAPI, asAPI, accountsDB, deviceDB, federation, *keyRing, userUpdateProducer, - syncProducer, typingProducer, transactionsCache, + syncProducer, typingProducer, transactionsCache, fedSenderAPI, ) } diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index 371c62f87..a35f66020 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -22,6 +22,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/common/config" + federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" @@ -33,6 +34,13 @@ type roomDirectoryResponse struct { Servers []string `json:"servers"` } +func (r *roomDirectoryResponse) fillServers(servers []gomatrixserverlib.ServerName) { + r.Servers = make([]string, len(servers)) + for i, s := range servers { + r.Servers[i] = string(s) + } +} + // DirectoryRoom looks up a room alias func DirectoryRoom( req *http.Request, @@ -40,6 +48,7 @@ func DirectoryRoom( federation *gomatrixserverlib.FederationClient, cfg *config.Dendrite, rsAPI roomserverAPI.RoomserverAliasAPI, + fedSenderAPI federationSenderAPI.FederationSenderQueryAPI, ) util.JSONResponse { _, domain, err := gomatrixserverlib.SplitID('#', roomAlias) if err != nil { @@ -49,52 +58,53 @@ func DirectoryRoom( } } - if domain == cfg.Matrix.ServerName { - // 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 { - return httputil.LogThenError(req, err) - } + var res roomDirectoryResponse - // List any roomIDs found associated with this alias - if len(queryRes.RoomID) > 0 { - return util.JSONResponse{ - Code: http.StatusOK, - JSON: roomDirectoryResponse{ - RoomID: queryRes.RoomID, - Servers: []string{}, // TODO-aliases - }, - } - } - } else { - // Query the federation for this room alias - resp, err := federation.LookupRoomAlias(req.Context(), domain, roomAlias) - if err != nil { - switch err.(type) { + // 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 { + return httputil.LogThenError(req, err) + } + + res.RoomID = queryRes.RoomID + + if res.RoomID == "" { + // If we don't know it locally, do a federation query. + fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias) + if fedErr != nil { + switch fedErr.(type) { case gomatrix.HTTPError: - default: // TODO: Return 502 if the remote server errored. // TODO: Return 504 if the remote server timed out. - return httputil.LogThenError(req, err) + return httputil.LogThenError(req, fedErr) + default: + return httputil.LogThenError(req, fedErr) } } - if len(resp.RoomID) > 0 { + if fedRes.RoomID == "" { return util.JSONResponse{ - Code: http.StatusOK, - JSON: roomDirectoryResponse{ - RoomID: resp.RoomID, - Servers: []string{}, // TODO-aliases - }, + Code: http.StatusNotFound, + JSON: jsonerror.NotFound( + fmt.Sprintf("Room alias %s not found", roomAlias), + ), } } + + res.RoomID = fedRes.RoomID + res.fillServers(fedRes.Servers) + } else { + joinedHostsReq := federationSenderAPI.QueryJoinedHostServerNamesInRoomRequest{RoomID: res.RoomID} + var joinedHostsRes federationSenderAPI.QueryJoinedHostServerNamesInRoomResponse + if err = fedSenderAPI.QueryJoinedHostServerNamesInRoom(req.Context(), &joinedHostsReq, &joinedHostsRes); err != nil { + return httputil.LogThenError(req, err) + } + res.fillServers(joinedHostsRes.ServerNames) } return util.JSONResponse{ - Code: http.StatusNotFound, - JSON: jsonerror.NotFound( - fmt.Sprintf("Room alias %s not found", roomAlias), - ), + Code: http.StatusOK, + JSON: res, } } diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index d4b323a2d..4a36661db 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -30,6 +30,7 @@ import ( "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/transactions" + federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -59,6 +60,7 @@ func Setup( syncProducer *producers.SyncAPIProducer, typingProducer *producers.TypingServerProducer, transactionsCache *transactions.Cache, + federationSender federationSenderAPI.FederationSenderQueryAPI, ) { apiMux.Handle("/_matrix/client/versions", @@ -185,7 +187,7 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI) + return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI, federationSender) }), ).Methods(http.MethodGet, http.MethodOptions) diff --git a/cmd/dendrite-client-api-server/main.go b/cmd/dendrite-client-api-server/main.go index dd0656441..e273ecadb 100644 --- a/cmd/dendrite-client-api-server/main.go +++ b/cmd/dendrite-client-api-server/main.go @@ -37,11 +37,12 @@ func main() { asQuery := base.CreateHTTPAppServiceAPIs() alias, input, query := base.CreateHTTPRoomserverAPIs() + fedSenderAPI := base.CreateHTTPFederationSenderAPIs() typingInputAPI := typingserver.SetupTypingServerComponent(base, cache.NewTypingCache()) clientapi.SetupClientAPIComponent( base, deviceDB, accountDB, federation, &keyRing, - alias, input, query, typingInputAPI, asQuery, transactions.New(), + alias, input, query, typingInputAPI, asQuery, transactions.New(), fedSenderAPI, ) base.SetupAndServeHTTP(string(base.Cfg.Listen.ClientAPI)) diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go index 87a625b8b..0a320616e 100644 --- a/cmd/dendrite-monolith-server/main.go +++ b/cmd/dendrite-monolith-server/main.go @@ -60,14 +60,14 @@ func main() { asQuery := appservice.SetupAppServiceAPIComponent( base, accountDB, deviceDB, federation, alias, query, transactions.New(), ) + fedSenderAPI := federationsender.SetupFederationSenderComponent(base, federation, query) clientapi.SetupClientAPIComponent( base, deviceDB, accountDB, federation, &keyRing, alias, input, query, - typingInputAPI, asQuery, transactions.New(), + typingInputAPI, asQuery, transactions.New(), fedSenderAPI, ) federationapi.SetupFederationAPIComponent(base, accountDB, deviceDB, federation, &keyRing, alias, input, query, asQuery) - federationsender.SetupFederationSenderComponent(base, federation, query) mediaapi.SetupMediaAPIComponent(base, deviceDB) publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB) syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query) diff --git a/common/basecomponent/base.go b/common/basecomponent/base.go index 6a20aca3b..503134b23 100644 --- a/common/basecomponent/base.go +++ b/common/basecomponent/base.go @@ -32,6 +32,7 @@ import ( appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/common/config" + federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" typingServerAPI "github.com/matrix-org/dendrite/typingserver/api" "github.com/sirupsen/logrus" @@ -107,6 +108,12 @@ func (b *BaseDendrite) CreateHTTPTypingServerAPIs() typingServerAPI.TypingServer return typingServerAPI.NewTypingServerInputAPIHTTP(b.Cfg.TypingServerURL(), nil) } +// CreateHTTPFederationSenderAPIs returns FederationSenderQueryAPI for hitting +// the federation sender over HTTP +func (b *BaseDendrite) CreateHTTPFederationSenderAPIs() federationSenderAPI.FederationSenderQueryAPI { + return federationSenderAPI.NewFederationSenderQueryAPIHTTP(b.Cfg.FederationSenderURL(), nil) +} + // CreateDeviceDB creates a new instance of the device database. Should only be // called once per component. func (b *BaseDendrite) CreateDeviceDB() *devices.Database { diff --git a/common/config/config.go b/common/config/config.go index 40232fb03..16cf26408 100644 --- a/common/config/config.go +++ b/common/config/config.go @@ -678,6 +678,15 @@ func (config *Dendrite) TypingServerURL() string { return "http://" + string(config.Listen.TypingServer) } +// FederationSenderURL returns an HTTP URL for where the federation sender is listening. +func (config *Dendrite) FederationSenderURL() string { + // Hard code the typing server to talk HTTP for now. + // If we support HTTPS we need to think of a practical way to do certificate validation. + // People setting up servers shouldn't need to get a certificate valid for the public + // internet for an internal API. + return "http://" + string(config.Listen.FederationSender) +} + // SetupTracing configures the opentracing using the supplied configuration. func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err error) { return config.Tracing.Jaeger.InitGlobalTracer( diff --git a/testfile b/testfile index a93dca16f..963c1f7ce 100644 --- a/testfile +++ b/testfile @@ -178,3 +178,6 @@ Creators can delete alias Alias creators can delete alias with no ops Alias creators can delete canonical alias with no ops Regular users cannot create room aliases within the AS namespace +Deleting a non-existent alias should return a 404 +Users can't delete other's aliases +Outbound federation can query room alias directory