diff --git a/controllers/auth_config_controller.go b/controllers/auth_config_controller.go index a646598c..5dbce879 100644 --- a/controllers/auth_config_controller.go +++ b/controllers/auth_config_controller.go @@ -183,14 +183,14 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf for identityCfgName, identity := range authConfigIdentityConfigs { extendedProperties := make([]evaluators.IdentityExtension, 0) for propertyName, property := range identity.Defaults { - if value, err := stringValueFrom(&property); err != nil { + if value, err := valueFrom(&property); err != nil { return nil, err } else { extendedProperties = append(extendedProperties, evaluators.NewIdentityExtension(propertyName, value, false)) } } for propertyName, property := range identity.Overrides { - if value, err := stringValueFrom(&property); err != nil { + if value, err := valueFrom(&property); err != nil { return nil, err } else { extendedProperties = append(extendedProperties, evaluators.NewIdentityExtension(propertyName, value, true)) @@ -285,7 +285,7 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf case api.PlainIdentityAuthentication: if identity.Plain.Expression != "" { - expression, err := cel.NewStringExpression(string(identity.Plain.Expression)) + expression, err := cel.NewExpression(string(identity.Plain.Expression)) if err != nil { return nil, err } @@ -461,7 +461,7 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf case api.KubernetesSubjectAccessReviewAuthorization: user := authorization.KubernetesSubjectAccessReview.User - authorinoUser, err := stringValueFrom(user) + authorinoUser, err := valueFrom(user) if err != nil { return nil, err } @@ -469,27 +469,27 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf var authorinoResourceAttributes *authorization_evaluators.KubernetesAuthzResourceAttributes resourceAttributes := authorization.KubernetesSubjectAccessReview.ResourceAttributes if resourceAttributes != nil { - namespace, err := stringValueFrom(&resourceAttributes.Namespace) + namespace, err := valueFrom(&resourceAttributes.Namespace) if err != nil { return nil, err } - group, err := stringValueFrom(&resourceAttributes.Group) + group, err := valueFrom(&resourceAttributes.Group) if err != nil { return nil, err } - resource, err := stringValueFrom(&resourceAttributes.Resource) + resource, err := valueFrom(&resourceAttributes.Resource) if err != nil { return nil, err } - name, err := stringValueFrom(&resourceAttributes.Name) + name, err := valueFrom(&resourceAttributes.Name) if err != nil { return nil, err } - subResource, err := stringValueFrom(&resourceAttributes.SubResource) + subResource, err := valueFrom(&resourceAttributes.SubResource) if err != nil { return nil, err } - verb, err := stringValueFrom(&resourceAttributes.Verb) + verb, err := valueFrom(&resourceAttributes.Verb) if err != nil { return nil, err } @@ -661,24 +661,11 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf return translatedAuthConfig, nil } -func stringValueFrom(user *api.ValueOrSelector) (expressions.Value, error) { - var strValue expressions.Value - var err error - if user.Expression != "" { - if strValue, err = cel.NewStringExpression(string(user.Expression)); err != nil { - return nil, err - } - } else { - strValue = &json.JSONValue{Static: user.Value, Pattern: user.Selector} - } - return strValue, nil -} - func valueFrom(user *api.ValueOrSelector) (expressions.Value, error) { var strValue expressions.Value var err error if user.Expression != "" { - if strValue, err = cel.NewStringExpression(string(user.Expression)); err != nil { + if strValue, err = cel.NewExpression(string(user.Expression)); err != nil { return nil, err } } else { @@ -717,7 +704,7 @@ func injectResponseConfig(ctx context.Context, authConfig *api.AuthConfig, succe customClaims := make([]json.JSONProperty, 0) for claimName, claim := range wristband.CustomClaims { - if value, err := stringValueFrom(&claim); err != nil { + if value, err := valueFrom(&claim); err != nil { return err } else { customClaims = append(customClaims, json.JSONProperty{ @@ -758,7 +745,7 @@ func injectResponseConfig(ctx context.Context, authConfig *api.AuthConfig, succe // plain case api.PlainAuthResponse: - if value, err := stringValueFrom((*api.ValueOrSelector)(successResponse.Plain)); err != nil { + if value, err := valueFrom((*api.ValueOrSelector)(successResponse.Plain)); err != nil { return err } else { translatedResponse.Plain = &response_evaluators.Plain{ @@ -932,7 +919,7 @@ func (r *AuthConfigReconciler) buildGenericHttpEvaluator(ctx context.Context, ht var body expressions.Value if b := http.Body; b != nil { - if value, err := stringValueFrom(b); err != nil { + if value, err := valueFrom(b); err != nil { return nil, err } else { body = value @@ -970,7 +957,7 @@ func (r *AuthConfigReconciler) buildGenericHttpEvaluator(ctx context.Context, ht var dynamicEndpoint expressions.Value if http.UrlExpression != "" { - endpoint, err := cel.NewStringExpression(string(http.UrlExpression)) + endpoint, err := cel.NewExpression(string(http.UrlExpression)) if err != nil { return nil, err } else { @@ -1099,7 +1086,7 @@ func buildAuthorinoDenyWithValues(denyWithSpec *api.DenyWithSpec) (*evaluators.D headers := make([]json.JSONProperty, 0, len(denyWithSpec.Headers)) for name, header := range denyWithSpec.Headers { - if value, err := stringValueFrom(&header); err != nil { + if value, err := valueFrom(&header); err != nil { return nil, err } else { headers = append(headers, json.JSONProperty{Name: name, Value: value}) @@ -1128,7 +1115,7 @@ func getJsonFromStaticDynamic(value *api.ValueOrSelector) (expressions.Value, er } expression := string(value.Expression) if expression != "" { - return cel.NewStringExpression(expression) + return cel.NewExpression(expression) } return &json.JSONValue{ diff --git a/install/manifests.yaml b/install/manifests.yaml index a0ed239b..f3aa8e3c 100644 --- a/install/manifests.yaml +++ b/install/manifests.yaml @@ -5274,6 +5274,80 @@ kind: ClusterRole metadata: name: authorino-manager-role rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - delete + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create - apiGroups: - authorino.kuadrant.io resources: @@ -5294,6 +5368,12 @@ rules: - get - patch - update +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create - apiGroups: - coordination.k8s.io resources: @@ -5311,3 +5391,69 @@ rules: - get - list - watch +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos/finalizers + verbs: + - update +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos/status + verbs: + - get + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - update + - watch diff --git a/install/rbac/role.yaml b/install/rbac/role.yaml index 69520e9e..2328df39 100644 --- a/install/rbac/role.yaml +++ b/install/rbac/role.yaml @@ -4,6 +4,80 @@ kind: ClusterRole metadata: name: manager-role rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - delete + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create - apiGroups: - authorino.kuadrant.io resources: @@ -24,6 +98,12 @@ rules: - get - patch - update +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create - apiGroups: - coordination.k8s.io resources: @@ -41,3 +121,69 @@ rules: - get - list - watch +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos/finalizers + verbs: + - update +- apiGroups: + - operator.authorino.kuadrant.io + resources: + - authorinos/status + verbs: + - get + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - update + - watch diff --git a/pkg/expressions/cel/expressions.go b/pkg/expressions/cel/expressions.go index 1fb22bf6..fc1941a5 100644 --- a/pkg/expressions/cel/expressions.go +++ b/pkg/expressions/cel/expressions.go @@ -2,6 +2,7 @@ package cel import ( "fmt" + "github.com/tidwall/gjson" "reflect" "strings" @@ -68,30 +69,18 @@ func NewExpression(source string) (*Expression, error) { }, nil } -func NewStringExpression(source string) (*StringExpression, error) { - program, err := Compile(source, cel.StringType) - if err != nil { - return nil, err - } - return &StringExpression{ - expression: Expression{ - program: program, - source: source, - }, - }, nil -} - func (e *Expression) ResolveFor(json string) (interface{}, error) { result, _, err := e.Evaluate(json) if err != nil { return nil, err } - return ValueToJSON(result) -} - -func (e *StringExpression) ResolveFor(json string) (interface{}, error) { - return e.expression.EvaluateStringValue(json) + // this is for backwards compatibility with JSONValue, these should interoperate seamlessly this way + if jsonLiteral, err := ValueToJSON(result); err != nil { + return nil, err + } else { + return gjson.Parse(jsonLiteral).Value(), nil + } } func (e *Expression) Evaluate(json string) (ref.Val, *cel.EvalDetails, error) { @@ -103,21 +92,6 @@ func (e *Expression) Evaluate(json string) (ref.Val, *cel.EvalDetails, error) { return e.program.Eval(input) } -func (e *Expression) EvaluateStringValue(json string) (string, error) { - if result, _, err := e.Evaluate(json); err != nil { - return "", err - } else if !reflect.DeepEqual(result.Type(), cel.StringType) { - toJSON, err := ValueToJSON(result) - return toJSON, err - } else { - str, err := result.ConvertToNative(reflect.TypeOf("")) - if err != nil { - return "", err - } - return str.(string), nil - } -} - func Compile(expression string, expectedType *cel.Type, opts ...cel.EnvOption) (cel.Program, error) { envOpts := append([]cel.EnvOption{cel.Declarations( decls.NewConst(RootMetadataBinding, decls.NewObjectType("google.protobuf.Struct"), nil),