diff --git a/app/api/roles/route.ts b/app/api/roles/route.ts new file mode 100644 index 00000000..8a0996c2 --- /dev/null +++ b/app/api/roles/route.ts @@ -0,0 +1,81 @@ +import { getServerSession } from "next-auth/next"; +import { authOptions } from "@/app/api/auth/[...nextauth]/route"; +import { NextResponse } from "next/server"; + +async function getAdminToken() { + try { + 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 data = await tokenResponse.json(); + + if (!tokenResponse.ok || !data.access_token) { + console.error('Token Error:', data); + return null; + } + + return data.access_token; + } catch (error) { + console.error('Token Error:', error); + return null; + } +} + +export async function GET() { + const session = await getServerSession(authOptions); + + if (!session) { + return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + } + + try { + const token = await getAdminToken(); + if (!token) { + return NextResponse.json({ error: "Erreur d'authentification" }, { status: 401 }); + } + + const response = await fetch( + `${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/roles`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + + if (!response.ok) { + const errorData = await response.json(); + console.error("Failed to fetch roles:", errorData); + return NextResponse.json({ error: "Erreur lors de la récupération des rôles" }, { status: response.status }); + } + + const roles = await response.json(); + + // Filter out system roles + const filteredRoles = roles.filter((role: any) => + !role.name.startsWith('default-roles-') && + role.name !== 'offline_access' && + role.name !== 'uma_authorization' + ); + + return NextResponse.json(filteredRoles); + } catch (error) { + console.error("Error fetching roles:", error); + return NextResponse.json( + { error: "Une erreur est survenue" }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/components/users/users-table.tsx b/components/users/users-table.tsx index d1ef9b99..2048cb64 100644 --- a/components/users/users-table.tsx +++ b/components/users/users-table.tsx @@ -48,22 +48,25 @@ interface User { roles: string[]; } +interface Role { + id: string; + name: string; + description: string; + composite: boolean; + clientRole: boolean; + containerId: string; +} + interface UsersTableProps { userRole?: string[]; } -// Constants for role names -const ROLES = { - ADMIN: "Admin", - TEACHER: "Teacher", - STUDENT: "Students" -} as const; - const ITEMS_PER_PAGE = 10; export function UsersTable({ userRole = [] }: UsersTableProps) { const { data: session, status } = useSession(); const [users, setUsers] = useState([]); + const [roles, setRoles] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [searchTerm, setSearchTerm] = useState(""); @@ -81,15 +84,32 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { useEffect(() => { fetchUsers(); + fetchRoles(); }, []); + const fetchRoles = async () => { + try { + const response = await fetch("/api/roles"); + if (!response.ok) { + throw new Error("Failed to fetch roles"); + } + const data = await response.json(); + setRoles(data); + } catch (error) { + console.error("Error fetching roles:", error); + toast({ + title: "Erreur", + description: "Erreur lors de la récupération des rôles", + variant: "destructive", + }); + } + }; + const fetchUsers = async () => { try { setLoading(true); const response = await fetch("/api/users"); const data = await response.json(); - console.log("Fetched users:", data); - console.log("Current user role:", session?.user?.role); // Debug log setUsers(data); } catch (error) { console.error("Error fetching users:", error); @@ -103,46 +123,6 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { } }; - const filterUsers = (users: User[]) => { - console.log("Filtering users with role:", userRole); // Debug log - - if (!Array.isArray(users)) return []; - - // If no role specified or user is admin, show all users - if (!userRole?.length || userRole.includes(ROLES.ADMIN)) { - console.log("Showing all users - admin or no role"); - return users; - } - - // If user is teacher, show teachers and students - if (userRole.includes(ROLES.TEACHER)) { - console.log("Filtering for teacher view"); - return users.filter(user => - user.roles?.includes(ROLES.TEACHER) || user.roles?.includes(ROLES.STUDENT) - ); - } - - // If user is student, show only students - if (userRole.includes(ROLES.STUDENT)) { - console.log("Filtering for student view"); - return users.filter(user => user.roles?.includes(ROLES.STUDENT)); - } - - // Default: show all users - console.log("Default case: showing all users"); - return users; - }; - - const canDelete = (targetUserRole: string[]) => { - if (!userRole?.length) return false; - - if (userRole.includes(ROLES.ADMIN)) return true; - if (userRole.includes(ROLES.TEACHER)) { - return targetUserRole.includes(ROLES.STUDENT); - } - return false; - }; - const handleAddUser = async (e: React.FormEvent) => { e.preventDefault(); try { @@ -320,9 +300,8 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { }; const filteredUsers = useMemo(() => { - let filtered = filterUsers(users); + let filtered = users; - // Apply search filter if (searchTerm) { filtered = filtered.filter(user => user.username.toLowerCase().includes(searchTerm.toLowerCase()) || @@ -333,26 +312,14 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { } return filtered; - }, [users, searchTerm, userRole]); + }, [users, searchTerm]); - // Calculate pagination const totalPages = Math.ceil(filteredUsers.length / ITEMS_PER_PAGE); const paginatedUsers = filteredUsers.slice( (currentPage - 1) * ITEMS_PER_PAGE, currentPage * ITEMS_PER_PAGE ); - const handlePageChange = (page: number) => { - setCurrentPage(page); - }; - - // First, let's debug the roles - console.log("Current session:", { - role: session?.user?.role, - isAdmin: session?.user?.role?.includes("Admin"), - isTeacher: session?.user?.role?.includes("Teacher") - }); - if (!session) return null; if (loading) return
Loading...
; @@ -430,9 +397,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { - Admin - Enseignant - Étudiant + {roles.map((role) => ( + + {role.name} + + ))} @@ -542,9 +511,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) { - Admin - Enseignant - Étudiant + {roles.map((role) => ( + + {role.name} + + ))}