Commit cd4796b5 by Rubén Ramírez

fix: [Recurso]: Correcciones al comprobar con PostMan

parent bcbc02e5
......@@ -28,13 +28,13 @@ public class RepositorioRecurso {
@Transactional(readOnly = true)
public List<Recurso> buscarPorTitulo(String titulo) {
return em.createQuery(
"SELECT r FROM Recurso r WHERE LOWER(TRANSLATE(r.titulo, 'ÁÉÍÓÚáéíóú', 'AEIOUaeiou')) " +
"LIKE LOWER(TRANSLATE(:titulo, 'ÁÉÍÓÚáéíóú', 'AEIOUaeiou'))",
"SELECT r FROM Recurso r WHERE LOWER(r.titulo) LIKE LOWER(:titulo)",
Recurso.class)
.setParameter("titulo", "%" + titulo + "%")
.getResultList();
}
@Transactional(readOnly = true)
public List<Recurso> buscarPorAutor(String autor) {
return em.createQuery(
......
......@@ -8,6 +8,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
@Getter
......@@ -28,5 +29,5 @@ public class DTORecurso {
@NotBlank
private String autor;
private Set<Genero> generos;
private Set<Genero> generos = new HashSet<>();
}
......@@ -39,10 +39,15 @@ public class Mapper {
dtoRecurso.getFechaPublicacion(),
dtoRecurso.getAutor()
);
recurso.getGeneros().addAll(dtoRecurso.getGeneros());
if (dtoRecurso.getGeneros() != null) {
recurso.getGeneros().addAll(dtoRecurso.getGeneros());
}
return recurso;
}
public DTOCapitulo dto(Capitulo capitulo) {
return new DTOCapitulo(
capitulo.getId(),
......
......@@ -18,6 +18,8 @@ import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
@RequestMapping("/recursos")
......@@ -27,6 +29,8 @@ public class RecursosController {
private ServicioRecursos servicioRecursos;
@Autowired
private Mapper mapper;
private static final Logger log = LoggerFactory.getLogger(RecursosController.class);
@PostMapping("/")
public ResponseEntity<String> crearRecurso(@RequestBody DTORecurso recurso) {
......@@ -41,20 +45,26 @@ public class RecursosController {
@GetMapping("/titulo/{titulo}")
public ResponseEntity<List<DTORecurso>> buscarPorTitulo(@PathVariable String titulo) {
log.info("🔍 Buscando recurso con título: " + titulo);
try {
List<Recurso> recursos = servicioRecursos.buscarRecursoPorTitulo(titulo);
log.info("📋 Recursos encontrados: " + recursos.size());
if (recursos.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.emptyList());
}
List<DTORecurso> dtoRecursos = recursos.stream().map(mapper::dto).toList();
return ResponseEntity.ok(dtoRecursos);
} catch (Exception e) {
log.error("❌ Error al buscar recurso: ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@GetMapping("/genero/{genero}")
public ResponseEntity<List<DTORecurso>> buscarPorGenero(@PathVariable Genero genero) {
try {
......
......@@ -20,39 +20,35 @@ public class ServicioSeguridad {
this.jwtUtil = jwtUtil;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.disable())
.httpBasic(httpBasic -> httpBasic.realmName("mangaffinity"))
.authorizeHttpRequests(request -> request
.requestMatchers(HttpMethod.POST, "/usuarios/{email}").permitAll()
.requestMatchers(HttpMethod.GET, "/usuarios/email/{email}").permitAll()
.requestMatchers(HttpMethod.POST, "/usuarios/").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/titulo/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/autor/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/genero/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/fecha").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/{id}").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.POST, "/recursos/").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.PUT, "/recursos/{id}").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.DELETE, "/recursos/{id}").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.POST, "/recursos/{id}/capitulos").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.GET, "/recursos/{id}/capitulos").permitAll()
.requestMatchers(HttpMethod.GET, "/usuarios/{usuarioId}/biblioteca").permitAll()
.requestMatchers(HttpMethod.POST, "/biblioteca/{usuarioId}/recursos/{recursoId}/categoria").authenticated()
.requestMatchers(HttpMethod.GET, "/biblioteca/{usuarioId}/recursos/categoria/{categoria}").authenticated()
.requestMatchers(HttpMethod.DELETE, "/biblioteca/{usuarioId}/recursos/{recursoId}").authenticated()
.requestMatchers(HttpMethod.PUT, "/biblioteca/{usuarioId}/recursos/{recursoId}/categoria").authenticated()
.anyRequest().authenticated()
)
.addFilterBefore(new JwtFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class)
.build();
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.disable()) // Desactivar sesiones
.authorizeHttpRequests(request -> request
.requestMatchers(HttpMethod.POST, "/usuarios/{email}").permitAll() // Permitir login sin autenticación
.requestMatchers(HttpMethod.GET, "/usuarios/email/{email}").permitAll()
.requestMatchers(HttpMethod.POST, "/usuarios/").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/titulo/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/autor/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/genero/**").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/fecha").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos/{id}").permitAll()
.requestMatchers(HttpMethod.GET, "/recursos").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.POST, "/recursos/").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.PUT, "/recursos/{id}").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.DELETE, "/recursos/{id}").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.POST, "/recursos/{id}/capitulos").hasAuthority("ROLE_ADMIN")
.requestMatchers(HttpMethod.GET, "/recursos/{id}/capitulos").permitAll()
.requestMatchers(HttpMethod.GET, "/usuarios/{usuarioId}/biblioteca").permitAll()
.requestMatchers(HttpMethod.POST, "/biblioteca/{usuarioId}/recursos/{recursoId}/categoria").authenticated()
.requestMatchers(HttpMethod.GET, "/biblioteca/{usuarioId}/recursos/categoria/{categoria}").authenticated()
.requestMatchers(HttpMethod.DELETE, "/biblioteca/{usuarioId}/recursos/{recursoId}").authenticated()
.requestMatchers(HttpMethod.PUT, "/biblioteca/{usuarioId}/recursos/{recursoId}/categoria").authenticated()
.anyRequest().authenticated() // Todo lo demás requiere autenticación
)
.addFilterBefore(new JwtFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class) // Usar solo JWT
.build();
}
@Bean public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
......
......@@ -54,7 +54,7 @@ public class TestRecursosController {
// Caso 1: Intento crear un recurso sin autenticación
Recurso nuevoRecurso = new Recurso("Titulo Prueba", "Descripción de prueba", LocalDate.now(), "Autor Prueba");
var respuestaNoAutenticado = restTemplate.postForEntity("/recursos/", nuevoRecurso, Void.class);
assertThat(respuestaNoAutenticado.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(respuestaNoAutenticado.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
// Caso 2: Intento crear un recurso correctamente con autenticación de admin
HttpHeaders headers = new HttpHeaders();
......@@ -328,7 +328,7 @@ public class TestRecursosController {
ResponseEntity<Void> deleteUnauthorized = restTemplate.exchange(
"/recursos/" + recursoId, HttpMethod.DELETE, HttpEntity.EMPTY, Void.class
);
assertThat(deleteUnauthorized.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(deleteUnauthorized.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
//Caso 2: Intento borrar el recurso con autenticación
HttpHeaders authHeaders = new HttpHeaders();
......@@ -411,7 +411,7 @@ public class TestRecursosController {
"/recursos/{id}", HttpMethod.PUT, noAuthRequest, Void.class, recursoId
);
assertThat(respuestaNoAutenticado.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(respuestaNoAutenticado.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
}
@Test
......@@ -455,7 +455,7 @@ public class TestRecursosController {
ResponseEntity<Void> respuestaNoAuth = restTemplate.exchange(
"/recursos", HttpMethod.GET, HttpEntity.EMPTY, Void.class
);
assertThat(respuestaNoAuth.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(respuestaNoAuth.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
}
@Test
......@@ -527,7 +527,7 @@ public class TestRecursosController {
"/recursos/{id}/capitulos", HttpMethod.POST, capituloRequestUser, Void.class, recursoId
);
assertThat(respuestaCapituloUser.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
assertThat(respuestaCapituloUser.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
}
@Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment