chore: ensure proper rbac permissions on 'Acquire' file in the cache (#18348)

The file cache was caching the `Unauthorized` errors if a user without
the right perms opened the file first. So all future opens would fail.

Now the cache always opens with a subject that can read files. And authz
is checked on the Acquire per user.
This commit is contained in:
Steven Masley
2025-06-16 08:40:45 -05:00
committed by GitHub
parent d83706bd5b
commit 1d1070d051
16 changed files with 218 additions and 51 deletions

View File

@ -47,14 +47,14 @@ func APIKey(r *http.Request) database.APIKey {
// UserAuthorizationOptional may return the roles and scope used for
// authorization. Depends on the ExtractAPIKey handler.
func UserAuthorizationOptional(r *http.Request) (rbac.Subject, bool) {
return dbauthz.ActorFromContext(r.Context())
func UserAuthorizationOptional(ctx context.Context) (rbac.Subject, bool) {
return dbauthz.ActorFromContext(ctx)
}
// UserAuthorization returns the roles and scope used for authorization. Depends
// on the ExtractAPIKey handler.
func UserAuthorization(r *http.Request) rbac.Subject {
auth, ok := UserAuthorizationOptional(r)
func UserAuthorization(ctx context.Context) rbac.Subject {
auth, ok := UserAuthorizationOptional(ctx)
if !ok {
panic("developer error: ExtractAPIKey middleware not provided")
}

View File

@ -58,7 +58,7 @@ func TestAPIKey(t *testing.T) {
assert.NoError(t, err, "actor rego ok")
}
auth, ok := httpmw.UserAuthorizationOptional(r)
auth, ok := httpmw.UserAuthorizationOptional(r.Context())
assert.True(t, ok, "httpmw auth ok")
if ok {
_, err := auth.Roles.Expand()
@ -904,7 +904,7 @@ func TestAPIKey(t *testing.T) {
})(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
assertActorOk(t, r)
auth := httpmw.UserAuthorization(r)
auth := httpmw.UserAuthorization(r.Context())
roles, err := auth.Roles.Expand()
assert.NoError(t, err, "expand user roles")
@ -968,7 +968,7 @@ func TestAPIKey(t *testing.T) {
RedirectToLogin: false,
})(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
assertActorOk(t, r)
auth := httpmw.UserAuthorization(r)
auth := httpmw.UserAuthorization(r.Context())
roles, err := auth.Roles.Expand()
assert.NoError(t, err, "expand user roles")

View File

@ -125,7 +125,7 @@ func TestExtractUserRoles(t *testing.T) {
}),
)
rtr.Get("/", func(_ http.ResponseWriter, r *http.Request) {
roles := httpmw.UserAuthorization(r)
roles := httpmw.UserAuthorization(r.Context())
require.Equal(t, user.ID.String(), roles.ID)
require.ElementsMatch(t, expRoles, roles.Roles.Names())
})

View File

@ -43,7 +43,7 @@ func RateLimit(count int, window time.Duration) func(http.Handler) http.Handler
// Allow Owner to bypass rate limiting for load tests
// and automation.
auth := UserAuthorization(r)
auth := UserAuthorization(r.Context())
// We avoid using rbac.Authorizer since rego is CPU-intensive
// and undermines the DoS-prevention goal of the rate limiter.