8 "git.curoverse.com/arvados.git/sdk/go/arvados"
12 maxPermCacheAge = time.Hour
13 minPermCacheAge = 5 * time.Minute
16 type permChecker interface {
17 SetToken(token string)
18 Check(uuid string) (bool, error)
21 func newPermChecker(ac arvados.Client) permChecker {
23 return &cachingPermChecker{
25 cache: make(map[string]cacheEnt),
30 type cacheEnt struct {
35 type cachingPermChecker struct {
37 cache map[string]cacheEnt
41 func (pc *cachingPermChecker) SetToken(token string) {
42 pc.Client.AuthToken = token
45 func (pc *cachingPermChecker) Check(uuid string) (bool, error) {
46 logger := logger(nil).
47 WithField("token", pc.Client.AuthToken).
48 WithField("uuid", uuid)
51 if perm, ok := pc.cache[uuid]; ok && now.Sub(perm.Time) < maxPermCacheAge {
52 logger.WithField("allowed", perm.allowed).Debug("cache hit")
53 return perm.allowed, nil
55 var buf map[string]interface{}
56 path, err := pc.PathForUUID("get", uuid)
60 err = pc.RequestAndDecode(&buf, "GET", path, nil, url.Values{
61 "select": {`["uuid"]`},
67 } else if txErr, ok := err.(*arvados.TransactionError); ok && txErr.StatusCode == http.StatusNotFound {
69 } else if txErr.StatusCode == http.StatusForbidden {
70 // Some requests are expressly forbidden for reasons
71 // other than "you aren't allowed to know whether this
72 // UUID exists" (404).
75 logger.WithError(err).Error("lookup error")
78 logger.WithField("allowed", allowed).Debug("cache miss")
79 pc.cache[uuid] = cacheEnt{Time: now, allowed: allowed}
83 func (pc *cachingPermChecker) tidy() {
84 if len(pc.cache) <= pc.maxCurrent*2 {
87 tooOld := time.Now().Add(-minPermCacheAge)
88 for uuid, t := range pc.cache {
90 delete(pc.cache, uuid)
93 pc.maxCurrent = len(pc.cache)