update api users and groups

This commit is contained in:
Alma 2025-04-09 20:12:35 +02:00
parent 7d95ac5a4d
commit 833f73a766
5 changed files with 359 additions and 8 deletions

View File

@ -0,0 +1,69 @@
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { NextResponse } from "next/server";
export async function PUT(
req: Request,
{ params }: { params: { userId: string } }
) {
const session = await getServerSession(authOptions);
if (!session) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
try {
const { password } = await req.json();
// Get client credentials token
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const tokenData = await tokenResponse.json();
if (!tokenResponse.ok) {
console.error("Failed to get token:", tokenData);
return NextResponse.json({ error: "Failed to get token" }, { status: 500 });
}
// Reset password
const passwordResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}/reset-password`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${tokenData.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: "password",
value: password,
temporary: false,
}),
}
);
if (!passwordResponse.ok) {
const errorData = await passwordResponse.json();
console.error("Failed to reset password:", errorData);
return NextResponse.json({ error: "Failed to reset password" }, { status: passwordResponse.status });
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error in reset password:", error);
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}

View File

@ -0,0 +1,92 @@
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { NextResponse } from "next/server";
export async function PUT(
req: Request,
{ params }: { params: { userId: string } }
) {
const session = await getServerSession(authOptions);
if (!session) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
try {
const { roles } = await req.json();
// Get client credentials token
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const tokenData = await tokenResponse.json();
if (!tokenResponse.ok) {
console.error("Failed to get token:", tokenData);
return NextResponse.json({ error: "Failed to get token" }, { status: 500 });
}
// Get available roles
const rolesResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/roles`,
{
headers: {
'Authorization': `Bearer ${tokenData.access_token}`,
},
}
);
if (!rolesResponse.ok) {
const errorData = await rolesResponse.json();
console.error("Failed to get roles:", errorData);
return NextResponse.json({ error: "Failed to get roles" }, { status: rolesResponse.status });
}
const availableRoles = await rolesResponse.json();
// Map role names to role objects
const roleObjects = roles.map((roleName: string) => {
const role = availableRoles.find((r: any) => r.name === roleName);
if (!role) {
throw new Error(`Role ${roleName} not found`);
}
return role;
});
// Update user roles
const updateResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}/role-mappings/realm`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${tokenData.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(roleObjects),
}
);
if (!updateResponse.ok) {
const errorData = await updateResponse.json();
console.error("Failed to update roles:", errorData);
return NextResponse.json({ error: "Failed to update roles" }, { status: updateResponse.status });
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error in update roles:", error);
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}

View File

@ -0,0 +1,123 @@
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { NextResponse } from "next/server";
export async function DELETE(
req: Request,
{ params }: { params: { userId: string } }
) {
const session = await getServerSession(authOptions);
if (!session) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
try {
// Get client credentials token
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const tokenData = await tokenResponse.json();
if (!tokenResponse.ok) {
console.error("Failed to get token:", tokenData);
return NextResponse.json({ error: "Failed to get token" }, { status: 500 });
}
// Delete user
const deleteResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${tokenData.access_token}`,
},
}
);
if (!deleteResponse.ok) {
const errorData = await deleteResponse.json();
console.error("Failed to delete user:", errorData);
return NextResponse.json({ error: "Failed to delete user" }, { status: deleteResponse.status });
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error in DELETE user:", error);
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}
export async function PUT(
req: Request,
{ params }: { params: { userId: string } }
) {
const session = await getServerSession(authOptions);
if (!session) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
try {
const body = await req.json();
// Get client credentials token
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const tokenData = await tokenResponse.json();
if (!tokenResponse.ok) {
console.error("Failed to get token:", tokenData);
return NextResponse.json({ error: "Failed to get token" }, { status: 500 });
}
// Update user
const updateResponse = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${tokenData.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
}
);
if (!updateResponse.ok) {
const errorData = await updateResponse.json();
console.error("Failed to update user:", errorData);
return NextResponse.json({ error: "Failed to update user" }, { status: updateResponse.status });
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error in PUT user:", error);
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}

View File

@ -53,11 +53,11 @@ export function AddUserButton({ userRole, handleAddUser }: AddUserButtonProps) {
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || "Une erreur est survenue");
setError(data.error || "Failed to create user");
return;
}
handleAddUser(data.user);
setOpen(false);
setFormData({
username: "",
firstName: "",
@ -65,8 +65,10 @@ export function AddUserButton({ userRole, handleAddUser }: AddUserButtonProps) {
email: "",
realmRoles: "",
});
} catch (error: any) {
setError(error.message);
setOpen(false);
} catch (error) {
setError("An error occurred while creating the user");
console.error("Error creating user:", error);
} finally {
setLoading(false);
}

View File

@ -184,14 +184,79 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
// Add this function for editing user
const handleEdit = async (userId: string) => {
// TODO: Implement edit functionality
console.log("Edit user:", userId);
try {
const user = users.find(u => u.id === userId);
if (!user) return;
const response = await fetch(`/api/users/${userId}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
enabled: true,
}),
});
const data = await response.json();
if (!response.ok) {
console.error("Edit error:", data);
// You might want to show an error message to the user here
return;
}
// Update the user in the local state
setUsers(prevUsers => prevUsers.map(u =>
u.id === userId ? { ...u, ...data } : u
));
// Optional: Show success message
console.log("User updated successfully");
} catch (error) {
console.error("Error updating user:", error);
// You might want to show an error message to the user here
}
};
// Add this function for managing roles
const handleManageRoles = async (userId: string) => {
// TODO: Implement role management
console.log("Manage roles for user:", userId);
try {
const user = users.find(u => u.id === userId);
if (!user) return;
const response = await fetch(`/api/users/${userId}/roles`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
roles: user.roles,
}),
});
const data = await response.json();
if (!response.ok) {
console.error("Role update error:", data);
// You might want to show an error message to the user here
return;
}
// Update the user's roles in the local state
setUsers(prevUsers => prevUsers.map(u =>
u.id === userId ? { ...u, roles: data.roles } : u
));
// Optional: Show success message
console.log("User roles updated successfully");
} catch (error) {
console.error("Error updating user roles:", error);
// You might want to show an error message to the user here
}
};
if (!session) return null;