update api users and groups and users 12

This commit is contained in:
Alma 2025-04-09 21:41:27 +02:00
parent 159ad9cbdf
commit 4a9bfebecf
5 changed files with 51 additions and 134 deletions

View File

@ -1,76 +0,0 @@
import { getServerSession } from "next-auth";
import { authOptions } from "../../auth/[...nextauth]/route";
import { NextResponse } from "next/server";
//TODO: Ajouter la suppression automatique du compte Nextcloud
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 {
// First get an admin token using client credentials
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 admin token:", tokenData);
return NextResponse.json(
{ error: "Erreur d'authentification" },
{ status: 401 }
);
}
// Delete user using admin token
const response = await fetch(
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${tokenData.access_token}`,
},
}
);
console.log("Delete response:", {
status: response.status,
ok: response.ok
});
if (!response.ok) {
const errorText = await response.text();
console.error("Delete error:", errorText);
return NextResponse.json(
{ error: "Erreur lors de la suppression", details: errorText },
{ status: response.status }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error deleting user:", error);
return NextResponse.json(
{ error: "Erreur serveur", details: error },
{ status: 500 }
);
}
}

View File

@ -62,9 +62,9 @@ export async function PUT(
// Find roles to add and remove
const rolesToAdd = roles.filter(
(role: string) => !currentRoles.clientMappings?.some((r: RoleRepresentation) => r.name === role)
(role: string) => !currentRoles.realmMappings?.some((r: RoleRepresentation) => r.name === role)
);
const rolesToRemove = currentRoles.clientMappings?.filter(
const rolesToRemove = currentRoles.realmMappings?.filter(
(role: RoleRepresentation) => !roles.includes(role.name)
);

View File

@ -1,5 +1,5 @@
import { getServerSession } from "next-auth";
import { authOptions } from "../../auth/[...nextauth]/route";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { NextResponse } from "next/server";
//TODO: Ajouter la suppression automatique du compte Nextcloud

View File

@ -432,64 +432,61 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
</DialogContent>
</Dialog>
<Dialog open={manageMembersDialog} onOpenChange={(open) => {
if (!open) {
setSelectedGroup(null);
setGroupMembers([]);
setAvailableUsers([]);
}
setManageMembersDialog(open);
}}>
<DialogContent className="max-w-2xl">
<Dialog open={manageMembersDialog} onOpenChange={setManageMembersDialog}>
<DialogContent className="max-h-[80vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Gérer les membres du groupe {selectedGroup?.name}</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="space-y-2">
<Label>Membres actuels</Label>
<div className="border rounded-md p-4 space-y-2">
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
{groupMembers.length === 0 ? (
<p className="text-sm text-gray-500">Aucun membre</p>
<p className="text-sm text-muted-foreground">Aucun membre</p>
) : (
groupMembers.map(member => (
<div key={member.id} className="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md">
<div className="space-y-2">
{groupMembers.map((member) => (
<div key={member.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
<div>
<p className="font-medium">{member.username}</p>
<p className="text-sm text-gray-500">{member.email}</p>
<p className="text-sm text-muted-foreground">{member.email}</p>
</div>
<Button
variant="ghost"
size="sm"
onClick={() => handleRemoveMember(member.id)}
>
Retirer
<Trash className="h-4 w-4" />
</Button>
</div>
))
))}
</div>
)}
</div>
</div>
<div className="space-y-2">
<Label>Ajouter des membres</Label>
<div className="border rounded-md p-4 space-y-2">
<Label>Ajouter un membre</Label>
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
{availableUsers.length === 0 ? (
<p className="text-sm text-gray-500">Aucun utilisateur disponible</p>
<p className="text-sm text-muted-foreground">Aucun utilisateur disponible</p>
) : (
availableUsers.map(user => (
<div key={user.id} className="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md">
<div className="space-y-2">
{availableUsers.map((user) => (
<div key={user.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
<div>
<p className="font-medium">{user.username}</p>
<p className="text-sm text-gray-500">{user.email}</p>
<p className="text-sm text-muted-foreground">{user.email}</p>
</div>
<Button
variant="ghost"
size="sm"
onClick={() => handleAddMember(user.id)}
>
Ajouter
<Plus className="h-4 w-4" />
</Button>
</div>
))
))}
</div>
)}
</div>
</div>

View File

@ -223,11 +223,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
throw new Error("Erreur lors de la mise à jour des rôles");
}
setUsers(prevUsers => prevUsers.map(user =>
user.id === selectedUser.id
? { ...user, roles: formData.roles }
: user
));
await fetchUsers();
setManageRolesDialog(false);
setSelectedUser(null);
@ -650,14 +646,6 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
<DialogTitle>Modifier l'utilisateur</DialogTitle>
</DialogHeader>
<form onSubmit={handleUpdateUser} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="edit-lastName">Nom</Label>
<Input
id="edit-lastName"
value={formData.lastName}
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-firstName">Prénom</Label>
<Input
@ -666,6 +654,14 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-lastName">Nom</Label>
<Input
id="edit-lastName"
value={formData.lastName}
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-email">Email</Label>
<Input