Skip to content

Commit

Permalink
Implement MSC3916 (#3397)
Browse files Browse the repository at this point in the history
  • Loading branch information
S7evinK authored Aug 16, 2024
1 parent 8c6cf51 commit 7a4ef24
Show file tree
Hide file tree
Showing 13 changed files with 364 additions and 45 deletions.
3 changes: 2 additions & 1 deletion clientapi/routing/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func Setup(
unstableFeatures := map[string]bool{
"org.matrix.e2e_cross_signing": true,
"org.matrix.msc2285.stable": true,
"org.matrix.msc3916.stable": true,
}
for _, msc := range cfg.MSCs.MSCs {
unstableFeatures["org.matrix."+msc] = true
Expand Down Expand Up @@ -732,7 +733,7 @@ func Setup(
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)

v3mux.Handle("/auth/{authType}/fallback/web",
httputil.MakeHTMLAPI("auth_fallback", enableMetrics, func(w http.ResponseWriter, req *http.Request) {
httputil.MakeHTTPAPI("auth_fallback", userAPI, enableMetrics, func(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
AuthFallback(w, req, vars["authType"], cfg)
}),
Expand Down
48 changes: 48 additions & 0 deletions federationapi/routing/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package routing

import (
"context"
"encoding/json"
"fmt"
"net/http"
"sync"
Expand Down Expand Up @@ -678,6 +679,53 @@ func MakeFedAPI(
return httputil.MakeExternalAPI(metricsName, h)
}

// MakeFedHTTPAPI makes an http.Handler that checks matrix federation authentication.
func MakeFedHTTPAPI(
serverName spec.ServerName,
isLocalServerName func(spec.ServerName) bool,
keyRing gomatrixserverlib.JSONVerifier,
f func(http.ResponseWriter, *http.Request),
) http.Handler {
h := func(w http.ResponseWriter, req *http.Request) {
fedReq, errResp := fclient.VerifyHTTPRequest(
req, time.Now(), serverName, isLocalServerName, keyRing,
)

enc := json.NewEncoder(w)
logger := util.GetLogger(req.Context())
if fedReq == nil {

logger.Debugf("VerifyUserFromRequest %s -> HTTP %d", req.RemoteAddr, errResp.Code)
w.WriteHeader(errResp.Code)
if err := enc.Encode(errResp); err != nil {
logger.WithError(err).Error("failed to encode JSON response")
}
return
}
// add the user to Sentry, if enabled
hub := sentry.GetHubFromContext(req.Context())
if hub != nil {
// clone the hub, so we don't send garbage events with e.g. mismatching rooms/event_ids
hub = hub.Clone()
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)
}
}()

f(w, req)
}

return http.HandlerFunc(h)
}

type FederationWakeups struct {
FsAPI *fedInternal.FederationInternalAPI
origins sync.Map
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
github.com/matrix-org/gomatrixserverlib v0.0.0-20240328203753-c2391f7113a5
github.com/matrix-org/gomatrixserverlib v0.0.0-20240801173829-d531860ad2cb
github.com/matrix-org/pinecone v0.11.1-0.20230810010612-ea4c33717fd7
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/mattn/go-sqlite3 v1.14.22
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20240328203753-c2391f7113a5 h1:GuxmpyjZQoqb6UFQgKq8Td3wIITlXln/sItqp1jbTTA=
github.com/matrix-org/gomatrixserverlib v0.0.0-20240328203753-c2391f7113a5/go.mod h1:HZGsVJ3bUE+DkZtufkH9H0mlsvbhEGK5CpX0Zlavylg=
github.com/matrix-org/gomatrixserverlib v0.0.0-20240801173829-d531860ad2cb h1:vb9RyAU+5r5jGTIjlteq8XK71X6Q+fqnmh8gSUUuLrI=
github.com/matrix-org/gomatrixserverlib v0.0.0-20240801173829-d531860ad2cb/go.mod h1:HZGsVJ3bUE+DkZtufkH9H0mlsvbhEGK5CpX0Zlavylg=
github.com/matrix-org/pinecone v0.11.1-0.20230810010612-ea4c33717fd7 h1:6t8kJr8i1/1I5nNttw6nn1ryQJgzVlBmSGgPiiaTdw4=
github.com/matrix-org/pinecone v0.11.1-0.20230810010612-ea4c33717fd7/go.mod h1:ReWMS/LoVnOiRAdq9sNUC2NZnd1mZkMNB52QhpTRWjg=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
Expand Down
32 changes: 30 additions & 2 deletions internal/httputil/httpapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package httputil

import (
"encoding/json"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -44,6 +45,7 @@ type BasicAuth struct {

type AuthAPIOpts struct {
GuestAccessAllowed bool
WithAuth bool
}

// AuthAPIOption is an option to MakeAuthAPI to add additional checks (e.g. guest access) to verify
Expand All @@ -57,6 +59,13 @@ func WithAllowGuests() AuthAPIOption {
}
}

// WithAuth is an option to MakeHTTPAPI to add authentication.
func WithAuth() AuthAPIOption {
return func(opts *AuthAPIOpts) {
opts.WithAuth = true
}
}

// MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which authenticates the request.
func MakeAuthAPI(
metricsName string, userAPI userapi.QueryAcccessTokenAPI,
Expand Down Expand Up @@ -197,13 +206,32 @@ func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse
return http.HandlerFunc(withSpan)
}

// MakeHTMLAPI adds Span metrics to the HTML Handler function
// MakeHTTPAPI adds Span metrics to the HTML Handler function
// This is used to serve HTML alongside JSON error messages
func MakeHTMLAPI(metricsName string, enableMetrics bool, f func(http.ResponseWriter, *http.Request)) http.Handler {
func MakeHTTPAPI(metricsName string, userAPI userapi.QueryAcccessTokenAPI, enableMetrics bool, f func(http.ResponseWriter, *http.Request), checks ...AuthAPIOption) http.Handler {
withSpan := func(w http.ResponseWriter, req *http.Request) {
trace, ctx := internal.StartTask(req.Context(), metricsName)
defer trace.EndTask()
req = req.WithContext(ctx)

// apply additional checks, if any
opts := AuthAPIOpts{}
for _, opt := range checks {
opt(&opts)
}

if opts.WithAuth {
logger := util.GetLogger(req.Context())
_, jsonErr := auth.VerifyUserFromRequest(req, userAPI)
if jsonErr != nil {
w.WriteHeader(jsonErr.Code)
if err := json.NewEncoder(w).Encode(jsonErr.JSON); err != nil {
logger.WithError(err).Error("failed to encode JSON response")
}
return
}
}

f(w, req)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/sqlutil/sqlutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,5 @@ func assertNoError(t *testing.T, err error, msg string) {
if err == nil {
return
}
t.Fatalf(msg)
t.Fatal(msg)
}
9 changes: 6 additions & 3 deletions mediaapi/mediaapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,33 @@
package mediaapi

import (
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/mediaapi/routing"
"github.com/matrix-org/dendrite/mediaapi/storage"
"github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/sirupsen/logrus"
)

// AddPublicRoutes sets up and registers HTTP handlers for the MediaAPI component.
func AddPublicRoutes(
mediaRouter *mux.Router,
routers httputil.Routers,
cm *sqlutil.Connections,
cfg *config.Dendrite,
userAPI userapi.MediaUserAPI,
client *fclient.Client,
fedClient fclient.FederationClient,
keyRing gomatrixserverlib.JSONVerifier,
) {
mediaDB, err := storage.NewMediaAPIDatasource(cm, &cfg.MediaAPI.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to media db")
}

routing.Setup(
mediaRouter, cfg, mediaDB, userAPI, client,
routers, cfg, mediaDB, userAPI, client, fedClient, keyRing,
)
}
Loading

0 comments on commit 7a4ef24

Please sign in to comment.