Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to springboot 3.2 #1349

Merged
merged 12 commits into from Apr 25, 2024
59 changes: 26 additions & 33 deletions build.gradle
Expand Up @@ -15,7 +15,7 @@ buildscript {
dependencies {
classpath 'org.postgresql:postgresql:42.5.1'
//this is for processing the index.html at compile time
classpath "ch.digitalfondue.jfiveparse:jfiveparse:1.0.0"
classpath "ch.digitalfondue.jfiveparse:jfiveparse:1.0.3"
//
}

Expand All @@ -32,13 +32,13 @@ plugins {
id 'java'
id 'idea'
id 'org.kordamp.gradle.jacoco' version '0.54.0'
id 'com.github.ben-manes.versions' version '0.50.0'
id 'com.github.ben-manes.versions' version '0.51.0'
id 'com.github.hierynomus.license' version '0.16.1'
id 'net.researchgate.release' version '3.0.2'
id 'org.springframework.boot' version '2.7.7'
id 'org.springframework.boot' version '3.2.0'
id 'org.sonarqube' version '4.4.1.3373'
// id 'net.ltgt.errorprone' version '3.1.0'
id 'com.github.node-gradle.node' version '7.0.1'
id 'com.github.node-gradle.node' version '7.0.2'
}

apply plugin: 'java'
Expand Down Expand Up @@ -103,66 +103,59 @@ repositories {

dependencies {
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
implementation 'com.auth0:java-jwt:4.2.1'
implementation 'com.auth0:java-jwt:4.4.0'
implementation "com.fasterxml.jackson.core:jackson-core"
implementation "com.fasterxml.jackson.core:jackson-databind"
implementation "org.springframework.boot:spring-boot-properties-migrator", {
exclude module : 'spring-boot-starter-logging'
}
implementation 'org.springframework.session:spring-session-jdbc'
implementation "ch.digitalfondue.npjt-extra:npjt-extra:2.0.4"
implementation "com.samskivert:jmustache:1.15"
implementation "javax.mail:mail:1.5.0-b01"
implementation "com.samskivert:jmustache:1.16"
implementation 'com.moodysalem:LatLongToTimezoneMaven:1.2'
/**/
implementation 'com.openhtmltopdf:openhtmltopdf-core:1.0.10'
implementation 'com.openhtmltopdf:openhtmltopdf-pdfbox:1.0.10'
implementation 'ch.digitalfondue.jfiveparse:jfiveparse:1.0.0'
implementation 'ch.digitalfondue.jfiveparse:jfiveparse:1.0.3'
/**/
implementation 'com.google.zxing:core:3.5.1'
implementation 'com.google.zxing:javase:3.5.1'
implementation 'com.google.zxing:core:3.5.3'
implementation 'com.google.zxing:javase:3.5.3'
implementation "org.flywaydb:flyway-core"
implementation "org.postgresql:postgresql"
implementation "com.zaxxer:HikariCP"

/* https://www.lunasec.io/docs/blog/log4j-zero-day/ */
implementation 'org.apache.logging.log4j:log4j-api:2.19.0'
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
implementation 'org.apache.logging.log4j:log4j-jul:2.19.0'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.19.0'
/**/

implementation "com.stripe:stripe-java:22.4.0"
implementation "com.stripe:stripe-java:25.3.0"
implementation 'com.paypal.sdk:checkout-sdk:2.0.0'
implementation 'com.google.code.gson:gson:2.10'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.fatboyindustrial.gson-javatime-serialisers:gson-javatime-serialisers:1.1.2', {
exclude module: 'gson'
}

implementation "org.apache.commons:commons-lang3:3.13.0"
implementation 'com.opencsv:opencsv:5.9'
implementation 'com.opencsv:opencsv:5.9', {
exclude module: 'commons-collections:commons-collections:3.2.2'
}
implementation 'commons-codec:commons-codec:1.15'
implementation 'net.sf.biweekly:biweekly:0.6.6'
implementation 'com.atlassian.commonmark:commonmark:0.17.0'
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.17.0'
implementation 'com.ryantenney.passkit4j:passkit4j:2.0.1'
implementation 'com.github.ben-manes.caffeine:caffeine'
implementation 'com.github.scribejava:scribejava-core:8.3.3'
implementation 'ch.digitalfondue.vatchecker:vatchecker:1.5.0'
implementation 'ch.digitalfondue.basicxlsx:basicxlsx:0.5.1'
implementation 'ch.digitalfondue.vatchecker:vatchecker:1.6.0'
implementation 'ch.digitalfondue.basicxlsx:basicxlsx:0.7.1'
implementation 'org.imgscalr:imgscalr-lib:4.2'
implementation 'org.mozilla:rhino-runtime:1.7.13'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.18.0'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.23.0'

compileOnly "javax.servlet:javax.servlet-api:4.0.1"
testImplementation "javax.servlet:javax.servlet-api:4.0.1"
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation 'org.testcontainers:postgresql:1.19.3'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:postgresql'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation "org.springframework.boot:spring-boot-starter-test", {
exclude module : 'spring-boot-starter-logging'
}
runtimeOnly "commons-fileupload:commons-fileupload:1.5"
implementation "org.springframework.boot:spring-boot-starter-web", {
exclude module : 'spring-boot-starter-logging'
exclude group: "org.springframework.boot", module: 'spring-boot-starter-tomcat'
Expand Down Expand Up @@ -193,8 +186,10 @@ dependencies {
testImplementation "org.junit.platform:junit-platform-engine"
testImplementation "org.mockito:mockito-inline:4.5.1"

testImplementation "org.springdoc:springdoc-openapi-ui:1.6.14"
testImplementation "org.openapitools.openapidiff:openapi-diff-core:2.0.1"
testImplementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0"
testImplementation "org.openapitools.openapidiff:openapi-diff-core:2.1.0-beta.10", {
exclude group: "io.swagger.core.v3", module: "swagger-core"
}

providedCompile "org.springframework.boot:spring-boot-starter-jetty", {
exclude group: "org.eclipse.jetty.websocket", module: "websocket-server"
Expand All @@ -209,9 +204,7 @@ dependencies {

implementation "org.joda:joda-money:1.0.3"

testImplementation 'org.mock-server:mockserver-netty:5.13.2', {
exclude group: 'org.mozilla', module: 'rhino'
}
testImplementation 'org.mock-server:mockserver-netty-no-dependencies:5.15.0'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

testImplementation 'org.seleniumhq.selenium:selenium-java:4.16.1'
Expand Down Expand Up @@ -275,7 +268,7 @@ compileTestJava {
}

compileJava {
options.compilerArgs = ['-Xlint:all,-serial,-processing']
options.compilerArgs = ['-parameters','-Xlint:all,-serial,-processing']

// both checks are problematic with lombok code
// options.errorprone.disable('UnusedVariable',
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/alfio/config/ConfigurationStatusChecker.java
Expand Up @@ -28,7 +28,6 @@
import lombok.extern.log4j.Log4j2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
Expand All @@ -49,7 +48,6 @@ public class ConfigurationStatusChecker implements ApplicationListener<ContextRe
private final String version;
private final DataMigrator dataMigrator;

@Autowired
public ConfigurationStatusChecker(ConfigurationManager configurationManager,
UserRepository userRepository,
AuthorityRepository authorityRepository,
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/alfio/config/DataSourceConfiguration.java
Expand Up @@ -330,5 +330,25 @@ public Connection getConnection() {
public Connection getConnection(String username, String password) {
return null;
}

public boolean isWrapperFor(Class<?> iface) throws java.sql.SQLException {
return iface.isAssignableFrom(this.getClass());
}

public <T> T unwrap(Class<T> iface) throws java.sql.SQLException {
try {
if(iface.isAssignableFrom(this.getClass())) {
return iface.cast(this);
}
throw new java.sql.SQLException("Auto-generated unwrap failed; Revisit implementation");
} catch (Exception e) {
throw new java.sql.SQLException(e);
}
}

public java.util.logging.Logger getParentLogger() {
// TODO Auto-generated method stub
return null;
}
}
}
27 changes: 3 additions & 24 deletions src/main/java/alfio/config/Initializer.java
Expand Up @@ -18,18 +18,14 @@

import alfio.util.DefaultExceptionHandler;
import com.openhtmltopdf.util.XRLog;
import org.apache.commons.lang3.Validate;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import jakarta.servlet.FilterRegistration.Dynamic;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.SessionCookieConfig;
import java.util.Objects;
import java.util.logging.Level;

Expand All @@ -44,16 +40,13 @@ public class Initializer extends AbstractAnnotationConfigDispatcherServletInitia
public static final String PROFILE_DISABLE_JOBS = "disable-jobs";
public static final String API_V2_PUBLIC_PATH = "/api/v2/public/";
public static final String XSRF_TOKEN = "XSRF-TOKEN";
private Environment environment;

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);

Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler());

configureSessionCookie(servletContext);

CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setEncoding("UTF-8");
cef.setForceEncoding(true);
Expand All @@ -72,23 +65,9 @@ public void onStartup(ServletContext servletContext) throws ServletException {
protected WebApplicationContext createRootApplicationContext() {
ConfigurableWebApplicationContext ctx = ((ConfigurableWebApplicationContext) super.createRootApplicationContext());
Objects.requireNonNull(ctx, "Something really bad is happening...");
this.environment = ctx.getEnvironment();
return ctx;
}

private void configureSessionCookie(ServletContext servletContext) {
SessionCookieConfig config = servletContext.getSessionCookieConfig();

config.setHttpOnly(true);

Validate.notNull(environment, "environment cannot be null!");
// set secure cookie only if current environment doesn't strictly need HTTP
config.setSecure(environment.acceptsProfiles(Profiles.of(Initializer.PROFILE_LIVE)));

// https://issues.jboss.org/browse/WFLY-3448 ?
config.setPath(servletContext.getContextPath() + "/");
}

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { ApplicationPropertiesConfiguration.class, DataSourceConfiguration.class, WebSecurityConfig.class };
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/alfio/config/MvcConfiguration.java
Expand Up @@ -17,6 +17,8 @@
package alfio.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
Expand All @@ -29,21 +31,20 @@
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -117,13 +118,6 @@ private MappingJackson2HttpMessageConverter jacksonMessageConverter(ObjectMapper
return converter;
}

@Bean
public CommonsMultipartResolver multipartResolver() {
var multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(500_000); // 500kB
return multipartResolver;
}

@Bean
public ViewResolver viewResolver() {
var resolver = new UrlBasedViewResolver();
Expand All @@ -137,9 +131,10 @@ public SpringSessionBackedSessionRegistry<?> sessionRegistry(FindByIndexNameSess
}

@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
public HttpSessionIdResolver httpSessionIdResolver(CookieSerializer cookieSerializer) {
var publicSessionIdResolver = HeaderHttpSessionIdResolver.xAuthToken();
var adminSessionIdResolver = new CookieHttpSessionIdResolver();
adminSessionIdResolver.setCookieSerializer(cookieSerializer);
return new HttpSessionIdResolver() {
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
Expand Down
Expand Up @@ -28,7 +28,7 @@
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;
Expand Down Expand Up @@ -94,9 +94,11 @@ private static boolean isAdmin() {
return false;
}

private static final String QUERY_ORG_FOR_USER = "(select organization.id from organization inner join j_user_organization on org_id = organization.id where j_user_organization.user_id = (select ba_user.id from ba_user where ba_user.username = ?)) " +
" union " +
"(select organization.id from organization where 'ROLE_ADMIN' in (select role from ba_user inner join authority on ba_user.username = authority.username where ba_user.username = ?))";
private static final String QUERY_ORG_FOR_USER = """
(select organization.id from organization inner join j_user_organization on org_id = organization.id where j_user_organization.user_id = (select ba_user.id from ba_user where ba_user.username = ?)) \
union \
(select organization.id from organization where 'ROLE_ADMIN' in (select role from ba_user inner join authority on ba_user.username = authority.username where ba_user.username = ?))\
""";

public static void prepareTransactionalConnection(Connection connection) throws SQLException {
if (!isInAHttpRequest()) {
Expand Down