update api users and groups and users 4
This commit is contained in:
parent
22bab9e845
commit
6a5155e855
81
app/api/roles/route.ts
Normal file
81
app/api/roles/route.ts
Normal file
@ -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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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<User[]>([]);
|
||||
const [roles, setRoles] = useState<Role[]>([]);
|
||||
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 <div className="text-center p-4">Loading...</div>;
|
||||
|
||||
@ -430,9 +397,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
<SelectValue placeholder="Sélectionner un rôle" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={ROLES.ADMIN}>Admin</SelectItem>
|
||||
<SelectItem value={ROLES.TEACHER}>Enseignant</SelectItem>
|
||||
<SelectItem value={ROLES.STUDENT}>Étudiant</SelectItem>
|
||||
{roles.map((role) => (
|
||||
<SelectItem key={role.id} value={role.name}>
|
||||
{role.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@ -542,9 +511,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
<SelectValue placeholder="Sélectionner un rôle" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={ROLES.ADMIN}>Admin</SelectItem>
|
||||
<SelectItem value={ROLES.TEACHER}>Enseignant</SelectItem>
|
||||
<SelectItem value={ROLES.STUDENT}>Étudiant</SelectItem>
|
||||
{roles.map((role) => (
|
||||
<SelectItem key={role.id} value={role.name}>
|
||||
{role.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user