fix: show descriptive error when creating local user with OIDC enabled
Return a JSON error body from UserAdminController instead of an empty 400, and extract API error messages in adminFetch so toasts display the reason. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,10 +87,11 @@ public class UserAdminController {
|
|||||||
@Operation(summary = "Create a local user")
|
@Operation(summary = "Create a local user")
|
||||||
@ApiResponse(responseCode = "200", description = "User created")
|
@ApiResponse(responseCode = "200", description = "User created")
|
||||||
@ApiResponse(responseCode = "400", description = "Disabled in OIDC mode")
|
@ApiResponse(responseCode = "400", description = "Disabled in OIDC mode")
|
||||||
public ResponseEntity<UserDetail> createUser(@RequestBody CreateUserRequest request,
|
public ResponseEntity<?> createUser(@RequestBody CreateUserRequest request,
|
||||||
HttpServletRequest httpRequest) {
|
HttpServletRequest httpRequest) {
|
||||||
if (oidcEnabled) {
|
if (oidcEnabled) {
|
||||||
return ResponseEntity.badRequest().build();
|
return ResponseEntity.badRequest()
|
||||||
|
.body(Map.of("error", "Local user creation is disabled when OIDC is enabled. Users are provisioned automatically via SSO."));
|
||||||
}
|
}
|
||||||
String userId = "user:" + request.username();
|
String userId = "user:" + request.username();
|
||||||
UserInfo user = new UserInfo(userId, "local",
|
UserInfo user = new UserInfo(userId, "local",
|
||||||
|
|||||||
@@ -16,7 +16,17 @@ export async function adminFetch<T>(path: string, options?: RequestInit): Promis
|
|||||||
useAuthStore.getState().logout();
|
useAuthStore.getState().logout();
|
||||||
throw new Error('Unauthorized');
|
throw new Error('Unauthorized');
|
||||||
}
|
}
|
||||||
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
if (!res.ok) {
|
||||||
|
let message = `API error: ${res.status}`;
|
||||||
|
try {
|
||||||
|
const body = await res.json();
|
||||||
|
if (body?.error) message = body.error;
|
||||||
|
else if (body?.message) message = body.message;
|
||||||
|
} catch {
|
||||||
|
// no JSON body — keep generic message
|
||||||
|
}
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
if (res.status === 204) return undefined as T;
|
if (res.status === 204) return undefined as T;
|
||||||
const text = await res.text();
|
const text = await res.text();
|
||||||
if (!text) return undefined as T;
|
if (!text) return undefined as T;
|
||||||
|
|||||||
@@ -145,8 +145,9 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig
|
|||||||
setNewPassword('');
|
setNewPassword('');
|
||||||
setNewProvider('local');
|
setNewProvider('local');
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: (err: unknown) => {
|
||||||
toast({ title: 'Failed to create user', variant: 'error', duration: 86_400_000 });
|
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||||
|
toast({ title: 'Failed to create user', description: message, variant: 'error', duration: 86_400_000 });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user