RoleController.java
package com.archiweb.api;
import com.archiweb.dto.RoleDTO;
import com.archiweb.model.Role;
import com.archiweb.repository.RoleRepository;
import com.archiweb.repository.UserRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/admin/roles")
@Tag(
name = "Gestion des Rôles",
description = """
Module de gestion des rôles utilisateurs.
Permet aux administrateurs de :
- Lister tous les rôles disponibles
- Consulter les détails d'un rôle
- Créer de nouveaux rôles
- Modifier les rôles existants
- Désactiver/Activer des rôles
- Voir le nombre d'utilisateurs par rôle
Tous les endpoints nécessitent le rôle **ADMIN**.
"""
)
public class RoleController {
private final RoleRepository roleRepository;
private final UserRepository userRepository;
public RoleController(RoleRepository roleRepository, UserRepository userRepository) {
this.roleRepository = roleRepository;
this.userRepository = userRepository;
}
/**
* Convertit un Role en RoleDTO avec le nombre d'utilisateurs
*/
private RoleDTO toDTO(Role role) {
RoleDTO dto = new RoleDTO();
dto.setId(role.getId());
dto.setName(role.getName());
dto.setDescription(role.getDescription());
dto.setActive(role.getActive());
// Compter les utilisateurs avec ce rôle
long userCount = userRepository.countByRole(role);
dto.setUserCount(userCount);
return dto;
}
// ================================================================
// 1️⃣ Lister tous les rôles
// ================================================================
@Operation(
summary = "Lister tous les rôles",
description = "Récupère la liste complète des rôles avec leurs descriptions et le nombre d'utilisateurs."
)
@GetMapping
public ResponseEntity<List<RoleDTO>> getAllRoles() {
List<Role> roles = roleRepository.findAll();
List<RoleDTO> roleDTOs = roles.stream()
.map(this::toDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(roleDTOs);
}
// ================================================================
// 2️⃣ Obtenir un rôle par ID
// ================================================================
@Operation(
summary = "Obtenir un rôle par ID",
description = "Récupère les détails d'un rôle spécifique."
)
@GetMapping("/{id}")
public ResponseEntity<RoleDTO> getRoleById(@PathVariable Long id) {
return roleRepository.findById(id)
.map(role -> ResponseEntity.ok(toDTO(role)))
.orElse(ResponseEntity.notFound().build());
}
// ================================================================
// 3️⃣ Obtenir un rôle par nom
// ================================================================
@Operation(
summary = "Obtenir un rôle par nom",
description = "Récupère les détails d'un rôle par son nom (ex: ROLE_USER, ROLE_ADMIN)."
)
@GetMapping("/name/{name}")
public ResponseEntity<RoleDTO> getRoleByName(@PathVariable String name) {
return roleRepository.findByName(name)
.map(role -> ResponseEntity.ok(toDTO(role)))
.orElse(ResponseEntity.notFound().build());
}
// ================================================================
// 4️⃣ Créer un nouveau rôle
// ================================================================
@Operation(
summary = "Créer un nouveau rôle",
description = "Crée un nouveau rôle avec un nom unique et une description."
)
@PostMapping
public ResponseEntity<RoleDTO> createRole(@RequestBody RoleDTO roleDTO) {
// Vérifier si le rôle existe déjà
if (roleRepository.findByName(roleDTO.getName()).isPresent()) {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
Role role = new Role();
role.setName(roleDTO.getName());
role.setDescription(roleDTO.getDescription());
role.setActive(roleDTO.getActive() != null ? roleDTO.getActive() : true);
Role savedRole = roleRepository.save(role);
return ResponseEntity.status(HttpStatus.CREATED).body(toDTO(savedRole));
}
// ================================================================
// 5️⃣ Mettre à jour un rôle
// ================================================================
@Operation(
summary = "Mettre à jour un rôle",
description = "Met à jour les informations d'un rôle existant (description, statut actif)."
)
@PutMapping("/{id}")
public ResponseEntity<RoleDTO> updateRole(@PathVariable Long id, @RequestBody RoleDTO roleDTO) {
Optional<Role> roleOpt = roleRepository.findById(id);
if (roleOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
Role role = roleOpt.get();
// Ne pas permettre la modification du nom des rôles système
if (!isSystemRole(role.getName())) {
if (roleDTO.getName() != null && !roleDTO.getName().equals(role.getName())) {
// Vérifier que le nouveau nom n'existe pas déjà
if (roleRepository.findByName(roleDTO.getName()).isPresent()) {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
role.setName(roleDTO.getName());
}
}
if (roleDTO.getDescription() != null) {
role.setDescription(roleDTO.getDescription());
}
if (roleDTO.getActive() != null) {
// Ne pas permettre de désactiver les rôles système
if (!isSystemRole(role.getName()) || roleDTO.getActive()) {
role.setActive(roleDTO.getActive());
}
}
Role updatedRole = roleRepository.save(role);
return ResponseEntity.ok(toDTO(updatedRole));
}
// ================================================================
// 6️⃣ Désactiver/Activer un rôle
// ================================================================
@Operation(
summary = "Désactiver/Activer un rôle",
description = "Active ou désactive un rôle. Les rôles système ne peuvent pas être désactivés."
)
@PatchMapping("/{id}/toggle")
public ResponseEntity<RoleDTO> toggleRole(@PathVariable Long id) {
Optional<Role> roleOpt = roleRepository.findById(id);
if (roleOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
Role role = roleOpt.get();
// Ne pas permettre de désactiver les rôles système
if (isSystemRole(role.getName())) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
role.setActive(!role.getActive());
Role updatedRole = roleRepository.save(role);
return ResponseEntity.ok(toDTO(updatedRole));
}
// ================================================================
// 7️⃣ Supprimer un rôle
// ================================================================
@Operation(
summary = "Supprimer un rôle",
description = "Supprime un rôle. Les rôles système ne peuvent pas être supprimés."
)
@DeleteMapping("/{id}")
@ApiResponse(
responseCode = "200",
description = "Rôle supprimé avec succès"
)
@ApiResponse(
responseCode = "400",
description = "Impossible de supprimer un rôle système ou un rôle utilisé",
content = @Content(examples = @ExampleObject(value = "{ \"error\": \"Cannot delete system role or role in use\" }"))
)
@ApiResponse(
responseCode = "404",
description = "Rôle non trouvé"
)
public ResponseEntity<Void> deleteRole(@PathVariable Long id) {
Optional<Role> roleOpt = roleRepository.findById(id);
if (roleOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
Role role = roleOpt.get();
// Ne pas permettre la suppression des rôles système
if (isSystemRole(role.getName())) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
// Vérifier si le rôle est utilisé
long userCount = userRepository.countByRole(role);
if (userCount > 0) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
roleRepository.delete(role);
return ResponseEntity.ok().build();
}
/**
* Vérifie si un rôle est un rôle système (ne peut pas être modifié/supprimé)
*/
private boolean isSystemRole(String roleName) {
return "ROLE_USER".equals(roleName) ||
"ROLE_ADMIN".equals(roleName) ||
"ROLE_EMPLOYEE".equals(roleName);
}
}