Merge pull request #1228 from Stirling-Tools/config

Config
This commit is contained in:
Anthony Stirling 2024-05-19 12:05:47 +01:00 committed by GitHub
commit b5de6a73cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 84 additions and 187 deletions

View file

@ -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

View file

@ -61,12 +61,34 @@ public class ConfigInitializer
List<String> userLines =
Files.exists(userPath) ? Files.readAllLines(userPath) : new ArrayList<>();
Map<String, String> templateEntries = extractEntries(templateLines);
Map<String, String> userEntries = extractEntries(userLines);
List<String> resultLines = new ArrayList<>();
List<String> 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<String, String> extractEntries(List<String> lines) {
Map<String, String> 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<String> resultLines, List<String> 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<String> mergeConfigs(
List<String> templateLines,
Map<String, String> templateEntries,
Map<String, String> userEntries) {
List<String> mergedLines = new ArrayList<>();
Set<String> 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<String> cleanInvalidYamlEntries(List<String> lines) {
List<String> 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<String> 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;
}
}

View file

@ -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="

View file

@ -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'