diff --git a/clientapi/routing/capabilities.go b/clientapi/routing/capabilities.go new file mode 100644 index 000000000..c392dc034 --- /dev/null +++ b/clientapi/routing/capabilities.go @@ -0,0 +1,51 @@ +// Copyright 2017 Vector Creations 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 ( + "net/http" + + "github.com/matrix-org/dendrite/clientapi/httputil" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + + "github.com/matrix-org/util" +) + +// SendMembership implements PUT /rooms/{roomID}/(join|kick|ban|unban|leave|invite) +// by building a m.room.member event then sending it to the room server +func GetCapabilities( + req *http.Request, queryAPI roomserverAPI.RoomserverQueryAPI, +) util.JSONResponse { + roomVersionsQueryReq := roomserverAPI.QueryRoomVersionCapabilitiesRequest{} + var roomVersionsQueryRes roomserverAPI.QueryRoomVersionCapabilitiesResponse + if err := queryAPI.QueryRoomVersionCapabilities( + req.Context(), + &roomVersionsQueryReq, + &roomVersionsQueryRes, + ); err != nil { + return httputil.LogThenError(req, err) + } + + response := map[string]interface{}{ + "capabilities": map[string]interface{}{ + "m.room_versions": roomVersionsQueryRes, + }, + } + + return util.JSONResponse{ + Code: http.StatusOK, + JSON: response, + } +} diff --git a/roomserver/api/query.go b/roomserver/api/query.go index edf4de983..1e94677de 100644 --- a/roomserver/api/query.go +++ b/roomserver/api/query.go @@ -244,12 +244,13 @@ type QueryServersInRoomAtEventResponse struct { Servers []gomatrixserverlib.ServerName `json:"servers"` } -// QueryDefaultRoomVersion asks for the default room version -type QueryDefaultRoomVersionRequest struct{} +// QueryRoomVersionCapabilities asks for the default room version +type QueryRoomVersionCapabilitiesRequest struct{} -// QueryDefaultRoomVersionResponse is a response to QueryServersInRoomAtEventResponse -type QueryDefaultRoomVersionResponse struct { - RoomVersion int64 +// QueryRoomVersionCapabilitiesResponse is a response to QueryServersInRoomAtEventResponse +type QueryRoomVersionCapabilitiesResponse struct { + DefaultRoomVersion string `json:"default"` + AvailableRoomVersions map[string]string `json:"available"` } // RoomserverQueryAPI is used to query information from the room server. @@ -333,10 +334,10 @@ type RoomserverQueryAPI interface { ) error // Asks for the default room version as preferred by the server. - QueryDefaultRoomVersion( + QueryRoomVersionCapabilities( ctx context.Context, - request *QueryDefaultRoomVersionRequest, - response *QueryDefaultRoomVersionResponse, + request *QueryRoomVersionCapabilitiesRequest, + response *QueryRoomVersionCapabilitiesResponse, ) error } @@ -373,8 +374,8 @@ const RoomserverQueryBackfillPath = "/api/roomserver/queryBackfill" // RoomserverQueryServersInRoomAtEventPath is the HTTP path for the QueryServersInRoomAtEvent API const RoomserverQueryServersInRoomAtEventPath = "/api/roomserver/queryServersInRoomAtEvents" -// RoomserverQueryDefaultRoomVersionPath is the HTTP path for the QueryDefaultRoomVersion API -const RoomserverQueryDefaultRoomVersionPath = "/api/roomserver/queryDefaultRoomVersion" +// RoomserverQueryRoomVersionCapabilitiesPath is the HTTP path for the QueryRoomVersionCapabilities API +const RoomserverQueryRoomVersionCapabilitiesPath = "/api/roomserver/queryRoomVersionCapabilities" // NewRoomserverQueryAPIHTTP creates a RoomserverQueryAPI implemented by talking to a HTTP POST API. // If httpClient is nil then it uses the http.DefaultClient @@ -534,14 +535,14 @@ func (h *httpRoomserverQueryAPI) QueryServersInRoomAtEvent( } // QueryServersInRoomAtEvent implements RoomServerQueryAPI -func (h *httpRoomserverQueryAPI) QueryDefaultRoomVersion( +func (h *httpRoomserverQueryAPI) QueryRoomVersionCapabilities( ctx context.Context, - request *QueryDefaultRoomVersionRequest, - response *QueryDefaultRoomVersionResponse, + request *QueryRoomVersionCapabilitiesRequest, + response *QueryRoomVersionCapabilitiesResponse, ) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "QueryDefaultRoomVersion") + span, ctx := opentracing.StartSpanFromContext(ctx, "QueryRoomVersionCapabilities") defer span.Finish() - apiURL := h.roomserverURL + RoomserverQueryDefaultRoomVersionPath + apiURL := h.roomserverURL + RoomserverQueryRoomVersionCapabilitiesPath return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } diff --git a/roomserver/query/query.go b/roomserver/query/query.go index 907e45bb7..9646ebde7 100644 --- a/roomserver/query/query.go +++ b/roomserver/query/query.go @@ -724,13 +724,21 @@ func (r *RoomserverQueryAPI) QueryServersInRoomAtEvent( return nil } -// QueryDefaultRoomVersion implements api.RoomserverQueryAPI -func (r *RoomserverQueryAPI) QueryDefaultRoomVersion( +// QueryRoomVersionCapabilities implements api.RoomserverQueryAPI +func (r *RoomserverQueryAPI) QueryRoomVersionCapabilities( ctx context.Context, - request *api.QueryDefaultRoomVersionRequest, - response *api.QueryDefaultRoomVersionResponse, + request *api.QueryRoomVersionCapabilitiesRequest, + response *api.QueryRoomVersionCapabilitiesResponse, ) error { - response.RoomVersion = int64(version.GetDefaultRoomVersion()) + response.DefaultRoomVersion = string(version.GetDefaultRoomVersion()) + response.AvailableRoomVersions = make(map[string]string) + for v, desc := range version.GetSupportedRoomVersions() { + if desc.Stable { + response.AvailableRoomVersions[string(v)] = "stable" + } else { + response.AvailableRoomVersions[string(v)] = "unstable" + } + } return nil } @@ -891,4 +899,18 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) + servMux.Handle( + api.RoomserverQueryRoomVersionCapabilitiesPath, + common.MakeInternalAPI("QueryRoomVersionCapabilities", func(req *http.Request) util.JSONResponse { + var request api.QueryRoomVersionCapabilitiesRequest + var response api.QueryRoomVersionCapabilitiesResponse + if err := json.NewDecoder(req.Body).Decode(&request); err != nil { + return util.ErrorResponse(err) + } + if err := r.QueryRoomVersionCapabilities(req.Context(), &request, &response); err != nil { + return util.ErrorResponse(err) + } + return util.JSONResponse{Code: http.StatusOK, JSON: &response} + }), + ) }