X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b49229f98012d7c08ce02b8d28dbcc165c8a6c53..aba81749d2477043232b82300c0ce15548b61888:/services/ws/permission.go diff --git a/services/ws/permission.go b/services/ws/permission.go index 745d28f952..f71ca61167 100644 --- a/services/ws/permission.go +++ b/services/ws/permission.go @@ -2,14 +2,16 @@ // // SPDX-License-Identifier: AGPL-3.0 -package main +package ws import ( + "context" "net/http" "net/url" "time" "git.arvados.org/arvados.git/sdk/go/arvados" + "git.arvados.org/arvados.git/sdk/go/ctxlog" ) const ( @@ -19,13 +21,13 @@ const ( type permChecker interface { SetToken(token string) - Check(uuid string) (bool, error) + Check(ctx context.Context, uuid string) (bool, error) } -func newPermChecker(ac arvados.Client) permChecker { - ac.AuthToken = "" +func newPermChecker(ac *arvados.Client) permChecker { return &cachingPermChecker{ - Client: &ac, + ac: ac, + token: "-", cache: make(map[string]cacheEnt), maxCurrent: 16, } @@ -37,7 +39,8 @@ type cacheEnt struct { } type cachingPermChecker struct { - *arvados.Client + ac *arvados.Client + token string cache map[string]cacheEnt maxCurrent int @@ -47,17 +50,17 @@ type cachingPermChecker struct { } func (pc *cachingPermChecker) SetToken(token string) { - if pc.Client.AuthToken == token { + if pc.token == token { return } - pc.Client.AuthToken = token + pc.token = token pc.cache = make(map[string]cacheEnt) } -func (pc *cachingPermChecker) Check(uuid string) (bool, error) { +func (pc *cachingPermChecker) Check(ctx context.Context, uuid string) (bool, error) { pc.nChecks++ - logger := logger(nil). - WithField("token", pc.Client.AuthToken). + logger := ctxlog.FromContext(ctx). + WithField("token", pc.token). WithField("uuid", uuid) pc.tidy() now := time.Now() @@ -65,15 +68,19 @@ func (pc *cachingPermChecker) Check(uuid string) (bool, error) { logger.WithField("allowed", perm.allowed).Debug("cache hit") return perm.allowed, nil } - var buf map[string]interface{} - path, err := pc.PathForUUID("get", uuid) + + path, err := pc.ac.PathForUUID("get", uuid) if err != nil { pc.nInvalid++ return false, err } pc.nMisses++ - err = pc.RequestAndDecode(&buf, "GET", path, nil, url.Values{ + ctx = arvados.ContextWithAuthorization(ctx, "Bearer "+pc.token) + ctx, cancel := context.WithDeadline(ctx, time.Now().Add(time.Minute)) + defer cancel() + var buf map[string]interface{} + err = pc.ac.RequestAndDecodeContext(ctx, &buf, "GET", path, nil, url.Values{ "include_trash": {"true"}, "select": {`["uuid"]`}, }) @@ -84,6 +91,9 @@ func (pc *cachingPermChecker) Check(uuid string) (bool, error) { } else if txErr, ok := err.(*arvados.TransactionError); ok && pc.isNotAllowed(txErr.StatusCode) { allowed = false } else { + // If "context deadline exceeded", "client + // disconnected", HTTP 5xx, network error, etc., don't + // cache the result. logger.WithError(err).Error("lookup error") return false, err }