equipes keycloak flow

This commit is contained in:
alma 2025-05-03 15:46:14 +02:00
parent 2663d6f23a
commit d2a1d119f4
2 changed files with 84 additions and 52 deletions

View File

@ -13,26 +13,37 @@ export async function GET(
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Safely access the userId parameter
const userId = String(params?.userId || '');
// Handle params correctly for Next.js App Router
// Convert to string primitive to avoid "used `params.userId`" error
const userIdParam = params.userId;
const userId = String(userIdParam);
if (!userId) {
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
}
const kcAdminClient = await getKeycloakAdminClient();
try {
const kcAdminClient = await getKeycloakAdminClient();
// Get all available roles
const availableRoles = await kcAdminClient.roles.find();
// Get user's current roles
const userRoles = await kcAdminClient.users.listRoleMappings({
id: userId,
});
// Get all available roles
const availableRoles = await kcAdminClient.roles.find();
// Get user's current roles
const userRoles = await kcAdminClient.users.listRoleMappings({
id: userId,
});
return NextResponse.json({
availableRoles,
userRoles,
});
return NextResponse.json({
availableRoles,
userRoles,
});
} catch (keycloakError) {
console.error("Error connecting to Keycloak:", keycloakError);
return NextResponse.json(
{ error: "Failed to connect to Keycloak service", details: String(keycloakError) },
{ status: 503 }
);
}
} catch (error) {
console.error("Error fetching roles:", error);
return NextResponse.json(
@ -52,51 +63,62 @@ export async function PUT(
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Safely access the userId parameter
const userId = String(params?.userId || '');
// Handle params correctly for Next.js App Router
// Convert to string primitive to avoid "used `params.userId`" error
const userIdParam = params.userId;
const userId = String(userIdParam);
if (!userId) {
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
}
const { roles } = await request.json();
const kcAdminClient = await getKeycloakAdminClient();
try {
const { roles } = await request.json();
const kcAdminClient = await getKeycloakAdminClient();
// Get all available roles
const availableRoles = await kcAdminClient.roles.find();
// Get current user roles
const currentRoles = await kcAdminClient.users.listRoleMappings({
id: userId,
});
// Get all available roles
const availableRoles = await kcAdminClient.roles.find();
// Get current user roles
const currentRoles = await kcAdminClient.users.listRoleMappings({
id: userId,
});
// Find roles to add and remove
const rolesToAdd = roles.filter(
(role: string) => !currentRoles.realmMappings?.some((r: any) => r.name === role)
);
const rolesToRemove = currentRoles.realmMappings?.filter(
(role: any) => !roles.includes(role.name)
);
// Find roles to add and remove
const rolesToAdd = roles.filter(
(role: string) => !currentRoles.realmMappings?.some((r: any) => r.name === role)
);
const rolesToRemove = currentRoles.realmMappings?.filter(
(role: any) => !roles.includes(role.name)
);
// Add new roles
for (const roleName of rolesToAdd) {
const role = availableRoles.find((r: any) => r.name === roleName);
if (role) {
await kcAdminClient.users.addRealmRoleMappings({
// Add new roles
for (const roleName of rolesToAdd) {
const role = availableRoles.find((r: any) => r.name === roleName);
if (role) {
await kcAdminClient.users.addRealmRoleMappings({
id: userId,
roles: [role as any],
});
}
}
// Remove old roles
if (rolesToRemove && rolesToRemove.length > 0) {
await kcAdminClient.users.delRealmRoleMappings({
id: userId,
roles: [role as any],
roles: rolesToRemove as any,
});
}
}
// Remove old roles
if (rolesToRemove && rolesToRemove.length > 0) {
await kcAdminClient.users.delRealmRoleMappings({
id: userId,
roles: rolesToRemove as any,
});
return NextResponse.json({ success: true });
} catch (keycloakError) {
console.error("Error connecting to Keycloak:", keycloakError);
return NextResponse.json(
{ error: "Failed to connect to Keycloak service", details: String(keycloakError) },
{ status: 503 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error updating roles:", error);
return NextResponse.json(

View File

@ -21,11 +21,21 @@ export async function getKeycloakAdminClient(): Promise<KcAdminClient> {
}
}
const keycloakUrl = process.env.KEYCLOAK_BASE_URL || process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER || 'http://localhost:8080';
const adminClientId = process.env.KEYCLOAK_ADMIN_CLIENT_ID || 'admin-cli';
const adminUsername = process.env.KEYCLOAK_ADMIN_USERNAME || 'admin';
const adminPassword = process.env.KEYCLOAK_ADMIN_PASSWORD || 'admin';
const realmName = process.env.KEYCLOAK_REALM || 'cercle';
// Only use environment variables - no hardcoded defaults
const keycloakUrl = process.env.KEYCLOAK_BASE_URL || process.env.KEYCLOAK_ISSUER || process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
const adminClientId = process.env.KEYCLOAK_ADMIN_CLIENT_ID;
const adminUsername = process.env.KEYCLOAK_ADMIN_USERNAME;
const adminPassword = process.env.KEYCLOAK_ADMIN_PASSWORD;
const realmName = process.env.KEYCLOAK_REALM;
// Validate required environment variables
if (!keycloakUrl) {
throw new Error('Missing Keycloak URL. Please set KEYCLOAK_BASE_URL or KEYCLOAK_ISSUER or NEXT_PUBLIC_KEYCLOAK_ISSUER in your environment variables.');
}
if (!adminClientId || !adminUsername || !adminPassword || !realmName) {
throw new Error('Missing Keycloak admin credentials. Please set KEYCLOAK_ADMIN_CLIENT_ID, KEYCLOAK_ADMIN_USERNAME, KEYCLOAK_ADMIN_PASSWORD, and KEYCLOAK_REALM in your environment variables.');
}
console.log(`Connecting to Keycloak at ${keycloakUrl}, realm: ${realmName}`);