From ea53558cca358f0b72141922ab37a8b41ee775f6 Mon Sep 17 00:00:00 2001 From: Ross Schulman Date: Mon, 20 Nov 2017 09:33:49 -0500 Subject: [PATCH] Implement room_alias federation end point (#338) * Add room alias query endpoint * Try to fix indentation problems * Fix linting errors and use of httpReq.FormValue Signed-off-by: Ross Schulman * Run gofmt * Check for empty alias parameter and fix route URL Signed-off-by: Ross Schulman * Fix some linting errors Signed-off-by: Ross Schulman * Delete extra copy of directory route --- .../dendrite-federation-api-server/main.go | 3 +- .../cmd/dendrite-monolith-server/main.go | 2 +- .../dendrite/federationapi/routing/query.go | 96 +++++++++++++++++++ .../dendrite/federationapi/routing/routing.go | 10 ++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/github.com/matrix-org/dendrite/federationapi/routing/query.go diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go index ba981d8c..53587ee2 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go @@ -80,6 +80,7 @@ func main() { queryAPI := api.NewRoomserverQueryAPIHTTP(cfg.RoomServerURL(), nil) inputAPI := api.NewRoomserverInputAPIHTTP(cfg.RoomServerURL(), nil) + aliasAPI := api.NewRoomserverAliasAPIHTTP(cfg.RoomServerURL(), nil) roomserverProducer := producers.NewRoomserverProducer(inputAPI) @@ -90,7 +91,7 @@ func main() { log.Info("Starting federation API server on ", cfg.Listen.FederationAPI) api := mux.NewRouter() - routing.Setup(api, *cfg, queryAPI, roomserverProducer, keyRing, federation, accountDB) + routing.Setup(api, *cfg, queryAPI, aliasAPI, roomserverProducer, keyRing, federation, accountDB) common.SetupHTTPAPI(http.DefaultServeMux, api) log.Fatal(http.ListenAndServe(string(cfg.Listen.FederationAPI), nil)) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go index fafd4cb8..05fc4252 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go @@ -348,7 +348,7 @@ func (m *monolith) setupAPIs() { ), m.syncAPIDB, m.deviceDB) federationapi_routing.Setup( - m.api, *m.cfg, m.queryAPI, m.roomServerProducer, m.keyRing, m.federation, + m.api, *m.cfg, m.queryAPI, m.aliasAPI, m.roomServerProducer, m.keyRing, m.federation, m.accountDB, ) diff --git a/src/github.com/matrix-org/dendrite/federationapi/routing/query.go b/src/github.com/matrix-org/dendrite/federationapi/routing/query.go new file mode 100644 index 00000000..ef4b8961 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/federationapi/routing/query.go @@ -0,0 +1,96 @@ +// Copyright 2017 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package routing + +import ( + "fmt" + "net/http" + + "github.com/matrix-org/dendrite/clientapi/httputil" + "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/dendrite/common/config" + "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/gomatrix" + "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/util" +) + +// RoomAliasToID converts the queried alias into a room ID and returns it +func RoomAliasToID( + httpReq *http.Request, + federation *gomatrixserverlib.FederationClient, + cfg config.Dendrite, + aliasAPI api.RoomserverAliasAPI, +) util.JSONResponse { + roomAlias := httpReq.FormValue("alias") + if roomAlias == "" { + return util.JSONResponse{ + Code: 400, + JSON: jsonerror.BadJSON("Must supply room alias parameter."), + } + } + _, domain, err := gomatrixserverlib.SplitID('#', roomAlias) + if err != nil { + return util.JSONResponse{ + Code: 400, + JSON: jsonerror.BadJSON("Room alias must be in the form '#localpart:domain'"), + } + } + + var resp gomatrixserverlib.RespDirectory + + if domain == cfg.Matrix.ServerName { + queryReq := api.GetAliasRoomIDRequest{Alias: roomAlias} + var queryRes api.GetAliasRoomIDResponse + if err = aliasAPI.GetAliasRoomID(httpReq.Context(), &queryReq, &queryRes); err != nil { + return httputil.LogThenError(httpReq, err) + } + + if queryRes.RoomID == "" { + // TODO: List servers that are aware of this room alias + resp = gomatrixserverlib.RespDirectory{ + RoomID: queryRes.RoomID, + Servers: []gomatrixserverlib.ServerName{}, + } + } else { + // If the response doesn't contain a non-empty string, return an error + return util.JSONResponse{ + Code: 404, + JSON: jsonerror.NotFound(fmt.Sprintf("Room alias %s not found", roomAlias)), + } + } + } else { + resp, err = federation.LookupRoomAlias(httpReq.Context(), domain, roomAlias) + if err != nil { + switch x := err.(type) { + case gomatrix.HTTPError: + if x.Code == 404 { + return util.JSONResponse{ + Code: 404, + JSON: jsonerror.NotFound("Room alias not found"), + } + } + } + // TODO: Return 502 if the remote server errored. + // TODO: Return 504 if the remote server timed out. + return httputil.LogThenError(httpReq, err) + } + } + + return util.JSONResponse{ + Code: 200, + JSON: resp, + } +} diff --git a/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go b/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go index c50afd6e..b23d738f 100644 --- a/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go @@ -38,6 +38,7 @@ func Setup( apiMux *mux.Router, cfg config.Dendrite, query api.RoomserverQueryAPI, + aliasAPI api.RoomserverAliasAPI, producer *producers.RoomserverProducer, keys gomatrixserverlib.KeyRing, federation *gomatrixserverlib.FederationClient, @@ -105,6 +106,15 @@ func Setup( }, )).Methods("GET") + v1fedmux.Handle("/query/directory/", common.MakeFedAPI( + "federation_query_room_alias", cfg.Matrix.ServerName, keys, + func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { + return RoomAliasToID( + httpReq, federation, cfg, aliasAPI, + ) + }, + )).Methods("GET") + v1fedmux.Handle("/query/profile", common.MakeFedAPI( "federation_query_profile", cfg.Matrix.ServerName, keys, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {