reviews
This commit is contained in:
parent
610ff22abe
commit
1b2df20fdd
12 changed files with 79 additions and 37 deletions
|
@ -12,6 +12,7 @@ import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
|
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
|
||||||
|
@ -28,7 +29,7 @@ public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthent
|
||||||
// Get the saved request
|
// Get the saved request
|
||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession(false);
|
||||||
SavedRequest savedRequest = session != null ? (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST") : null;
|
SavedRequest savedRequest = session != null ? (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST") : null;
|
||||||
if (savedRequest != null && !isStaticResource(savedRequest)) {
|
if (savedRequest != null && !RequestUriUtils.isStaticResource(savedRequest.getRedirectUrl())) {
|
||||||
// Redirect to the original destination
|
// Redirect to the original destination
|
||||||
super.onAuthenticationSuccess(request, response, authentication);
|
super.onAuthenticationSuccess(request, response, authentication);
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,14 +40,5 @@ public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthent
|
||||||
//super.onAuthenticationSuccess(request, response, authentication);
|
//super.onAuthenticationSuccess(request, response, authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isStaticResource(SavedRequest savedRequest) {
|
|
||||||
String requestURI = savedRequest.getRedirectUrl();
|
|
||||||
return requestURI.startsWith("/css/")
|
|
||||||
|| requestURI.startsWith("/js/")
|
|
||||||
|| requestURI.startsWith("/images/")
|
|
||||||
|| requestURI.startsWith("/public/")
|
|
||||||
|| requestURI.startsWith("/pdfjs/")
|
|
||||||
|| requestURI.endsWith(".svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class FirstLoginFilter extends OncePerRequestFilter {
|
public class FirstLoginFilter extends OncePerRequestFilter {
|
||||||
|
@ -28,11 +29,7 @@ public class FirstLoginFilter extends OncePerRequestFilter {
|
||||||
String method = request.getMethod();
|
String method = request.getMethod();
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
// Check if the request is for static resources
|
// Check if the request is for static resources
|
||||||
boolean isStaticResource = requestURI.startsWith("/css/")
|
boolean isStaticResource = RequestUriUtils.isStaticResource(requestURI);
|
||||||
|| requestURI.startsWith("/js/")
|
|
||||||
|| requestURI.startsWith("/images/")
|
|
||||||
|| requestURI.startsWith("/public/")
|
|
||||||
|| requestURI.endsWith(".svg");
|
|
||||||
|
|
||||||
// If it's a static resource, just continue the filter chain and skip the logic below
|
// If it's a static resource, just continue the filter chain and skip the logic below
|
||||||
if (isStaticResource) {
|
if (isStaticResource) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.ServletRequest;
|
import jakarta.servlet.ServletRequest;
|
||||||
import jakarta.servlet.ServletResponse;
|
import jakarta.servlet.ServletResponse;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
public class IPRateLimitingFilter implements Filter {
|
public class IPRateLimitingFilter implements Filter {
|
||||||
|
|
||||||
|
@ -29,12 +30,7 @@ public class IPRateLimitingFilter implements Filter {
|
||||||
String method = httpRequest.getMethod();
|
String method = httpRequest.getMethod();
|
||||||
String requestURI = httpRequest.getRequestURI();
|
String requestURI = httpRequest.getRequestURI();
|
||||||
// Check if the request is for static resources
|
// Check if the request is for static resources
|
||||||
boolean isStaticResource = requestURI.startsWith("/css/")
|
boolean isStaticResource = RequestUriUtils.isStaticResource(requestURI);
|
||||||
|| requestURI.startsWith("/js/")
|
|
||||||
|| requestURI.startsWith("/images/")
|
|
||||||
|| requestURI.startsWith("/public/")
|
|
||||||
|| requestURI.startsWith("/pdfjs/")
|
|
||||||
|| requestURI.endsWith(".svg");
|
|
||||||
|
|
||||||
// If it's a static resource, just continue the filter chain and skip the logic below
|
// If it's a static resource, just continue the filter chain and skip the logic below
|
||||||
if (isStaticResource) {
|
if (isStaticResource) {
|
||||||
|
|
|
@ -2,15 +2,30 @@ package stirling.software.SPDF.config.security;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.AttemptCounter;
|
import stirling.software.SPDF.model.AttemptCounter;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoginAttemptService {
|
public class LoginAttemptService {
|
||||||
|
|
||||||
private final int MAX_ATTEMPTS = 10;
|
|
||||||
private final long ATTEMPT_INCREMENT_TIME = TimeUnit.MINUTES.toMillis(1);
|
@Autowired
|
||||||
|
ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
private int MAX_ATTEMPTS;
|
||||||
|
private long ATTEMPT_INCREMENT_TIME;
|
||||||
|
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
MAX_ATTEMPTS = applicationProperties.getSecurity().getLoginAttemptCount();
|
||||||
|
ATTEMPT_INCREMENT_TIME = TimeUnit.MINUTES.toMillis(applicationProperties.getSecurity().getLoginResetTimeMinutes());
|
||||||
|
}
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, AttemptCounter> attemptsCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, AttemptCounter> attemptsCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public void loginSucceeded(String key) {
|
public void loginSucceeded(String key) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class RateLimitResetScheduler {
|
||||||
this.rateLimitingFilter = rateLimitingFilter;
|
this.rateLimitingFilter = rateLimitingFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 0 0 * * MON") // At 00:00 every Monday
|
@Scheduled(cron = "0 0 0 * * MON") // At 00:00 every Monday TODO: configurable
|
||||||
public void resetRateLimit() {
|
public void resetRateLimit() {
|
||||||
rateLimitingFilter.resetRequestCounts();
|
rateLimitingFilter.resetRequestCounts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,12 @@ public class ApiDocService {
|
||||||
|
|
||||||
private String getApiDocsUrl() {
|
private String getApiDocsUrl() {
|
||||||
String contextPath = servletContext.getContextPath();
|
String contextPath = servletContext.getContextPath();
|
||||||
return "http://localhost:8080" + contextPath + "/v1/api-docs";
|
String port = System.getProperty("local.server.port");
|
||||||
|
if(port == null || port.length() == 0) {
|
||||||
|
port="8080";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "http://localhost:"+ port + contextPath + "/v1/api-docs";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class PipelineDirectoryProcessor {
|
||||||
|
|
||||||
private PipelineConfig readAndParseJson(Path jsonFile) throws IOException {
|
private PipelineConfig readAndParseJson(Path jsonFile) throws IOException {
|
||||||
String jsonString = new String(Files.readAllBytes(jsonFile), StandardCharsets.UTF_8);
|
String jsonString = new String(Files.readAllBytes(jsonFile), StandardCharsets.UTF_8);
|
||||||
logger.info("Reading JSON file: {}", jsonFile);
|
logger.debug("Reading JSON file: {}", jsonFile);
|
||||||
return objectMapper.readValue(jsonString, PipelineConfig.class);
|
return objectMapper.readValue(jsonString, PipelineConfig.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ public class PipelineDirectoryProcessor {
|
||||||
validateOperation(operation);
|
validateOperation(operation);
|
||||||
File[] files = collectFilesForProcessing(dir, jsonFile, operation);
|
File[] files = collectFilesForProcessing(dir, jsonFile, operation);
|
||||||
if(files == null || files.length == 0) {
|
if(files == null || files.length == 0) {
|
||||||
logger.info("No files detected for {} ", dir);
|
logger.debug("No files detected for {} ", dir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<File> filesToProcess = prepareFilesForProcessing(files, processingDir);
|
List<File> filesToProcess = prepareFilesForProcessing(files, processingDir);
|
||||||
|
|
|
@ -238,7 +238,7 @@ public class PipelineProcessor {
|
||||||
|
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
Path path = Paths.get(file.getAbsolutePath());
|
Path path = Paths.get(file.getAbsolutePath());
|
||||||
System.out.println("Reading file: " + path); // debug statement
|
logger.info("Reading file: " + path); // debug statement
|
||||||
|
|
||||||
if (Files.exists(path)) {
|
if (Files.exists(path)) {
|
||||||
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
|
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
|
||||||
|
@ -249,7 +249,7 @@ public class PipelineProcessor {
|
||||||
};
|
};
|
||||||
outputFiles.add(fileResource);
|
outputFiles.add(fileResource);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("File not found: " + path); // debug statement
|
logger.info("File not found: " + path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info("Files successfully loaded. Starting processing...");
|
logger.info("Files successfully loaded. Starting processing...");
|
||||||
|
|
|
@ -106,6 +106,25 @@ public class ApplicationProperties {
|
||||||
private Boolean enableLogin;
|
private Boolean enableLogin;
|
||||||
private Boolean csrfDisabled;
|
private Boolean csrfDisabled;
|
||||||
private InitialLogin initialLogin;
|
private InitialLogin initialLogin;
|
||||||
|
private int loginAttemptCount;
|
||||||
|
private long loginResetTimeMinutes;
|
||||||
|
|
||||||
|
|
||||||
|
public int getLoginAttemptCount() {
|
||||||
|
return loginAttemptCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoginAttemptCount(int loginAttemptCount) {
|
||||||
|
this.loginAttemptCount = loginAttemptCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLoginResetTimeMinutes() {
|
||||||
|
return loginResetTimeMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoginResetTimeMinutes(long loginResetTimeMinutes) {
|
||||||
|
this.loginResetTimeMinutes = loginResetTimeMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
public InitialLogin getInitialLogin() {
|
public InitialLogin getInitialLogin() {
|
||||||
return initialLogin != null ? initialLogin : new InitialLogin();
|
return initialLogin != null ? initialLogin : new InitialLogin();
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
package stirling.software.SPDF.model;
|
package stirling.software.SPDF.model;
|
||||||
public class AttemptCounter {
|
public class AttemptCounter {
|
||||||
private int attemptCount;
|
private int attemptCount;
|
||||||
private long firstAttemptTime;
|
private long lastAttemptTime;
|
||||||
|
|
||||||
public AttemptCounter() {
|
public AttemptCounter() {
|
||||||
this.attemptCount = 1;
|
this.attemptCount = 1;
|
||||||
this.firstAttemptTime = System.currentTimeMillis();
|
this.lastAttemptTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increment() {
|
public void increment() {
|
||||||
this.attemptCount++;
|
this.attemptCount++;
|
||||||
this.firstAttemptTime = System.currentTimeMillis();
|
this.lastAttemptTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAttemptCount() {
|
public int getAttemptCount() {
|
||||||
return attemptCount;
|
return attemptCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFirstAttemptTime() {
|
public long getlastAttemptTime() {
|
||||||
return firstAttemptTime;
|
return lastAttemptTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldReset(long ATTEMPT_INCREMENT_TIME) {
|
public boolean shouldReset(long ATTEMPT_INCREMENT_TIME) {
|
||||||
return System.currentTimeMillis() - firstAttemptTime > ATTEMPT_INCREMENT_TIME;
|
return System.currentTimeMillis() - lastAttemptTime > ATTEMPT_INCREMENT_TIME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package stirling.software.SPDF.utils;
|
||||||
|
|
||||||
|
public class RequestUriUtils {
|
||||||
|
|
||||||
|
public static boolean isStaticResource(String requestURI) {
|
||||||
|
|
||||||
|
return requestURI.startsWith("/css/")
|
||||||
|
|| requestURI.startsWith("/js/")
|
||||||
|
|| requestURI.startsWith("/images/")
|
||||||
|
|| requestURI.startsWith("/public/")
|
||||||
|
|| requestURI.startsWith("/pdfjs/")
|
||||||
|
|| requestURI.endsWith(".svg");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,8 @@
|
||||||
security:
|
security:
|
||||||
enableLogin: false # set to 'true' to enable login
|
enableLogin: false # set to 'true' to enable login
|
||||||
csrfDisabled: true
|
csrfDisabled: true
|
||||||
|
loginAttemptCount: 5 # lock user account after 5 tries
|
||||||
|
loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts
|
||||||
|
|
||||||
system:
|
system:
|
||||||
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||||
|
|
Loading…
Reference in a new issue