Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.opencommercial</groupId>
<artifactId>api</artifactId>
<version>1.3.17</version>
<version>1.4.0</version>
<packaging>jar</packaging>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.7</version>
<version>4.0.1</version>
<relativePath/>
</parent>

Expand All @@ -23,16 +23,17 @@
<dom4j.version>1.6.1</dom4j.version>
<jasperreports.version>6.17.0</jasperreports.version>
<apache-poi.version>3.17</apache-poi.version>
<jjwt.version>0.12.6</jjwt.version>
<jjwt.version>0.13.0</jjwt.version>
<bouncycastle-bcmail.version>1.46</bouncycastle-bcmail.version>
<commons-io.version>2.14.0</commons-io.version>
<xml-soap.version>1.4.0</xml-soap.version>
<messaging-saaj.version>3.0.4</messaging-saaj.version>
<cloudinary.version>1.39.0</cloudinary.version>
<newrelic-agent.version>8.17.0</newrelic-agent.version>
<newrelic-agent.version>8.25.1</newrelic-agent.version>
<mercadopago.version>2.1.4</mercadopago.version>
<google-gson.version>2.8.9</google-gson.version>
<resend.version>2.2.1</resend.version>
<resend.version>2.3.0</resend.version>
<querydsl.version>5.1.0</querydsl.version>
<sonar.exclusions>
src/main/java/org/opencommercial/model/**,
src/main/java/org/opencommercial/exception/**
Expand Down Expand Up @@ -64,15 +65,11 @@
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
Expand Down Expand Up @@ -129,7 +126,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -139,6 +136,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
Expand Down Expand Up @@ -167,19 +168,44 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<artifactId>testcontainers-mysql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/org/opencommercial/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@EnableAsync
@EnableCaching
public class App {

public static void main(String[] args) {
Expand Down
62 changes: 30 additions & 32 deletions src/main/java/org/opencommercial/config/AppConfig.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.opencommercial.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.opencommercial.model.Cliente;
import org.opencommercial.model.Ubicacion;
import org.opencommercial.model.dto.ClienteDTO;
import org.opencommercial.model.dto.UbicacionDTO;
import org.opencommercial.service.AfipWebServiceSOAPClient;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -17,41 +17,39 @@
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.opencommercial.model.Cliente;
import org.opencommercial.model.Ubicacion;
import org.opencommercial.model.dto.ClienteDTO;
import org.opencommercial.model.dto.UbicacionDTO;
import org.opencommercial.service.AfipWebServiceSOAPClient;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueSerializer;
import tools.jackson.databind.module.SimpleModule;

import java.io.IOException;
import java.time.Clock;

@Configuration
public class AppConfig {

@Bean
public Module springDataPageModule() {
public SimpleModule springDataPageModule() {
return new SimpleModule()
.addSerializer(
Page.class,
new JsonSerializer<Page>() {
@Override
public void serialize(Page value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeNumberField("totalElements", value.getTotalElements());
gen.writeNumberField("totalPages", value.getTotalPages());
gen.writeNumberField("number", value.getNumber());
gen.writeNumberField("numberOfElements", value.getNumberOfElements());
gen.writeNumberField("size", value.getSize());
gen.writeBooleanField("first", value.isFirst());
gen.writeBooleanField("last", value.isLast());
gen.writeFieldName("content");
serializers.defaultSerializeValue(value.getContent(), gen);
gen.writeObjectField("sort", value.getSort());
gen.writeEndObject();
}
});
.addSerializer(
Page.class,
new ValueSerializer<Page>() {

@Override
public void serialize(Page value, JsonGenerator gen, SerializationContext sc) throws JacksonException {
gen.writeStartObject();
gen.writeNumberProperty("totalElements", value.getTotalElements());
gen.writeNumberProperty("totalPages", value.getTotalPages());
gen.writeNumberProperty("number", value.getNumber());
gen.writeNumberProperty("numberOfElements", value.getNumberOfElements());
gen.writeNumberProperty("size", value.getSize());
gen.writeBooleanProperty("first", value.isFirst());
gen.writeBooleanProperty("last", value.isLast());
sc.defaultSerializeProperty("content", value.getContent(), gen);
gen.writePOJOProperty("sort", value.getSort());
gen.writeEndObject();
}
});
}

@Bean
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/opencommercial/config/CacheConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.opencommercial.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package org.opencommercial.config;

import com.fasterxml.jackson.annotation.JsonView;
import jakarta.servlet.http.HttpServletRequest;
import org.jspecify.annotations.NonNull;
import org.opencommercial.model.Rol;
import org.opencommercial.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice;
import org.opencommercial.model.Rol;
import org.opencommercial.service.AuthService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestControllerAdvice
public class SecurityJsonViewControllerAdvice extends AbstractMappingJacksonResponseBodyAdvice {
public class SecurityJsonViewControllerAdvice implements ResponseBodyAdvice<Object> {

private final AuthService authService;
private static final String AUTHORIZATION_HEADER = "Authorization";
Expand All @@ -26,32 +34,79 @@ public SecurityJsonViewControllerAdvice(AuthService authService) {
}

@Override
protected void beforeBodyWriteInternal(
MappingJacksonValue mappingJacksonValue,
MediaType mediaType,
MethodParameter methodParameter,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {

var headers = serverHttpRequest.getHeaders().get(AUTHORIZATION_HEADER);
public boolean supports(@NonNull MethodParameter returnType,
@NonNull Class<? extends HttpMessageConverter<?>> converterType) {
return converterType == JacksonJsonHttpMessageConverter.class;
}

@Override
public Map<@NonNull String, @NonNull Object> determineWriteHints(
Object body,
@NonNull MethodParameter returnType,
@NonNull MediaType selectedContentType,
@NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType) {

if (body == null) {
return null;
}

var httpRequest = this.getCurrentHttpRequest();
if (httpRequest == null) {
return null;
}

var viewClass = this.determineViewClass(httpRequest);
if (viewClass != null) {
return Map.of(JsonView.class.getName(), viewClass);
}

return null;
}

@Override
public Object beforeBodyWrite(
Object body,
@NonNull MethodParameter returnType,
@NonNull MediaType selectedContentType,
@NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType,
@NonNull ServerHttpRequest request,
@NonNull ServerHttpResponse response) {
return body;
}

private Class<?> determineViewClass(HttpServletRequest httpServletRequest) {
var headers = httpServletRequest.getHeader(AUTHORIZATION_HEADER);
if (headers != null && !headers.isEmpty()) {
var claims = authService.getClaimsDelToken(headers.get(0));
var rolesDelUsuario = claims.get(CLAIM_ROLES, List.class);
if (rolesDelUsuario != null && !rolesDelUsuario.isEmpty()) {
if (rolesDelUsuario.contains(Rol.ADMINISTRADOR.name())) {
mappingJacksonValue.setSerializationView(Views.Administrador.class);
} else if (rolesDelUsuario.contains(Rol.ENCARGADO.name())) {
mappingJacksonValue.setSerializationView(Views.Encargado.class);
} else if (rolesDelUsuario.contains(Rol.VENDEDOR.name())) {
mappingJacksonValue.setSerializationView(Views.Vendedor.class);
} else if (rolesDelUsuario.contains(Rol.VIAJANTE.name())) {
mappingJacksonValue.setSerializationView(Views.Viajante.class);
} else if (rolesDelUsuario.contains(Rol.COMPRADOR.name())) {
mappingJacksonValue.setSerializationView(Views.Comprador.class);
try {
var claims = authService.getClaimsDelToken(headers);
var rolesDelUsuario = claims.get(CLAIM_ROLES, List.class);
if (rolesDelUsuario != null && !rolesDelUsuario.isEmpty()) {
if (rolesDelUsuario.contains(Rol.ADMINISTRADOR.name())) {
return Views.Administrador.class;
} else if (rolesDelUsuario.contains(Rol.ENCARGADO.name())) {
return Views.Encargado.class;
} else if (rolesDelUsuario.contains(Rol.VENDEDOR.name())) {
return Views.Vendedor.class;
} else if (rolesDelUsuario.contains(Rol.VIAJANTE.name())) {
return Views.Viajante.class;
} else if (rolesDelUsuario.contains(Rol.COMPRADOR.name())) {
return Views.Comprador.class;
}
}
} catch (Exception ex) {
return Views.Comprador.class;
}
} else {
mappingJacksonValue.setSerializationView(Views.Comprador.class);
}

return Views.Comprador.class;
}

private HttpServletRequest getCurrentHttpRequest() {
return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
.filter(ServletRequestAttributes.class::isInstance)
.map(ServletRequestAttributes.class::cast)
.map(ServletRequestAttributes::getRequest)
.orElse(null);
}
}

Loading