-package main
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package ws
import (
+ "context"
"net/http"
"net/url"
"time"
- "git.curoverse.com/arvados.git/sdk/go/arvados"
+ "git.arvados.org/arvados.git/sdk/go/arvados"
+ "git.arvados.org/arvados.git/sdk/go/ctxlog"
)
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 {
*arvados.Client
cache map[string]cacheEnt
maxCurrent int
+
+ nChecks uint64
+ nMisses uint64
+ nInvalid uint64
}
func (pc *cachingPermChecker) SetToken(token string) {
+ if pc.Client.AuthToken == token {
+ return
+ }
pc.Client.AuthToken = token
+ pc.cache = make(map[string]cacheEnt)
}
-func (pc *cachingPermChecker) Check(uuid string) (bool, error) {
- logger := logger(nil).
+func (pc *cachingPermChecker) Check(ctx context.Context, uuid string) (bool, error) {
+ pc.nChecks++
+ logger := ctxlog.FromContext(ctx).
WithField("token", pc.Client.AuthToken).
WithField("uuid", uuid)
pc.tidy()
var buf map[string]interface{}
path, err := pc.PathForUUID("get", uuid)
if err != nil {
+ pc.nInvalid++
return false, err
}
+
+ pc.nMisses++
err = pc.RequestAndDecode(&buf, "GET", path, nil, url.Values{
- "select": {`["uuid"]`},
+ "include_trash": {"true"},
+ "select": {`["uuid"]`},
})
var allowed bool
if err == nil {
allowed = true
- } else if txErr, ok := err.(*arvados.TransactionError); ok && txErr.StatusCode == http.StatusNotFound {
- allowed = false
- } else if txErr.StatusCode == http.StatusForbidden {
- // Some requests are expressly forbidden for reasons
- // other than "you aren't allowed to know whether this
- // UUID exists" (404).
+ } else if txErr, ok := err.(*arvados.TransactionError); ok && pc.isNotAllowed(txErr.StatusCode) {
allowed = false
} else {
logger.WithError(err).Error("lookup error")
return allowed, nil
}
+func (pc *cachingPermChecker) isNotAllowed(status int) bool {
+ switch status {
+ case http.StatusForbidden, http.StatusUnauthorized, http.StatusNotFound:
+ return true
+ default:
+ return false
+ }
+}
+
func (pc *cachingPermChecker) tidy() {
if len(pc.cache) <= pc.maxCurrent*2 {
return