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 <ross@rbs.io>

* Run gofmt

* Check for empty alias parameter and fix route URL

Signed-off-by: Ross Schulman <ross@rbs.io>

* Fix some linting errors

Signed-off-by: Ross Schulman <ross@rbs.io>

* Delete extra copy of directory route
This commit is contained in:
Ross Schulman 2017-11-20 09:33:49 -05:00 committed by Erik Johnston
parent 19a716e7da
commit ea53558cca
4 changed files with 109 additions and 2 deletions

View File

@ -80,6 +80,7 @@ func main() {
queryAPI := api.NewRoomserverQueryAPIHTTP(cfg.RoomServerURL(), nil) queryAPI := api.NewRoomserverQueryAPIHTTP(cfg.RoomServerURL(), nil)
inputAPI := api.NewRoomserverInputAPIHTTP(cfg.RoomServerURL(), nil) inputAPI := api.NewRoomserverInputAPIHTTP(cfg.RoomServerURL(), nil)
aliasAPI := api.NewRoomserverAliasAPIHTTP(cfg.RoomServerURL(), nil)
roomserverProducer := producers.NewRoomserverProducer(inputAPI) roomserverProducer := producers.NewRoomserverProducer(inputAPI)
@ -90,7 +91,7 @@ func main() {
log.Info("Starting federation API server on ", cfg.Listen.FederationAPI) log.Info("Starting federation API server on ", cfg.Listen.FederationAPI)
api := mux.NewRouter() 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) common.SetupHTTPAPI(http.DefaultServeMux, api)
log.Fatal(http.ListenAndServe(string(cfg.Listen.FederationAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.FederationAPI), nil))

View File

@ -348,7 +348,7 @@ func (m *monolith) setupAPIs() {
), m.syncAPIDB, m.deviceDB) ), m.syncAPIDB, m.deviceDB)
federationapi_routing.Setup( 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, m.accountDB,
) )

View File

@ -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,
}
}

View File

@ -38,6 +38,7 @@ func Setup(
apiMux *mux.Router, apiMux *mux.Router,
cfg config.Dendrite, cfg config.Dendrite,
query api.RoomserverQueryAPI, query api.RoomserverQueryAPI,
aliasAPI api.RoomserverAliasAPI,
producer *producers.RoomserverProducer, producer *producers.RoomserverProducer,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.KeyRing,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
@ -105,6 +106,15 @@ func Setup(
}, },
)).Methods("GET") )).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( v1fedmux.Handle("/query/profile", common.MakeFedAPI(
"federation_query_profile", cfg.Matrix.ServerName, keys, "federation_query_profile", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {