github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/datastore/crdb/keys.go (about)

     1  package crdb
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"github.com/authzed/authzed-go/pkg/requestmeta"
     8  	"google.golang.org/grpc/metadata"
     9  )
    10  
    11  type keySet map[string]struct{}
    12  
    13  func newKeySet(_ context.Context) keySet {
    14  	return make(map[string]struct{})
    15  }
    16  
    17  type overlapKeyer interface {
    18  	addKey(keySet keySet, namespace string)
    19  }
    20  
    21  type keySetAddFunc func(keySet keySet, namespace string)
    22  
    23  func (f keySetAddFunc) addKey(keySet keySet, namespace string) {
    24  	f(keySet, namespace)
    25  }
    26  
    27  var (
    28  	noOverlapKeyer overlapKeyer = keySetAddFunc(noOverlap)
    29  	prefixKeyer    overlapKeyer = keySetAddFunc(appendKeysFromNamespaceComponents)
    30  	_              overlapKeyer = appendStaticKey("")
    31  )
    32  
    33  // noOverlap adds no keys to the overlap set
    34  func noOverlap(_ keySet, _ string) {}
    35  
    36  // appendStaticKey adds the same transaction overlap key for every namespace
    37  func appendStaticKey(key string) keySetAddFunc {
    38  	return func(m keySet, _ string) {
    39  		m[key] = struct{}{}
    40  	}
    41  }
    42  
    43  // appendKeysFromNamespaceComponents adds an overlap key for namespace prefixes
    44  // This should not be used in deployments where non-prefixed namespaces are
    45  // allowed.
    46  func appendKeysFromNamespaceComponents(keySet keySet, namespace string) {
    47  	keySet[prefix(namespace)] = struct{}{}
    48  }
    49  
    50  // prefix returns the first namespace prefix or the default overlap key
    51  func prefix(s string) string {
    52  	prefix, _, ok := strings.Cut(s, "/")
    53  	if !ok {
    54  		return defaultOverlapKey
    55  	}
    56  	return prefix
    57  }
    58  
    59  // overlapKeysFromContext reads the request-provided initial overlap key set
    60  // from the grpc request metadata.
    61  func overlapKeysFromContext(ctx context.Context) keySet {
    62  	keys := newKeySet(ctx)
    63  	md, ok := metadata.FromIncomingContext(ctx)
    64  	if !ok {
    65  		return keys
    66  	}
    67  
    68  	for _, keyList := range md[string(requestmeta.RequestOverlapKey)] {
    69  		for _, key := range strings.Split(keyList, ",") {
    70  			key = strings.TrimSpace(key)
    71  			if len(key) > 0 {
    72  				keys[key] = struct{}{}
    73  			}
    74  		}
    75  	}
    76  	return keys
    77  }