mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 12:42:46 +00:00
Clean up interface definitions (#2427)
* tidy up interfaces * remove unused GetCreatorIDForAlias * Add RoomserverUserAPI interface * Define more interfaces * Use AppServiceInternalAPI for consistent naming * clean up federationapi constructor a bit * Fix monolith in -http mode
This commit is contained in:
parent
4705f5761e
commit
85704eff20
37 changed files with 236 additions and 429 deletions
|
@ -10,30 +10,6 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
// FederationClient is a subset of gomatrixserverlib.FederationClient functions which the fedsender
|
||||
// implements as proxy calls, with built-in backoff/retries/etc. Errors returned from functions in
|
||||
// this interface are of type FederationClientError
|
||||
type FederationClient interface {
|
||||
gomatrixserverlib.FederatedStateClient
|
||||
GetUserDevices(ctx context.Context, s gomatrixserverlib.ServerName, userID string) (res gomatrixserverlib.RespUserDevices, err error)
|
||||
ClaimKeys(ctx context.Context, s gomatrixserverlib.ServerName, oneTimeKeys map[string]map[string]string) (res gomatrixserverlib.RespClaimKeys, err error)
|
||||
QueryKeys(ctx context.Context, s gomatrixserverlib.ServerName, keys map[string][]string) (res gomatrixserverlib.RespQueryKeys, err error)
|
||||
MSC2836EventRelationships(ctx context.Context, dst gomatrixserverlib.ServerName, r gomatrixserverlib.MSC2836EventRelationshipsRequest, roomVersion gomatrixserverlib.RoomVersion) (res gomatrixserverlib.MSC2836EventRelationshipsResponse, err error)
|
||||
MSC2946Spaces(ctx context.Context, dst gomatrixserverlib.ServerName, roomID string, suggestedOnly bool) (res gomatrixserverlib.MSC2946SpacesResponse, err error)
|
||||
LookupServerKeys(ctx context.Context, s gomatrixserverlib.ServerName, keyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp) ([]gomatrixserverlib.ServerKeys, error)
|
||||
}
|
||||
|
||||
// FederationClientError is returned from FederationClient methods in the event of a problem.
|
||||
type FederationClientError struct {
|
||||
Err string
|
||||
RetryAfter time.Duration
|
||||
Blacklisted bool
|
||||
}
|
||||
|
||||
func (e *FederationClientError) Error() string {
|
||||
return fmt.Sprintf("%s - (retry_after=%s, blacklisted=%v)", e.Err, e.RetryAfter.String(), e.Blacklisted)
|
||||
}
|
||||
|
||||
// FederationInternalAPI is used to query information from the federation sender.
|
||||
type FederationInternalAPI interface {
|
||||
FederationClient
|
||||
|
@ -43,22 +19,7 @@ type FederationInternalAPI interface {
|
|||
|
||||
QueryServerKeys(ctx context.Context, request *QueryServerKeysRequest, response *QueryServerKeysResponse) error
|
||||
|
||||
// Query the server names of the joined hosts in a room.
|
||||
// Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice
|
||||
// containing only the server names (without information for membership events).
|
||||
// The response will include this server if they are joined to the room.
|
||||
QueryJoinedHostServerNamesInRoom(
|
||||
ctx context.Context,
|
||||
request *QueryJoinedHostServerNamesInRoomRequest,
|
||||
response *QueryJoinedHostServerNamesInRoomResponse,
|
||||
) error
|
||||
// Notifies the federation sender that these servers may be online and to retry sending messages.
|
||||
PerformServersAlive(
|
||||
ctx context.Context,
|
||||
request *PerformServersAliveRequest,
|
||||
response *PerformServersAliveResponse,
|
||||
) error
|
||||
// Broadcasts an EDU to all servers in rooms we are joined to.
|
||||
// Broadcasts an EDU to all servers in rooms we are joined to. Used in the yggdrasil demos.
|
||||
PerformBroadcastEDU(
|
||||
ctx context.Context,
|
||||
request *PerformBroadcastEDURequest,
|
||||
|
@ -67,6 +28,10 @@ type FederationInternalAPI interface {
|
|||
}
|
||||
|
||||
type ClientFederationAPI interface {
|
||||
// Query the server names of the joined hosts in a room.
|
||||
// Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice
|
||||
// containing only the server names (without information for membership events).
|
||||
// The response will include this server if they are joined to the room.
|
||||
QueryJoinedHostServerNamesInRoom(ctx context.Context, request *QueryJoinedHostServerNamesInRoomRequest, response *QueryJoinedHostServerNamesInRoomResponse) error
|
||||
}
|
||||
|
||||
|
@ -95,6 +60,30 @@ type RoomserverFederationAPI interface {
|
|||
LookupMissingEvents(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, missing gomatrixserverlib.MissingEvents, roomVersion gomatrixserverlib.RoomVersion) (res gomatrixserverlib.RespMissingEvents, err error)
|
||||
}
|
||||
|
||||
// FederationClient is a subset of gomatrixserverlib.FederationClient functions which the fedsender
|
||||
// implements as proxy calls, with built-in backoff/retries/etc. Errors returned from functions in
|
||||
// this interface are of type FederationClientError
|
||||
type FederationClient interface {
|
||||
gomatrixserverlib.FederatedStateClient
|
||||
GetUserDevices(ctx context.Context, s gomatrixserverlib.ServerName, userID string) (res gomatrixserverlib.RespUserDevices, err error)
|
||||
ClaimKeys(ctx context.Context, s gomatrixserverlib.ServerName, oneTimeKeys map[string]map[string]string) (res gomatrixserverlib.RespClaimKeys, err error)
|
||||
QueryKeys(ctx context.Context, s gomatrixserverlib.ServerName, keys map[string][]string) (res gomatrixserverlib.RespQueryKeys, err error)
|
||||
MSC2836EventRelationships(ctx context.Context, dst gomatrixserverlib.ServerName, r gomatrixserverlib.MSC2836EventRelationshipsRequest, roomVersion gomatrixserverlib.RoomVersion) (res gomatrixserverlib.MSC2836EventRelationshipsResponse, err error)
|
||||
MSC2946Spaces(ctx context.Context, dst gomatrixserverlib.ServerName, roomID string, suggestedOnly bool) (res gomatrixserverlib.MSC2946SpacesResponse, err error)
|
||||
LookupServerKeys(ctx context.Context, s gomatrixserverlib.ServerName, keyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp) ([]gomatrixserverlib.ServerKeys, error)
|
||||
}
|
||||
|
||||
// FederationClientError is returned from FederationClient methods in the event of a problem.
|
||||
type FederationClientError struct {
|
||||
Err string
|
||||
RetryAfter time.Duration
|
||||
Blacklisted bool
|
||||
}
|
||||
|
||||
func (e *FederationClientError) Error() string {
|
||||
return fmt.Sprintf("%s - (retry_after=%s, blacklisted=%v)", e.Err, e.RetryAfter.String(), e.Blacklisted)
|
||||
}
|
||||
|
||||
type QueryServerKeysRequest struct {
|
||||
ServerName gomatrixserverlib.ServerName
|
||||
KeyIDToCriteria map[gomatrixserverlib.KeyID]gomatrixserverlib.PublicKeyNotaryQueryCriteria
|
||||
|
@ -174,13 +163,6 @@ type PerformInviteResponse struct {
|
|||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
}
|
||||
|
||||
type PerformServersAliveRequest struct {
|
||||
Servers []gomatrixserverlib.ServerName
|
||||
}
|
||||
|
||||
type PerformServersAliveResponse struct {
|
||||
}
|
||||
|
||||
// QueryJoinedHostServerNamesInRoomRequest is a request to QueryJoinedHostServerNames
|
||||
type QueryJoinedHostServerNamesInRoomRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
|
|
|
@ -50,8 +50,8 @@ func AddPublicRoutes(
|
|||
federation *gomatrixserverlib.FederationClient,
|
||||
keyRing gomatrixserverlib.JSONVerifier,
|
||||
rsAPI roomserverAPI.FederationRoomserverAPI,
|
||||
federationAPI federationAPI.FederationInternalAPI,
|
||||
keyAPI keyserverAPI.KeyInternalAPI,
|
||||
fedAPI federationAPI.FederationInternalAPI,
|
||||
keyAPI keyserverAPI.FederationKeyAPI,
|
||||
servers federationAPI.ServersInRoomProvider,
|
||||
) {
|
||||
cfg := &base.Cfg.FederationAPI
|
||||
|
@ -67,12 +67,23 @@ func AddPublicRoutes(
|
|||
UserAPI: userAPI,
|
||||
}
|
||||
|
||||
// the federationapi component is a bit unique in that it attaches public routes AND serves
|
||||
// internal APIs (because it used to be 2 components: the 2nd being fedsender). As a result,
|
||||
// the constructor shape is a bit wonky in that it is not valid to AddPublicRoutes without a
|
||||
// concrete impl of FederationInternalAPI as the public routes and the internal API _should_
|
||||
// be the same thing now.
|
||||
f, ok := fedAPI.(*internal.FederationInternalAPI)
|
||||
if !ok {
|
||||
panic("federationapi.AddPublicRoutes called with a FederationInternalAPI impl which was not " +
|
||||
"FederationInternalAPI. This is a programming error.")
|
||||
}
|
||||
|
||||
routing.Setup(
|
||||
base.PublicFederationAPIMux,
|
||||
base.PublicKeyAPIMux,
|
||||
base.PublicWellKnownAPIMux,
|
||||
cfg,
|
||||
rsAPI, federationAPI, keyRing,
|
||||
rsAPI, f, keyRing,
|
||||
federation, userAPI, keyAPI, mscCfg,
|
||||
servers, producer,
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi"
|
||||
"github.com/matrix-org/dendrite/federationapi/internal"
|
||||
"github.com/matrix-org/dendrite/internal/test"
|
||||
"github.com/matrix-org/dendrite/setup/base"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
|
@ -27,10 +28,9 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
|
|||
cfg.FederationAPI.Database.ConnectionString = config.DataSource("file::memory:")
|
||||
base := base.NewBaseDendrite(cfg, "Monolith")
|
||||
keyRing := &test.NopJSONVerifier{}
|
||||
fsAPI := base.FederationAPIHTTPClient()
|
||||
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
|
||||
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
|
||||
federationapi.AddPublicRoutes(base, nil, nil, keyRing, nil, fsAPI, nil, nil)
|
||||
federationapi.AddPublicRoutes(base, nil, nil, keyRing, nil, &internal.FederationInternalAPI{}, nil, nil)
|
||||
baseURL, cancel := test.ListenAndServe(t, base.PublicFederationAPIMux, true)
|
||||
defer cancel()
|
||||
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))
|
||||
|
|
|
@ -563,20 +563,6 @@ func (r *FederationInternalAPI) PerformInvite(
|
|||
return nil
|
||||
}
|
||||
|
||||
// PerformServersAlive implements api.FederationInternalAPI
|
||||
func (r *FederationInternalAPI) PerformServersAlive(
|
||||
ctx context.Context,
|
||||
request *api.PerformServersAliveRequest,
|
||||
response *api.PerformServersAliveResponse,
|
||||
) (err error) {
|
||||
for _, srv := range request.Servers {
|
||||
_ = r.db.RemoveServerFromBlacklist(srv)
|
||||
r.queues.RetryServer(srv)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PerformServersAlive implements api.FederationInternalAPI
|
||||
func (r *FederationInternalAPI) PerformBroadcastEDU(
|
||||
ctx context.Context,
|
||||
|
@ -600,18 +586,18 @@ func (r *FederationInternalAPI) PerformBroadcastEDU(
|
|||
if err = r.queues.SendEDU(edu, r.cfg.Matrix.ServerName, destinations); err != nil {
|
||||
return fmt.Errorf("r.queues.SendEDU: %w", err)
|
||||
}
|
||||
|
||||
wakeReq := &api.PerformServersAliveRequest{
|
||||
Servers: destinations,
|
||||
}
|
||||
wakeRes := &api.PerformServersAliveResponse{}
|
||||
if err := r.PerformServersAlive(ctx, wakeReq, wakeRes); err != nil {
|
||||
return fmt.Errorf("r.PerformServersAlive: %w", err)
|
||||
}
|
||||
r.MarkServersAlive(destinations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *FederationInternalAPI) MarkServersAlive(destinations []gomatrixserverlib.ServerName) {
|
||||
for _, srv := range destinations {
|
||||
_ = r.db.RemoveServerFromBlacklist(srv)
|
||||
r.queues.RetryServer(srv)
|
||||
}
|
||||
}
|
||||
|
||||
func sanityCheckAuthChain(authChain []*gomatrixserverlib.Event) error {
|
||||
// sanity check we have a create event and it has a known room version
|
||||
for _, ev := range authChain {
|
||||
|
|
|
@ -23,7 +23,6 @@ const (
|
|||
FederationAPIPerformLeaveRequestPath = "/federationapi/performLeaveRequest"
|
||||
FederationAPIPerformInviteRequestPath = "/federationapi/performInviteRequest"
|
||||
FederationAPIPerformOutboundPeekRequestPath = "/federationapi/performOutboundPeekRequest"
|
||||
FederationAPIPerformServersAlivePath = "/federationapi/performServersAlive"
|
||||
FederationAPIPerformBroadcastEDUPath = "/federationapi/performBroadcastEDU"
|
||||
|
||||
FederationAPIGetUserDevicesPath = "/federationapi/client/getUserDevices"
|
||||
|
@ -97,18 +96,6 @@ func (h *httpFederationInternalAPI) PerformOutboundPeek(
|
|||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) PerformServersAlive(
|
||||
ctx context.Context,
|
||||
request *api.PerformServersAliveRequest,
|
||||
response *api.PerformServersAliveResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformServersAlive")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformServersAlivePath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
}
|
||||
|
||||
// QueryJoinedHostServerNamesInRoom implements FederationInternalAPI
|
||||
func (h *httpFederationInternalAPI) QueryJoinedHostServerNamesInRoom(
|
||||
ctx context.Context,
|
||||
|
|
|
@ -81,20 +81,6 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
|||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
)
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformServersAlivePath,
|
||||
httputil.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformServersAliveRequest
|
||||
var response api.PerformServersAliveResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.PerformServersAlive(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
)
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformBroadcastEDUPath,
|
||||
httputil.MakeInternalAPI("PerformBroadcastEDU", func(req *http.Request) util.JSONResponse {
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
// GetUserDevices for the given user id
|
||||
func GetUserDevices(
|
||||
req *http.Request,
|
||||
keyAPI keyapi.KeyInternalAPI,
|
||||
keyAPI keyapi.FederationKeyAPI,
|
||||
userID string,
|
||||
) util.JSONResponse {
|
||||
var res keyapi.QueryDeviceMessagesResponse
|
||||
|
|
|
@ -37,7 +37,7 @@ type queryKeysRequest struct {
|
|||
// QueryDeviceKeys returns device keys for users on this server.
|
||||
// https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-query
|
||||
func QueryDeviceKeys(
|
||||
httpReq *http.Request, request *gomatrixserverlib.FederationRequest, keyAPI api.KeyInternalAPI, thisServer gomatrixserverlib.ServerName,
|
||||
httpReq *http.Request, request *gomatrixserverlib.FederationRequest, keyAPI api.FederationKeyAPI, thisServer gomatrixserverlib.ServerName,
|
||||
) util.JSONResponse {
|
||||
var qkr queryKeysRequest
|
||||
err := json.Unmarshal(request.Content(), &qkr)
|
||||
|
@ -89,7 +89,7 @@ type claimOTKsRequest struct {
|
|||
// ClaimOneTimeKeys claims OTKs for users on this server.
|
||||
// https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-claim
|
||||
func ClaimOneTimeKeys(
|
||||
httpReq *http.Request, request *gomatrixserverlib.FederationRequest, keyAPI api.KeyInternalAPI, thisServer gomatrixserverlib.ServerName,
|
||||
httpReq *http.Request, request *gomatrixserverlib.FederationRequest, keyAPI api.FederationKeyAPI, thisServer gomatrixserverlib.ServerName,
|
||||
) util.JSONResponse {
|
||||
var cor claimOTKsRequest
|
||||
err := json.Unmarshal(request.Content(), &cor)
|
||||
|
|
|
@ -18,10 +18,14 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||
fedInternal "github.com/matrix-org/dendrite/federationapi/internal"
|
||||
"github.com/matrix-org/dendrite/federationapi/producers"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
|
@ -48,11 +52,11 @@ func Setup(
|
|||
fedMux, keyMux, wkMux *mux.Router,
|
||||
cfg *config.FederationAPI,
|
||||
rsAPI roomserverAPI.FederationRoomserverAPI,
|
||||
fsAPI federationAPI.FederationInternalAPI,
|
||||
fsAPI *fedInternal.FederationInternalAPI,
|
||||
keys gomatrixserverlib.JSONVerifier,
|
||||
federation *gomatrixserverlib.FederationClient,
|
||||
userAPI userapi.FederationUserAPI,
|
||||
keyAPI keyserverAPI.KeyInternalAPI,
|
||||
keyAPI keyserverAPI.FederationKeyAPI,
|
||||
mscCfg *config.MSCs,
|
||||
servers federationAPI.ServersInRoomProvider,
|
||||
producer *producers.SyncAPIProducer,
|
||||
|
@ -65,7 +69,7 @@ func Setup(
|
|||
v1fedmux := fedMux.PathPrefix("/v1").Subrouter()
|
||||
v2fedmux := fedMux.PathPrefix("/v2").Subrouter()
|
||||
|
||||
wakeup := &httputil.FederationWakeups{
|
||||
wakeup := &FederationWakeups{
|
||||
FsAPI: fsAPI,
|
||||
}
|
||||
|
||||
|
@ -119,7 +123,7 @@ func Setup(
|
|||
v2keysmux.Handle("/query/{serverName}/{keyID}", notaryKeys).Methods(http.MethodGet)
|
||||
|
||||
mu := internal.NewMutexByRoom()
|
||||
v1fedmux.Handle("/send/{txnID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/send/{txnID}", MakeFedAPI(
|
||||
"federation_send", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return Send(
|
||||
|
@ -129,7 +133,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut, http.MethodOptions)
|
||||
|
||||
v1fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -145,7 +149,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut, http.MethodOptions)
|
||||
|
||||
v2fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v2fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -167,7 +171,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPost, http.MethodOptions)
|
||||
|
||||
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", MakeFedAPI(
|
||||
"exchange_third_party_invite", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return ExchangeThirdPartyInvite(
|
||||
|
@ -176,7 +180,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut, http.MethodOptions)
|
||||
|
||||
v1fedmux.Handle("/event/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/event/{eventID}", MakeFedAPI(
|
||||
"federation_get_event", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return GetEvent(
|
||||
|
@ -185,7 +189,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/state/{roomID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/state/{roomID}", MakeFedAPI(
|
||||
"federation_get_state", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -200,7 +204,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/state_ids/{roomID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/state_ids/{roomID}", MakeFedAPI(
|
||||
"federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -215,7 +219,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -230,7 +234,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/query/directory", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/query/directory", MakeFedAPI(
|
||||
"federation_query_room_alias", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return RoomAliasToID(
|
||||
|
@ -239,7 +243,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/query/profile", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/query/profile", MakeFedAPI(
|
||||
"federation_query_profile", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return GetProfile(
|
||||
|
@ -248,7 +252,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/user/devices/{userID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/user/devices/{userID}", MakeFedAPI(
|
||||
"federation_user_devices", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return GetUserDevices(
|
||||
|
@ -258,7 +262,7 @@ func Setup(
|
|||
)).Methods(http.MethodGet)
|
||||
|
||||
if mscCfg.Enabled("msc2444") {
|
||||
v1fedmux.Handle("/peek/{roomID}/{peekID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/peek/{roomID}/{peekID}", MakeFedAPI(
|
||||
"federation_peek", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -289,7 +293,7 @@ func Setup(
|
|||
)).Methods(http.MethodPut, http.MethodDelete)
|
||||
}
|
||||
|
||||
v1fedmux.Handle("/make_join/{roomID}/{userID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/make_join/{roomID}/{userID}", MakeFedAPI(
|
||||
"federation_make_join", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -320,7 +324,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -352,7 +356,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut)
|
||||
|
||||
v2fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v2fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -369,7 +373,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut)
|
||||
|
||||
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_make_leave", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -386,7 +390,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -418,7 +422,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPut)
|
||||
|
||||
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
|
||||
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -442,7 +446,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodGet)
|
||||
|
||||
v1fedmux.Handle("/get_missing_events/{roomID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/get_missing_events/{roomID}", MakeFedAPI(
|
||||
"federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -455,7 +459,7 @@ func Setup(
|
|||
},
|
||||
)).Methods(http.MethodPost)
|
||||
|
||||
v1fedmux.Handle("/backfill/{roomID}", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/backfill/{roomID}", MakeFedAPI(
|
||||
"federation_backfill", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||
|
@ -474,14 +478,14 @@ func Setup(
|
|||
}),
|
||||
).Methods(http.MethodGet, http.MethodPost)
|
||||
|
||||
v1fedmux.Handle("/user/keys/claim", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/user/keys/claim", MakeFedAPI(
|
||||
"federation_keys_claim", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return ClaimOneTimeKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
||||
},
|
||||
)).Methods(http.MethodPost)
|
||||
|
||||
v1fedmux.Handle("/user/keys/query", httputil.MakeFedAPI(
|
||||
v1fedmux.Handle("/user/keys/query", MakeFedAPI(
|
||||
"federation_keys_query", cfg.Matrix.ServerName, keys, wakeup,
|
||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||
return QueryDeviceKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
||||
|
@ -518,3 +522,67 @@ func ErrorIfLocalServerNotInRoom(
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeFedAPI makes an http.Handler that checks matrix federation authentication.
|
||||
func MakeFedAPI(
|
||||
metricsName string,
|
||||
serverName gomatrixserverlib.ServerName,
|
||||
keyRing gomatrixserverlib.JSONVerifier,
|
||||
wakeup *FederationWakeups,
|
||||
f func(*http.Request, *gomatrixserverlib.FederationRequest, map[string]string) util.JSONResponse,
|
||||
) http.Handler {
|
||||
h := func(req *http.Request) util.JSONResponse {
|
||||
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
||||
req, time.Now(), serverName, keyRing,
|
||||
)
|
||||
if fedReq == nil {
|
||||
return errResp
|
||||
}
|
||||
// add the user to Sentry, if enabled
|
||||
hub := sentry.GetHubFromContext(req.Context())
|
||||
if hub != nil {
|
||||
hub.Scope().SetTag("origin", string(fedReq.Origin()))
|
||||
hub.Scope().SetTag("uri", fedReq.RequestURI())
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if hub != nil {
|
||||
hub.CaptureException(fmt.Errorf("%s panicked", req.URL.Path))
|
||||
}
|
||||
// re-panic to return the 500
|
||||
panic(r)
|
||||
}
|
||||
}()
|
||||
go wakeup.Wakeup(req.Context(), fedReq.Origin())
|
||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||
if err != nil {
|
||||
return util.MatrixErrorResponse(400, "M_UNRECOGNISED", "badly encoded query params")
|
||||
}
|
||||
|
||||
jsonRes := f(req, fedReq, vars)
|
||||
// do not log 4xx as errors as they are client fails, not server fails
|
||||
if hub != nil && jsonRes.Code >= 500 {
|
||||
hub.Scope().SetExtra("response", jsonRes)
|
||||
hub.CaptureException(fmt.Errorf("%s returned HTTP %d", req.URL.Path, jsonRes.Code))
|
||||
}
|
||||
return jsonRes
|
||||
}
|
||||
return httputil.MakeExternalAPI(metricsName, h)
|
||||
}
|
||||
|
||||
type FederationWakeups struct {
|
||||
FsAPI *fedInternal.FederationInternalAPI
|
||||
origins sync.Map
|
||||
}
|
||||
|
||||
func (f *FederationWakeups) Wakeup(ctx context.Context, origin gomatrixserverlib.ServerName) {
|
||||
key, keyok := f.origins.Load(origin)
|
||||
if keyok {
|
||||
lastTime, ok := key.(time.Time)
|
||||
if ok && time.Since(lastTime) < time.Minute {
|
||||
return
|
||||
}
|
||||
}
|
||||
f.FsAPI.MarkServersAlive([]gomatrixserverlib.ServerName{origin})
|
||||
f.origins.Store(origin, time.Now())
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ func Send(
|
|||
txnID gomatrixserverlib.TransactionID,
|
||||
cfg *config.FederationAPI,
|
||||
rsAPI api.FederationRoomserverAPI,
|
||||
keyAPI keyapi.KeyInternalAPI,
|
||||
keyAPI keyapi.FederationKeyAPI,
|
||||
keys gomatrixserverlib.JSONVerifier,
|
||||
federation *gomatrixserverlib.FederationClient,
|
||||
mu *internal.MutexByRoom,
|
||||
|
@ -183,7 +183,7 @@ func Send(
|
|||
type txnReq struct {
|
||||
gomatrixserverlib.Transaction
|
||||
rsAPI api.FederationRoomserverAPI
|
||||
keyAPI keyapi.KeyInternalAPI
|
||||
keyAPI keyapi.FederationKeyAPI
|
||||
ourServerName gomatrixserverlib.ServerName
|
||||
keys gomatrixserverlib.JSONVerifier
|
||||
federation txnFederationClient
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue