pr comments

This commit is contained in:
DarioGii
2026-01-24 12:43:52 +00:00
parent 7f4aa8db9b
commit 8d6d0b0cdd
6 changed files with 53 additions and 36 deletions
@@ -1,12 +1,11 @@
multipart.enabled=true
logging.level.org.springframework=WARN
logging.level.org.springframework.security=WARN
logging.level.org.hibernate=WARN
logging.level.org.eclipse.jetty=WARN
#logging.level.org.springframework.security=DEBUG
#logging.level.org.springframework.security.oauth2=DEBUG
logging.level.org.springframework.security=DEBUG
#logging.level.org.opensaml=DEBUG
logging.level.stirling.software.proprietary.security=DEBUG
#logging.level.stirling.software.proprietary.security=DEBUG
logging.level.com.zaxxer.hikari=WARN
logging.level.stirling.software.SPDF.service.PdfJsonConversionService=INFO
logging.level.stirling.software.common.service.JobExecutorService=INFO
@@ -210,7 +210,10 @@ public class ProprietaryUIDataController {
SAML2 saml2 = securityProps.getSaml2();
// Only add SAML2 providers if loginMethod allows it
if (securityProps.isSaml2Active() && applicationProperties.getPremium().isEnabled()) {
String samlIdp = saml2.getIdpIssuer();
String samlIdp =
saml2.getProvider().getEntityId() != null
? saml2.getProvider().getEntityId()
: saml2.getIdpIssuer(); // legacy fallback
String saml2AuthenticationPath = "/saml2/authenticate/" + saml2.getRegistrationId();
// For SAML, we need to use the backend URL directly, not a relative path
@@ -99,7 +99,8 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
String samlResponse = request.getParameter("SAMLResponse");
if (samlResponse != null && !samlResponse.isBlank()) {
if (samlResponse.contains("/saml2/slo")) {
log.info("Received SAML LogoutResponse at /logout endpoint, completing logout locally");
log.info(
"Received SAML LogoutResponse at /logout endpoint, completing logout locally");
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
return true;
}
@@ -109,10 +110,16 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
log.info("SP-initiated SLO detected, logging out via IdP");
if (authentication instanceof Saml2Authentication samlAuthentication) {
try {
samlLogoutHandler.onLogoutSuccess(request, response, samlAuthentication);
} catch (Exception e) {
log.error("SP-initiated SLO failed, falling back to local logout", e);
if (samlLogoutHandler != null) {
try {
samlLogoutHandler.onLogoutSuccess(request, response, samlAuthentication);
} catch (Exception e) {
log.error("SP-initiated SLO failed, falling back to local logout", e);
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
}
} else {
log.warn(
"SAML SLO enabled but handler not configured, performing local logout only");
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
}
@@ -125,19 +132,22 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
if (reconstructedAuth.isPresent()) {
Saml2Authentication samlAuth = reconstructedAuth.get();
try {
samlLogoutHandler.onLogoutSuccess(request, response, samlAuth);
} catch (Exception e) {
log.error("SP-initiated SLO failed, falling back to local logout", e);
if (samlLogoutHandler != null) {
try {
samlLogoutHandler.onLogoutSuccess(request, response, samlAuth);
} catch (Exception e) {
log.error("SP-initiated SLO failed, falling back to local logout", e);
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
}
} else {
log.warn(
"SAML SLO enabled but handler not configured, performing local logout only");
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
}
return true;
}
}
} else {
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
return true;
}
return false;
@@ -7,7 +7,6 @@ import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -71,7 +70,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testSuccessfulLogoutViaOAuth2() throws IOException {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
@@ -80,6 +78,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getScheme()).thenReturn("http");
@@ -95,7 +96,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testUserIsDisabledRedirect() throws IOException {
String error = "userIsDisabled";
String url = "http://localhost:8080";
@@ -106,6 +106,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
@@ -127,7 +130,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testUserAlreadyExistsWebRedirect() throws IOException {
String error = "oAuth2AuthenticationErrorWeb";
String errorPath = "userAlreadyExistsWeb";
@@ -139,6 +141,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter(error)).thenReturn("true");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
@@ -153,7 +158,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testErrorOAuthRedirect() throws IOException {
String error = "testError";
String url = "http://localhost:8080";
@@ -164,6 +168,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn("!!!" + error + "!!!");
when(request.getScheme()).thenReturn("http");
@@ -179,7 +186,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testOAuth2AutoCreateDisabled() throws IOException {
String error = "oAuth2AutoCreateDisabled";
String url = "http://localhost:8080";
@@ -190,10 +196,12 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter(error)).thenReturn("true");
when(request.getContextPath()).thenReturn(url);
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
@@ -207,7 +215,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testOAuth2Error() throws IOException {
String error = "test";
String url = "http://localhost:8080";
@@ -218,6 +225,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
@@ -240,7 +250,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testOAuth2BadCredentialsError() throws IOException {
String error = "badCredentials";
String url = "http://localhost:8080";
@@ -251,6 +260,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
@@ -274,7 +286,6 @@ class CustomLogoutSuccessHandlerTest {
}
@Test
@Disabled("TODO: Fix OAuth2 logout tests - need to properly mock UrlUtils.getOrigin")
void testOAuth2AdminBlockedUser() throws IOException {
String error = "oAuth2AdminBlockedUser";
String url = "http://localhost:8080";
@@ -285,6 +296,9 @@ class CustomLogoutSuccessHandlerTest {
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("SAMLResponse")).thenReturn(null);
when(securityProperties.getSaml2()).thenReturn(saml2);
when(saml2.getEnableSingleLogout()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
+1 -1
View File
@@ -537,4 +537,4 @@ tasks.register('buildRestartHelper', Jar) {
doLast {
println "restart-helper.jar created at: ${destinationDirectory.get()}/restart-helper.jar"
}
}
}
@@ -100,15 +100,6 @@ const TestWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
</MantineProvider>
);
// Helper to create mock API responses with full response structure
const _createMockResponse = <T,>(data: T, status = 200, statusText = 'OK') => ({
data,
status,
statusText,
headers: {},
config: {},
});
describe('Convert Tool Integration Tests', () => {
beforeEach(() => {