Compare commits

..

23 Commits

Author SHA1 Message Date
Freddy Heredia 6eab0ddb8c agrega la base de datos
2 years ago
Freddy Heredia d0080463ee agrega control de fecha en el contralor del producto
2 years ago
Freddy Heredia c1b07bbecb nuevo compilado
2 years ago
Freddy Heredia bb4f0d8977 nuevo compilado
2 years ago
Freddy Heredia d4eae7767a cambia nombre de host
2 years ago
Freddy Heredia 1a27d055d5 corrige variable de entorno
2 years ago
Freddy Heredia 2e4b91f35b corrige variable de entorno
2 years ago
Freddy Heredia 716e54cff5 corrige variable de entorno
2 years ago
Freddy Heredia 18fe18265d corrige variable de entorno
2 years ago
Freddy Heredia 5cea50049c corrige variable de entorno
2 years ago
Freddy Heredia 7f652033e7 corrige variable de entorno
2 years ago
Freddy Heredia 75f633f38f corrige variable de entorno
2 years ago
Freddy Heredia addc450e19 cambia imagen
2 years ago
Freddy Heredia c95b3a1562 agrega perfil
2 years ago
Freddy Heredia b4732245df agrega nuevo compilado
2 years ago
Freddy Heredia 68dc23a204 actualiza puerto
2 years ago
Freddy Heredia 6083a1b650 nuevo jar
2 years ago
Freddy Heredia 034963599e limpieza
2 years ago
Freddy Heredia 84670bf75f agrega manejo de ManyToOne en path
2 years ago
Freddy Heredia 30d9594113 agrega utf-8 para soporte de ñ
2 years ago
Freddy Heredia 5f7179408e escapa doble comillas en respuesta 401
2 years ago
Freddy Heredia a8dd0a50cc agrega control options
2 years ago
Freddy Heredia d023288574 clase de autenticacion, autorización, documentacion y relaciones one to many
2 years ago

@ -32,6 +32,7 @@ dependencies {
implementation 'org.hibernate.validator:hibernate-validator:8.0.0.Final'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
}
tasks.named('test') {

@ -1,6 +1,4 @@
FROM debian:11
RUN apt update && apt install -y openjdk-17-jre
FROM openjdk:17-bullseye
COPY pedidos.core-0.0.1-SNAPSHOT.jar /app.jar

@ -4,7 +4,6 @@ services:
backend:
image: pedidosbackend:1
environment:
- TZ=America/Guayaquil
- SPRING_PROFILES_ACTIVE=prod
ports:
- target: 8080
@ -13,7 +12,7 @@ services:
mode: host
networks:
- desarrollo_net
db:
dbclases:
image: postgres:15.0-bullseye
environment:
- TZ=America/Guayaquil

Binary file not shown.

Binary file not shown.

@ -107,7 +107,7 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
response.setStatus(401);
response.setContentType("application/json");
response.setContentType("application/json; charset=utf-8");
response.getWriter().append(json(exception.getLocalizedMessage()));
}
@ -117,7 +117,7 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
return "{\"timestamp\": " + date + ", "
+ "\"status\": 401, "
+ "\"error\": \"Not authorized\", "
+ "\"message\": "+ message+ ", "
+ "\"message\": \""+ message+ "\", "
+ "\"path\": \"/login\"}";
}
}

@ -1,5 +1,8 @@
package pedidos.pedidos.core.authz.conf;
import java.util.Arrays;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -8,6 +11,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import pedidos.pedidos.core.authz.service.UserService;
@Configuration
@ -23,6 +30,8 @@ public class SecurityConfiguration{
http
.csrf().disable()
.cors()
.and()
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/login").permitAll()
.requestMatchers("/swagger-ui/*").permitAll()
@ -36,4 +45,33 @@ public class SecurityConfiguration{
return http.build();
}
@Bean
protected CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
// NOTE: setAllowCredentials(true) is important,
// otherwise, the value of the 'Access-Control-Allow-Origin' header in the response
// must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// NOTE: setAllowedHeaders is important!
// Without it, OPTIONS preflight request will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(Arrays.asList(
"Authorization",
"Accept",
"Cache-Control",
"Content-Type",
"Origin",
"x-csrf-token",
"x-requested-with"
));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}

@ -1,6 +1,7 @@
package pedidos.pedidos.core.cliente;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@ -11,6 +12,16 @@ import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.ManyToOne;
import pedidos.pedidos.core.compania.CompaniaService;
import java.util.List;
import java.lang.reflect.Field;
import java.util.Map;
@ -18,10 +29,14 @@ import java.util.Map;
@RestController
@RequestMapping("api/cliente")
@CrossOrigin({"*"})
@Tag(name = "Controlador de Cliente (Tabla cliente)")
public class ClienteController {
@Autowired ClienteService clienteService;
@Autowired CompaniaService companiaService;
@PreAuthorize("hasAuthority('Cliente_LeerTodos')")
@GetMapping("/")
@Operation(summary = "Obtiene todos los clientes, requiere el permiso Cliente_LeerTodos ")
public List<Cliente> findAll(){
return clienteService.findAll();
}
@ -32,6 +47,7 @@ public class ClienteController {
}
@PostMapping("/")
@PreAuthorize("hasAuthority('Cliente_Crear')")
public Cliente save(@RequestBody Cliente entity){
return clienteService.save(entity);
}
@ -58,9 +74,20 @@ public class ClienteController {
// utiliza reflection para establecer el valor del campo en la entidad
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Field campoEntidad = Cliente.class.getDeclaredField(fieldName);
campoEntidad.setAccessible(true);
campoEntidad.set(cliente, fieldValue);
if (campoEntidad.isAnnotationPresent(ManyToOne.class)) {
java.util.LinkedHashMap<String, Long> keyValue = mapper.convertValue(fieldValue, new TypeReference<java.util.LinkedHashMap<String, Long>>(){});
Object relatedEntity = companiaService.findById(keyValue.get("id"));
campoEntidad.set(cliente, relatedEntity);
}else{
campoEntidad.set(cliente, fieldValue);
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
// maneja la excepción si ocurre algún error al acceder al campo
}

@ -1,11 +1,14 @@
package pedidos.pedidos.core.compania;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@ -13,6 +16,13 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.persistence.ManyToOne;
import pedidos.pedidos.core.cliente.Cliente;
@RestController
@RequestMapping("api/compania")
@CrossOrigin({"*"})
@ -50,4 +60,37 @@ public class CompaniaController {
companiaService.deleteById(id);
}
@PatchMapping("/{id}/")
public Compania partialUpdate(@PathVariable long id, @RequestBody Map<String, Object> fields){
Compania entity = findById(id);
// itera sobre los campos que se desean actualizar
for (Map.Entry<String, Object> field : fields.entrySet()) {
String fieldName = field.getKey();
Object fieldValue = field.getValue();
// utiliza reflection para establecer el valor del campo en la entidad
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Field campoEntidad = Compania.class.getDeclaredField(fieldName);
campoEntidad.setAccessible(true);
if (campoEntidad.isAnnotationPresent(ManyToOne.class)) {
java.util.LinkedHashMap<String, Long> keyValue = mapper.convertValue(fieldValue, new TypeReference<java.util.LinkedHashMap<String, Long>>(){});
Object relatedEntity = companiaService.findById(keyValue.get("id"));
campoEntidad.set(entity, relatedEntity);
}else{
campoEntidad.set(entity, fieldValue);
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
// maneja la excepción si ocurre algún error al acceder al campo
}
}
return update(entity);
}
}

@ -0,0 +1,24 @@
package pedidos.pedidos.core.pedidos;
import java.math.BigDecimal;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.Data;
import pedidos.pedidos.core.producto.Producto;
@Data
@Entity
public class DetallePedido {
@Id
@GeneratedValue(strategy = GenerationType.AUTO )
private long id;
@ManyToOne
private Producto producto;
private Integer cantidad;
private BigDecimal precio;
}

@ -0,0 +1,31 @@
package pedidos.pedidos.core.pedidos;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import lombok.Data;
import pedidos.pedidos.core.cliente.Cliente;
@Data
@Entity
public class Pedido {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE )
private long id;
private String numero;
@ManyToOne
private Cliente cliente;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = false)
@JoinColumn(name="pedido_id")
private List<DetallePedido> detalle = new ArrayList<>();
}

@ -0,0 +1,135 @@
package pedidos.pedidos.core.pedidos;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import pedidos.pedidos.core.cliente.ClienteService;
@RestController
@RequestMapping("/api/pedido")
@CrossOrigin({"*"})
public class PedidoController {
@Autowired
PedidoService service;
@Autowired ClienteService clienteService;
@GetMapping("/{id}/")
public Pedido findById(@PathVariable Integer id){
return service.findById(id);
}
@GetMapping("/")
public List<Pedido> findAll(){
return service.findAll();
}
//Create
//Delimitador de acceso (public, private), tipo de dato de retorno, nombre del método, parametros de entrada { Sentencias }
@PostMapping("/")
public Pedido save (@RequestBody Pedido entity ){
return service.save(entity);
}
@PutMapping("/")
public Pedido update (@RequestBody Pedido entity){
return service.save(entity);
}
@DeleteMapping("/{id}/")
public void deleteById(@PathVariable Integer id){
service.deleteById(id);
}
@PatchMapping("/{id}/")
public Pedido partialUpdate(@PathVariable long id, @RequestBody Map<String, Object> fields){
Pedido entity = service.findById(id);
// itera sobre los campos que se desean actualizar
for (Map.Entry<String, Object> field : fields.entrySet()) {
String fieldName = field.getKey();
Object fieldValue = null;
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
java.lang.reflect.Field campoEntidad = org.springframework.util.ReflectionUtils.findField(Pedido.class, fieldName);
campoEntidad.setAccessible(true);
if (fieldName.equals("precio")){
fieldValue= new BigDecimal (field.getValue().toString());
}else if (fieldName.equals("creado")){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm");
fieldValue = LocalDateTime.parse(field.getValue().toString(),formatter);
}else if (fieldName.equals("detalle")){
List<?> originalList = mapper.convertValue(fields.get(fieldName), new TypeReference<List<?>>() {});
try {
Class<?> type = Class.forName("pedidos.pedidos.core.pedidos.DetallePedido");
List<Object> newList = new java.util.ArrayList<>();
for (Object o : originalList) {
newList.add(mapper.convertValue(o, type));
}
campoEntidad.set(entity,newList);
} catch(ClassNotFoundException ex) {
System.out.println("Error occuured");
ex.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
fieldValue =field.getValue();
}
// utiliza reflection para establecer el valor del campo en la entidad
try {
//Field campoEntidad = Pedido.class.getDeclaredField(fieldName);
if (campoEntidad.isAnnotationPresent(ManyToOne.class)) {
java.util.LinkedHashMap<String, Long> keyValue = mapper.convertValue(fieldValue, new TypeReference<java.util.LinkedHashMap<String, Long>>(){});
Object relatedEntity = clienteService.findById(keyValue.get("id"));
campoEntidad.set(entity, relatedEntity);
} if (campoEntidad.isAnnotationPresent(OneToMany.class)) {
//java.util.LinkedHashMap<String, Long> keyValue = mapper.convertValue(fieldValue, new TypeReference<java.util.LinkedHashMap<String, Long>>(){});
//Object relatedEntity = entidadService.findById(keyValue.get("id"));
//campoEntidad.set(entity, relatedEntity);
}
else{
//campoEntidad.set(entity, fieldValue);
campoEntidad.set(entity, mapper.convertValue(fieldValue, campoEntidad.getType()));
}
} catch ( IllegalAccessException ex) {
// maneja la excepción si ocurre algún error al acceder al campo
}
}
return update(entity);
}
}

@ -0,0 +1,10 @@
package pedidos.pedidos.core.pedidos;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface PedidoRepository extends CrudRepository <Pedido, Long> {
List<Pedido> findAll();
}

@ -0,0 +1,28 @@
package pedidos.pedidos.core.pedidos;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PedidoService {
@Autowired
PedidoRepository repository;
public Pedido save( Pedido entity){
return repository.save(entity);
}
public void deleteById(long id){
repository.deleteById(id);
}
public Pedido findById(long id){
return repository.findById(id).orElse(null);
}
public List<Pedido> findAll(){
return repository.findAll();
}
}

@ -8,6 +8,7 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
@Data
@Entity
@ -15,11 +16,12 @@ public class Producto {
//Atributos: Delimitador de acceso, Tipo de dato, Nombre del atributo
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String nombre;
private String codigo;
private BigDecimal precio;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm", shape = JsonFormat.Shape.STRING)
private LocalDateTime creado = LocalDateTime.now();;
}

@ -11,10 +11,20 @@ import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.lang.reflect.Field;
import java.util.Map;
import org.springframework.security.access.prepost.PreAuthorize;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.core.type.TypeReference;
import jakarta.persistence.ManyToOne;
@RestController
@RequestMapping("api/producto")
@ -22,7 +32,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
public class ProductoController {
@Autowired ProductoService productoService;
@PreAuthorize("hasAuthority('Product_Read')")
@GetMapping("/")
public List<Producto> findAll(){
return productoService.findAll();
@ -51,22 +60,51 @@ public class ProductoController {
@PatchMapping("/{id}/")
public Producto partialUpdate(@PathVariable long id, @RequestBody Map<String, Object> fields){
Producto producto = findById(id);
Producto entity = findById(id);
// itera sobre los campos que se desean actualizar
for (Map.Entry<String, Object> field : fields.entrySet()) {
String fieldName = field.getKey();
Object fieldValue = field.getValue();
Object fieldValue = null;
if (fieldName.equals("precio")){
fieldValue= new BigDecimal (field.getValue().toString());
}else if (fieldName.equals("creado")){
DateTimeFormatter formatter;
String dateString = field.getValue().toString();
if (field.getValue().toString().length()>16){
dateString = dateString.substring(0, 16);
}
formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm");
fieldValue = LocalDateTime.parse(dateString,formatter);
}else {
fieldValue =field.getValue();
}
// utiliza reflection para establecer el valor del campo en la entidad
try {
Field campoEntidad = Producto.class.getDeclaredField(fieldName);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
//Field campoEntidad = Producto.class.getDeclaredField(fieldName);
java.lang.reflect.Field campoEntidad = org.springframework.util.ReflectionUtils.findField(Producto.class, fieldName);
campoEntidad.setAccessible(true);
campoEntidad.set(producto, fieldValue);
} catch (NoSuchFieldException | IllegalAccessException ex) {
if (campoEntidad.isAnnotationPresent(ManyToOne.class)) {
//java.util.LinkedHashMap<String, Long> keyValue = mapper.convertValue(fieldValue, new TypeReference<java.util.LinkedHashMap<String, Long>>(){});
//Object relatedEntity = entidadService.findById(keyValue.get("id"));
//campoEntidad.set(entity, relatedEntity);
}else{
//campoEntidad.set(entity, fieldValue);
campoEntidad.set(entity, mapper.convertValue(fieldValue, campoEntidad.getType()));
}
} catch ( IllegalAccessException ex) {
// maneja la excepción si ocurre algún error al acceder al campo
}
}
return update(producto);
return update(entity);
}
}

@ -3,6 +3,7 @@ package pedidos.pedidos.core.producto;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigInteger;
@Service
public class ProductoService {

@ -1,7 +1,6 @@
spring.datasource.url=jdbc:postgresql://db:5432/pedidosdb
spring.datasource.url=jdbc:postgresql://dbclases:5432/pedidosdb
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.show-sql=true
#spring.sql.init.mode=always
server.port=8081
server.port=8080
Loading…
Cancel
Save