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  }