From c7e5b4b2f987d6ad869d8e0414fbeec2f6a96ce7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2024 10:42:39 -0600 Subject: [PATCH] Support receiving `/versions` and enabling MSC3916 support --- api/r0/versions.go | 26 ++++++++++++++++++++++++++ api/routes.go | 5 +++++ dev/homeserver.nginx.conf | 10 ++++++++++ matrix/breakers.go | 4 ---- matrix/requests_info.go | 17 +++++++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 api/r0/versions.go create mode 100644 matrix/requests_info.go diff --git a/api/r0/versions.go b/api/r0/versions.go new file mode 100644 index 00000000..023f9a66 --- /dev/null +++ b/api/r0/versions.go @@ -0,0 +1,26 @@ +package r0 + +import ( + "github.com/getsentry/sentry-go" + "github.com/t2bot/matrix-media-repo/api/_apimeta" + "github.com/t2bot/matrix-media-repo/api/_responses" + "github.com/t2bot/matrix-media-repo/matrix" + + "net/http" + + "github.com/t2bot/matrix-media-repo/common/rcontext" +) + +func ClientVersions(r *http.Request, rctx rcontext.RequestContext, user _apimeta.UserInfo) interface{} { + versions, err := matrix.ClientVersions(rctx, r.Host, user.UserId, user.AccessToken, r.RemoteAddr) + if err != nil { + rctx.Log.Error(err) + sentry.CaptureException(err) + return _responses.InternalServerError("unable to get versions") + } + if versions.UnstableFeatures == nil { + versions.UnstableFeatures = make(map[string]bool) + } + versions.UnstableFeatures["org.matrix.msc3916"] = true + return versions +} diff --git a/api/routes.go b/api/routes.go index d30feea9..d7393a52 100644 --- a/api/routes.go +++ b/api/routes.go @@ -45,6 +45,7 @@ func buildRoutes() http.Handler { register([]string{"POST"}, PrefixClient, "logout", mxSpecV3TransitionCS, router, makeRoute(_routers.RequireAccessToken(r0.Logout), "logout", counter)) register([]string{"POST"}, PrefixClient, "logout/all", mxSpecV3TransitionCS, router, makeRoute(_routers.RequireAccessToken(r0.LogoutAll), "logout_all", counter)) register([]string{"POST"}, PrefixMedia, "create", mxV1, router, makeRoute(_routers.RequireAccessToken(v1.CreateMedia), "create", counter)) + register([]string{"GET"}, PrefixClient, "versions", mxNoVersion, router, makeRoute(_routers.OptionalAccessToken(r0.ClientVersions), "client_versions", counter)) // MSC3916 - Authentication & endpoint API separation register([]string{"GET"}, PrefixClient, "media/preview_url", msc3916, router, previewUrlRoute) @@ -148,12 +149,16 @@ var ( mxR0 matrixVersions = []string{"r0"} mxV1 matrixVersions = []string{"v1"} mxV3 matrixVersions = []string{"v3"} + mxNoVersion matrixVersions = []string{""} ) func register(methods []string, prefix string, postfix string, versions matrixVersions, router *httprouter.Router, handler http.Handler) { for _, method := range methods { for _, version := range versions { path := fmt.Sprintf("%s/%s/%s", prefix, version, postfix) + if version == "" { + path = fmt.Sprintf("%s/%s", prefix, postfix) + } router.Handler(method, path, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { defer func() { // hopefully the body was already closed, but maybe it wasn't diff --git a/dev/homeserver.nginx.conf b/dev/homeserver.nginx.conf index 10f39142..8a975aa1 100644 --- a/dev/homeserver.nginx.conf +++ b/dev/homeserver.nginx.conf @@ -9,6 +9,16 @@ server { proxy_pass http://host.docker.internal:8001; } + location /_matrix/client/versions { + proxy_set_header Host localhost; + proxy_pass http://host.docker.internal:8001; + } + + location /_matrix/client/unstable/org.matrix.msc3916 { + proxy_set_header Host localhost; + proxy_pass http://host.docker.internal:8001; + } + location /_matrix { proxy_pass http://media_repo_synapse:8008; } diff --git a/matrix/breakers.go b/matrix/breakers.go index 5f6ee6a9..911f92f2 100644 --- a/matrix/breakers.go +++ b/matrix/breakers.go @@ -50,10 +50,6 @@ func getFederationBreaker(hostname string) *circuit.Breaker { } func doBreakerRequest(ctx rcontext.RequestContext, serverName string, accessToken string, appserviceUserId string, ipAddr string, method string, path string, resp interface{}) error { - if accessToken == "" { - return ErrInvalidToken - } - hs, cb := getBreakerAndConfig(serverName) var replyError error diff --git a/matrix/requests_info.go b/matrix/requests_info.go new file mode 100644 index 00000000..c2cc1de0 --- /dev/null +++ b/matrix/requests_info.go @@ -0,0 +1,17 @@ +package matrix + +import "github.com/t2bot/matrix-media-repo/common/rcontext" + +type ClientVersionsResponse struct { + Versions []string `json:"versions"` + UnstableFeatures map[string]bool `json:"unstable_features"` +} + +func ClientVersions(ctx rcontext.RequestContext, serverName string, accessToken string, appserviceUserId string, ipAddr string) (*ClientVersionsResponse, error) { + response := &ClientVersionsResponse{} + err := doBreakerRequest(ctx, serverName, accessToken, appserviceUserId, ipAddr, "GET", "/_matrix/client/versions", response) + if err != nil { + return nil, err + } + return response, nil +}