github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/namespace/caveats.go (about) 1 package namespace 2 3 import ( 4 "fmt" 5 6 "golang.org/x/exp/maps" 7 8 "github.com/authzed/spicedb/pkg/caveats" 9 caveattypes "github.com/authzed/spicedb/pkg/caveats/types" 10 core "github.com/authzed/spicedb/pkg/proto/core/v1" 11 "github.com/authzed/spicedb/pkg/typesystem" 12 ) 13 14 // ValidateCaveatDefinition validates the parameters and types within the given caveat 15 // definition, including usage of the parameters. 16 func ValidateCaveatDefinition(caveat *core.CaveatDefinition) error { 17 // Ensure all parameters are used by the caveat expression itself. 18 parameterTypes, err := caveattypes.DecodeParameterTypes(caveat.ParameterTypes) 19 if err != nil { 20 return typesystem.NewTypeErrorWithSource( 21 fmt.Errorf("could not decode caveat parameters `%s`: %w", caveat.Name, err), 22 caveat, 23 caveat.Name, 24 ) 25 } 26 27 deserialized, err := caveats.DeserializeCaveat(caveat.SerializedExpression, parameterTypes) 28 if err != nil { 29 return typesystem.NewTypeErrorWithSource( 30 fmt.Errorf("could not decode caveat `%s`: %w", caveat.Name, err), 31 caveat, 32 caveat.Name, 33 ) 34 } 35 36 if len(caveat.ParameterTypes) == 0 { 37 return typesystem.NewTypeErrorWithSource( 38 fmt.Errorf("caveat `%s` must have at least one parameter defined", caveat.Name), 39 caveat, 40 caveat.Name, 41 ) 42 } 43 44 referencedNames, err := deserialized.ReferencedParameters(maps.Keys(caveat.ParameterTypes)) 45 if err != nil { 46 return err 47 } 48 49 for paramName, paramType := range caveat.ParameterTypes { 50 _, err := caveattypes.DecodeParameterType(paramType) 51 if err != nil { 52 return typesystem.NewTypeErrorWithSource( 53 fmt.Errorf("type error for parameter `%s` for caveat `%s`: %w", paramName, caveat.Name, err), 54 caveat, 55 paramName, 56 ) 57 } 58 59 if !referencedNames.Has(paramName) { 60 return typesystem.NewTypeErrorWithSource( 61 NewUnusedCaveatParameterErr(caveat.Name, paramName), 62 caveat, 63 paramName, 64 ) 65 } 66 } 67 68 return nil 69 }