k8s.io/apiserver@v0.31.1/pkg/authentication/cel/mapper.go (about)

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cel
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    24  )
    25  
    26  var _ ClaimsMapper = &mapper{}
    27  var _ UserMapper = &mapper{}
    28  
    29  // mapper implements the ClaimsMapper and UserMapper interface.
    30  type mapper struct {
    31  	compilationResults []CompilationResult
    32  }
    33  
    34  // CELMapper is a struct that holds the compiled expressions for
    35  // username, groups, uid, extra, claimValidation and userValidation
    36  type CELMapper struct {
    37  	Username             ClaimsMapper
    38  	Groups               ClaimsMapper
    39  	UID                  ClaimsMapper
    40  	Extra                ClaimsMapper
    41  	ClaimValidationRules ClaimsMapper
    42  	UserValidationRules  UserMapper
    43  }
    44  
    45  // NewClaimsMapper returns a new ClaimsMapper.
    46  func NewClaimsMapper(compilationResults []CompilationResult) ClaimsMapper {
    47  	return &mapper{
    48  		compilationResults: compilationResults,
    49  	}
    50  }
    51  
    52  // NewUserMapper returns a new UserMapper.
    53  func NewUserMapper(compilationResults []CompilationResult) UserMapper {
    54  	return &mapper{
    55  		compilationResults: compilationResults,
    56  	}
    57  }
    58  
    59  // EvalClaimMapping evaluates the given claim mapping expression and returns a EvaluationResult.
    60  func (m *mapper) EvalClaimMapping(ctx context.Context, claims *unstructured.Unstructured) (EvaluationResult, error) {
    61  	results, err := m.eval(ctx, map[string]interface{}{claimsVarName: claims.Object})
    62  	if err != nil {
    63  		return EvaluationResult{}, err
    64  	}
    65  	if len(results) != 1 {
    66  		return EvaluationResult{}, fmt.Errorf("expected 1 evaluation result, got %d", len(results))
    67  	}
    68  	return results[0], nil
    69  }
    70  
    71  // EvalClaimMappings evaluates the given expressions and returns a list of EvaluationResult.
    72  func (m *mapper) EvalClaimMappings(ctx context.Context, claims *unstructured.Unstructured) ([]EvaluationResult, error) {
    73  	return m.eval(ctx, map[string]interface{}{claimsVarName: claims.Object})
    74  }
    75  
    76  // EvalUser evaluates the given user expressions and returns a list of EvaluationResult.
    77  func (m *mapper) EvalUser(ctx context.Context, userInfo *unstructured.Unstructured) ([]EvaluationResult, error) {
    78  	return m.eval(ctx, map[string]interface{}{userVarName: userInfo.Object})
    79  }
    80  
    81  func (m *mapper) eval(ctx context.Context, input map[string]interface{}) ([]EvaluationResult, error) {
    82  	evaluations := make([]EvaluationResult, len(m.compilationResults))
    83  
    84  	for i, compilationResult := range m.compilationResults {
    85  		var evaluation = &evaluations[i]
    86  		evaluation.ExpressionAccessor = compilationResult.ExpressionAccessor
    87  
    88  		evalResult, _, err := compilationResult.Program.ContextEval(ctx, input)
    89  		if err != nil {
    90  			return nil, fmt.Errorf("expression '%s' resulted in error: %w", compilationResult.ExpressionAccessor.GetExpression(), err)
    91  		}
    92  
    93  		evaluation.EvalResult = evalResult
    94  	}
    95  
    96  	return evaluations, nil
    97  }