github.com/zntrio/harp/v2@v2.0.9/pkg/bundle/ruleset/engine/cel/ext/secret.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package ext 19 20 import ( 21 "encoding/json" 22 "fmt" 23 "reflect" 24 25 validation "github.com/go-ozzo/ozzo-validation/v4" 26 "github.com/go-ozzo/ozzo-validation/v4/is" 27 "github.com/google/cel-go/cel" 28 "github.com/google/cel-go/common/types" 29 "github.com/google/cel-go/common/types/ref" 30 31 bundlev1 "github.com/zntrio/harp/v2/api/gen/go/harp/bundle/v1" 32 "github.com/zntrio/harp/v2/pkg/bundle/secret" 33 ) 34 35 // Secrets exported secret operations. 36 func Secrets() cel.EnvOption { 37 return cel.Lib(secretLib{}) 38 } 39 40 type secretLib struct{} 41 42 func (secretLib) CompileOptions() []cel.EnvOption { 43 return []cel.EnvOption{ 44 cel.Function( 45 "is_base64", 46 cel.MemberOverload("kv_is_base64", []*cel.Type{harpKVObjectType}, cel.BoolType, 47 cel.UnaryBinding(celValidatorBuilder(is.Base64)), 48 ), 49 ), 50 cel.Function( 51 "is_required", 52 cel.MemberOverload("kv_is_required", []*cel.Type{harpKVObjectType}, cel.BoolType, 53 cel.UnaryBinding(celValidatorBuilder(validation.Required)), 54 ), 55 ), 56 cel.Function( 57 "is_url", 58 cel.MemberOverload("kv_is_url", []*cel.Type{harpKVObjectType}, cel.BoolType, 59 cel.UnaryBinding(celValidatorBuilder(is.URL)), 60 ), 61 ), 62 cel.Function( 63 "is_uuid", 64 cel.MemberOverload("kv_is_uuid", []*cel.Type{harpKVObjectType}, cel.BoolType, 65 cel.UnaryBinding(celValidatorBuilder(is.UUID)), 66 ), 67 ), 68 cel.Function( 69 "is_email", 70 cel.MemberOverload("kv_is_email", []*cel.Type{harpKVObjectType}, cel.BoolType, 71 cel.UnaryBinding(celValidatorBuilder(is.EmailFormat)), 72 ), 73 ), 74 cel.Function( 75 "is_json", 76 cel.MemberOverload("kv_is_json", []*cel.Type{harpKVObjectType}, cel.BoolType, 77 cel.UnaryBinding(celValidatorBuilder(&jsonValidator{})), 78 ), 79 ), 80 } 81 } 82 83 func (secretLib) ProgramOptions() []cel.ProgramOption { 84 return []cel.ProgramOption{} 85 } 86 87 // ----------------------------------------------------------------------------- 88 89 func celValidatorBuilder(rules ...validation.Rule) func(ref.Val) ref.Val { 90 return func(lhs ref.Val) ref.Val { 91 x, _ := lhs.ConvertToNative(reflect.TypeOf(&bundlev1.KV{})) 92 p, ok := x.(*bundlev1.KV) 93 if !ok { 94 return types.Bool(false) 95 } 96 97 var out string 98 if err := secret.Unpack(p.Value, &out); err != nil { 99 return types.Bool(false) 100 } 101 102 if err := validation.Validate(out, rules...); err != nil { 103 return types.Bool(false) 104 } 105 106 return types.Bool(true) 107 } 108 } 109 110 // ----------------------------------------------------------------------------- 111 112 var _ validation.Rule = (*jsonValidator)(nil) 113 114 type jsonValidator struct{} 115 116 func (v *jsonValidator) Validate(in interface{}) error { 117 // Process input 118 if data, ok := in.([]byte); ok { 119 if !json.Valid(data) { 120 return fmt.Errorf("invalid JSON payload") 121 } 122 } 123 124 return fmt.Errorf("unable to validate JSON for %T type", in) 125 }