From fc65fbce6f94746d443418e02e437a64511f6af7 Mon Sep 17 00:00:00 2001 From: Alex Snaps Date: Mon, 14 Oct 2024 16:03:21 -0400 Subject: [PATCH] Refactored Cel into own pkg, removed CelResponse Signed-off-by: Alex Snaps --- api/v1beta2/auth_config_types.go | 3 -- controllers/auth_config_controller.go | 7 ---- pkg/evaluators/response/dynamic_cel.go | 45 ++++-------------------- pkg/expressions/cel.go | 47 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 49 deletions(-) create mode 100644 pkg/expressions/cel.go diff --git a/api/v1beta2/auth_config_types.go b/api/v1beta2/auth_config_types.go index 147f8ae5..098ceb05 100644 --- a/api/v1beta2/auth_config_types.go +++ b/api/v1beta2/auth_config_types.go @@ -51,7 +51,6 @@ const ( PlainAuthResponse JsonAuthResponse WristbandAuthResponse - CelAuthResponse // The following constants are used to identify the different methods of callback functions. UnknownCallbackMethod CallbackMethod = iota @@ -734,8 +733,6 @@ func (s *SuccessResponseSpec) GetMethod() AuthResponseMethod { type AuthResponseMethodSpec struct { // Plain text content Plain *PlainAuthResponseSpec `json:"plain,omitempty"` - // Cel Expression, where the result is outputted as JSON - Expression string `json:"expression,omitempty"` // JSON object // Specify it as the list of properties of the object, whose values can combine static values and values selected from the authorization JSON. Json *JsonAuthResponseSpec `json:"json,omitempty"` diff --git a/controllers/auth_config_controller.go b/controllers/auth_config_controller.go index 1cae2acf..cca5ff1f 100644 --- a/controllers/auth_config_controller.go +++ b/controllers/auth_config_controller.go @@ -628,13 +628,6 @@ func injectResponseConfig(ctx context.Context, authConfig *api.AuthConfig, succe translatedResponse.DynamicJSON = response_evaluators.NewDynamicJSONResponse(jsonProperties) - case api.CelAuthResponse: - if exp, err := response_evaluators.NewDynamicCelResponse(string(*successResponse.Expression)); err != nil { - return err - } else { - translatedResponse.DynamicCEL = exp - } - // plain case api.PlainAuthResponse: translatedResponse.Plain = &response_evaluators.Plain{ diff --git a/pkg/evaluators/response/dynamic_cel.go b/pkg/evaluators/response/dynamic_cel.go index e4be22dc..47f81cc1 100644 --- a/pkg/evaluators/response/dynamic_cel.go +++ b/pkg/evaluators/response/dynamic_cel.go @@ -2,18 +2,14 @@ package response import ( "context" - "reflect" "strings" "github.com/golang/protobuf/jsonpb" "github.com/google/cel-go/cel" "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types/ref" "github.com/kuadrant/authorino/pkg/auth" + "github.com/kuadrant/authorino/pkg/expressions" "google.golang.org/protobuf/types/known/structpb" - - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" ) const rootBinding = "auth" @@ -22,30 +18,14 @@ func NewDynamicCelResponse(expression string) (*DynamicCEL, error) { cel_exp := DynamicCEL{} - env, err := cel.NewEnv(cel.Declarations( + if program, err := expressions.CelCompile(expression, cel.Declarations( decls.NewConst(rootBinding, decls.NewObjectType("google.protobuf.Struct"), nil), - )) - if err != nil { - return nil, err - } - - ast, issues := env.Parse(expression) - if issues.Err() != nil { - return nil, issues.Err() - } - - checked, issues := env.Check(ast) - if issues.Err() != nil { - return nil, issues.Err() - } - - program, err := env.Program(checked) - if err != nil { + )); err != nil { return nil, err + } else { + cel_exp.program = program } - cel_exp.program = program - return &cel_exp, nil } @@ -69,22 +49,9 @@ func (c *DynamicCEL) Call(pipeline auth.AuthPipeline, ctx context.Context) (inte return nil, err } - if jsonVal, err := valueToJSON(result); err != nil { + if jsonVal, err := expressions.CelValueToJSON(result); err != nil { return nil, err } else { return jsonVal, nil } } - -func valueToJSON(val ref.Val) (string, error) { - v, err := val.ConvertToNative(reflect.TypeOf(&structpb.Value{})) - if err != nil { - return "", err - } - marshaller := protojson.MarshalOptions{Multiline: false} - bytes, err := marshaller.Marshal(v.(proto.Message)) - if err != nil { - return "", err - } - return string(bytes), nil -} diff --git a/pkg/expressions/cel.go b/pkg/expressions/cel.go new file mode 100644 index 00000000..71286573 --- /dev/null +++ b/pkg/expressions/cel.go @@ -0,0 +1,47 @@ +package expressions + +import ( + "reflect" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" +) + +func CelCompile(expression string, opts ...cel.EnvOption) (cel.Program, error) { + env, env_err := cel.NewEnv(opts...) + if env_err != nil { + return nil, env_err + } + + ast, issues := env.Parse(expression) + if issues.Err() != nil { + return nil, issues.Err() + } + + checked, issues := env.Check(ast) + if issues.Err() != nil { + return nil, issues.Err() + } + + program, err := env.Program(checked) + if err != nil { + return nil, err + } + return program, nil +} + +func CelValueToJSON(val ref.Val) (string, error) { + v, err := val.ConvertToNative(reflect.TypeOf(&structpb.Value{})) + if err != nil { + return "", err + } + marshaller := protojson.MarshalOptions{Multiline: false} + bytes, err := marshaller.Marshal(v.(proto.Message)) + if err != nil { + return "", err + } + return string(bytes), nil +}