Skip to content

Commit d8d4d6f

Browse files
angrycubclaude
andcommitted
fix: add proper OIDC user role validation
When creating OIDC users, the provider was calling UpdateUserRoles even with empty roles due to the default schema value, causing the server error "User Role Field is set in the OIDC configuration". OIDC users should get their roles exclusively from the OIDC provider's role mapping, not from explicit API calls. This fix: - Errors if explicit roles are provided for OIDC users - Skips role assignment entirely for OIDC users - Provides clear error messaging about OIDC role behavior 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e5680f3 commit d8d4d6f

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

internal/provider/user_resource.go

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,28 @@ func (r *UserResource) Create(ctx context.Context, req resource.CreateRequest, r
213213
resp.Diagnostics.Append(
214214
data.Roles.ElementsAs(ctx, &roles, false)...,
215215
)
216-
tflog.Info(ctx, "updating user roles", map[string]any{
217-
"new_roles": roles,
218-
})
219-
user, err = client.UpdateUserRoles(ctx, user.ID.String(), codersdk.UpdateRoles{
220-
Roles: roles,
221-
})
222-
if err != nil {
223-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update newly created user roles, got error: %s", err))
224-
return
216+
217+
// OIDC users get their roles from the OIDC provider's role mapping
218+
if loginType == codersdk.LoginTypeOIDC {
219+
if len(roles) > 0 {
220+
resp.Diagnostics.AddError("Configuration Error", "Cannot set explicit roles for OIDC users. OIDC users get their roles from the OIDC provider's role mapping configuration.")
221+
return
222+
}
223+
tflog.Info(ctx, "skipping role assignment for OIDC user (roles come from OIDC provider)")
224+
} else {
225+
// For non-OIDC users, set roles explicitly
226+
tflog.Info(ctx, "updating user roles", map[string]any{
227+
"new_roles": roles,
228+
})
229+
user, err = client.UpdateUserRoles(ctx, user.ID.String(), codersdk.UpdateRoles{
230+
Roles: roles,
231+
})
232+
if err != nil {
233+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update newly created user roles, got error: %s", err))
234+
return
235+
}
236+
tflog.Info(ctx, "successfully updated user roles")
225237
}
226-
tflog.Info(ctx, "successfully updated user roles")
227238

228239
if data.Suspended.ValueBool() {
229240
_, err = client.UpdateUserStatus(ctx, data.ID.ValueString(), codersdk.UserStatus("suspended"))
@@ -348,17 +359,29 @@ func (r *UserResource) Update(ctx context.Context, req resource.UpdateRequest, r
348359
resp.Diagnostics.Append(
349360
data.Roles.ElementsAs(ctx, &roles, false)...,
350361
)
351-
tflog.Info(ctx, "updating user roles", map[string]any{
352-
"new_roles": roles,
353-
})
354-
_, err = client.UpdateUserRoles(ctx, user.ID.String(), codersdk.UpdateRoles{
355-
Roles: roles,
356-
})
357-
if err != nil {
358-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update user roles, got error: %s", err))
359-
return
362+
363+
// OIDC users get their roles from the OIDC provider's role mapping
364+
loginType := codersdk.LoginType(data.LoginType.ValueString())
365+
if loginType == codersdk.LoginTypeOIDC {
366+
if len(roles) > 0 {
367+
resp.Diagnostics.AddError("Configuration Error", "Cannot set explicit roles for OIDC users. OIDC users get their roles from the OIDC provider's role mapping configuration.")
368+
return
369+
}
370+
tflog.Info(ctx, "skipping role assignment for OIDC user (roles come from OIDC provider)")
371+
} else {
372+
// For non-OIDC users, set roles explicitly
373+
tflog.Info(ctx, "updating user roles", map[string]any{
374+
"new_roles": roles,
375+
})
376+
_, err = client.UpdateUserRoles(ctx, user.ID.String(), codersdk.UpdateRoles{
377+
Roles: roles,
378+
})
379+
if err != nil {
380+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update user roles, got error: %s", err))
381+
return
382+
}
383+
tflog.Info(ctx, "successfully updated user roles")
360384
}
361-
tflog.Info(ctx, "successfully updated user roles")
362385

363386
if data.LoginType.ValueString() == string(codersdk.LoginTypePassword) && !data.Password.IsNull() {
364387
tflog.Info(ctx, "updating password")

0 commit comments

Comments
 (0)