diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/LicenseBeanConfig.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/LicenseBeanConfig.java new file mode 100644 index 00000000..c3a0fb02 --- /dev/null +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/LicenseBeanConfig.java @@ -0,0 +1,68 @@ +package com.cameleer3.server.app.config; + +import com.cameleer3.server.core.license.LicenseGate; +import com.cameleer3.server.core.license.LicenseInfo; +import com.cameleer3.server.core.license.LicenseValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.nio.file.Files; +import java.nio.file.Path; + +@Configuration +public class LicenseBeanConfig { + + private static final Logger log = LoggerFactory.getLogger(LicenseBeanConfig.class); + + @Value("${license.token:}") + private String licenseToken; + + @Value("${license.file:}") + private String licenseFile; + + @Value("${license.public-key:}") + private String licensePublicKey; + + @Bean + public LicenseGate licenseGate() { + LicenseGate gate = new LicenseGate(); + + String token = resolveLicenseToken(); + if (token == null || token.isBlank()) { + log.info("No license configured — running in open mode (all features enabled)"); + return gate; + } + + if (licensePublicKey == null || licensePublicKey.isBlank()) { + log.warn("License token provided but no public key configured (CAMELEER_LICENSE_PUBLIC_KEY). Running in open mode."); + return gate; + } + + try { + LicenseValidator validator = new LicenseValidator(licensePublicKey); + LicenseInfo info = validator.validate(token); + gate.load(info); + } catch (Exception e) { + log.error("Failed to validate license: {}. Running in open mode.", e.getMessage()); + } + + return gate; + } + + private String resolveLicenseToken() { + if (licenseToken != null && !licenseToken.isBlank()) { + return licenseToken; + } + if (licenseFile != null && !licenseFile.isBlank()) { + try { + return Files.readString(Path.of(licenseFile)).trim(); + } catch (Exception e) { + log.warn("Failed to read license file {}: {}", licenseFile, e.getMessage()); + } + } + return null; + } +} diff --git a/cameleer3-server-app/src/main/resources/application.yml b/cameleer3-server-app/src/main/resources/application.yml index f4c1c28d..e3b58c04 100644 --- a/cameleer3-server-app/src/main/resources/application.yml +++ b/cameleer3-server-app/src/main/resources/application.yml @@ -41,6 +41,11 @@ cameleer: debounce-ms: ${CAMELEER_INDEXER_DEBOUNCE_MS:2000} queue-size: ${CAMELEER_INDEXER_QUEUE_SIZE:10000} +license: + token: ${CAMELEER_LICENSE_TOKEN:} + file: ${CAMELEER_LICENSE_FILE:} + public-key: ${CAMELEER_LICENSE_PUBLIC_KEY:} + security: access-token-expiry-ms: 3600000 refresh-token-expiry-ms: 604800000