Skip to content

Commit

Permalink
Merge branch 'main' into travis/authed-default
Browse files Browse the repository at this point in the history
  • Loading branch information
turt2live committed Dec 23, 2024
2 parents 598d3d1 + 0e4274f commit 6e3d04b
Show file tree
Hide file tree
Showing 27 changed files with 394 additions and 301 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'

- name: Install libheif (linux)
if: runner.os == 'linux'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'
- name: "Install libheif"
run: "chmod +x ./.github/workflows/build-libheif.sh && ./.github/workflows/build-libheif.sh"
- run: './build.sh' # verify the thing compiles
Expand All @@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'
- name: "Install libheif"
run: "chmod +x ./.github/workflows/build-libheif.sh && ./.github/workflows/build-libheif.sh"
- name: "Prepare: compile assets"
Expand All @@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'
- name: "Prepare: compile assets"
run: "GOBIN=$PWD/bin go install -v ./cmd/utilities/compile_assets"
- name: "Run: compile assets"
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

* Allow guests to access uploaded media, as per [MSC4189](https://github.com/matrix-org/matrix-spec-proposals/pull/4189).

### Changed

* MMR now requires Go 1.22 for compilation.
* The global `repo.freezeUnauthenticatedMedia` option now defaults to `true`, enabling authenticated media by default. A future release will remove this option, requiring the freeze behaviour. See `config.sample.yaml` for details.

### Fixed

* Return a 404 instead of 500 when clients access media which is frozen.
* Return a 403 instead of 500 when guests access endpoints that are for registered users only.
* Ensure the request parameters are correctly set for authenticated media client requests.
* Ensure remote signing keys expire after at most 7 days.
* Fixed parsing of `Authorization` headers for federated servers.
* Ensure `ignoredHosts` is applied to unauthenticated requests.

## [1.3.7] - July 30, 2024

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ---- Stage 0 ----
# Builds media repo binaries
FROM golang:1.21-alpine3.18 AS builder
FROM golang:1.22-alpine3.18 AS builder

# Install build dependencies
RUN apk add --no-cache git musl-dev dos2unix build-base libde265-dev
Expand Down
38 changes: 20 additions & 18 deletions api/_auth_cache/auth_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ var rwLock = &sync.RWMutex{}
var regexCache = make(map[string]*regexp.Regexp)

type cachedToken struct {
userId string
err error
userId string
isGuest bool
err error
}

func cacheKey(accessToken string, appserviceUserId string) string {
Expand Down Expand Up @@ -70,15 +71,15 @@ func InvalidateAllTokens(ctx rcontext.RequestContext, accessToken string, appser
return nil
}

func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId string) (string, error) {
func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId string) (string, bool, error) {
if ctx.Request == nil {
ctx.Log.Warn("Tried to get user ID for access token without a valid request reference")
return "", errors.New("invalid context - missing request")
return "", false, errors.New("invalid context - missing request")
}

if accessToken == "" {
ctx.Log.Warn("No access token supplied - cannot get user ID")
return "", matrix.ErrInvalidToken
return "", false, matrix.ErrInvalidToken
}

if ctx.Config.AccessTokens.MaxCacheTimeSeconds <= 0 {
Expand All @@ -92,10 +93,10 @@ func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId
if ok {
token := record.(cachedToken)
if token.err != nil {
return "", token.err
return "", false, token.err
}
ctx.Log.Debugf("Access token belongs to %s", token.userId)
return token.userId, nil
return token.userId, token.isGuest, nil
}

if !ctx.Config.AccessTokens.UseAppservices {
Expand All @@ -110,8 +111,8 @@ func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId

if r.SenderUserId != "" && (r.SenderUserId == appserviceUserId || appserviceUserId == "") {
ctx.Log.Debugf("Access token belongs to appservice (sender user ID): %s", r.Id)
cacheToken(ctx, accessToken, appserviceUserId, r.SenderUserId, nil)
return r.SenderUserId, nil
cacheToken(ctx, accessToken, appserviceUserId, r.SenderUserId, false, nil)
return r.SenderUserId, false, nil
}

for _, n := range r.UserNamespaces {
Expand All @@ -122,8 +123,8 @@ func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId
}
if regex.MatchString(appserviceUserId) {
ctx.Log.Debugf("Access token belongs to appservice: %s", r.Id)
cacheToken(ctx, accessToken, appserviceUserId, appserviceUserId, nil)
return appserviceUserId, nil
cacheToken(ctx, accessToken, appserviceUserId, appserviceUserId, false, nil)
return appserviceUserId, false, nil
}
}
}
Expand All @@ -132,23 +133,24 @@ func GetUserId(ctx rcontext.RequestContext, accessToken string, appserviceUserId
return checkTokenWithHomeserver(ctx, accessToken, appserviceUserId, true)
}

func cacheToken(ctx rcontext.RequestContext, accessToken string, appserviceUserId string, userId string, err error) {
func cacheToken(ctx rcontext.RequestContext, accessToken string, appserviceUserId string, userId string, isGuest bool, err error) {
v := cachedToken{
userId: userId,
err: err,
userId: userId,
isGuest: isGuest,
err: err,
}
t := time.Duration(ctx.Config.AccessTokens.MaxCacheTimeSeconds) * time.Second
rwLock.Lock()
tokenCache.Set(cacheKey(accessToken, appserviceUserId), v, t)
rwLock.Unlock()
}

func checkTokenWithHomeserver(ctx rcontext.RequestContext, accessToken string, appserviceUserId string, withCache bool) (string, error) {
func checkTokenWithHomeserver(ctx rcontext.RequestContext, accessToken string, appserviceUserId string, withCache bool) (string, bool, error) {
ctx.Log.Debug("Checking access token with homeserver")
hsUserId, err := matrix.GetUserIdFromToken(ctx, ctx.Request.Host, accessToken, appserviceUserId, ctx.Request.RemoteAddr)
hsUserId, hsIsGuest, err := matrix.GetUserIdFromToken(ctx, ctx.Request.Host, accessToken, appserviceUserId, ctx.Request.RemoteAddr)
if withCache {
ctx.Log.Debug("Caching access token response from homeserver")
cacheToken(ctx, accessToken, appserviceUserId, hsUserId, err)
cacheToken(ctx, accessToken, appserviceUserId, hsUserId, hsIsGuest, err)
}
return hsUserId, err
return hsUserId, hsIsGuest, err
}
5 changes: 4 additions & 1 deletion api/_routers/97-optional-access-token.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ func OptionalAccessToken(generator GeneratorWithUserFn) GeneratorFn {
})
}
appserviceUserId := util.GetAppserviceUserIdFromRequest(r)
userId, err := _auth_cache.GetUserId(ctx, accessToken, appserviceUserId)
userId, isGuest, err := _auth_cache.GetUserId(ctx, accessToken, appserviceUserId)
if isGuest {
return _responses.GuestAuthFailed()
}
if err != nil {
if !errors.Is(err, matrix.ErrInvalidToken) {
sentry.CaptureException(err)
Expand Down
10 changes: 5 additions & 5 deletions api/_routers/97-require-access-token.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (

type GeneratorWithUserFn = func(r *http.Request, ctx rcontext.RequestContext, user _apimeta.UserInfo) interface{}

func RequireAccessToken(generator GeneratorWithUserFn) GeneratorFn {
func RequireAccessToken(generator GeneratorWithUserFn, allowGuests bool) GeneratorFn {
return func(r *http.Request, ctx rcontext.RequestContext) interface{} {
accessToken := util.GetAccessTokenFromRequest(r)
if accessToken == "" {
Expand All @@ -37,11 +37,11 @@ func RequireAccessToken(generator GeneratorWithUserFn) GeneratorFn {
})
}
appserviceUserId := util.GetAppserviceUserIdFromRequest(r)
userId, err := _auth_cache.GetUserId(ctx, accessToken, appserviceUserId)
userId, isGuest, err := _auth_cache.GetUserId(ctx, accessToken, appserviceUserId)
if isGuest && !allowGuests {
return _responses.GuestAuthFailed()
}
if err != nil || userId == "" {
if errors.Is(err, matrix.ErrGuestToken) {
return _responses.GuestAuthFailed()
}
if err != nil && !errors.Is(err, matrix.ErrInvalidToken) {
sentry.CaptureException(err)
ctx.Log.Error("Error verifying token: ", err)
Expand Down
2 changes: 1 addition & 1 deletion api/_routers/97-require-repo-admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ func RequireRepoAdmin(generator GeneratorWithUserFn) GeneratorFn {
}

return generator(r, ctx, user)
})(r, ctx)
}, false)(r, ctx)
}
}
3 changes: 3 additions & 0 deletions api/_routers/98-use-rcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ beforeParseDownload:
case common.ErrCodeForbidden:
proposedStatusCode = http.StatusForbidden
break
case common.ErrCodeNoGuests:
proposedStatusCode = http.StatusForbidden
break
case common.ErrCodeCannotOverwrite:
proposedStatusCode = http.StatusConflict
break
Expand Down
4 changes: 2 additions & 2 deletions api/r0/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func DownloadMedia(r *http.Request, rctx rcontext.RequestContext, auth _apimeta.
"authServerName": auth.Server.ServerName,
})

if auth.User.UserId != "" {
if !util.IsGlobalAdmin(auth.User.UserId) && util.IsHostIgnored(server) {
if util.IsHostIgnored(server) {
if auth.User.UserId == "" || !util.IsGlobalAdmin(auth.User.UserId) {
rctx.Log.Warn("Request blocked due to domain being ignored.")
return _responses.MediaBlocked()
}
Expand Down
4 changes: 2 additions & 2 deletions api/r0/thumbnail.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ func ThumbnailMedia(r *http.Request, rctx rcontext.RequestContext, auth _apimeta
"authServerName": auth.Server.ServerName,
})

if auth.User.UserId != "" {
if !util.IsGlobalAdmin(auth.User.UserId) && util.IsHostIgnored(server) {
if util.IsHostIgnored(server) {
if auth.User.UserId == "" || !util.IsGlobalAdmin(auth.User.UserId) {
rctx.Log.Warn("Request blocked due to domain being ignored.")
return _responses.MediaBlocked()
}
Expand Down
Loading

0 comments on commit 6e3d04b

Please sign in to comment.