Skip to content

Commit 2bafe7a

Browse files
authored
Move username validation to happen before manage-users check (#1016)
1 parent fc2e283 commit 2bafe7a

File tree

2 files changed

+44
-41
lines changed

2 files changed

+44
-41
lines changed

pkg/resources/management.cattle.io/v3/users/validator.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ func (v *Validator) Admitters() []admission.Admitter {
7373
}
7474

7575
func (a *admitter) Admit(request *admission.Request) (*admissionv1.AdmissionResponse, error) {
76+
oldUser, newUser, err := objectsv3.UserOldAndNewFromRequest(&request.AdmissionRequest)
77+
if err != nil {
78+
return nil, fmt.Errorf("failed to get current User from request: %w", err)
79+
}
80+
81+
// Validate update fields
82+
fieldPath := field.NewPath("user")
83+
if request.Operation == admissionv1.Update {
84+
if err := validateUpdateFields(oldUser, newUser, fieldPath); err != nil {
85+
return admission.ResponseBadRequest(err.Error()), nil
86+
}
87+
}
88+
7689
// Check if requester has manage-user verb
7790
hasManageUsers, err := auth.RequestUserHasVerb(request, gvr, a.sar, manageUsersVerb, "", "")
7891
if err != nil {
@@ -83,11 +96,6 @@ func (a *admitter) Admit(request *admission.Request) (*admissionv1.AdmissionResp
8396
return &admissionv1.AdmissionResponse{Allowed: true}, nil
8497
}
8598

86-
oldUser, newUser, err := objectsv3.UserOldAndNewFromRequest(&request.AdmissionRequest)
87-
if err != nil {
88-
return nil, fmt.Errorf("failed to get current User from request: %w", err)
89-
}
90-
9199
// Need the UserAttribute to find the groups
92100
userAttribute, err := a.userAttributeCache.Get(oldUser.Name)
93101
if err != nil && !apierrors.IsNotFound(err) {
@@ -118,13 +126,6 @@ func (a *admitter) Admit(request *admission.Request) (*admissionv1.AdmissionResp
118126
}, nil
119127
}
120128

121-
fieldPath := field.NewPath("user")
122-
if request.Operation == admissionv1.Update {
123-
if err := validateUpdateFields(oldUser, newUser, fieldPath); err != nil {
124-
return admission.ResponseBadRequest(err.Error()), nil
125-
}
126-
}
127-
128129
return &admissionv1.AdmissionResponse{Allowed: true}, nil
129130
}
130131

@@ -144,7 +145,7 @@ func getGroupsFromUserAttribute(userAttribute *v3.UserAttribute) []string {
144145
return result
145146
}
146147

147-
// validateUpdateFields
148+
// validateUpdateFields validates fields during an update. The manage-users verb does not apply to these validations.
148149
func validateUpdateFields(oldUser, newUser *v3.User, fieldPath *field.Path) error {
149150
const reason = "field is immutable"
150151
if oldUser.Username != "" && oldUser.Username != newUser.Username {

pkg/resources/management.cattle.io/v3/users/validator_test.go

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,12 @@ func Test_Admit(t *testing.T) {
115115
oldUser: defaultUser.DeepCopy(),
116116
requestUserName: requesterUserName,
117117
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
118-
if s == requesterUserName {
119-
return getPods, nil
120-
} else if s == defaultUserName {
118+
switch s {
119+
case requesterUserName, defaultUserName:
121120
return getPods, nil
121+
default:
122+
return nil, fmt.Errorf("unexpected error")
122123
}
123-
return nil, fmt.Errorf("unexpected error")
124124
},
125125
allowed: true,
126126
},
@@ -130,12 +130,12 @@ func Test_Admit(t *testing.T) {
130130
newUser: defaultUser.DeepCopy(),
131131
requestUserName: requesterUserName,
132132
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
133-
if s == requesterUserName {
134-
return getPods, nil
135-
} else if s == defaultUserName {
133+
switch s {
134+
case requesterUserName, defaultUserName:
136135
return getPods, nil
136+
default:
137+
return nil, fmt.Errorf("unexpected error")
137138
}
138-
return nil, fmt.Errorf("unexpected error")
139139
},
140140
allowed: true,
141141
},
@@ -144,12 +144,14 @@ func Test_Admit(t *testing.T) {
144144
oldUser: defaultUser.DeepCopy(),
145145
requestUserName: requesterUserName,
146146
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
147-
if s == requesterUserName {
147+
switch s {
148+
case requesterUserName:
148149
return starPods, nil
149-
} else if s == defaultUserName {
150+
case defaultUserName:
150151
return getPods, nil
152+
default:
153+
return nil, fmt.Errorf("unexpected error")
151154
}
152-
return nil, fmt.Errorf("unexpected error")
153155
},
154156
allowed: true,
155157
},
@@ -159,12 +161,14 @@ func Test_Admit(t *testing.T) {
159161
newUser: defaultUser.DeepCopy(),
160162
requestUserName: requesterUserName,
161163
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
162-
if s == requesterUserName {
164+
switch s {
165+
case requesterUserName:
163166
return starPods, nil
164-
} else if s == defaultUserName {
167+
case defaultUserName:
165168
return getPods, nil
169+
default:
170+
return nil, fmt.Errorf("unexpected error")
166171
}
167-
return nil, fmt.Errorf("unexpected error")
168172
},
169173
allowed: true,
170174
},
@@ -173,12 +177,14 @@ func Test_Admit(t *testing.T) {
173177
oldUser: defaultUser.DeepCopy(),
174178
requestUserName: requesterUserName,
175179
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
176-
if s == requesterUserName {
180+
switch s {
181+
case requesterUserName:
177182
return getPods, nil
178-
} else if s == defaultUserName {
183+
case defaultUserName:
179184
return starPods, nil
185+
default:
186+
return nil, fmt.Errorf("unexpected error")
180187
}
181-
return nil, fmt.Errorf("unexpected error")
182188
},
183189
allowed: false,
184190
},
@@ -188,12 +194,14 @@ func Test_Admit(t *testing.T) {
188194
newUser: defaultUser.DeepCopy(),
189195
requestUserName: requesterUserName,
190196
resolverRulesFor: func(s string) ([]rbacv1.PolicyRule, error) {
191-
if s == requesterUserName {
197+
switch s {
198+
case requesterUserName:
192199
return getPods, nil
193-
} else if s == defaultUserName {
200+
case defaultUserName:
194201
return starPods, nil
202+
default:
203+
return nil, fmt.Errorf("unexpected error")
195204
}
196-
return nil, fmt.Errorf("unexpected error")
197205
},
198206
allowed: false,
199207
},
@@ -207,10 +215,7 @@ func Test_Admit(t *testing.T) {
207215
Username: "new-username",
208216
},
209217
requestUserName: requesterUserName,
210-
resolverRulesFor: func(string) ([]rbacv1.PolicyRule, error) {
211-
return getPods, nil
212-
},
213-
allowed: false,
218+
allowed: false,
214219
},
215220
{
216221
name: "adding a new username allowed",
@@ -235,10 +240,7 @@ func Test_Admit(t *testing.T) {
235240
},
236241
},
237242
requestUserName: requesterUserName,
238-
resolverRulesFor: func(string) ([]rbacv1.PolicyRule, error) {
239-
return getPods, nil
240-
},
241-
allowed: false,
243+
allowed: false,
242244
},
243245
}
244246
for _, tt := range tests {

0 commit comments

Comments
 (0)