Compare commits

..

4 Commits

9 changed files with 113 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
SPRING_PROFILES_ACTIVE=dev
APP_ENCRYPTION_SECRET=123456789
APP_ALLOWED_ORIGINS=http://localhost:8080
DB_NAME=EXAMPLE_DB
DB_USER=EXAMPLE

View File

@@ -10,4 +10,4 @@ COPY --from=build /app/bootstrap/target/*.jar app.jar
EXPOSE 8080
EXPOSE 5005
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "app.jar"]
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-Xmx512m", "-Xms256m", "-jar", "app.jar"]

View File

@@ -0,0 +1,29 @@
package com.pablotj.restemailbridge.bootstrap;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
public class EnvironmentValidatorInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext ctx) {
String[] requiredProperties = {
"APP_ENCRYPTION_SECRET",
"APP_ALLOWED_ORIGINS",
"DB_NAME",
"DB_USER",
"DB_PASSWORD",
"DB_HOST",
"DB_PORT",
"GMAIL_OAUTH_CLIENT_ID",
"GMAIL_OAUTH_CLIENT_SECRET"
};
for (String prop : requiredProperties) {
String value = ctx.getEnvironment().getProperty(prop);
if (value == null || value.isEmpty()) {
throw new IllegalStateException("ERROR: Property '" + prop + "' is not defined or empty");
}
}
}
}

View File

@@ -11,6 +11,8 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
public class RestEmailBridgeApplication {
public static void main(String[] args) {
SpringApplication.run(RestEmailBridgeApplication.class, args);
SpringApplication app = new SpringApplication(RestEmailBridgeApplication.class);
app.addInitializers(new EnvironmentValidatorInitializer());
app.run(args);
}
}

View File

@@ -5,6 +5,8 @@ info:
app:
encryption:
secret: ${APP_ENCRYPTION_SECRET}
cors:
allowed-origins: ${APP_ALLOWED_ORIGINS:http://localhost:8080}
server:
port: 8080
@@ -25,8 +27,11 @@ spring:
password: ${DB_PASSWORD:postgres}
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
maximum-pool-size: 3
minimum-idle: 1
idle-timeout: 30000
connection-timeout: 10000
leak-detection-threshold: 10000
jpa:
hibernate:

View File

@@ -14,6 +14,7 @@ services:
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
APP_ENCRYPTION_SECRET: ${APP_ENCRYPTION_SECRET}
APP_ALLOWED_ORIGINS: ${APP_ALLOWED_ORIGINS}
GMAIL_OAUTH_CLIENT_ID: ${GMAIL_OAUTH_CLIENT_ID}
GMAIL_OAUTH_CLIENT_SECRET: ${GMAIL_OAUTH_CLIENT_SECRET}
networks:

View File

@@ -49,6 +49,11 @@
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>

View File

@@ -0,0 +1,35 @@
package com.pablotj.restemailbridge.infrastructure.config;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.List;
@Configuration
public class CorsConfig {
@Value("${app.cors.allowed-origins}")
private String allowedOriginsString;
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
List<String> allowedOrigins = Arrays.asList(allowedOriginsString.split(","));
config.setAllowedOriginPatterns(allowedOrigins);
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}

View File

@@ -0,0 +1,31 @@
package com.pablotj.restemailbridge.infrastructure.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfigurationSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CorsConfigurationSource corsConfigurationSource;
public SecurityConfig(CorsConfigurationSource corsConfigurationSource) {
this.corsConfigurationSource = corsConfigurationSource;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.cors(cors -> cors.configurationSource(corsConfigurationSource))
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()
);
return http.build();
}
}