github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/dispatch/keys/computed.go (about) 1 package keys 2 3 import ( 4 "github.com/authzed/spicedb/pkg/caveats" 5 v1 "github.com/authzed/spicedb/pkg/proto/dispatch/v1" 6 "github.com/authzed/spicedb/pkg/spiceerrors" 7 "github.com/authzed/spicedb/pkg/tuple" 8 ) 9 10 type dispatchCacheKeyHashComputeOption int 11 12 const ( 13 computeOnlyStableHash dispatchCacheKeyHashComputeOption = 0 14 computeBothHashes dispatchCacheKeyHashComputeOption = 1 15 ) 16 17 // cachePrefix defines a unique prefix for a type of cache key. 18 type cachePrefix string 19 20 // Define the various prefixes for the cache entries. These must *all* be unique and must *all* 21 // also be placed into the cachePrefixes slice below. 22 const ( 23 checkViaRelationPrefix cachePrefix = "cr" 24 checkViaCanonicalPrefix cachePrefix = "cc" 25 lookupPrefix cachePrefix = "l" 26 expandPrefix cachePrefix = "e" 27 reachableResourcesPrefix cachePrefix = "rr" 28 lookupSubjectsPrefix cachePrefix = "ls" 29 ) 30 31 var cachePrefixes = []cachePrefix{ 32 checkViaRelationPrefix, 33 checkViaCanonicalPrefix, 34 lookupPrefix, 35 expandPrefix, 36 reachableResourcesPrefix, 37 lookupSubjectsPrefix, 38 } 39 40 // checkRequestToKey converts a check request into a cache key based on the relation 41 func checkRequestToKey(req *v1.DispatchCheckRequest, option dispatchCacheKeyHashComputeOption) DispatchCacheKey { 42 return dispatchCacheKeyHash(checkViaRelationPrefix, req.Metadata.AtRevision, option, 43 hashableRelationReference{req.ResourceRelation}, 44 hashableIds(req.ResourceIds), 45 hashableOnr{req.Subject}, 46 hashableResultSetting(req.ResultsSetting), 47 ) 48 } 49 50 // checkRequestToKeyWithCanonical converts a check request into a cache key based 51 // on the canonical key. 52 func checkRequestToKeyWithCanonical(req *v1.DispatchCheckRequest, canonicalKey string) (DispatchCacheKey, error) { 53 // NOTE: canonical cache keys are only unique *within* a version of a namespace. 54 cacheKey := dispatchCacheKeyHash(checkViaCanonicalPrefix, req.Metadata.AtRevision, computeBothHashes, 55 hashableString(req.ResourceRelation.Namespace), 56 hashableString(canonicalKey), 57 hashableIds(req.ResourceIds), 58 hashableOnr{req.Subject}, 59 hashableResultSetting(req.ResultsSetting), 60 ) 61 62 if canonicalKey == "" { 63 return cacheKey, spiceerrors.MustBugf("given empty canonical key for request: %s => %s", req.ResourceRelation, tuple.StringONR(req.Subject)) 64 } 65 66 return cacheKey, nil 67 } 68 69 // expandRequestToKey converts an expand request into a cache key 70 func expandRequestToKey(req *v1.DispatchExpandRequest, option dispatchCacheKeyHashComputeOption) DispatchCacheKey { 71 return dispatchCacheKeyHash(expandPrefix, req.Metadata.AtRevision, option, 72 hashableOnr{req.ResourceAndRelation}, 73 ) 74 } 75 76 // reachableResourcesRequestToKey converts a reachable resources request into a cache key 77 func reachableResourcesRequestToKey(req *v1.DispatchReachableResourcesRequest, option dispatchCacheKeyHashComputeOption) DispatchCacheKey { 78 return dispatchCacheKeyHash(reachableResourcesPrefix, req.Metadata.AtRevision, option, 79 hashableRelationReference{req.ResourceRelation}, 80 hashableRelationReference{req.SubjectRelation}, 81 hashableIds(req.SubjectIds), 82 hashableCursor{req.OptionalCursor}, 83 hashableLimit(req.OptionalLimit), 84 ) 85 } 86 87 // lookupResourcesRequestToKey converts a lookup request into a cache key 88 func lookupResourcesRequestToKey(req *v1.DispatchLookupResourcesRequest, option dispatchCacheKeyHashComputeOption) DispatchCacheKey { 89 return dispatchCacheKeyHash(lookupPrefix, req.Metadata.AtRevision, option, 90 hashableRelationReference{req.ObjectRelation}, 91 hashableOnr{req.Subject}, 92 hashableContext{HashableContext: caveats.HashableContext{Struct: req.Context}}, // NOTE: context is included here because lookup does a single dispatch 93 hashableCursor{req.OptionalCursor}, 94 hashableLimit(req.OptionalLimit), 95 ) 96 } 97 98 // lookupSubjectsRequestToKey converts a lookup subjects request into a cache key 99 func lookupSubjectsRequestToKey(req *v1.DispatchLookupSubjectsRequest, option dispatchCacheKeyHashComputeOption) DispatchCacheKey { 100 return dispatchCacheKeyHash(lookupSubjectsPrefix, req.Metadata.AtRevision, option, 101 hashableRelationReference{req.ResourceRelation}, 102 hashableRelationReference{req.SubjectRelation}, 103 hashableIds(req.ResourceIds), 104 hashableCursor{req.OptionalCursor}, 105 hashableLimit(req.OptionalLimit), 106 ) 107 }