Add function for making authed federation APIs (#208)

This commit is contained in:
Mark Haines 2017-09-04 13:14:01 +01:00 committed by GitHub
parent d4cce7369f
commit 643d05b157
4 changed files with 44 additions and 40 deletions

View file

@ -2,24 +2,26 @@ package common
import (
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/prometheus/client_golang/prometheus"
)
// MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which checks the access token in the request.
func MakeAuthAPI(metricsName string, deviceDB auth.DeviceDatabase, f func(*http.Request, *authtypes.Device) util.JSONResponse) http.Handler {
h := util.NewJSONRequestHandler(func(req *http.Request) util.JSONResponse {
h := func(req *http.Request) util.JSONResponse {
device, resErr := auth.VerifyAccessToken(req, deviceDB)
if resErr != nil {
return *resErr
}
return f(req, device)
})
return prometheus.InstrumentHandler(metricsName, util.MakeJSONAPI(h))
}
return MakeAPI(metricsName, h)
}
// MakeAPI turns a util.JSONRequestHandler function into an http.Handler.
@ -28,6 +30,25 @@ func MakeAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.H
return prometheus.InstrumentHandler(metricsName, util.MakeJSONAPI(h))
}
// MakeFedAPI makes an http.Handler that checks matrix federation authentication.
func MakeFedAPI(
metricsName string,
serverName gomatrixserverlib.ServerName,
keyRing gomatrixserverlib.KeyRing,
f func(*http.Request, *gomatrixserverlib.FederationRequest) 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
}
return f(req, fedReq)
}
return MakeAPI(metricsName, h)
}
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics
// listener.
func SetupHTTPAPI(servMux *http.ServeMux, apiMux *mux.Router) {

View file

@ -16,17 +16,16 @@ package routing
import (
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/dendrite/federationapi/readers"
"github.com/matrix-org/dendrite/federationapi/writers"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/prometheus/client_golang/prometheus"
)
const (
@ -46,7 +45,7 @@ func Setup(
v2keysmux := apiMux.PathPrefix(pathPrefixV2Keys).Subrouter()
v1fedmux := apiMux.PathPrefix(pathPrefixV1Federation).Subrouter()
localKeys := makeAPI("localkeys", func(req *http.Request) util.JSONResponse {
localKeys := common.MakeAPI("localkeys", func(req *http.Request) util.JSONResponse {
return readers.LocalKeys(req, cfg)
})
@ -57,30 +56,25 @@ func Setup(
v2keysmux.Handle("/server/{keyID}", localKeys)
v2keysmux.Handle("/server/", localKeys)
v1fedmux.Handle("/send/{txnID}/", makeAPI("federation_send",
func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req)
v1fedmux.Handle("/send/{txnID}/", common.MakeFedAPI(
"federation_send", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars := mux.Vars(httpReq)
return writers.Send(
req, gomatrixserverlib.TransactionID(vars["txnID"]),
time.Now(),
httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]),
cfg, query, producer, keys, federation,
)
},
))
v1fedmux.Handle("/invite/{roomID}/{eventID}", makeAPI("federation_invite",
func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req)
v1fedmux.Handle("/invite/{roomID}/{eventID}", common.MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars := mux.Vars(httpReq)
return writers.Invite(
req, vars["roomID"], vars["eventID"],
time.Now(),
httpReq, request, vars["roomID"], vars["eventID"],
cfg, producer, keys,
)
},
))
}
func makeAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler {
h := util.NewJSONRequestHandler(f)
return prometheus.InstrumentHandler(metricsName, util.MakeJSONAPI(h))
}

View file

@ -3,31 +3,25 @@ package writers
import (
"encoding/json"
"net/http"
"time"
"github.com/matrix-org/util"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
)
// Invite implements /_matrix/federation/v1/invite/{roomID}/{eventID}
func Invite(
req *http.Request,
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
roomID string,
eventID string,
now time.Time,
cfg config.Dendrite,
producer *producers.RoomserverProducer,
keys gomatrixserverlib.KeyRing,
) util.JSONResponse {
request, errResp := gomatrixserverlib.VerifyHTTPRequest(req, now, cfg.Matrix.ServerName, keys)
if request == nil {
return errResp
}
// Decode the event JSON from the request.
var event gomatrixserverlib.Event
@ -70,7 +64,7 @@ func Invite(
}}
verifyResults, err := keys.VerifyJSONs(verifyRequests)
if err != nil {
return httputil.LogThenError(req, err)
return httputil.LogThenError(httpReq, err)
}
if verifyResults[0].Error != nil {
return util.JSONResponse{
@ -86,7 +80,7 @@ func Invite(
// Add the invite event to the roomserver.
if err = producer.SendInvite(signedEvent); err != nil {
return httputil.LogThenError(req, err)
return httputil.LogThenError(httpReq, err)
}
// Return the signed event to the originating server, it should then tell

View file

@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
@ -17,19 +16,15 @@ import (
// Send implements /_matrix/federation/v1/send/{txnID}
func Send(
req *http.Request,
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
txnID gomatrixserverlib.TransactionID,
now time.Time,
cfg config.Dendrite,
query api.RoomserverQueryAPI,
producer *producers.RoomserverProducer,
keys gomatrixserverlib.KeyRing,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
request, errResp := gomatrixserverlib.VerifyHTTPRequest(req, now, cfg.Matrix.ServerName, keys)
if request == nil {
return errResp
}
t := txnReq{
query: query,
@ -50,7 +45,7 @@ func Send(
resp, err := t.processTransaction()
if err != nil {
return httputil.LogThenError(req, err)
return httputil.LogThenError(httpReq, err)
}
return util.JSONResponse{