From 96cb193db0d0011641bdd5e2f994c9c3734067ca Mon Sep 17 00:00:00 2001 From: Anant Prakash Date: Wed, 6 Jun 2018 22:25:33 +0530 Subject: [PATCH] [federationapi] Add state APIs --- .../dendrite/federationapi/routing/routing.go | 22 +++ .../dendrite/federationapi/routing/state.go | 127 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/github.com/matrix-org/dendrite/federationapi/routing/state.go 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 f43866ea1..52e00f2b5 100644 --- a/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go @@ -106,6 +106,28 @@ func Setup( }, )).Methods(http.MethodGet) + v1fedmux.Handle("/state/{roomID}/{eventID}", common.MakeFedAPI( + "federation_get_event_auth", cfg.Matrix.ServerName, keys, + func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { + vars := mux.Vars(httpReq) + return GetState( + httpReq.Context(), request, cfg, query, time.Now(), + keys, vars["roomID"], vars["eventID"], + ) + }, + )).Methods(http.MethodGet) + + v1fedmux.Handle("/state_ids/{roomID}/{eventID}", common.MakeFedAPI( + "federation_get_event_auth", cfg.Matrix.ServerName, keys, + func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { + vars := mux.Vars(httpReq) + return GetStateIDs( + httpReq.Context(), request, cfg, query, time.Now(), + keys, vars["roomID"], vars["eventID"], + ) + }, + )).Methods(http.MethodGet) + v1fedmux.Handle("/query/directory/", common.MakeFedAPI( "federation_query_room_alias", cfg.Matrix.ServerName, keys, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { diff --git a/src/github.com/matrix-org/dendrite/federationapi/routing/state.go b/src/github.com/matrix-org/dendrite/federationapi/routing/state.go new file mode 100644 index 000000000..03046ece1 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/federationapi/routing/state.go @@ -0,0 +1,127 @@ +// 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 ( + "context" + "net/http" + "time" + + "github.com/matrix-org/dendrite/common/config" + "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/util" +) + +// GetState returns state events & auth events for the roomID, eventID +func GetState( + ctx context.Context, + request *gomatrixserverlib.FederationRequest, + _ config.Dendrite, + query api.RoomserverQueryAPI, + _ time.Time, + _ gomatrixserverlib.KeyRing, + roomID string, + eventID string, +) util.JSONResponse { + state, err := getState(ctx, request, query, roomID, eventID) + if err != nil { + return *err + } + + return util.JSONResponse{Code: http.StatusOK, JSON: state} +} + +// GetStateIDs returns state event IDs & auth event IDs for the roomID, eventID +func GetStateIDs( + ctx context.Context, + request *gomatrixserverlib.FederationRequest, + _ config.Dendrite, + query api.RoomserverQueryAPI, + _ time.Time, + _ gomatrixserverlib.KeyRing, + roomID string, + eventID string, +) util.JSONResponse { + state, err := getState(ctx, request, query, roomID, eventID) + if err != nil { + return *err + } + + stateEventIDs := getIDsFromEvent(state.StateEvents) + authEventIDs := getIDsFromEvent(state.AuthEvents) + + return util.JSONResponse{Code: http.StatusOK, JSON: gomatrixserverlib.RespStateIDs{ + StateEventIDs: stateEventIDs, + AuthEventIDs: authEventIDs, + }, + } +} + +func getState( + ctx context.Context, + request *gomatrixserverlib.FederationRequest, + query api.RoomserverQueryAPI, + roomID string, + eventID string, +) (*gomatrixserverlib.RespState, *util.JSONResponse) { + event, resErr := getEvent(ctx, request, query, eventID) + if resErr != nil { + return nil, resErr + } + + prevEventIDs := getIDsFromEventRef(event.PrevEvents()) + authEventIDs := getIDsFromEventRef(event.AuthEvents()) + + var response api.QueryStateAndAuthChainResponse + err := query.QueryStateAndAuthChain( + ctx, + &api.QueryStateAndAuthChainRequest{ + RoomID: roomID, + PrevEventIDs: prevEventIDs, + AuthEventIDs: authEventIDs, + }, + &response, + ) + if err != nil { + resErr := util.ErrorResponse(err) + return nil, &resErr + } + + if !response.RoomExists { + return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil} + } + + return &gomatrixserverlib.RespState{ + StateEvents: response.StateEvents, + AuthEvents: response.AuthChainEvents, + }, nil +} + +func getIDsFromEventRef(events []gomatrixserverlib.EventReference) []string { + IDs := make([]string, len(events)) + for i := range events { + IDs[i] = events[i].EventID + } + + return IDs +} + +func getIDsFromEvent(events []gomatrixserverlib.Event) []string { + IDs := make([]string, len(events)) + for i := range events { + IDs[i] = events[i].EventID() + } + + return IDs +}