From cfe82ca725839c25f6ab3ddb917811c64042967e Mon Sep 17 00:00:00 2001 From: Ludy Date: Tue, 25 Feb 2025 22:31:50 +0100 Subject: [PATCH] Improve Type-Safe Casting with Pattern Matching (#2990) # Description of Changes Please provide a summary of the changes, including: This PR refactors multiple instances of type casting throughout the codebase by replacing them with Java's pattern matching for `instanceof`. This approach eliminates redundant type casting, improves code readability, and reduces the chances of `ClassCastException`. The changes primarily affect authentication handling, PDF processing, and certificate validation. ### Key Changes: - Replaced traditional `instanceof` checks followed by explicit casting with pattern matching. - Improved readability and maintainability of type-related operations. - Applied changes across security modules, PDF utilities, and image processing functions. This refactor does not introduce new functionality but enhances the robustness and clarity of the existing code. pending until #2818 is published --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --- .../security/CustomLogoutSuccessHandler.java | 57 ++++++++++++------- .../config/security/IPRateLimitingFilter.java | 4 +- .../security/UserAuthenticationFilter.java | 26 +++++---- .../SPDF/config/security/UserService.java | 28 ++++----- ...tomOAuth2AuthenticationFailureHandler.java | 6 +- ...tomOAuth2AuthenticationSuccessHandler.java | 8 +-- .../security/oauth2/OAuth2Configuration.java | 4 +- .../security/saml2/CertificateUtils.java | 7 +-- .../CustomSaml2AuthenticatedPrincipal.java | 7 ++- ...stomSaml2AuthenticationSuccessHandler.java | 4 +- .../session/SessionPersistentRegistry.java | 32 +++++------ .../SPDF/controller/api/UserController.java | 16 +++--- .../api/misc/AutoSplitPdfController.java | 17 ++++-- .../api/misc/CompressController.java | 9 +-- .../api/pipeline/PipelineProcessor.java | 14 ++--- .../api/security/CertSignController.java | 17 +++--- .../controller/api/security/GetInfoOnPDF.java | 27 +++------ .../api/security/SanitizeController.java | 12 ++-- .../controller/web/AccountWebController.java | 24 ++++---- .../SPDF/model/provider/GitHubProvider.java | 1 + .../SPDF/model/provider/GoogleProvider.java | 1 + .../SPDF/model/provider/KeycloakProvider.java | 1 + .../service/CertificateValidationService.java | 4 +- .../SPDF/utils/ImageProcessingUtils.java | 8 +-- .../CustomLogoutSuccessHandlerTest.java | 2 +- .../converters/ConvertWebsiteToPdfTest.java | 2 +- .../SPDF/utils/validation/ValidatorTest.java | 2 +- 27 files changed, 175 insertions(+), 165 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java b/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java index c455f0ebd..b570d625d 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java @@ -45,12 +45,12 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { throws IOException { if (!response.isCommitted()) { if (authentication != null) { - if (authentication instanceof Saml2Authentication) { + if (authentication instanceof Saml2Authentication samlAuthentication) { // Handle SAML2 logout redirection - getRedirect_saml2(request, response, authentication); - } else if (authentication instanceof OAuth2AuthenticationToken) { + getRedirect_saml2(request, response, samlAuthentication); + } else if (authentication instanceof OAuth2AuthenticationToken oAuthToken) { // Handle OAuth2 logout redirection - getRedirect_oauth2(request, response, authentication); + getRedirect_oauth2(request, response, oAuthToken); } else if (authentication instanceof UsernamePasswordAuthenticationToken) { // Handle Username/Password logout getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH); @@ -71,13 +71,14 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { // Redirect for SAML2 authentication logout private void getRedirect_saml2( - HttpServletRequest request, HttpServletResponse response, Authentication authentication) + HttpServletRequest request, + HttpServletResponse response, + Saml2Authentication samlAuthentication) throws IOException { SAML2 samlConf = applicationProperties.getSecurity().getSaml2(); String registrationId = samlConf.getRegistrationId(); - Saml2Authentication samlAuthentication = (Saml2Authentication) authentication; CustomSaml2AuthenticatedPrincipal principal = (CustomSaml2AuthenticatedPrincipal) samlAuthentication.getPrincipal(); @@ -115,32 +116,46 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { // Redirect for OAuth2 authentication logout private void getRedirect_oauth2( - HttpServletRequest request, HttpServletResponse response, Authentication authentication) + HttpServletRequest request, + HttpServletResponse response, + OAuth2AuthenticationToken oAuthToken) throws IOException { String registrationId; OAUTH2 oauth = applicationProperties.getSecurity().getOauth2(); String path = checkForErrors(request); - if (authentication instanceof OAuth2AuthenticationToken oauthToken) { - registrationId = oauthToken.getAuthorizedClientRegistrationId(); - } else { - registrationId = oauth.getProvider() != null ? oauth.getProvider() : ""; - } - String redirectUrl = UrlUtils.getOrigin(request) + "/login?" + path; + registrationId = oAuthToken.getAuthorizedClientRegistrationId(); // Redirect based on OAuth2 provider switch (registrationId.toLowerCase()) { case "keycloak" -> { KeycloakProvider keycloak = oauth.getClient().getKeycloak(); - String logoutUrl = - keycloak.getIssuer() - + "/protocol/openid-connect/logout" - + "?client_id=" - + keycloak.getClientId() - + "&post_logout_redirect_uri=" - + response.encodeRedirectURL(redirectUrl); - log.info("Redirecting to Keycloak logout URL: {}", logoutUrl); + + boolean isKeycloak = !keycloak.getIssuer().isBlank(); + boolean isCustomOAuth = !oauth.getIssuer().isBlank(); + + String logoutUrl = redirectUrl; + + if (isKeycloak) { + logoutUrl = keycloak.getIssuer(); + } else if (isCustomOAuth) { + logoutUrl = oauth.getIssuer(); + } + if (isKeycloak || isCustomOAuth) { + logoutUrl += + "/protocol/openid-connect/logout" + + "?client_id=" + + oauth.getClientId() + + "&post_logout_redirect_uri=" + + response.encodeRedirectURL(redirectUrl); + log.info("Redirecting to Keycloak logout URL: {}", logoutUrl); + } else { + log.info( + "No redirect URL for {} available. Redirecting to default logout URL: {}", + registrationId, + logoutUrl); + } response.sendRedirect(logoutUrl); } case "github", "google" -> { diff --git a/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java b/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java index 3599a833f..ed269c4d1 100644 --- a/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java +++ b/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java @@ -25,8 +25,8 @@ public class IPRateLimitingFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - if (request instanceof HttpServletRequest) { - HttpServletRequest httpRequest = (HttpServletRequest) request; + if (request instanceof HttpServletRequest httpServletRequest) { + HttpServletRequest httpRequest = httpServletRequest; String method = httpRequest.getMethod(); String requestURI = httpRequest.getRequestURI(); // Check if the request is for static resources diff --git a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java index e8fafda74..714096c61 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java @@ -123,9 +123,11 @@ public class UserAuthenticationFilter extends OncePerRequestFilter { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter() .write( - "Authentication required. Please provide a X-API-KEY in request header.\n" + "Authentication required. Please provide a X-API-KEY in request" + + " header.\n" + "This is found in Settings -> Account Settings -> API Key\n" - + "Alternatively you can disable authentication if this is unexpected"); + + "Alternatively you can disable authentication if this is" + + " unexpected"); return; } } @@ -141,21 +143,21 @@ public class UserAuthenticationFilter extends OncePerRequestFilter { // Extract username and determine the login method Object principal = authentication.getPrincipal(); String username = null; - if (principal instanceof UserDetails) { - username = ((UserDetails) principal).getUsername(); + if (principal instanceof UserDetails detailsUser) { + username = detailsUser.getUsername(); loginMethod = LoginMethod.USERDETAILS; - } else if (principal instanceof OAuth2User) { - username = ((OAuth2User) principal).getName(); + } else if (principal instanceof OAuth2User oAuth2User) { + username = oAuth2User.getName(); loginMethod = LoginMethod.OAUTH2USER; OAUTH2 oAuth = securityProp.getOauth2(); blockRegistration = oAuth != null && oAuth.getBlockRegistration(); - } else if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - username = ((CustomSaml2AuthenticatedPrincipal) principal).name(); + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + username = saml2User.name(); loginMethod = LoginMethod.SAML2USER; SAML2 saml2 = securityProp.getSaml2(); blockRegistration = saml2 != null && saml2.getBlockRegistration(); - } else if (principal instanceof String) { - username = (String) principal; + } else if (principal instanceof String stringUser) { + username = stringUser; loginMethod = LoginMethod.STRINGUSER; } @@ -170,8 +172,8 @@ public class UserAuthenticationFilter extends OncePerRequestFilter { boolean isUserDisabled = userService.isUserDisabled(username); boolean notSsoLogin = - !loginMethod.equals(LoginMethod.OAUTH2USER) - && !loginMethod.equals(LoginMethod.SAML2USER); + !LoginMethod.OAUTH2USER.equals(loginMethod) + && !LoginMethod.SAML2USER.equals(loginMethod); // Block user registration if not allowed by configuration if (blockRegistration && !isUserExists) { diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/src/main/java/stirling/software/SPDF/config/security/UserService.java index e5ecc64e8..61b7c40af 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserService.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserService.java @@ -385,14 +385,14 @@ public class UserService implements UserServiceInterface { for (Object principal : sessionRegistry.getAllPrincipals()) { for (SessionInformation sessionsInformation : sessionRegistry.getAllSessions(principal, false)) { - if (principal instanceof UserDetails userDetails) { - usernameP = userDetails.getUsername(); + if (principal instanceof UserDetails detailsUser) { + usernameP = detailsUser.getUsername(); } else if (principal instanceof OAuth2User oAuth2User) { usernameP = oAuth2User.getName(); } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { usernameP = saml2User.name(); - } else if (principal instanceof String) { - usernameP = (String) principal; + } else if (principal instanceof String stringUser) { + usernameP = stringUser; } if (usernameP.equalsIgnoreCase(username)) { sessionRegistry.expireSession(sessionsInformation.getSessionId()); @@ -404,17 +404,17 @@ public class UserService implements UserServiceInterface { public String getCurrentUsername() { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - if (principal instanceof UserDetails) { - return ((UserDetails) principal).getUsername(); - } else if (principal instanceof OAuth2User) { - return ((OAuth2User) principal) - .getAttribute( - applicationProperties.getSecurity().getOauth2().getUseAsUsername()); - } else if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - return ((CustomSaml2AuthenticatedPrincipal) principal).name(); - } else { - return principal.toString(); + if (principal instanceof UserDetails detailsUser) { + return detailsUser.getUsername(); + } else if (principal instanceof OAuth2User oAuth2User) { + return oAuth2User.getAttribute( + applicationProperties.getSecurity().getOauth2().getUseAsUsername()); + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + return saml2User.name(); + } else if (principal instanceof String stringUser) { + return stringUser; } + return null; } @Transactional diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index be58ac776..9440a6718 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -42,12 +42,12 @@ public class CustomOAuth2AuthenticationFailureHandler getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked"); return; } - if (exception instanceof OAuth2AuthenticationException) { - OAuth2Error error = ((OAuth2AuthenticationException) exception).getError(); + if (exception instanceof OAuth2AuthenticationException oAuth2Exception) { + OAuth2Error error = oAuth2Exception.getError(); String errorCode = error.getErrorCode(); - if (error.getErrorCode().equals("Password must not be null")) { + if ("Password must not be null".equals(error.getErrorCode())) { errorCode = "userAlreadyExistsWeb"; } diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java index b33efd9ca..4ee49aed4 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java @@ -47,10 +47,10 @@ public class CustomOAuth2AuthenticationSuccessHandler Object principal = authentication.getPrincipal(); String username = ""; - if (principal instanceof OAuth2User oauthUser) { - username = oauthUser.getName(); - } else if (principal instanceof UserDetails oauthUser) { - username = oauthUser.getUsername(); + if (principal instanceof OAuth2User oAuth2User) { + username = oAuth2User.getName(); + } else if (principal instanceof UserDetails detailsUser) { + username = detailsUser.getUsername(); } // Get the saved request diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java index 764c9533c..afe83bc7f 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java @@ -230,7 +230,7 @@ public class OAuth2Configuration { // Add existing OAUTH2 Authorities mappedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority())); // Add Authorities from database for existing user, if user is present. - if (authority instanceof OAuth2UserAuthority oauth2Auth) { + if (authority instanceof OAuth2UserAuthority oAuth2Auth) { String useAsUsername = applicationProperties .getSecurity() @@ -238,7 +238,7 @@ public class OAuth2Configuration { .getUseAsUsername(); Optional userOpt = userService.findByUsernameIgnoreCase( - (String) oauth2Auth.getAttributes().get(useAsUsername)); + (String) oAuth2Auth.getAttributes().get(useAsUsername)); if (userOpt.isPresent()) { User user = userOpt.get(); mappedAuthorities.add( diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java b/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java index 6788d6716..354e78750 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java +++ b/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java @@ -40,13 +40,12 @@ public class CertificateUtils { Object object = pemParser.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); - if (object instanceof PEMKeyPair) { + if (object instanceof PEMKeyPair keypair) { // Handle traditional RSA private key format - PEMKeyPair keypair = (PEMKeyPair) object; return (RSAPrivateKey) converter.getPrivateKey(keypair.getPrivateKeyInfo()); - } else if (object instanceof PrivateKeyInfo) { + } else if (object instanceof PrivateKeyInfo keyInfo) { // Handle PKCS#8 format - return (RSAPrivateKey) converter.getPrivateKey((PrivateKeyInfo) object); + return (RSAPrivateKey) converter.getPrivateKey(keyInfo); } else { throw new IllegalArgumentException( "Unsupported key format: " diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java index 04a83f4d8..fbcdb31b4 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java +++ b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java @@ -8,7 +8,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") -public record CustomSaml2AuthenticatedPrincipal(String name, Map> attributes, String nameId, List sessionIndexes) +public record CustomSaml2AuthenticatedPrincipal( + String name, + Map> attributes, + String nameId, + List sessionIndexes) implements Saml2AuthenticatedPrincipal, Serializable { @Override @@ -20,5 +24,4 @@ public record CustomSaml2AuthenticatedPrincipal(String name, Map> getAttributes() { return this.attributes; } - } diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java index b7c2256c4..e4e2d88ca 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java @@ -41,8 +41,8 @@ public class CustomSaml2AuthenticationSuccessHandler Object principal = authentication.getPrincipal(); log.debug("Starting SAML2 authentication success handling"); - if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - String username = ((CustomSaml2AuthenticatedPrincipal) principal).name(); + if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2Principal) { + String username = saml2Principal.name(); log.debug("Authenticated principal found for user: {}", username); HttpSession session = request.getSession(false); diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java b/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java index be3de6f90..18b037164 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java +++ b/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java @@ -43,14 +43,14 @@ public class SessionPersistentRegistry implements SessionRegistry { List sessionInformations = new ArrayList<>(); String principalName = null; - if (principal instanceof UserDetails) { - principalName = ((UserDetails) principal).getUsername(); - } else if (principal instanceof OAuth2User) { - principalName = ((OAuth2User) principal).getName(); - } else if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - principalName = ((CustomSaml2AuthenticatedPrincipal) principal).name(); - } else if (principal instanceof String) { - principalName = (String) principal; + if (principal instanceof UserDetails detailsUser) { + principalName = detailsUser.getUsername(); + } else if (principal instanceof OAuth2User oAuth2User) { + principalName = oAuth2User.getName(); + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + principalName = saml2User.name(); + } else if (principal instanceof String stringUser) { + principalName = stringUser; } if (principalName != null) { @@ -74,14 +74,14 @@ public class SessionPersistentRegistry implements SessionRegistry { public void registerNewSession(String sessionId, Object principal) { String principalName = null; - if (principal instanceof UserDetails) { - principalName = ((UserDetails) principal).getUsername(); - } else if (principal instanceof OAuth2User) { - principalName = ((OAuth2User) principal).getName(); - } else if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - principalName = ((CustomSaml2AuthenticatedPrincipal) principal).name(); - } else if (principal instanceof String) { - principalName = (String) principal; + if (principal instanceof UserDetails detailsUser) { + principalName = detailsUser.getUsername(); + } else if (principal instanceof OAuth2User oAuth2User) { + principalName = oAuth2User.getName(); + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + principalName = saml2User.name(); + } else if (principal instanceof String stringUser) { + principalName = stringUser; } if (principalName != null) { diff --git a/src/main/java/stirling/software/SPDF/controller/api/UserController.java b/src/main/java/stirling/software/SPDF/controller/api/UserController.java index 9af61553c..3a9fd3c23 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/UserController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/UserController.java @@ -297,14 +297,14 @@ public class UserController { for (Object principal : principals) { List sessionsInformation = sessionRegistry.getAllSessions(principal, false); - if (principal instanceof UserDetails) { - userNameP = ((UserDetails) principal).getUsername(); - } else if (principal instanceof OAuth2User) { - userNameP = ((OAuth2User) principal).getName(); - } else if (principal instanceof CustomSaml2AuthenticatedPrincipal) { - userNameP = ((CustomSaml2AuthenticatedPrincipal) principal).name(); - } else if (principal instanceof String) { - userNameP = (String) principal; + if (principal instanceof UserDetails detailsUser) { + userNameP = detailsUser.getUsername(); + } else if (principal instanceof OAuth2User oAuth2User) { + userNameP = oAuth2User.getName(); + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + userNameP = saml2User.name(); + } else if (principal instanceof String stringUser) { + userNameP = stringUser; } if (userNameP.equalsIgnoreCase(username)) { for (SessionInformation sessionInfo : sessionsInformation) { diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java index 4700284cb..50e7032ce 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java @@ -61,8 +61,8 @@ public class AutoSplitPdfController { private static String decodeQRCode(BufferedImage bufferedImage) { LuminanceSource source; - if (bufferedImage.getRaster().getDataBuffer() instanceof DataBufferByte) { - byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); + if (bufferedImage.getRaster().getDataBuffer() instanceof DataBufferByte dataBufferByte) { + byte[] pixels = dataBufferByte.getData(); source = new PlanarYUVLuminanceSource( pixels, @@ -73,8 +73,9 @@ public class AutoSplitPdfController { bufferedImage.getWidth(), bufferedImage.getHeight(), false); - } else if (bufferedImage.getRaster().getDataBuffer() instanceof DataBufferInt) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); + } else if (bufferedImage.getRaster().getDataBuffer() + instanceof DataBufferInt dataBufferInt) { + int[] pixels = dataBufferInt.getData(); byte[] newPixels = new byte[pixels.length]; for (int i = 0; i < pixels.length; i++) { newPixels[i] = (byte) (pixels[i] & 0xff); @@ -91,7 +92,8 @@ public class AutoSplitPdfController { false); } else { throw new IllegalArgumentException( - "BufferedImage must have 8-bit gray scale, 24-bit RGB, 32-bit ARGB (packed int), byte gray, or 3-byte/4-byte RGB image data"); + "BufferedImage must have 8-bit gray scale, 24-bit RGB, 32-bit ARGB (packed" + + " int), byte gray, or 3-byte/4-byte RGB image data"); } BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); @@ -108,7 +110,10 @@ public class AutoSplitPdfController { @Operation( summary = "Auto split PDF pages into separate documents", description = - "This endpoint accepts a PDF file, scans each page for a specific QR code, and splits the document at the QR code boundaries. The output is a zip file containing each separate PDF document. Input:PDF Output:ZIP-PDF Type:SISO") + "This endpoint accepts a PDF file, scans each page for a specific QR code, and" + + " splits the document at the QR code boundaries. The output is a zip file" + + " containing each separate PDF document. Input:PDF Output:ZIP-PDF" + + " Type:SISO") public ResponseEntity autoSplitPdf(@ModelAttribute AutoSplitPdfRequest request) throws IOException { MultipartFile file = request.getFileInput(); diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index 53ef95cdb..f107f67fc 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -63,8 +63,7 @@ public class CompressController { if (res != null && res.getXObjectNames() != null) { for (COSName name : res.getXObjectNames()) { PDXObject xobj = res.getXObject(name); - if (xobj instanceof PDImageXObject) { - PDImageXObject image = (PDImageXObject) xobj; + if (xobj instanceof PDImageXObject image) { BufferedImage bufferedImage = image.getImage(); int newWidth = (int) (bufferedImage.getWidth() * scaleFactor); @@ -119,7 +118,8 @@ public class CompressController { @Operation( summary = "Optimize PDF file", description = - "This endpoint accepts a PDF file and optimizes it based on the provided parameters. Input:PDF Output:PDF Type:SISO") + "This endpoint accepts a PDF file and optimizes it based on the provided" + + " parameters. Input:PDF Output:PDF Type:SISO") public ResponseEntity optimizePdf(@ModelAttribute OptimizePdfRequest request) throws Exception { MultipartFile inputFile = request.getFileInput(); @@ -221,7 +221,8 @@ public class CompressController { // Check if optimized file is larger than the original if (pdfBytes.length > inputFileSize) { log.warn( - "Optimized file is larger than the original. Returning the original file instead."); + "Optimized file is larger than the original. Returning the original file" + + " instead."); finalFile = tempInputFile; } diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java index cc533e4cc..56fe768a0 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java @@ -118,9 +118,8 @@ public class PipelineProcessor { MultiValueMap body = new LinkedMultiValueMap<>(); body.add("fileInput", file); for (Entry entry : parameters.entrySet()) { - if (entry.getValue() instanceof List) { - List list = (List) entry.getValue(); - for (Object item : list) { + if (entry.getValue() instanceof List entryList) { + for (Object item : entryList) { body.add(entry.getKey(), item); } } else { @@ -139,7 +138,7 @@ public class PipelineProcessor { log.info("Skipping file due to filtering {}", operation); continue; } - if (!response.getStatusCode().equals(HttpStatus.OK)) { + if (!HttpStatus.OK.equals(response.getStatusCode())) { logPrintStream.println("Error: " + response.getBody()); hasErrors = true; continue; @@ -180,9 +179,8 @@ public class PipelineProcessor { body.add("fileInput", file); } for (Entry entry : parameters.entrySet()) { - if (entry.getValue() instanceof List) { - List list = (List) entry.getValue(); - for (Object item : list) { + if (entry.getValue() instanceof List entryList) { + for (Object item : entryList) { body.add(entry.getKey(), item); } } else { @@ -191,7 +189,7 @@ public class PipelineProcessor { } ResponseEntity response = sendWebRequest(url, body); // Handle the response - if (response.getStatusCode().equals(HttpStatus.OK)) { + if (HttpStatus.OK.equals(response.getStatusCode())) { processOutputFiles(operation, response, newOutputFiles); } else { // Log error if the response status is not OK diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java index 355755996..3a19e9b60 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java @@ -129,9 +129,9 @@ public class CertSignController { @Operation( summary = "Sign PDF with a Digital Certificate", description = - "This endpoint accepts a PDF file, a digital certificate and related information to sign" - + " the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF" - + " Type:SISO") + "This endpoint accepts a PDF file, a digital certificate and related" + + " information to sign the PDF. It then returns the digitally signed PDF" + + " file. Input:PDF Output:PDF Type:SISO") public ResponseEntity signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request) throws Exception { MultipartFile pdf = request.getFileInput(); @@ -201,17 +201,14 @@ public class CertSignController { Object pemObject = pemParser.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PrivateKeyInfo pkInfo; - if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) { + if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo) { InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray()); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv); - } else if (pemObject instanceof PEMEncryptedKeyPair) { + pkInfo = pkcs8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(decProv); + } else if (pemObject instanceof PEMEncryptedKeyPair pemEncryptedKeyPair) { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray()); - pkInfo = - ((PEMEncryptedKeyPair) pemObject) - .decryptKeyPair(decProv) - .getPrivateKeyInfo(); + pkInfo = pemEncryptedKeyPair.decryptKeyPair(decProv).getPrivateKeyInfo(); } else { pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo(); } diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java index b2bcfb535..1f30bccf8 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java @@ -214,10 +214,7 @@ public class GetInfoOnPDF { ArrayNode attachmentsArray = objectMapper.createArrayNode(); for (PDPage page : pdfBoxDoc.getPages()) { for (PDAnnotation annotation : page.getAnnotations()) { - if (annotation instanceof PDAnnotationFileAttachment) { - PDAnnotationFileAttachment fileAttachmentAnnotation = - (PDAnnotationFileAttachment) annotation; - + if (annotation instanceof PDAnnotationFileAttachment fileAttachmentAnnotation) { ObjectNode attachmentNode = objectMapper.createObjectNode(); attachmentNode.put("Name", fileAttachmentAnnotation.getAttachmentName()); attachmentNode.put("Description", fileAttachmentAnnotation.getContents()); @@ -437,9 +434,7 @@ public class GetInfoOnPDF { for (COSName name : resources.getXObjectNames()) { PDXObject xObject = resources.getXObject(name); - if (xObject instanceof PDImageXObject) { - PDImageXObject image = (PDImageXObject) xObject; - + if (xObject instanceof PDImageXObject image) { ObjectNode imageNode = objectMapper.createObjectNode(); imageNode.put("Width", image.getWidth()); imageNode.put("Height", image.getHeight()); @@ -462,10 +457,8 @@ public class GetInfoOnPDF { Set uniqueURIs = new HashSet<>(); // To store unique URIs for (PDAnnotation annotation : annotations) { - if (annotation instanceof PDAnnotationLink) { - PDAnnotationLink linkAnnotation = (PDAnnotationLink) annotation; - if (linkAnnotation.getAction() instanceof PDActionURI) { - PDActionURI uriAction = (PDActionURI) linkAnnotation.getAction(); + if (annotation instanceof PDAnnotationLink linkAnnotation) { + if (linkAnnotation.getAction() instanceof PDActionURI uriAction) { String uri = uriAction.getURI(); uniqueURIs.add(uri); // Add to set to ensure uniqueness } @@ -541,8 +534,7 @@ public class GetInfoOnPDF { Iterable colorSpaceNames = resources.getColorSpaceNames(); for (COSName name : colorSpaceNames) { PDColorSpace colorSpace = resources.getColorSpace(name); - if (colorSpace instanceof PDICCBased) { - PDICCBased iccBased = (PDICCBased) colorSpace; + if (colorSpace instanceof PDICCBased iccBased) { PDStream iccData = iccBased.getPDStream(); byte[] iccBytes = iccData.toByteArray(); @@ -698,12 +690,10 @@ public class GetInfoOnPDF { ArrayNode elementsArray = objectMapper.createArrayNode(); if (nodes != null) { for (Object obj : nodes) { - if (obj instanceof PDStructureNode) { - PDStructureNode node = (PDStructureNode) obj; + if (obj instanceof PDStructureNode node) { ObjectNode elementNode = objectMapper.createObjectNode(); - if (node instanceof PDStructureElement) { - PDStructureElement structureElement = (PDStructureElement) node; + if (node instanceof PDStructureElement structureElement) { elementNode.put("Type", structureElement.getStructureType()); elementNode.put("Content", getContent(structureElement)); @@ -724,8 +714,7 @@ public class GetInfoOnPDF { StringBuilder contentBuilder = new StringBuilder(); for (Object item : structureElement.getKids()) { - if (item instanceof COSString) { - COSString cosString = (COSString) item; + if (item instanceof COSString cosString) { contentBuilder.append(cosString.getString()); } else if (item instanceof PDStructureElement) { // For simplicity, we're handling only COSString and PDStructureElement here diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java b/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java index bd8904fa2..9b42e23b3 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java @@ -44,7 +44,8 @@ public class SanitizeController { @Operation( summary = "Sanitize a PDF file", description = - "This endpoint processes a PDF file and removes specific elements based on the provided options. Input:PDF Output:PDF Type:SISO") + "This endpoint processes a PDF file and removes specific elements based on the" + + " provided options. Input:PDF Output:PDF Type:SISO") public ResponseEntity sanitizePDF(@ModelAttribute SanitizePdfRequest request) throws IOException { MultipartFile inputFile = request.getFileInput(); @@ -103,8 +104,7 @@ public class SanitizeController { for (PDPage page : document.getPages()) { for (PDAnnotation annotation : page.getAnnotations()) { - if (annotation instanceof PDAnnotationWidget) { - PDAnnotationWidget widget = (PDAnnotationWidget) annotation; + if (annotation instanceof PDAnnotationWidget widget) { PDAction action = widget.getAction(); if (action instanceof PDActionJavaScript) { widget.setAction(null); @@ -157,12 +157,12 @@ public class SanitizeController { private void sanitizeLinks(PDDocument document) throws IOException { for (PDPage page : document.getPages()) { for (PDAnnotation annotation : page.getAnnotations()) { - if (annotation != null && annotation instanceof PDAnnotationLink) { - PDAction action = ((PDAnnotationLink) annotation).getAction(); + if (annotation != null && annotation instanceof PDAnnotationLink linkAnnotation) { + PDAction action = linkAnnotation.getAction(); if (action != null && (action instanceof PDActionLaunch || action instanceof PDActionURI)) { - ((PDAnnotationLink) annotation).setAction(null); + linkAnnotation.setAction(null); } } } diff --git a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java index b979e5184..65e1d055a 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java @@ -123,9 +123,7 @@ public class AccountWebController { String saml2AuthenticationPath = "/saml2/authenticate/" + saml2.getRegistrationId(); if (applicationProperties.getEnterpriseEdition().isSsoAutoLogin()) { - return "redirect:" - + request.getRequestURL() - + saml2AuthenticationPath; + return "redirect:" + request.getRequestURL() + saml2AuthenticationPath; } else { providerList.put(saml2AuthenticationPath, samlIdp + " (SAML 2)"); } @@ -329,21 +327,21 @@ public class AccountWebController { if (authentication == null || !authentication.isAuthenticated()) { return "redirect:/"; } - if (authentication != null && authentication.isAuthenticated()) { + if (authentication.isAuthenticated()) { Object principal = authentication.getPrincipal(); String username = null; // Retrieve username and other attributes and add login attributes to the model - if (principal instanceof UserDetails userDetails) { - username = userDetails.getUsername(); + if (principal instanceof UserDetails detailsUser) { + username = detailsUser.getUsername(); model.addAttribute("oAuth2Login", false); } - if (principal instanceof OAuth2User userDetails) { - username = userDetails.getName(); + if (principal instanceof OAuth2User oAuth2User) { + username = oAuth2User.getName(); model.addAttribute("oAuth2Login", true); } - if (principal instanceof CustomSaml2AuthenticatedPrincipal userDetails) { - username = userDetails.name(); + if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + username = saml2User.name(); model.addAttribute("saml2Login", true); } if (username != null) { @@ -395,10 +393,10 @@ public class AccountWebController { if (authentication == null || !authentication.isAuthenticated()) { return "redirect:/"; } - if (authentication != null && authentication.isAuthenticated()) { + if (authentication.isAuthenticated()) { Object principal = authentication.getPrincipal(); - if (principal instanceof UserDetails userDetails) { - String username = userDetails.getUsername(); + if (principal instanceof UserDetails detailsUser) { + String username = detailsUser.getUsername(); // Fetch user details from the database Optional user = userRepository.findByUsernameIgnoreCase(username); if (user.isEmpty()) { diff --git a/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java b/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java index 8ca61094f..8d8aaf80c 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import lombok.NoArgsConstructor; + import stirling.software.SPDF.model.UsernameAttribute; @NoArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java b/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java index 4cf29c402..a8e65c61e 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import lombok.NoArgsConstructor; + import stirling.software.SPDF.model.UsernameAttribute; @NoArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java b/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java index 6b89e5b1e..bf2725995 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import lombok.NoArgsConstructor; + import stirling.software.SPDF.model.UsernameAttribute; @NoArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/service/CertificateValidationService.java b/src/main/java/stirling/software/SPDF/service/CertificateValidationService.java index 7b4dc6dd8..f8b94f8df 100644 --- a/src/main/java/stirling/software/SPDF/service/CertificateValidationService.java +++ b/src/main/java/stirling/software/SPDF/service/CertificateValidationService.java @@ -84,8 +84,8 @@ public class CertificateValidationService { Enumeration aliases = trustStore.aliases(); while (aliases.hasMoreElements()) { Object trustCert = trustStore.getCertificate(aliases.nextElement()); - if (trustCert instanceof X509Certificate) { - anchors.add(new TrustAnchor((X509Certificate) trustCert, null)); + if (trustCert instanceof X509Certificate x509Cert) { + anchors.add(new TrustAnchor(x509Cert, null)); } } diff --git a/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java b/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java index 8bec891cc..f6a496021 100644 --- a/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java @@ -49,10 +49,10 @@ public class ImageProcessingUtils { public static byte[] getImageData(BufferedImage image) { DataBuffer dataBuffer = image.getRaster().getDataBuffer(); - if (dataBuffer instanceof DataBufferByte) { - return ((DataBufferByte) dataBuffer).getData(); - } else if (dataBuffer instanceof DataBufferInt) { - int[] intData = ((DataBufferInt) dataBuffer).getData(); + if (dataBuffer instanceof DataBufferByte dataBufferByte) { + return dataBufferByte.getData(); + } else if (dataBuffer instanceof DataBufferInt dataBufferInt) { + int[] intData = dataBufferInt.getData(); ByteBuffer byteBuffer = ByteBuffer.allocate(intData.length * 4); byteBuffer.asIntBuffer().put(intData); return byteBuffer.array(); diff --git a/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java b/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java index 904a533d2..37a9f86e6 100644 --- a/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java +++ b/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java @@ -259,4 +259,4 @@ class CustomLogoutSuccessHandlerTest { verify(response).sendRedirect(url + "/login?errorOAuth=" + error); } -} \ No newline at end of file +} diff --git a/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java b/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java index b2efad0b6..986ca55c2 100644 --- a/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java +++ b/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java @@ -21,7 +21,7 @@ public class ConvertWebsiteToPdfTest { @Mock private RuntimePathConfig runtimePathConfig; - + private ConvertWebsiteToPDF convertWebsiteToPDF; @BeforeEach diff --git a/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java b/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java index 57b8f1ba2..1e2b075ac 100644 --- a/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java +++ b/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java @@ -51,4 +51,4 @@ class ValidatorTest { ); } -} \ No newline at end of file +}