diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/directory.go b/src/github.com/matrix-org/dendrite/clientapi/readers/directory.go index 1651fa889..fd5fc778f 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/directory.go +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/directory.go @@ -15,7 +15,6 @@ package readers import ( - "fmt" "net/http" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" @@ -39,6 +38,7 @@ func DirectoryRoom( roomAlias string, federation *gomatrixserverlib.FederationClient, cfg *config.Dendrite, + queryAPI api.RoomserverQueryAPI, ) util.JSONResponse { _, domain, err := gomatrixserverlib.SplitID('#', roomAlias) if err != nil { @@ -48,11 +48,30 @@ func DirectoryRoom( } } + var resp gomatrixserverlib.RespDirectory + if domain == cfg.Matrix.ServerName { - // TODO: Implement lookup up local room aliases. - panic(fmt.Errorf("Looking up local room aliases is not implemented")) + queryReq := api.GetAliasRoomIDRequest{Alias: roomAlias} + var queryRes api.GetAliasRoomIDResponse + if err = queryAPI.GetAliasRoomID(&queryReq, &queryRes); err != nil { + return httputil.LogThenError(req, err) + } + + if len(queryRes.RoomID) > 0 { + // 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("Room alias " + roomAlias + " not found."), + } + } } else { - resp, err := federation.LookupRoomAlias(domain, roomAlias) + resp, err = federation.LookupRoomAlias(domain, roomAlias) if err != nil { switch x := err.(type) { case gomatrix.HTTPError: @@ -67,11 +86,11 @@ func DirectoryRoom( // TODO: Return 504 if the remote server timed out. return httputil.LogThenError(req, err) } + } - return util.JSONResponse{ - Code: 200, - JSON: resp, - } + return util.JSONResponse{ + Code: 200, + JSON: resp, } } diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go index 839783c48..217ba4158 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -109,7 +109,7 @@ func Setup( r0mux.Handle("/directory/room/{roomAlias}", common.MakeAuthAPI("directory_room", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { vars := mux.Vars(req) - return readers.DirectoryRoom(req, device, vars["roomAlias"], federation, &cfg) + return readers.DirectoryRoom(req, device, vars["roomAlias"], federation, &cfg, queryAPI) }), ).Methods("GET") diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/query.go b/src/github.com/matrix-org/dendrite/roomserver/api/query.go index dc2acaacf..cae7ec1ae 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/query.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/query.go @@ -116,6 +116,18 @@ type SetRoomAliasResponse struct { AliasExists bool `json:"alias_exists"` } +// GetAliasRoomIDRequest is a request to GetAliasRoomID +type GetAliasRoomIDRequest struct { + // Alias we want to lookup + Alias string `json:"alias"` +} + +// GetAliasRoomIDResponse is a response to GetAliasRoomID +type GetAliasRoomIDResponse struct { + // The room ID the alias refers to + RoomID string `json:"room_id"` +} + // RoomserverQueryAPI is used to query information from the room server. type RoomserverQueryAPI interface { // Query the latest events and state for a room from the room server. @@ -141,6 +153,12 @@ type RoomserverQueryAPI interface { request *SetRoomAliasRequest, response *SetRoomAliasResponse, ) error + + // Get the room ID for an alias + GetAliasRoomID( + request *GetAliasRoomIDRequest, + response *GetAliasRoomIDResponse, + ) error } // RoomserverQueryLatestEventsAndStatePath is the HTTP path for the QueryLatestEventsAndState API. @@ -155,6 +173,9 @@ const RoomserverQueryEventsByIDPath = "/api/roomserver/queryEventsByID" // RoomserverSetRoomAliasPath is the HTTP path for the SetRoomAlias API. const RoomserverSetRoomAliasPath = "/api/roomserver/setRoomAlias" +// RoomserverGetAliasRoomIDPath is the HTTP path for the GetAliasRoomID API. +const RoomserverGetAliasRoomIDPath = "/api/roomserver/getAliasRoomID" + // NewRoomserverQueryAPIHTTP creates a RoomserverQueryAPI implemented by talking to a HTTP POST API. // If httpClient is nil then it uses the http.DefaultClient func NewRoomserverQueryAPIHTTP(roomserverURL string, httpClient *http.Client) RoomserverQueryAPI { @@ -205,6 +226,15 @@ func (h *httpRoomserverQueryAPI) SetRoomAlias( return postJSON(h.httpClient, apiURL, request, response) } +// GetAliasRoomID implements RoomserverQueryAPI +func (h *httpRoomserverQueryAPI) GetAliasRoomID( + request *GetAliasRoomIDRequest, + response *GetAliasRoomIDResponse, +) error { + apiURL := h.roomserverURL + RoomserverGetAliasRoomIDPath + return postJSON(h.httpClient, apiURL, request, response) +} + func postJSON(httpClient *http.Client, apiURL string, request, response interface{}) error { jsonBytes, err := json.Marshal(request) if err != nil { diff --git a/src/github.com/matrix-org/dendrite/roomserver/query/query.go b/src/github.com/matrix-org/dendrite/roomserver/query/query.go index 0b72f43aa..a58b586bf 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/query/query.go +++ b/src/github.com/matrix-org/dendrite/roomserver/query/query.go @@ -197,6 +197,21 @@ func (r *RoomserverQueryAPI) SetRoomAlias( return nil } +// GetAliasRoomID implements api.RoomserverQueryAPI +func (r *RoomserverQueryAPI) GetAliasRoomID( + request *api.GetAliasRoomIDRequest, + response *api.GetAliasRoomIDResponse, +) error { + // Lookup the room ID in the database + roomID, err := r.DB.GetRoomIDFromAlias(request.Alias) + if err != nil { + return err + } + + response.RoomID = roomID + return nil +} + type roomAliasesContent struct { Aliases []string `json:"aliases"` } @@ -363,4 +378,18 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) { return util.JSONResponse{Code: 200, JSON: &response} }), ) + servMux.Handle( + api.RoomserverGetAliasRoomIDPath, + common.MakeAPI("getAliasRoomID", func(req *http.Request) util.JSONResponse { + var request api.GetAliasRoomIDRequest + var response api.GetAliasRoomIDResponse + if err := json.NewDecoder(req.Body).Decode(&request); err != nil { + return util.ErrorResponse(err) + } + if err := r.GetAliasRoomID(&request, &response); err != nil { + return util.ErrorResponse(err) + } + return util.JSONResponse{Code: 200, JSON: &response} + }), + ) }