Refactor button management in UserController; implement role-based button filtering and update views to use dynamic button lists

This commit is contained in:
jon ander 2025-04-14 19:00:10 +02:00
parent bde7cc3407
commit 458d79d401
6 changed files with 88 additions and 57 deletions

View File

@ -5,14 +5,20 @@ import com.ieslamar.GestionInventario.dto.BotonDTO;
import com.ieslamar.GestionInventario.entities.User; import com.ieslamar.GestionInventario.entities.User;
import com.ieslamar.GestionInventario.services.UserService; import com.ieslamar.GestionInventario.services.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@Controller @Controller
@ -25,28 +31,75 @@ public class UserController {
this.userService = userService; this.userService = userService;
} }
private final BotonDTO gestionUsuarios = new BotonDTO("Gestión de usuarios", "/user_management", true, null);
private final BotonDTO gestionProductos = new BotonDTO("Gestión de Productos", "/user_management", true, null);
private final BotonDTO gestionDepartamentos = new BotonDTO("Gestión de Departamentos", "/user_management", true, null);
private final BotonDTO gestionCategorias = new BotonDTO("Gestión de Categorías", "/user_management", true, null);
private final BotonDTO gestionUbicaciones = new BotonDTO("Gestión de Ubicaciones", "/user_management", true, null);
private final BotonDTO gestionInventario = new BotonDTO("Gestión de Inventario", "/user_management", true, null);
private final BotonDTO gestionTiposDatos = new BotonDTO("Gestión de Tipos de dato", "/user_management", true, null);
private final BotonDTO inventario = new BotonDTO("Inventario", "/management", false, null);
private final BotonDTO gestion = new BotonDTO("Gestión", "/management", true, null);
private final BotonDTO home = new BotonDTO("Salir", "/home", false, "button_salir");
private List<BotonDTO> filtrarBotones(Authentication auth,List<BotonDTO> botones){
List<BotonDTO> botones_response = new ArrayList<>();
List<String> roles = auth.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.toList();
if (roles.contains("ROLE_ADMIN")) {
return botones;
}
for (BotonDTO botone : botones) {
if (!botone.isRequireAdmin()) {
botones_response.add(botone);
}
}
return botones_response;
}
@GetMapping("/login") @GetMapping("/login")
public String loginPage() { public String loginPage() {
return "login"; // Retorna la vista login.html return "login"; // Retorna la vista login.html
} }
@GetMapping("/filtered-buttons") @GetMapping("/home")
public String getFilteredButtons(Model model, Authentication authentication) { public String homePage(Model model) {
List<BotonDTO> botones = List.of( Authentication auth = SecurityContextHolder.getContext().getAuthentication();
new BotonDTO("Inventario", "/management", false, null), List<BotonDTO> botones = filtrarBotones(auth,new ArrayList<>(List.of(
new BotonDTO("Gestión", "/management", true, null) inventario,
); gestion
)));
model.addAttribute("buttons", botones);
return "home";
}
// Filtrar botones según el rol del usuario @GetMapping("/management")
List<BotonDTO> filteredButtons = botones.stream() public String managementPage(Model model){
.filter(button -> !button.isRequireAdmin() || Authentication auth = SecurityContextHolder.getContext().getAuthentication();
(authentication != null && authentication.getAuthorities().stream() List<BotonDTO>botones = filtrarBotones(auth,new ArrayList<>(List.of(
.anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN")))) gestionUsuarios,
.toList(); gestionProductos,
gestionDepartamentos,
gestionCategorias,
gestionUbicaciones,
gestionInventario,
gestionCategorias,
gestionTiposDatos,
home
)));
model.addAttribute("buttons", botones);
return "management";
}
model.addAttribute("buttons", filteredButtons);
return "home"; // Retorna la vista home.html
}
@GetMapping("/register") @GetMapping("/register")
public String registerPage() { public String registerPage() {
@ -58,10 +111,6 @@ public String getFilteredButtons(Model model, Authentication authentication) {
userService.registerUser(username, password, role, mail, null); userService.registerUser(username, password, role, mail, null);
return "redirect:/login?success"; // Redirige al login tras registrarse return "redirect:/login?success"; // Redirige al login tras registrarse
} }
@GetMapping("/management")
public String managementPage(){
return "management";
}
@GetMapping("/user_management") @GetMapping("/user_management")

View File

@ -20,6 +20,7 @@ p {
.container1{ .container1{
margin: 10px;
background-color: rgba(255,255,255,0.4); background-color: rgba(255,255,255,0.4);
display: inline-flex; display: inline-flex;
flex-direction: column; flex-direction: column;

View File

@ -2,15 +2,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"> <html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
<body> <body>
<div th:fragment="buttonList(buttons)"> <div th:fragment="buttonList(buttons)" class="container1">
<div class="container1">
<div th:each="button : ${buttons}"> <div th:each="button : ${buttons}">
<a th:href="@{${button.getUrl()}}"> <a th:href="@{${button.getUrl()}}">
<button th:class="${button.getCssClass()}" th:text="${button.getTexto()}"></button> <button th:class="${button.getCssClass()}" th:text="${button.getTexto()}"></button>
</a> </a>
</div> </div>
</div> </div>
</div>
</body> </body>
</html> </html>

View File

@ -0,0 +1,13 @@
<!-- fragments/buttons.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
<body>
<div th:fragment="List()" class="container1">
</div>
</body>
</html>

View File

@ -11,7 +11,7 @@
<div th:replace="fragments/buttons :: buttonList(${buttons})"></div> <div th:replace="fragments/buttons :: buttonList(${buttons})"></div>
<!-- Formulario de Logout (estático y fuera del fragmento) --> <!-- Formulario de Logout (estático y fuera del fragmento) -->
<form th:action="@{/logout}" method="post"> <form class="container1" th:action="@{/logout}" method="post">
<button class="button_salir" type="submit">Cerrar Sesión</button> <button class="button_salir" type="submit">Cerrar Sesión</button>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/> <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</form> </form>

View File

@ -6,37 +6,7 @@
</head> </head>
<body> <body>
<h2 th:text="'Gestión'"></h2> <h2 th:text="'Gestión'"></h2>
<div class="container1"> <div th:replace="fragments/buttons :: buttonList(${buttons})"></div>
<a href="/Inventario/user_management">
<button>Gestión de Usuarios</button>
</a>
<!-- TODO: Cambiar la ruta a la de gestionar inventario -->
<a href="/Inventario/user_management">
<button>Gestión de Productos</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Departamentos</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Categorías</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Ubicaciones</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Inventario</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Categorías</button>
</a>
<a href="/Inventario/user_management">
<button>Gestión de Tipos de dato</button>
</a>
<a href="/Inventario/home">
<button class="button_salir">Volver al inicio</button>
</a>
</div>
</body> </body>
</html> </html>