equipes keycloak flow
This commit is contained in:
parent
2663d6f23a
commit
d2a1d119f4
@ -13,26 +13,37 @@ export async function GET(
|
|||||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safely access the userId parameter
|
// Handle params correctly for Next.js App Router
|
||||||
const userId = String(params?.userId || '');
|
// Convert to string primitive to avoid "used `params.userId`" error
|
||||||
|
const userIdParam = params.userId;
|
||||||
|
const userId = String(userIdParam);
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
|
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const kcAdminClient = await getKeycloakAdminClient();
|
try {
|
||||||
|
const kcAdminClient = await getKeycloakAdminClient();
|
||||||
|
|
||||||
// Get all available roles
|
// Get all available roles
|
||||||
const availableRoles = await kcAdminClient.roles.find();
|
const availableRoles = await kcAdminClient.roles.find();
|
||||||
|
|
||||||
// Get user's current roles
|
// Get user's current roles
|
||||||
const userRoles = await kcAdminClient.users.listRoleMappings({
|
const userRoles = await kcAdminClient.users.listRoleMappings({
|
||||||
id: userId,
|
id: userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
availableRoles,
|
availableRoles,
|
||||||
userRoles,
|
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) {
|
} catch (error) {
|
||||||
console.error("Error fetching roles:", error);
|
console.error("Error fetching roles:", error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@ -52,51 +63,62 @@ export async function PUT(
|
|||||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safely access the userId parameter
|
// Handle params correctly for Next.js App Router
|
||||||
const userId = String(params?.userId || '');
|
// Convert to string primitive to avoid "used `params.userId`" error
|
||||||
|
const userIdParam = params.userId;
|
||||||
|
const userId = String(userIdParam);
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
|
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { roles } = await request.json();
|
try {
|
||||||
const kcAdminClient = await getKeycloakAdminClient();
|
const { roles } = await request.json();
|
||||||
|
const kcAdminClient = await getKeycloakAdminClient();
|
||||||
|
|
||||||
// Get all available roles
|
// Get all available roles
|
||||||
const availableRoles = await kcAdminClient.roles.find();
|
const availableRoles = await kcAdminClient.roles.find();
|
||||||
|
|
||||||
// Get current user roles
|
// Get current user roles
|
||||||
const currentRoles = await kcAdminClient.users.listRoleMappings({
|
const currentRoles = await kcAdminClient.users.listRoleMappings({
|
||||||
id: userId,
|
id: userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find roles to add and remove
|
// Find roles to add and remove
|
||||||
const rolesToAdd = roles.filter(
|
const rolesToAdd = roles.filter(
|
||||||
(role: string) => !currentRoles.realmMappings?.some((r: any) => r.name === role)
|
(role: string) => !currentRoles.realmMappings?.some((r: any) => r.name === role)
|
||||||
);
|
);
|
||||||
const rolesToRemove = currentRoles.realmMappings?.filter(
|
const rolesToRemove = currentRoles.realmMappings?.filter(
|
||||||
(role: any) => !roles.includes(role.name)
|
(role: any) => !roles.includes(role.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add new roles
|
// Add new roles
|
||||||
for (const roleName of rolesToAdd) {
|
for (const roleName of rolesToAdd) {
|
||||||
const role = availableRoles.find((r: any) => r.name === roleName);
|
const role = availableRoles.find((r: any) => r.name === roleName);
|
||||||
if (role) {
|
if (role) {
|
||||||
await kcAdminClient.users.addRealmRoleMappings({
|
await kcAdminClient.users.addRealmRoleMappings({
|
||||||
|
id: userId,
|
||||||
|
roles: [role as any],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old roles
|
||||||
|
if (rolesToRemove && rolesToRemove.length > 0) {
|
||||||
|
await kcAdminClient.users.delRealmRoleMappings({
|
||||||
id: userId,
|
id: userId,
|
||||||
roles: [role as any],
|
roles: rolesToRemove as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Remove old roles
|
return NextResponse.json({ success: true });
|
||||||
if (rolesToRemove && rolesToRemove.length > 0) {
|
} catch (keycloakError) {
|
||||||
await kcAdminClient.users.delRealmRoleMappings({
|
console.error("Error connecting to Keycloak:", keycloakError);
|
||||||
id: userId,
|
return NextResponse.json(
|
||||||
roles: rolesToRemove as any,
|
{ error: "Failed to connect to Keycloak service", details: String(keycloakError) },
|
||||||
});
|
{ status: 503 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({ success: true });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating roles:", error);
|
console.error("Error updating roles:", error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@ -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';
|
// Only use environment variables - no hardcoded defaults
|
||||||
const adminClientId = process.env.KEYCLOAK_ADMIN_CLIENT_ID || 'admin-cli';
|
const keycloakUrl = process.env.KEYCLOAK_BASE_URL || process.env.KEYCLOAK_ISSUER || process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
|
||||||
const adminUsername = process.env.KEYCLOAK_ADMIN_USERNAME || 'admin';
|
const adminClientId = process.env.KEYCLOAK_ADMIN_CLIENT_ID;
|
||||||
const adminPassword = process.env.KEYCLOAK_ADMIN_PASSWORD || 'admin';
|
const adminUsername = process.env.KEYCLOAK_ADMIN_USERNAME;
|
||||||
const realmName = process.env.KEYCLOAK_REALM || 'cercle';
|
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}`);
|
console.log(`Connecting to Keycloak at ${keycloakUrl}, realm: ${realmName}`);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user