From fa746a2b518b55310d4b62b95b06b8df3cdf7551 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com.> Date: Sun, 19 May 2024 11:54:45 +0100 Subject: [PATCH 1/2] config stuff --- .../SPDF/config/ConfigInitializer.java | 180 ++++++------------ 1 file changed, 58 insertions(+), 122 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java index 394baeb1..e82e8f3f 100644 --- a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java +++ b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java @@ -61,12 +61,34 @@ public class ConfigInitializer List userLines = Files.exists(userPath) ? Files.readAllLines(userPath) : new ArrayList<>(); - Map templateEntries = extractEntries(templateLines); - Map userEntries = extractEntries(userLines); + List resultLines = new ArrayList<>(); - List mergedLines = mergeConfigs(templateLines, templateEntries, userEntries); - mergedLines = cleanInvalidYamlEntries(mergedLines); - Files.write(userPath, mergedLines); + for (String templateLine : templateLines) { + // Check if the line is a comment + if (templateLine.trim().startsWith("#")) { + String entry = templateLine.trim().substring(1).trim(); + if (!entry.isEmpty()) { + // Check if this comment has been uncommented in userLines + String key = entry.split(":")[0].trim(); + System.out.println("key=" + key + ", entry=" + entry ); + addLine(resultLines, userLines, templateLine, key); + } else { + resultLines.add(templateLine); + } + } + // Check if the line is a key-value pair + else if (templateLine.contains(":")) { + String key = templateLine.split(":")[0].trim(); + addLine(resultLines, userLines, templateLine, key); + } + // Handle empty lines + else if (templateLine.trim().length() == 0) { + resultLines.add(""); + } + } + + // Write the result to the user settings file + Files.write(userPath, resultLines); } Path customSettingsPath = Paths.get("configs", "custom_settings.yml"); @@ -74,129 +96,43 @@ public class ConfigInitializer Files.createFile(customSettingsPath); } } - - private static Map extractEntries(List lines) { - Map entries = new HashMap<>(); - StringBuilder currentEntry = new StringBuilder(); - String currentKey = null; - int blockIndent = -1; - - for (String line : lines) { - if (line.trim().isEmpty()) { - if (currentKey != null) { - currentEntry.append(line).append("\n"); + + + + //TODO check parent value instead of just indent lines for duplicate keys (like enabled etc) + private static void addLine(List resultLines, List userLines, String templateLine, String key) { + boolean added = false; + int templateIndentationLevel = getIndentationLevel(templateLine); + for (String settingsLine : userLines) { + if(settingsLine.contains("oauth2") || settingsLine.contains("enabled") ) + if (settingsLine.trim().startsWith(key + ":")) { + int settingsIndentationLevel = getIndentationLevel(settingsLine); + // Check if it is correct settingsLine and has the same parent as templateLine + if (settingsIndentationLevel == templateIndentationLevel) { + resultLines.add(settingsLine); + added = true; + break; } - continue; - } - - int indentLevel = getIndentationLevel(line); - if (line.trim().startsWith("#")) { - if (indentLevel <= blockIndent || blockIndent == -1) { - if (currentKey != null) { - entries.put(currentKey, currentEntry.toString().trim()); - currentEntry = new StringBuilder(); - } - currentKey = line.trim().replaceAll("#", "").split(":")[0].trim(); - blockIndent = indentLevel; - } - currentEntry.append(line).append("\n"); - } else if (indentLevel == 0 || indentLevel <= blockIndent) { - if (currentKey != null) { - entries.put(currentKey, currentEntry.toString().trim()); - currentEntry = new StringBuilder(); - } - currentKey = line.split(":")[0].trim(); - blockIndent = indentLevel; - currentEntry.append(line).append("\n"); - } else { - currentEntry.append(line).append("\n"); } } - - if (currentKey != null) { - entries.put(currentKey, currentEntry.toString().trim()); + if (!added) { + resultLines.add(templateLine); } - - return entries; - } - - private static List mergeConfigs( - List templateLines, - Map templateEntries, - Map userEntries) { - List mergedLines = new ArrayList<>(); - Set handledKeys = new HashSet<>(); - - String currentBlockKey = null; - int blockIndent = -1; - - for (String line : templateLines) { - if (line.trim().isEmpty()) { - mergedLines.add(line); - continue; - } - - int indentLevel = getIndentationLevel(line); - if (indentLevel == 0 || (indentLevel <= blockIndent && !line.trim().startsWith("#"))) { - currentBlockKey = line.split(":")[0].trim(); - blockIndent = indentLevel; - } - - if (userEntries.containsKey(currentBlockKey) - && !handledKeys.contains(currentBlockKey)) { - mergedLines.add(userEntries.get(currentBlockKey)); - handledKeys.add(currentBlockKey); - } else if (!handledKeys.contains(currentBlockKey)) { - mergedLines.add(line); - } - } - - return mergedLines; - } - - private static List cleanInvalidYamlEntries(List lines) { - List cleanedLines = new ArrayList<>(); - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - String trimmedLine = line.trim(); - - if (trimmedLine.startsWith("#") - || !trimmedLine.endsWith(":") - || trimmedLine.contains(" ")) { - cleanedLines.add(line); - continue; - } - - if (isKeyWithoutChildrenOrValue(i, lines)) { - continue; - } - - cleanedLines.add(line); - } - return cleanedLines; - } - - private static boolean isKeyWithoutChildrenOrValue(int currentIndex, List lines) { - if (currentIndex + 1 < lines.size()) { - String currentLine = lines.get(currentIndex); - String nextLine = lines.get(currentIndex + 1); - int currentIndentation = getIndentationLevel(currentLine); - int nextIndentation = getIndentationLevel(nextLine); - - // If the next line is less or equally indented, it's not a child or value - return nextIndentation <= currentIndentation; - } - - // If it's the last line, then it definitely has no children or value - return true; - } + } private static int getIndentationLevel(String line) { - int count = 0; - for (char ch : line.toCharArray()) { - if (ch == ' ') count++; - else break; + int indentationLevel = 0; + String trimmedLine = line.trim(); + if (trimmedLine.startsWith("#")) { + line = trimmedLine.substring(1); } - return count; + for (char c : line.toCharArray()) { + if (c == ' ') { + indentationLevel++; + } else { + break; + } + } + return indentationLevel; } } From 45e2623b9bcb7b88a179553535b82929293bc18b Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com.> Date: Sun, 19 May 2024 12:00:46 +0100 Subject: [PATCH 2/2] change configs --- README.md | 32 ++++++++----------- .../SPDF/model/ApplicationProperties.java | 32 +------------------ src/main/resources/settings.yml.template | 27 +++++++--------- 3 files changed, 26 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 50928630..9895e206 100644 --- a/README.md +++ b/README.md @@ -222,28 +222,25 @@ The Current list of settings is ```yaml security: enableLogin: false # set to 'true' to enable login - csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production) + csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production) loginAttemptCount: 5 # lock user account after 5 tries loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts - # initialLogin: - # username: "admin" # Initial username for the first login - # password: "stirling" # Initial password for the first login - # oauth2: - # enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work) - # issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point - # clientId: "" # Client ID from your provider - # clientSecret: "" # Client Secret from your provider - # autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users - # useAsUsername: "email" # Default is 'email'; custom fields can be used as the username - # scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions - # provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' +# initialLogin: +# username: "admin" # Initial username for the first login (these are defaulted) +# password: "stirling" # Initial password for the first login +# oauth2: +# enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work) +# issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point +# clientId: "" # Client ID from your provider +# clientSecret: "" # Client Secret from your provider +# autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users +# useAsUsername: "email" # Default is 'email'; custom fields can be used as the username +# scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions +# provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' system: defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow - rootURIPath: '/pdf-app' # ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app - customStaticFilePath: '/customFiles/static/' # Customise static files (e.g., logo, images, CSS) by placing them in this directory. - maxFileSize: 10485760 # Maximum file size for uploads in bytes. enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes) showUpdate: true # see when a new update is available showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true' @@ -260,9 +257,6 @@ endpoints: metrics: enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable - -autoPipeline: - outputFolder: /output # Directory for auto-pipeline outputs. ``` There is an additional config file ``/configs/custom_settings.yml`` were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 2623d8f8..ae96d07b 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -327,9 +327,6 @@ public class ApplicationProperties { public static class System { private String defaultLocale; private Boolean googlevisibility; - private String rootURIPath; - private String customStaticFilePath; - private Integer maxFileSize; private boolean showUpdate; private Boolean showUpdateOnlyAdmin; private boolean customHTMLFiles; @@ -384,29 +381,8 @@ public class ApplicationProperties { this.googlevisibility = googlevisibility; } - public String getRootURIPath() { - return rootURIPath; - } + - public void setRootURIPath(String rootURIPath) { - this.rootURIPath = rootURIPath; - } - - public String getCustomStaticFilePath() { - return customStaticFilePath; - } - - public void setCustomStaticFilePath(String customStaticFilePath) { - this.customStaticFilePath = customStaticFilePath; - } - - public Integer getMaxFileSize() { - return maxFileSize; - } - - public void setMaxFileSize(Integer maxFileSize) { - this.maxFileSize = maxFileSize; - } @Override public String toString() { @@ -414,12 +390,6 @@ public class ApplicationProperties { + defaultLocale + ", googlevisibility=" + googlevisibility - + ", rootURIPath=" - + rootURIPath - + ", customStaticFilePath=" - + customStaticFilePath - + ", maxFileSize=" - + maxFileSize + ", enableAlphaFunctionality=" + enableAlphaFunctionality + ", showUpdate=" diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index d504e82e..d771f9c9 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -7,25 +7,22 @@ security: csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production) loginAttemptCount: 5 # lock user account after 5 tries loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts - # initialLogin: - # username: "admin" # Initial username for the first login - # password: "stirling" # Initial password for the first login - # oauth2: - # enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work) - # issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point - # clientId: "" # Client ID from your provider - # clientSecret: "" # Client Secret from your provider - # autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users - # useAsUsername: "email" # Default is 'email'; custom fields can be used as the username - # scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions - # provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' +# initialLogin: +# username: "admin" # Initial username for the first login +# password: "stirling" # Initial password for the first login +# oauth2: +# enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work) +# issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point +# clientId: "" # Client ID from your provider +# clientSecret: "" # Client Secret from your provider +# autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users +# useAsUsername: "email" # Default is 'email'; custom fields can be used as the username +# scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions +# provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' system: defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow - rootURIPath: '/pdf-app' # ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app - customStaticFilePath: '/customFiles/static/' # Customise static files (e.g., logo, images, CSS) by placing them in this directory. - maxFileSize: 10485760 # Maximum file size for uploads in bytes. enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes) showUpdate: true # see when a new update is available showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'