diff --git a/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java b/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java index b651b8534..f20abfdae 100644 --- a/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java +++ b/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java @@ -6,7 +6,7 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import lombok.extern.slf4j.Slf4j; - +import stirling.software.SPDF.EE.KeygenLicenseVerifier.License; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties.EnterpriseEdition; import stirling.software.SPDF.model.ApplicationProperties.Premium; @@ -27,11 +27,16 @@ public class EEAppConfig { migrateEnterpriseSettingsToPremium(this.applicationProperties); } - @Bean(name = "runningEE") - public boolean runningEnterpriseEdition() { - return licenseKeyChecker.getEnterpriseEnabledResult(); + @Bean(name = "runningProOrHigher") + public boolean runningProOrHigher() { + return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL; } + @Bean(name = "runningEE") + public boolean runningEnterprise() { + return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE; + } + @Bean(name = "SSOAutoLogin") public boolean ssoAutoLogin() { return applicationProperties.getPremium().getProFeatures().isSsoAutoLogin(); diff --git a/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java b/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java index 28e0c7e7e..ba6f2611f 100644 --- a/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java +++ b/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java @@ -25,6 +25,12 @@ import stirling.software.SPDF.utils.GeneralUtils; @Service @Slf4j public class KeygenLicenseVerifier { + + + enum License{ + NORMAL, PRO, ENTERPRISE + + } // License verification configuration private static final String ACCOUNT_ID = "e5430f69-e834-4ae4-befd-b602aae5f372"; private static final String BASE_URL = "https://api.keygen.sh/v1/accounts"; @@ -45,18 +51,25 @@ public class KeygenLicenseVerifier { this.applicationProperties = applicationProperties; } - public boolean verifyLicense(String licenseKeyOrCert) { + public License verifyLicense(String licenseKeyOrCert) { if (isCertificateLicense(licenseKeyOrCert)) { log.info("Detected certificate-based license. Processing..."); - return verifyCertificateLicense(licenseKeyOrCert); + return resultToEnum(verifyCertificateLicense(licenseKeyOrCert), License.ENTERPRISE); } else if (isJWTLicense(licenseKeyOrCert)) { log.info("Detected JWT-style license key. Processing..."); - return verifyJWTLicense(licenseKeyOrCert); + return resultToEnum( verifyJWTLicense(licenseKeyOrCert), License.ENTERPRISE); } else { log.info("Detected standard license key. Processing..."); - return verifyStandardLicense(licenseKeyOrCert); + return resultToEnum( verifyStandardLicense(licenseKeyOrCert), License.PRO); } } + + private License resultToEnum(boolean result, License option) { + if(result) { + return option; + } + return License.NORMAL; + } private boolean isCertificateLicense(String license) { return license != null && license.trim().startsWith(CERT_PREFIX); diff --git a/src/main/java/stirling/software/SPDF/EE/LicenseKeyChecker.java b/src/main/java/stirling/software/SPDF/EE/LicenseKeyChecker.java index d29351125..26ed6a7ff 100644 --- a/src/main/java/stirling/software/SPDF/EE/LicenseKeyChecker.java +++ b/src/main/java/stirling/software/SPDF/EE/LicenseKeyChecker.java @@ -10,7 +10,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; - +import stirling.software.SPDF.EE.KeygenLicenseVerifier.License; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.utils.GeneralUtils; @@ -24,7 +24,7 @@ public class LicenseKeyChecker { private final ApplicationProperties applicationProperties; - private boolean premiumEnabledResult = false; + private License premiumEnabledResult = License.NORMAL; @Autowired public LicenseKeyChecker( @@ -41,19 +41,21 @@ public class LicenseKeyChecker { private void checkLicense() { if (!applicationProperties.getPremium().isEnabled()) { - premiumEnabledResult = false; + premiumEnabledResult = License.NORMAL; } else { String licenseKey = getLicenseKeyContent(applicationProperties.getPremium().getKey()); if (licenseKey != null) { premiumEnabledResult = licenseService.verifyLicense(licenseKey); - if (premiumEnabledResult) { - log.info("License key is valid."); + if (License.ENTERPRISE == premiumEnabledResult) { + log.info("License key is Enterprise."); + } else if(License.PRO == premiumEnabledResult){ + log.info("License key is Pro."); } else { - log.info("License key is invalid."); + log.info("License key is invalid, defaulting to non pro license."); } } else { log.error("Failed to obtain license key content."); - premiumEnabledResult = false; + premiumEnabledResult = License.NORMAL; } } } @@ -91,7 +93,7 @@ public class LicenseKeyChecker { checkLicense(); } - public boolean getEnterpriseEnabledResult() { + public License getPremiumLicenseEnabledResult() { return premiumEnabledResult; } } diff --git a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java index e92466534..acd3c9e45 100644 --- a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java @@ -23,14 +23,14 @@ public class EndpointConfiguration { private final ApplicationProperties applicationProperties; private Map endpointStatuses = new ConcurrentHashMap<>(); private Map> endpointGroups = new ConcurrentHashMap<>(); - private final boolean runningEE; + private final boolean runningProOrHigher; @Autowired public EndpointConfiguration( ApplicationProperties applicationProperties, - @Qualifier("runningEE") boolean runningEE) { + @Qualifier("runningProOrHigher") boolean runningProOrHigher) { this.applicationProperties = applicationProperties; - this.runningEE = runningEE; + this.runningProOrHigher = runningProOrHigher; init(); processEnvironmentConfigs(); } @@ -286,7 +286,7 @@ public class EndpointConfiguration { } } } - if (!runningEE) { + if (!runningProOrHigher) { disableGroup("enterprise"); } diff --git a/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java b/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java index e0534b999..040e0e070 100644 --- a/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java +++ b/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java @@ -14,10 +14,10 @@ import jakarta.servlet.http.HttpServletResponse; @Component public class EnterpriseEndpointFilter extends OncePerRequestFilter { - private final boolean runningEE; + private final boolean runningProOrHigher; - public EnterpriseEndpointFilter(@Qualifier("runningEE") boolean runningEE) { - this.runningEE = runningEE; + public EnterpriseEndpointFilter(@Qualifier("runningProOrHigher") boolean runningProOrHigher) { + this.runningProOrHigher = runningProOrHigher; } @Override @@ -25,7 +25,7 @@ public class EnterpriseEndpointFilter extends OncePerRequestFilter { HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - if (!runningEE && isPrometheusEndpointRequest(request)) { + if (!runningProOrHigher && isPrometheusEndpointRequest(request)) { response.setStatus(HttpStatus.NOT_FOUND.value()); return; } diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 289071b03..a4c10d1ae 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -46,13 +46,13 @@ import stirling.software.SPDF.repository.PersistentLoginRepository; @EnableWebSecurity @EnableMethodSecurity @Slf4j -@DependsOn("runningEE") +@DependsOn("runningProOrHigher") public class SecurityConfiguration { private final CustomUserDetailsService userDetailsService; private final UserService userService; private final boolean loginEnabledValue; - private final boolean runningEE; + private final boolean runningProOrHigher; private final ApplicationProperties applicationProperties; private final UserAuthenticationFilter userAuthenticationFilter; @@ -69,7 +69,7 @@ public class SecurityConfiguration { CustomUserDetailsService userDetailsService, @Lazy UserService userService, @Qualifier("loginEnabled") boolean loginEnabledValue, - @Qualifier("runningEE") boolean runningEE, + @Qualifier("runningProOrHigher") boolean runningProOrHigher, ApplicationProperties applicationProperties, UserAuthenticationFilter userAuthenticationFilter, LoginAttemptService loginAttemptService, @@ -83,7 +83,7 @@ public class SecurityConfiguration { this.userDetailsService = userDetailsService; this.userService = userService; this.loginEnabledValue = loginEnabledValue; - this.runningEE = runningEE; + this.runningProOrHigher = runningProOrHigher; this.applicationProperties = applicationProperties; this.userAuthenticationFilter = userAuthenticationFilter; this.loginAttemptService = loginAttemptService; @@ -254,7 +254,7 @@ public class SecurityConfiguration { .permitAll()); } // Handle SAML - if (applicationProperties.getSecurity().isSaml2Active() && runningEE) { + if (applicationProperties.getSecurity().isSaml2Active() && runningProOrHigher) { // Configure the authentication provider OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider(); diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java index ba4a02f00..d221704ea 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java +++ b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java @@ -27,18 +27,18 @@ public class DatabaseConfig { public static final String POSTGRES_DRIVER = "org.postgresql.Driver"; private final ApplicationProperties applicationProperties; - private final boolean runningEE; + private final boolean runningProOrHigher; public DatabaseConfig( ApplicationProperties applicationProperties, - @Qualifier("runningEE") boolean runningEE) { + @Qualifier("runningProOrHigher") boolean runningProOrHigher) { DATASOURCE_DEFAULT_URL = "jdbc:h2:file:" + InstallationPathConfig.getConfigPath() + "stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"; log.debug("Database URL: {}", DATASOURCE_DEFAULT_URL); this.applicationProperties = applicationProperties; - this.runningEE = runningEE; + this.runningProOrHigher = runningProOrHigher; } /** @@ -54,7 +54,7 @@ public class DatabaseConfig { public DataSource dataSource() throws UnsupportedProviderException { DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); - if (!runningEE) { + if (!runningProOrHigher) { return useDefaultDataSource(dataSourceBuilder); } 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 93e98d032..94586d060 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java @@ -12,6 +12,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; @@ -56,14 +57,15 @@ public class AccountWebController { private final SessionPersistentRegistry sessionPersistentRegistry; // Assuming you have a repository for user operations private final UserRepository userRepository; - + private final boolean runningEE; public AccountWebController( ApplicationProperties applicationProperties, SessionPersistentRegistry sessionPersistentRegistry, - UserRepository userRepository) { + UserRepository userRepository, @Qualifier("runningEE") boolean runningEE) { this.applicationProperties = applicationProperties; this.sessionPersistentRegistry = sessionPersistentRegistry; this.userRepository = userRepository; + this.runningEE = runningEE; } @GetMapping("/login") @@ -197,6 +199,9 @@ public class AccountWebController { @PreAuthorize("hasRole('ROLE_ADMIN')") @GetMapping("/usage") public String showUsage() { + if(!runningEE) { + return "error"; + } return "usage"; } @@ -325,7 +330,7 @@ public class AccountWebController { model.addAttribute("activeUsers", activeUsers); model.addAttribute("disabledUsers", disabledUsers); - model.addAttribute("maxEnterpriseUsers", applicationProperties.getPremium().getMaxUsers()); + model.addAttribute("maxPaidUsers", applicationProperties.getPremium().getMaxUsers()); return "adminSettings"; } diff --git a/src/main/java/stirling/software/SPDF/service/PdfMetadataService.java b/src/main/java/stirling/software/SPDF/service/PdfMetadataService.java index 9586ad341..173de33f4 100644 --- a/src/main/java/stirling/software/SPDF/service/PdfMetadataService.java +++ b/src/main/java/stirling/software/SPDF/service/PdfMetadataService.java @@ -17,18 +17,18 @@ public class PdfMetadataService { private final ApplicationProperties applicationProperties; private final String stirlingPDFLabel; private final UserServiceInterface userService; - private final boolean runningEE; + private final boolean runningProOrHigher; @Autowired public PdfMetadataService( ApplicationProperties applicationProperties, @Qualifier("StirlingPDFLabel") String stirlingPDFLabel, - @Qualifier("runningEE") boolean runningEE, + @Qualifier("runningProOrHigher") boolean runningProOrHigher, @Autowired(required = false) UserServiceInterface userService) { this.applicationProperties = applicationProperties; this.stirlingPDFLabel = stirlingPDFLabel; this.userService = userService; - this.runningEE = runningEE; + this.runningProOrHigher = runningProOrHigher; } public PdfMetadata extractMetadataFromPdf(PDDocument pdf) { @@ -69,7 +69,7 @@ public class PdfMetadataService { .getProFeatures() .getCustomMetadata() .isAutoUpdateMetadata() - && runningEE) { + && runningProOrHigher) { creator = applicationProperties @@ -98,7 +98,7 @@ public class PdfMetadataService { .getProFeatures() .getCustomMetadata() .isAutoUpdateMetadata() - && runningEE) { + && runningProOrHigher) { author = applicationProperties .getPremium() diff --git a/src/main/resources/templates/adminSettings.html b/src/main/resources/templates/adminSettings.html index ecd9defd7..da4d16c1c 100644 --- a/src/main/resources/templates/adminSettings.html +++ b/src/main/resources/templates/adminSettings.html @@ -34,10 +34,10 @@
+ th:data-bs-toggle="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : 'modal'" + th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'" + th:class="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'" + th:title="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}"> person_add Add New User @@ -51,7 +51,7 @@ Change User's Role - analytics @@ -61,7 +61,7 @@
Total Users: - + Active Users: @@ -126,7 +126,7 @@
-

+