github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/caveats/parameters.go (about)

     1  package caveats
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/authzed/spicedb/pkg/caveats/types"
     8  	core "github.com/authzed/spicedb/pkg/proto/core/v1"
     9  )
    10  
    11  // UnknownParameterOption is the option to ConvertContextToParameters around handling
    12  // of unknown parameters.
    13  type UnknownParameterOption int
    14  
    15  const (
    16  	// SkipUnknownParameters indicates that unknown parameters should be skipped in conversion.
    17  	SkipUnknownParameters UnknownParameterOption = 0
    18  
    19  	// ErrorForUnknownParameters indicates that unknown parameters should return an error.
    20  	ErrorForUnknownParameters UnknownParameterOption = 1
    21  )
    22  
    23  // ConvertContextToParameters converts the given context into parameters of the types specified.
    24  // Returns a type error if type conversion failed.
    25  func ConvertContextToParameters(
    26  	contextMap map[string]any,
    27  	parameterTypes map[string]*core.CaveatTypeReference,
    28  	unknownParametersOption UnknownParameterOption,
    29  ) (map[string]any, error) {
    30  	if len(contextMap) == 0 {
    31  		return nil, nil
    32  	}
    33  
    34  	if len(parameterTypes) == 0 {
    35  		return nil, fmt.Errorf("missing parameters for caveat")
    36  	}
    37  
    38  	converted := make(map[string]any, len(contextMap))
    39  
    40  	for key, value := range contextMap {
    41  		paramType, ok := parameterTypes[key]
    42  		if !ok {
    43  			if unknownParametersOption == ErrorForUnknownParameters {
    44  				return nil, fmt.Errorf("unknown parameter `%s`", key)
    45  			}
    46  
    47  			continue
    48  		}
    49  
    50  		varType, err := types.DecodeParameterType(paramType)
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  
    55  		convertedParam, err := varType.ConvertValue(value)
    56  		if err != nil {
    57  			return nil, ParameterConversionErr{fmt.Errorf("could not convert context parameter `%s`: %w", key, err), key}
    58  		}
    59  
    60  		converted[key] = convertedParam
    61  	}
    62  	return converted, nil
    63  }
    64  
    65  // ParameterTypeString returns the string form of the type reference.
    66  func ParameterTypeString(typeRef *core.CaveatTypeReference) string {
    67  	var sb strings.Builder
    68  	sb.WriteString(typeRef.TypeName)
    69  	if len(typeRef.ChildTypes) > 0 {
    70  		sb.WriteString("<")
    71  		for idx, childType := range typeRef.ChildTypes {
    72  			if idx > 0 {
    73  				sb.WriteString(", ")
    74  			}
    75  			sb.WriteString(ParameterTypeString(childType))
    76  		}
    77  		sb.WriteString(">")
    78  	}
    79  
    80  	return sb.String()
    81  }