package validation import ( "testing" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/util/validation/field" authorizationapi "github.com/openshift/origin/pkg/authorization/api" ) func TestValidatePolicy(t *testing.T) { errs := ValidatePolicy( &authorizationapi.Policy{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.PolicyName}, }, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.Policy T field.ErrorType F string }{ "zero-length namespace": { A: authorizationapi.Policy{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName}, }, T: field.ErrorTypeRequired, F: "metadata.namespace", }, "zero-length name": { A: authorizationapi.Policy{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault}, }, T: field.ErrorTypeRequired, F: "metadata.name", }, "invalid name": { A: authorizationapi.Policy{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "name"}, }, T: field.ErrorTypeInvalid, F: "metadata.name", }, "mismatched name": { A: authorizationapi.Policy{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.PolicyName}, Roles: map[string]*authorizationapi.Role{ "any1": { ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "any"}, }, }, }, T: field.ErrorTypeInvalid, F: "roles[any1].metadata.name", }, } for k, v := range errorCases { errs := ValidatePolicy(&v.A, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } } func TestValidatePolicyBinding(t *testing.T) { errs := ValidatePolicyBinding( &authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName("master")}, PolicyRef: kapi.ObjectReference{Namespace: "master"}, }, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.PolicyBinding T field.ErrorType F string }{ "zero-length namespace": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: field.ErrorTypeRequired, F: "metadata.namespace", }, "zero-length name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: field.ErrorTypeRequired, F: "metadata.name", }, "invalid name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "name"}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: field.ErrorTypeInvalid, F: "metadata.name", }, "bad role": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, RoleBindings: map[string]*authorizationapi.RoleBinding{ "any": { ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "any"}, RoleRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, }, }, T: field.ErrorTypeRequired, F: "roleBindings[any].roleRef.name", }, "mismatched name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, RoleBindings: map[string]*authorizationapi.RoleBinding{ "any1": { ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "any"}, RoleRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName, Name: "valid"}, }, }, }, T: field.ErrorTypeInvalid, F: "roleBindings[any1].metadata.name", }, } for k, v := range errorCases { errs := ValidatePolicyBinding(&v.A, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } } func TestValidateRoleBinding(t *testing.T) { errs := ValidateRoleBinding( &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{ {Name: "validsaname", Kind: authorizationapi.ServiceAccountKind}, {Name: "valid@username", Kind: authorizationapi.UserKind}, {Name: "system:admin", Kind: authorizationapi.SystemUserKind}, {Name: "valid@groupname", Kind: authorizationapi.GroupKind}, {Name: "system:authenticated", Kind: authorizationapi.SystemGroupKind}, }, }, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.RoleBinding T field.ErrorType F string }{ "zero-length namespace": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, }, T: field.ErrorTypeRequired, F: "metadata.namespace", }, "zero-length name": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, }, T: field.ErrorTypeRequired, F: "metadata.name", }, "invalid ref": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "name"}, RoleRef: kapi.ObjectReference{Namespace: "-192083", Name: "valid"}, }, T: field.ErrorTypeInvalid, F: "roleRef.namespace", }, "bad role": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.PolicyName}, RoleRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: field.ErrorTypeRequired, F: "roleRef.name", }, "bad subject kind": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Name: "subject"}}, }, T: field.ErrorTypeNotSupported, F: "subjects[0].kind", }, "bad subject name": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Name: "subject:bad", Kind: authorizationapi.ServiceAccountKind}}, }, T: field.ErrorTypeInvalid, F: "subjects[0].name", }, "bad system user name": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Name: "user", Kind: authorizationapi.SystemUserKind}}, }, T: field.ErrorTypeInvalid, F: "subjects[0].name", }, "bad system group name": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Name: "valid", Kind: authorizationapi.SystemGroupKind}}, }, T: field.ErrorTypeInvalid, F: "subjects[0].name", }, "forbidden fields": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Name: "subject", Kind: authorizationapi.ServiceAccountKind, APIVersion: "foo"}}, }, T: field.ErrorTypeForbidden, F: "subjects[0].apiVersion", }, "missing subject name": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, Subjects: []kapi.ObjectReference{{Kind: authorizationapi.ServiceAccountKind}}, }, T: field.ErrorTypeRequired, F: "subjects[0].name", }, } for k, v := range errorCases { errs := ValidateRoleBinding(&v.A, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } } func TestValidateRoleBindingUpdate(t *testing.T) { old := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master", ResourceVersion: "1"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, } errs := ValidateRoleBindingUpdate( &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master", ResourceVersion: "1"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "valid"}, }, old, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.RoleBinding T field.ErrorType F string }{ "changedRef": { A: authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master", ResourceVersion: "1"}, RoleRef: kapi.ObjectReference{Namespace: "master", Name: "changed"}, }, T: field.ErrorTypeInvalid, F: "roleRef", }, } for k, v := range errorCases { errs := ValidateRoleBindingUpdate(&v.A, old, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } } func TestValidateRole(t *testing.T) { errs := ValidateRole( &authorizationapi.Role{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"}, }, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.Role T field.ErrorType F string }{ "zero-length namespace": { A: authorizationapi.Role{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName}, }, T: field.ErrorTypeRequired, F: "metadata.namespace", }, "zero-length name": { A: authorizationapi.Role{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault}, }, T: field.ErrorTypeRequired, F: "metadata.name", }, } for k, v := range errorCases { errs := ValidateRole(&v.A, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } } func TestValidateClusterPolicyBinding(t *testing.T) { errorCases := map[string]struct { A authorizationapi.PolicyBinding T field.ErrorType F string }{ "external namespace ref": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName("master")}, PolicyRef: kapi.ObjectReference{Namespace: "master"}, }, T: field.ErrorTypeInvalid, F: "policyRef.namespace", }, } for k, v := range errorCases { errs := ValidatePolicyBinding(&v.A, false) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } }