1/* 2Copyright 2015 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package validation 18 19import ( 20 apiequality "k8s.io/apimachinery/pkg/api/equality" 21 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 "k8s.io/apimachinery/pkg/util/validation/field" 23 authorizationapi "k8s.io/kubernetes/pkg/apis/authorization" 24) 25 26// ValidateSubjectAccessReviewSpec validates a SubjectAccessReviewSpec and returns an 27// ErrorList with any errors. 28func ValidateSubjectAccessReviewSpec(spec authorizationapi.SubjectAccessReviewSpec, fldPath *field.Path) field.ErrorList { 29 allErrs := field.ErrorList{} 30 if spec.ResourceAttributes != nil && spec.NonResourceAttributes != nil { 31 allErrs = append(allErrs, field.Invalid(fldPath.Child("nonResourceAttributes"), spec.NonResourceAttributes, `cannot be specified in combination with resourceAttributes`)) 32 } 33 if spec.ResourceAttributes == nil && spec.NonResourceAttributes == nil { 34 allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceAttributes"), spec.NonResourceAttributes, `exactly one of nonResourceAttributes or resourceAttributes must be specified`)) 35 } 36 if len(spec.User) == 0 && len(spec.Groups) == 0 { 37 allErrs = append(allErrs, field.Invalid(fldPath.Child("user"), spec.User, `at least one of user or group must be specified`)) 38 } 39 40 return allErrs 41} 42 43// ValidateSelfSubjectAccessReviewSpec validates a SelfSubjectAccessReviewSpec and returns an 44// ErrorList with any errors. 45func ValidateSelfSubjectAccessReviewSpec(spec authorizationapi.SelfSubjectAccessReviewSpec, fldPath *field.Path) field.ErrorList { 46 allErrs := field.ErrorList{} 47 if spec.ResourceAttributes != nil && spec.NonResourceAttributes != nil { 48 allErrs = append(allErrs, field.Invalid(fldPath.Child("nonResourceAttributes"), spec.NonResourceAttributes, `cannot be specified in combination with resourceAttributes`)) 49 } 50 if spec.ResourceAttributes == nil && spec.NonResourceAttributes == nil { 51 allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceAttributes"), spec.NonResourceAttributes, `exactly one of nonResourceAttributes or resourceAttributes must be specified`)) 52 } 53 54 return allErrs 55} 56 57// ValidateSelfSubjectRulesReview validates a SelfSubjectRulesReview and returns an 58// ErrorList with any errors. 59func ValidateSelfSubjectRulesReview(review *authorizationapi.SelfSubjectRulesReview) field.ErrorList { 60 return field.ErrorList{} 61} 62 63// ValidateSubjectAccessReview validates a SubjectAccessReview and returns an 64// ErrorList with any errors. 65func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList { 66 allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) 67 objectMetaShallowCopy := sar.ObjectMeta 68 objectMetaShallowCopy.ManagedFields = nil 69 if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) { 70 allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`)) 71 } 72 return allErrs 73} 74 75// ValidateSelfSubjectAccessReview validates a SelfSubjectAccessReview and returns an 76// ErrorList with any errors. 77func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList { 78 allErrs := ValidateSelfSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) 79 objectMetaShallowCopy := sar.ObjectMeta 80 objectMetaShallowCopy.ManagedFields = nil 81 if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) { 82 allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`)) 83 } 84 return allErrs 85} 86 87// ValidateLocalSubjectAccessReview validates a LocalSubjectAccessReview and returns an 88// ErrorList with any errors. 89func ValidateLocalSubjectAccessReview(sar *authorizationapi.LocalSubjectAccessReview) field.ErrorList { 90 allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) 91 92 objectMetaShallowCopy := sar.ObjectMeta 93 objectMetaShallowCopy.Namespace = "" 94 objectMetaShallowCopy.ManagedFields = nil 95 if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) { 96 allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty except for namespace`)) 97 } 98 99 if sar.Spec.ResourceAttributes != nil && sar.Spec.ResourceAttributes.Namespace != sar.Namespace { 100 allErrs = append(allErrs, field.Invalid(field.NewPath("spec.resourceAttributes.namespace"), sar.Spec.ResourceAttributes.Namespace, `must match metadata.namespace`)) 101 } 102 if sar.Spec.NonResourceAttributes != nil { 103 allErrs = append(allErrs, field.Invalid(field.NewPath("spec.nonResourceAttributes"), sar.Spec.NonResourceAttributes, `disallowed on this kind of request`)) 104 } 105 106 return allErrs 107} 108