package dev.lions.user.manager.resource; import dev.lions.user.manager.api.UserResourceApi; import dev.lions.user.manager.dto.common.ApiErrorDTO; import dev.lions.user.manager.dto.importexport.ImportResultDTO; import dev.lions.user.manager.dto.user.*; import dev.lions.user.manager.service.UserService; import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import lombok.extern.slf4j.Slf4j; import java.util.List; /** * REST Resource pour la gestion des utilisateurs * Implémente l'interface API commune. */ @Slf4j @jakarta.enterprise.context.ApplicationScoped @jakarta.ws.rs.Path("/api/users") public class UserResource implements UserResourceApi { @Inject UserService userService; @Override @RolesAllowed({ "admin", "user_manager", "ADMIN", "SUPER_ADMIN" }) public UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria) { log.info("POST /api/users/search - Recherche d'utilisateurs"); return userService.searchUsers(criteria); } @Override @RolesAllowed({ "admin", "user_manager", "user_viewer", "ADMIN", "SUPER_ADMIN", "USER" }) public UserDTO getUserById(String userId, String realmName) { log.info("GET /api/users/{} - realm: {}", userId, realmName); return userService.getUserById(userId, realmName) .orElseThrow(() -> new RuntimeException("Utilisateur non trouvé")); // ExceptionMapper should handle/map // to 404 } @Override @RolesAllowed({ "admin", "user_manager", "user_viewer", "ADMIN", "SUPER_ADMIN", "USER" }) public UserSearchResultDTO getAllUsers(String realmName, int page, int pageSize) { log.info("GET /api/users - realm: {}, page: {}, pageSize: {}", realmName, page, pageSize); return userService.getAllUsers(realmName, page, pageSize); } @Override @RolesAllowed({ "admin", "user_manager", "ADMIN", "SUPER_ADMIN" }) public Response createUser(@Valid @NotNull UserDTO user, String realmName) { log.info("POST /api/users - Création d'un utilisateur: {}", user.getUsername()); try { UserDTO createdUser = userService.createUser(user, realmName); return Response.status(Response.Status.CREATED).entity(createdUser).build(); } catch (IllegalArgumentException e) { log.warn("Données invalides lors de la création: {}", e.getMessage()); return Response.status(Response.Status.CONFLICT) .entity(new ApiErrorDTO(e.getMessage())) .build(); } catch (Exception e) { log.error("Erreur lors de la création de l'utilisateur", e); throw new RuntimeException(e); } } @Override @RolesAllowed({ "admin", "user_manager", "ADMIN", "SUPER_ADMIN" }) public UserDTO updateUser(String userId, @Valid @NotNull UserDTO user, String realmName) { log.info("PUT /api/users/{} - Mise à jour", userId); return userService.updateUser(userId, user, realmName); } @Override @RolesAllowed({ "admin", "ADMIN", "SUPER_ADMIN" }) public void deleteUser(String userId, String realmName, boolean hardDelete) { log.info("DELETE /api/users/{} - realm: {}, hardDelete: {}", userId, realmName, hardDelete); userService.deleteUser(userId, realmName, hardDelete); } @Override @RolesAllowed({ "admin", "user_manager", "ADMIN", "SUPER_ADMIN" }) public void activateUser(String userId, String realmName) { log.info("POST /api/users/{}/activate", userId); userService.activateUser(userId, realmName); } @Override @RolesAllowed({ "admin", "user_manager", "ADMIN", "SUPER_ADMIN" }) public void deactivateUser(String userId, String realmName, String raison) { log.info("POST /api/users/{}/deactivate - raison: {}", userId, raison); userService.deactivateUser(userId, realmName, raison); } @Override @RolesAllowed({ "admin", "user_manager" }) public void resetPassword(String userId, String realmName, @NotNull PasswordResetRequestDTO request) { log.info("POST /api/users/{}/reset-password - temporary: {}", userId, request.isTemporary()); userService.resetPassword(userId, realmName, request.getPassword(), request.isTemporary()); } @Override @RolesAllowed({ "admin", "user_manager" }) public Response sendVerificationEmail(String userId, String realmName) { log.info("POST /api/users/{}/send-verification-email", userId); userService.sendVerificationEmail(userId, realmName); return Response.accepted().build(); } @Override @RolesAllowed({ "admin", "user_manager" }) public SessionsRevokedDTO logoutAllSessions(String userId, String realmName) { log.info("POST /api/users/{}/logout-sessions", userId); int count = userService.logoutAllSessions(userId, realmName); return new SessionsRevokedDTO(count); } @Override @RolesAllowed({ "admin", "user_manager", "user_viewer" }) public List getActiveSessions(String userId, String realmName) { log.info("GET /api/users/{}/sessions", userId); return userService.getActiveSessions(userId, realmName); } @Override @GET @jakarta.ws.rs.Path("/export/csv") @jakarta.ws.rs.Produces("text/csv") @RolesAllowed({ "admin", "user_manager" }) public Response exportUsersToCSV(@QueryParam("realm") String realmName) { log.info("GET /api/users/export/csv - realm: {}", realmName); UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() .realmName(realmName) .page(0) .pageSize(10_000) .build(); String csv = userService.exportUsersToCSV(criteria); return Response.ok(csv) .type(MediaType.valueOf("text/csv")) .header("Content-Disposition", "attachment; filename=\"users-" + (realmName != null ? realmName : "export") + ".csv\"") .build(); } @Override @POST @jakarta.ws.rs.Path("/import/csv") @jakarta.ws.rs.Consumes(MediaType.TEXT_PLAIN) @RolesAllowed({ "admin", "user_manager" }) public ImportResultDTO importUsersFromCSV(@QueryParam("realm") String realmName, String csvContent) { log.info("POST /api/users/import/csv - realm: {}", realmName); return userService.importUsersFromCSV(csvContent, realmName); } }