Commit de6e3ef3 by Antonio Rueda

Autenticación básica HTTP mediante Spring Security para acceso al API.

parent 9e6ce320
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
......
...@@ -11,7 +11,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan; ...@@ -11,7 +11,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
@SpringBootApplication(scanBasePackages={ @SpringBootApplication(scanBasePackages={
"es.ujaen.dae.ujacoin.servicios", "es.ujaen.dae.ujacoin.servicios",
"es.ujaen.dae.ujacoin.repositorios", "es.ujaen.dae.ujacoin.repositorios",
"es.ujaen.dae.ujacoin.controladoresREST" "es.ujaen.dae.ujacoin.controladoresREST",
"es.ujaen.dae.ujacoin.seguridad"
}) })
@EntityScan(basePackages="es.ujaen.dae.ujacoin.entidades") @EntityScan(basePackages="es.ujaen.dae.ujacoin.entidades")
public class UjaCoinApp { public class UjaCoinApp {
......
...@@ -74,8 +74,8 @@ public class ControladorREST { ...@@ -74,8 +74,8 @@ public class ControladorREST {
/** Login de clientes (temporal hasta incluir autenticación mediante Spring Security */ /** Login de clientes (temporal hasta incluir autenticación mediante Spring Security */
@GetMapping("/clientes/{dni}") @GetMapping("/clientes/{dni}")
ResponseEntity<DTOCliente> loginCliente(@PathVariable String dni, @RequestParam String clave) { ResponseEntity<DTOCliente> verCliente(@PathVariable String dni) {
Optional<Cliente> cliente = servicios.loginCliente(dni, clave); Optional<Cliente> cliente = servicios.verCliente(dni);
return cliente return cliente
.map(c -> ResponseEntity.ok(new DTOCliente(c))) .map(c -> ResponseEntity.ok(new DTOCliente(c)))
.orElse(ResponseEntity.notFound().build()); .orElse(ResponseEntity.notFound().build());
......
package es.ujaen.dae.ujacoin.entidades; package es.ujaen.dae.ujacoin.entidades;
import es.ujaen.dae.ujacoin.util.ExprReg; import es.ujaen.dae.ujacoin.util.ExprReg;
import es.ujaen.dae.ujacoin.util.CodificadorMd5; import es.ujaen.dae.ujacoin.util.CodificadorPassword;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -80,7 +80,8 @@ public class Cliente implements Serializable { ...@@ -80,7 +80,8 @@ public class Cliente implements Serializable {
this.tlf = tlf; this.tlf = tlf;
this.email = email; this.email = email;
this.clave = (clave != null ? CodificadorMd5.codificar(clave) : null); this.clave = (clave != null ? CodificadorPassword.codificar(clave) : null);
// this.clave = clave;
tarjetas = new ArrayList<>(); tarjetas = new ArrayList<>();
cuentas = new ArrayList<>(); cuentas = new ArrayList<>();
...@@ -116,7 +117,12 @@ public class Cliente implements Serializable { ...@@ -116,7 +117,12 @@ public class Cliente implements Serializable {
* @return * @return
*/ */
public boolean claveValida(String clave) { public boolean claveValida(String clave) {
return this.clave.equals(CodificadorMd5.codificar(clave)); return CodificadorPassword.igual(clave, this.clave);
//return this.clave.equals(clave);
}
public String getClave() {
return clave;
} }
/** /**
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import es.ujaen.dae.ujacoin.entidades.Cliente;
import es.ujaen.dae.ujacoin.servicios.ServicioUjaCoin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
/**
* Servicio que proporciona los datos del cliente
* @author ajrueda
*/
@Service
public class ServicioDatosCliente implements UserDetailsService {
@Autowired
ServicioUjaCoin servicioUjaCoin;
PasswordEncoder encoder;
public ServicioDatosCliente() {
encoder = new BCryptPasswordEncoder();
}
PasswordEncoder getEncoder() {
return encoder;
}
@Override
public UserDetails loadUserByUsername(String dni) throws UsernameNotFoundException {
Cliente cliente = servicioUjaCoin.verCliente(dni)
.orElseThrow(() -> new UsernameNotFoundException(""));
return User.withUsername(cliente.getDni())
.roles("CLIENTE").password(cliente.getClave())
.build();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Proveedor de datos de seguridad de UJaCoin
*
* @author ajrueda
*/
@Configuration
@EnableWebSecurity
public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter {
@Autowired
ServicioDatosCliente servicioDatosCliente;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(servicioDatosCliente)
.passwordEncoder(new BCryptPasswordEncoder());
// auth.inMemoryAuthentication()
// .withUser("ujacoin").roles("CLIENTE").password("{noop}secret");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable();
httpSecurity.httpBasic();
httpSecurity.authorizeRequests().antMatchers(HttpMethod.POST, "/ujacoin/clientes").anonymous();
// Permitir el acceso de un cliente sólo a sus recursos asociados (datos personales, cuentas, tarjetas, etc.)
httpSecurity.authorizeRequests().antMatchers("/ujacoin/clientes/{dni}/**")
.access("hasRole('CLIENTE') and #dni == principal.username");
}
}
...@@ -83,6 +83,21 @@ public class ServicioUjaCoin { ...@@ -83,6 +83,21 @@ public class ServicioUjaCoin {
} }
/** /**
* Realiza un login de un cliente
* @param dni el DNI del cliente
* @param clave la clave de acceso
* @return el objeto de la clase Cliente asociado
*/
@Transactional
public Optional<Cliente> verCliente(@NotBlank String dni) {
Optional<Cliente> clienteLogin = repositorioClientes.buscar(dni);
// Asegurarnos de que se devuelve el cliente con los datos precargados
clienteLogin.ifPresent(c -> c.verCuentas().size());
return clienteLogin;
}
/**
* Crear una cuenta adicional para el cliente * Crear una cuenta adicional para el cliente
* @param dni el DNI delcliente * @param dni el DNI delcliente
* @return la cuenta creada * @return la cuenta creada
......
package es.ujaen.dae.ujacoin.util; package es.ujaen.dae.ujacoin.util;
import java.security.MessageDigest; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/** /**
* Codificador sencillo para contraseñas basado en Md5 (no seguro) * Codificador sencillo para contraseñas basado en Md5 (no seguro)
* @author ajrueda * @author ajrueda
*/ */
public class CodificadorMd5 { public class CodificadorPassword {
private CodificadorMd5() { static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
private CodificadorPassword() {
} }
public static String codificar(String cadena) { public static String codificar(String cadena) {
/*
String cadenaCodificada = null; String cadenaCodificada = null;
try { try {
...@@ -25,6 +26,11 @@ public class CodificadorMd5 { ...@@ -25,6 +26,11 @@ public class CodificadorMd5 {
// No debe ocurrir puesto que MD5 es un algoritmo que existe en la // No debe ocurrir puesto que MD5 es un algoritmo que existe en la
// implementación Java estándar // implementación Java estándar
} }
return cadenaCodificada; */
return encoder.encode(cadena);
}
public static boolean igual(String password, String passwordCodificado) {
return encoder.matches(password, passwordCodificado);
} }
} }
...@@ -27,6 +27,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert ...@@ -27,6 +27,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
/** /**
* Test para controlador REST de clientes * Test para controlador REST de clientes
*
* @author ajrueda * @author ajrueda
*/ */
@SpringBootTest(classes = es.ujaen.dae.ujacoin.app.UjaCoinApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = es.ujaen.dae.ujacoin.app.UjaCoinApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
...@@ -41,19 +42,21 @@ public class ControladorRESTTest { ...@@ -41,19 +42,21 @@ public class ControladorRESTTest {
@Autowired @Autowired
MappingJackson2HttpMessageConverter springBootJacksonConverter; MappingJackson2HttpMessageConverter springBootJacksonConverter;
TestRestTemplate restTemplate; RestTemplateBuilder restTemplateBuilder;
/** Crear un TestRestTemplate para las pruebas */ /**
* Crear un TestRestTemplate para las pruebas
*/
@PostConstruct @PostConstruct
void crearRestTemplate() { void crearRestTemplateBuilder() {
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder() restTemplateBuilder = new RestTemplateBuilder()
.rootUri("http://localhost:" + localPort + "/ujacoin") .rootUri("http://localhost:" + localPort + "/ujacoin")
.additionalMessageConverters(List.of(springBootJacksonConverter)); .additionalMessageConverters(List.of(springBootJacksonConverter));
restTemplate = new TestRestTemplate(restTemplateBuilder);
} }
/** Intento de creación de un cliente inválido */ /**
* Intento de creación de un cliente inválido
*/
@Test @Test
public void testAltaClienteInvalido() { public void testAltaClienteInvalido() {
// Cliente con e-mail incorrecto!!! // Cliente con e-mail incorrecto!!!
...@@ -66,6 +69,7 @@ public class ControladorRESTTest { ...@@ -66,6 +69,7 @@ public class ControladorRESTTest {
"jeegmail.com", "jeegmail.com",
"clave"); "clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
ResponseEntity<DTOCuenta> respuesta = restTemplate.postForEntity( ResponseEntity<DTOCuenta> respuesta = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -75,7 +79,9 @@ public class ControladorRESTTest { ...@@ -75,7 +79,9 @@ public class ControladorRESTTest {
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
} }
/** test de alta y login de cliente */ /**
* test de alta y login de cliente
*/
@Test @Test
public void testAltaYLoginClienteCuenta() { public void testAltaYLoginClienteCuenta() {
DTOCliente cliente = new DTOCliente( DTOCliente cliente = new DTOCliente(
...@@ -87,6 +93,7 @@ public class ControladorRESTTest { ...@@ -87,6 +93,7 @@ public class ControladorRESTTest {
"jee@gmail.com", "jee@gmail.com",
"clave"); "clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
ResponseEntity<DTOCuenta> respuestaAlta = restTemplate.postForEntity( ResponseEntity<DTOCuenta> respuestaAlta = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -95,8 +102,11 @@ public class ControladorRESTTest { ...@@ -95,8 +102,11 @@ public class ControladorRESTTest {
Assertions.assertThat(respuestaAlta.getStatusCode()).isEqualTo(HttpStatus.CREATED); Assertions.assertThat(respuestaAlta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<DTOCliente> respuestaLogin = restTemplate.getForEntity( TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
"/clientes/{dni}?clave={clave}",
ResponseEntity<DTOCliente> respuestaLogin = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}",
DTOCliente.class, DTOCliente.class,
cliente.getDni(), cliente.getClave() cliente.getDni(), cliente.getClave()
); );
...@@ -107,7 +117,9 @@ public class ControladorRESTTest { ...@@ -107,7 +117,9 @@ public class ControladorRESTTest {
Assertions.assertThat(clienteLogin.getDni()).isEqualTo(cliente.getDni()); Assertions.assertThat(clienteLogin.getDni()).isEqualTo(cliente.getDni());
} }
/** Creación de cuenta adicional */ /**
* Creación de cuenta adicional
*/
@Test @Test
public void testCuentaAdicional() { public void testCuentaAdicional() {
DTOCliente cliente = new DTOCliente( DTOCliente cliente = new DTOCliente(
...@@ -119,13 +131,16 @@ public class ControladorRESTTest { ...@@ -119,13 +131,16 @@ public class ControladorRESTTest {
"jee@gmail.com", "jee@gmail.com",
"clave"); "clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
restTemplate.postForEntity( restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
DTOCuenta.class DTOCuenta.class
); );
ResponseEntity<DTOCuenta> respuesta = restTemplate.postForEntity( TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
ResponseEntity<DTOCuenta> respuesta = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/cuentas", "/clientes/{dni}/cuentas",
null, null,
DTOCuenta.class, DTOCuenta.class,
...@@ -134,7 +149,8 @@ public class ControladorRESTTest { ...@@ -134,7 +149,8 @@ public class ControladorRESTTest {
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED); Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
DTOCuenta[] cuentas = restTemplate.getForEntity( DTOCuenta[] cuentas = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/cuentas", "/clientes/{dni}/cuentas",
DTOCuenta[].class, DTOCuenta[].class,
cliente.getDni() cliente.getDni()
...@@ -144,7 +160,9 @@ public class ControladorRESTTest { ...@@ -144,7 +160,9 @@ public class ControladorRESTTest {
Assertions.assertThat(cuentas[0].getNum()).isNotEqualTo(cuentas[1].getNum()); Assertions.assertThat(cuentas[0].getNum()).isNotEqualTo(cuentas[1].getNum());
} }
/** Test de creación de tarjeta */ /**
* Test de creación de tarjeta
*/
@Test @Test
public void testAnadirTarjetaACliente() { public void testAnadirTarjetaACliente() {
// Registrar cliente // Registrar cliente
...@@ -157,10 +175,14 @@ public class ControladorRESTTest { ...@@ -157,10 +175,14 @@ public class ControladorRESTTest {
"jee@gmail.com", "jee@gmail.com",
"clave"); "clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
restTemplate.postForEntity("/clientes", cliente, DTOCuenta.class); restTemplate.postForEntity("/clientes", cliente, DTOCuenta.class);
DTOTarjeta tarjeta = new DTOTarjeta("4111111111111111", cliente.getNombre(), LocalDate.of(2022, 12, 1), "365"); DTOTarjeta tarjeta = new DTOTarjeta("4111111111111111", cliente.getNombre(), LocalDate.of(2022, 12, 1), "365");
ResponseEntity<DTOTarjeta> respuesta = restTemplate.postForEntity(
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
ResponseEntity<DTOTarjeta> respuesta = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/tarjetas", "/clientes/{dni}/tarjetas",
tarjeta, tarjeta,
DTOTarjeta.class, DTOTarjeta.class,
...@@ -169,7 +191,8 @@ public class ControladorRESTTest { ...@@ -169,7 +191,8 @@ public class ControladorRESTTest {
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED); Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
respuesta = restTemplate.getForEntity( respuesta = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/tarjetas/{num}", "/clientes/{dni}/tarjetas/{num}",
DTOTarjeta.class, DTOTarjeta.class,
cliente.getDni(), cliente.getDni(),
...@@ -185,7 +208,9 @@ public class ControladorRESTTest { ...@@ -185,7 +208,9 @@ public class ControladorRESTTest {
Assertions.assertThat(tarjetaRecibida.getCvc()).isEqualTo(tarjeta.getCvc()); Assertions.assertThat(tarjetaRecibida.getCvc()).isEqualTo(tarjeta.getCvc());
} }
/** Test de ingreso en cuenta */ /**
* Test de ingreso en cuenta
*/
@Test @Test
public void testIngreso() { public void testIngreso() {
// Registrar cliente // Registrar cliente
...@@ -199,6 +224,7 @@ public class ControladorRESTTest { ...@@ -199,6 +224,7 @@ public class ControladorRESTTest {
"clave" "clave"
); );
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity( DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -212,17 +238,19 @@ public class ControladorRESTTest { ...@@ -212,17 +238,19 @@ public class ControladorRESTTest {
"365" "365"
); );
restTemplate.postForEntity( TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/tarjetas", "/clientes/{dni}/tarjetas",
tarjeta, tarjeta,
DTOTarjeta.class, DTOTarjeta.class,
cliente.getDni() cliente.getDni()
); );
// Realizar ingreso y comprobar estado de la cuenta // Realizar ingreso y comprobar estado de la cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000); DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
ResponseEntity<Void> respuestaRegistroMovimiento = restTemplate.postForEntity( ResponseEntity<Void> respuestaRegistroMovimiento = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
ingreso, ingreso,
Void.class, Void.class,
...@@ -232,13 +260,15 @@ public class ControladorRESTTest { ...@@ -232,13 +260,15 @@ public class ControladorRESTTest {
Assertions.assertThat(respuestaRegistroMovimiento.getStatusCode()).isEqualTo(HttpStatus.CREATED); Assertions.assertThat(respuestaRegistroMovimiento.getStatusCode()).isEqualTo(HttpStatus.CREATED);
// Refrescar estado de la cuenta y comprobar saldo // Refrescar estado de la cuenta y comprobar saldo
cuenta = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}", cuenta = restTemplateAutenticado
.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class, DTOCuenta.class,
cliente.getDni(), cuenta.getNum()); cliente.getDni(), cuenta.getNum());
Assertions.assertThat(cuenta.getSaldo()).isEqualTo(1000); Assertions.assertThat(cuenta.getSaldo()).isEqualTo(1000);
ResponseEntity<DTOMovimiento[]> respuestaListadoMovimientos = restTemplate.getForEntity( ResponseEntity<DTOMovimiento[]> respuestaListadoMovimientos = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum() cliente.getDni(), cuenta.getNum()
...@@ -251,7 +281,9 @@ public class ControladorRESTTest { ...@@ -251,7 +281,9 @@ public class ControladorRESTTest {
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(ingreso.getImporte()); Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(ingreso.getImporte());
} }
/** Test de transferencia entre cuentas */ /**
* Test de transferencia entre cuentas
*/
@Test @Test
public void testTransferencia() { public void testTransferencia() {
// Registrar cliente // Registrar cliente
...@@ -265,6 +297,7 @@ public class ControladorRESTTest { ...@@ -265,6 +297,7 @@ public class ControladorRESTTest {
"clave" "clave"
); );
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuentaOrigen = restTemplate.postForEntity( DTOCuenta cuentaOrigen = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -278,7 +311,8 @@ public class ControladorRESTTest { ...@@ -278,7 +311,8 @@ public class ControladorRESTTest {
"365" "365"
); );
restTemplate.postForEntity( TestRestTemplate restTemplateAutenticado1 = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/tarjetas", "/clientes/{dni}/tarjetas",
tarjeta, tarjeta,
DTOTarjeta.class, DTOTarjeta.class,
...@@ -287,7 +321,7 @@ public class ControladorRESTTest { ...@@ -287,7 +321,7 @@ public class ControladorRESTTest {
// Realizar ingreso y comprobar estado de la cuenta // Realizar ingreso y comprobar estado de la cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000); DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
restTemplate.postForEntity( restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
ingreso, ingreso,
Void.class, Void.class,
...@@ -302,7 +336,8 @@ public class ControladorRESTTest { ...@@ -302,7 +336,8 @@ public class ControladorRESTTest {
"Cl La Paz, 20 - Jaén", "Cl La Paz, 20 - Jaén",
"670701570", "670701570",
"pjj@gmail.com", "pjj@gmail.com",
"clavezzz"); "clavezzz"
);
DTOCuenta cuentaDestino = restTemplate.postForEntity( DTOCuenta cuentaDestino = restTemplate.postForEntity(
"/clientes", "/clientes",
...@@ -312,7 +347,7 @@ public class ControladorRESTTest { ...@@ -312,7 +347,7 @@ public class ControladorRESTTest {
// Realizar transferencia // Realizar transferencia
DTOMovimiento transferencia = DTOMovimiento.transferencia(cuentaDestino.getNum(), 500); DTOMovimiento transferencia = DTOMovimiento.transferencia(cuentaDestino.getNum(), 500);
restTemplate.postForEntity( restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
transferencia, transferencia,
Void.class, Void.class,
...@@ -321,18 +356,19 @@ public class ControladorRESTTest { ...@@ -321,18 +356,19 @@ public class ControladorRESTTest {
// Refrescar cuenta origen y destino // Refrescar cuenta origen y destino
// Refrescar estados de la cuentas y comprobar saldos // Refrescar estados de la cuentas y comprobar saldos
cuentaOrigen = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}", cuentaOrigen = restTemplateAutenticado1.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class, DTOCuenta.class,
cliente.getDni(), cuentaOrigen.getNum()); cliente.getDni(), cuentaOrigen.getNum());
Assertions.assertThat(cuentaOrigen.getSaldo()).isEqualTo(500); Assertions.assertThat(cuentaOrigen.getSaldo()).isEqualTo(500);
cuentaDestino = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}", TestRestTemplate restTemplateAutenticado2 = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente2.getDni(), cliente2.getClave()));
cuentaDestino = restTemplateAutenticado2.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class, DTOCuenta.class,
cliente2.getDni(), cuentaDestino.getNum()); cliente2.getDni(), cuentaDestino.getNum());
Assertions.assertThat(cuentaDestino.getSaldo()).isEqualTo(500); Assertions.assertThat(cuentaDestino.getSaldo()).isEqualTo(500);
// Listar movimientos de la cuenta origen // Listar movimientos de la cuenta origen
DTOMovimiento[] movimientos = restTemplate.getForEntity( DTOMovimiento[] movimientos = restTemplateAutenticado1.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente.getDni(), cuentaOrigen.getNum() cliente.getDni(), cuentaOrigen.getNum()
...@@ -342,7 +378,7 @@ public class ControladorRESTTest { ...@@ -342,7 +378,7 @@ public class ControladorRESTTest {
Assertions.assertThat(movimientos[1].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_EMITIDA); Assertions.assertThat(movimientos[1].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_EMITIDA);
// Listar movimientos de la cuenta destino // Listar movimientos de la cuenta destino
movimientos = restTemplate.getForEntity( movimientos = restTemplateAutenticado2.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente2.getDni(), cuentaDestino.getNum() cliente2.getDni(), cuentaDestino.getNum()
...@@ -352,7 +388,9 @@ public class ControladorRESTTest { ...@@ -352,7 +388,9 @@ public class ControladorRESTTest {
Assertions.assertThat(movimientos[0].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_RECIBIDA); Assertions.assertThat(movimientos[0].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_RECIBIDA);
} }
/** Reintegro sin saldo suficiente */ /**
* Reintegro sin saldo suficiente
*/
@Test @Test
public void testReintegroSinSaldo() { public void testReintegroSinSaldo() {
// Registrar cliente // Registrar cliente
...@@ -366,6 +404,7 @@ public class ControladorRESTTest { ...@@ -366,6 +404,7 @@ public class ControladorRESTTest {
"clave" "clave"
); );
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity( DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -379,17 +418,17 @@ public class ControladorRESTTest { ...@@ -379,17 +418,17 @@ public class ControladorRESTTest {
"365" "365"
); );
restTemplate.postForEntity( TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/tarjetas", "/clientes/{dni}/tarjetas",
tarjeta, tarjeta,
DTOTarjeta.class, DTOTarjeta.class,
cliente.getDni() cliente.getDni()
); );
// Realizar ingreso en cuenta // Realizar ingreso en cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000); DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
restTemplate.postForEntity( restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
ingreso, ingreso,
Void.class, Void.class,
...@@ -398,7 +437,7 @@ public class ControladorRESTTest { ...@@ -398,7 +437,7 @@ public class ControladorRESTTest {
// Primer reintegro correcto // Primer reintegro correcto
DTOMovimiento reintegro = DTOMovimiento.reintegro(tarjeta.getNum(), 1000); DTOMovimiento reintegro = DTOMovimiento.reintegro(tarjeta.getNum(), 1000);
ResponseEntity<Void> respuesta = restTemplate.postForEntity( ResponseEntity<Void> respuesta = restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
reintegro, reintegro,
Void.class, Void.class,
...@@ -408,16 +447,19 @@ public class ControladorRESTTest { ...@@ -408,16 +447,19 @@ public class ControladorRESTTest {
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED); Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
// No hay saldo suficiente para el segundo reintegro // No hay saldo suficiente para el segundo reintegro
respuesta = restTemplate.postForEntity( respuesta = restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
reintegro, reintegro,
Void.class, Void.class,
cliente.getDni(), cuenta.getNum() cliente.getDni(), cuenta.getNum()
); );
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.PRECONDITION_FAILED); Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.PRECONDITION_FAILED);
} }
/** Test de listado de movimientos con paginación */ /**
* Test de listado de movimientos con paginación
*/
@Test @Test
public void testListadoMovimientosPaginado() { public void testListadoMovimientosPaginado() {
// Registrar cliente // Registrar cliente
...@@ -431,6 +473,7 @@ public class ControladorRESTTest { ...@@ -431,6 +473,7 @@ public class ControladorRESTTest {
"clave" "clave"
); );
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity( DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes", "/clientes",
cliente, cliente,
...@@ -444,21 +487,21 @@ public class ControladorRESTTest { ...@@ -444,21 +487,21 @@ public class ControladorRESTTest {
"365" "365"
); );
restTemplate.postForEntity( TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/tarjetas", "/clientes/{dni}/tarjetas",
tarjeta, tarjeta,
DTOTarjeta.class, DTOTarjeta.class,
cliente.getDni() cliente.getDni()
); );
// Realizar ingreso en cuenta // Realizar ingreso en cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000); DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
float[] importeIngresos = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120}; float[] importeIngresos = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120};
for (float importe: importeIngresos) { for (float importe : importeIngresos) {
restTemplate.postForEntity( restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento.ingreso(tarjeta.getNum(), importe), DTOMovimiento.ingreso(tarjeta.getNum(), importe),
Void.class, Void.class,
...@@ -467,7 +510,7 @@ public class ControladorRESTTest { ...@@ -467,7 +510,7 @@ public class ControladorRESTTest {
} }
// Obtener primera página (10 elementos) // Obtener primera página (10 elementos)
ResponseEntity<DTOMovimiento[]> respuesta1 = restTemplate.getForEntity( ResponseEntity<DTOMovimiento[]> respuesta1 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos", "/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum() cliente.getDni(), cuenta.getNum()
...@@ -479,7 +522,7 @@ public class ControladorRESTTest { ...@@ -479,7 +522,7 @@ public class ControladorRESTTest {
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(10); Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(10);
// Obtener segunda página (2 selementos) // Obtener segunda página (2 selementos)
ResponseEntity<DTOMovimiento[]> respuesta2 = restTemplate.getForEntity( ResponseEntity<DTOMovimiento[]> respuesta2 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=2", "/clientes/{dni}/cuentas/{num}/movimientos?pag=2",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum() cliente.getDni(), cuenta.getNum()
...@@ -491,7 +534,7 @@ public class ControladorRESTTest { ...@@ -491,7 +534,7 @@ public class ControladorRESTTest {
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(110); Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(110);
// Obtener primera página con 5 elementos solo // Obtener primera página con 5 elementos solo
ResponseEntity<DTOMovimiento[]> respuesta3 = restTemplate.getForEntity( ResponseEntity<DTOMovimiento[]> respuesta3 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=1&num=5", "/clientes/{dni}/cuentas/{num}/movimientos?pag=1&num=5",
DTOMovimiento[].class, DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum() cliente.getDni(), cuenta.getNum()
......
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