1
16
17 package validation
18
19 import (
20 "strings"
21 "testing"
22
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/apimachinery/pkg/util/validation/field"
25 authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
26 )
27
28 func TestValidateSARSpec(t *testing.T) {
29 successCases := []authorizationapi.SubjectAccessReviewSpec{
30 {ResourceAttributes: &authorizationapi.ResourceAttributes{}, User: "me"},
31 {NonResourceAttributes: &authorizationapi.NonResourceAttributes{}, Groups: []string{"my-group"}},
32 }
33 for _, successCase := range successCases {
34 if errs := ValidateSubjectAccessReviewSpec(successCase, field.NewPath("spec")); len(errs) != 0 {
35 t.Errorf("expected success: %v", errs)
36 }
37 }
38
39 errorCases := []struct {
40 name string
41 obj authorizationapi.SubjectAccessReviewSpec
42 msg string
43 }{{
44 name: "neither request",
45 obj: authorizationapi.SubjectAccessReviewSpec{User: "me"},
46 msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
47 }, {
48 name: "both requests",
49 obj: authorizationapi.SubjectAccessReviewSpec{
50 ResourceAttributes: &authorizationapi.ResourceAttributes{},
51 NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
52 User: "me",
53 },
54 msg: "cannot be specified in combination with resourceAttributes",
55 }, {
56 name: "no subject",
57 obj: authorizationapi.SubjectAccessReviewSpec{
58 ResourceAttributes: &authorizationapi.ResourceAttributes{},
59 },
60 msg: `spec.user: Invalid value: "": at least one of user or group must be specified`,
61 }}
62
63 for _, c := range errorCases {
64 errs := ValidateSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
65 if len(errs) == 0 {
66 t.Errorf("%s: expected failure for %q", c.name, c.msg)
67 } else if !strings.Contains(errs[0].Error(), c.msg) {
68 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
69 }
70
71 errs = ValidateSubjectAccessReview(&authorizationapi.SubjectAccessReview{Spec: c.obj})
72 if len(errs) == 0 {
73 t.Errorf("%s: expected failure for %q", c.name, c.msg)
74 } else if !strings.Contains(errs[0].Error(), c.msg) {
75 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
76 }
77 errs = ValidateLocalSubjectAccessReview(&authorizationapi.LocalSubjectAccessReview{Spec: c.obj})
78 if len(errs) == 0 {
79 t.Errorf("%s: expected failure for %q", c.name, c.msg)
80 } else if !strings.Contains(errs[0].Error(), c.msg) {
81 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
82 }
83
84 }
85 }
86
87 func TestValidateSelfSAR(t *testing.T) {
88 successCases := []authorizationapi.SelfSubjectAccessReviewSpec{
89 {ResourceAttributes: &authorizationapi.ResourceAttributes{}},
90 }
91 for _, successCase := range successCases {
92 if errs := ValidateSelfSubjectAccessReviewSpec(successCase, field.NewPath("spec")); len(errs) != 0 {
93 t.Errorf("expected success: %v", errs)
94 }
95 }
96
97 errorCases := []struct {
98 name string
99 obj authorizationapi.SelfSubjectAccessReviewSpec
100 msg string
101 }{{
102 name: "neither request",
103 obj: authorizationapi.SelfSubjectAccessReviewSpec{},
104 msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
105 }, {
106 name: "both requests",
107 obj: authorizationapi.SelfSubjectAccessReviewSpec{
108 ResourceAttributes: &authorizationapi.ResourceAttributes{},
109 NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
110 },
111 msg: "cannot be specified in combination with resourceAttributes",
112 }}
113
114 for _, c := range errorCases {
115 errs := ValidateSelfSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
116 if len(errs) == 0 {
117 t.Errorf("%s: expected failure for %q", c.name, c.msg)
118 } else if !strings.Contains(errs[0].Error(), c.msg) {
119 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
120 }
121
122 errs = ValidateSelfSubjectAccessReview(&authorizationapi.SelfSubjectAccessReview{Spec: c.obj})
123 if len(errs) == 0 {
124 t.Errorf("%s: expected failure for %q", c.name, c.msg)
125 } else if !strings.Contains(errs[0].Error(), c.msg) {
126 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
127 }
128 }
129 }
130
131 func TestValidateLocalSAR(t *testing.T) {
132 successCases := []authorizationapi.LocalSubjectAccessReview{{
133 Spec: authorizationapi.SubjectAccessReviewSpec{
134 ResourceAttributes: &authorizationapi.ResourceAttributes{},
135 User: "user",
136 },
137 }}
138 for _, successCase := range successCases {
139 if errs := ValidateLocalSubjectAccessReview(&successCase); len(errs) != 0 {
140 t.Errorf("expected success: %v", errs)
141 }
142 }
143
144 errorCases := []struct {
145 name string
146 obj *authorizationapi.LocalSubjectAccessReview
147 msg string
148 }{{
149 name: "name",
150 obj: &authorizationapi.LocalSubjectAccessReview{
151 ObjectMeta: metav1.ObjectMeta{Name: "a"},
152 Spec: authorizationapi.SubjectAccessReviewSpec{
153 ResourceAttributes: &authorizationapi.ResourceAttributes{},
154 User: "user",
155 },
156 },
157 msg: "must be empty except for namespace",
158 }, {
159 name: "namespace conflict",
160 obj: &authorizationapi.LocalSubjectAccessReview{
161 ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
162 Spec: authorizationapi.SubjectAccessReviewSpec{
163 ResourceAttributes: &authorizationapi.ResourceAttributes{},
164 User: "user",
165 },
166 },
167 msg: "must match metadata.namespace",
168 }, {
169 name: "nonresource",
170 obj: &authorizationapi.LocalSubjectAccessReview{
171 ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
172 Spec: authorizationapi.SubjectAccessReviewSpec{
173 NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
174 User: "user",
175 },
176 },
177 msg: "disallowed on this kind of request",
178 }}
179
180 for _, c := range errorCases {
181 errs := ValidateLocalSubjectAccessReview(c.obj)
182 if len(errs) == 0 {
183 t.Errorf("%s: expected failure for %q", c.name, c.msg)
184 } else if !strings.Contains(errs[0].Error(), c.msg) {
185 t.Errorf("%s: unexpected error: %q, expected: %q", c.name, errs[0], c.msg)
186 }
187 }
188 }
189
View as plain text