Skip to content

Commit

Permalink
Move preferences to ArgValue's (qzind#1164)
Browse files Browse the repository at this point in the history
Move preferences to ArgValue's
  • Loading branch information
tresf authored Aug 11, 2023
1 parent e1e0593 commit 95db68d
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 125 deletions.
7 changes: 3 additions & 4 deletions src/qz/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,12 @@ private static void setupFileLogging() {
System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
System.setProperty("org.eclipse.jetty.LEVEL", "OFF");

Properties app = CertificateManager.loadProperties();
if(PrefsSearch.get(app, Constants.PREFS_LOG_DISABLE, false)) {
if(PrefsSearch.getBoolean(ArgValue.LOG_DISABLE)) {
return;
}

int logSize = PrefsSearch.get(app, Constants.PREFS_LOG_SIZE, Constants.DEFAULT_LOG_SIZE);
int logRotate = PrefsSearch.get(app, Constants.PREFS_LOG_ROTATE, Constants.DEFAULT_LOG_ROTATIONS);
int logSize = PrefsSearch.getInt(ArgValue.LOG_SIZE);
int logRotate = PrefsSearch.getInt(ArgValue.LOG_ROTATE);
RollingFileAppender fileAppender = RollingFileAppender.newBuilder()
.setName("log-file")
.withAppend(true)
Expand Down
11 changes: 3 additions & 8 deletions src/qz/auth/Certificate.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
import org.apache.logging.log4j.Logger;
import qz.App;
import qz.common.Constants;
import qz.utils.ByteUtilities;
import qz.utils.FileUtilities;
import qz.utils.SystemUtilities;
import qz.utils.*;

import java.io.*;
import java.nio.file.Files;
Expand Down Expand Up @@ -139,15 +137,12 @@ public enum Algorithm {

public static void scanAdditionalCAs() {
ArrayList<Map.Entry<Path, String>> certPaths = new ArrayList<>();
// First, look for "-DtrustedRootCert" command line property
certPaths.addAll(FileUtilities.parseDelimitedPaths(System.getProperty(Constants.PREFS_OVERRIDE_CA_CLI)));
// First, look for "authcert.override", "-DtrustedRootCert"
certPaths.addAll(FileUtilities.parseDelimitedPaths(PrefsSearch.getString(ArgValue.AUTHCERT_OVERRIDE, App.getTrayProperties())));

// Second, look for "override.crt" within App directory
certPaths.add(new AbstractMap.SimpleEntry<>(SystemUtilities.getJarParentPath().resolve(Constants.OVERRIDE_CERT), QUIETLY_FAIL));

// Third, look for "authcert.override" property in qz-tray.properties
certPaths.addAll(FileUtilities.parseDelimitedPaths(App.getTrayProperties(), Constants.PREFS_OVERRIDE_CA));

for(Map.Entry<Path, String> certPath : certPaths) {
if(certPath.getKey() != null) {
if (certPath.getKey().toFile().exists()) {
Expand Down
22 changes: 1 addition & 21 deletions src/qz/common/Constants.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package qz.common;

import com.github.zafarkhaja.semver.Version;
import qz.utils.ArgValue;
import qz.utils.SystemUtilities;

import java.awt.*;
Expand Down Expand Up @@ -28,8 +29,6 @@ public class Constants {
public static final String[] PERSIST_PROPS = {"file.whitelist", "file.allow", "networking.hostname", "networking.port", STEAL_WEBSOCKET_PROPERTY };
public static final String AUTOSTART_FILE = ".autostart";
public static final String DATA_DIR = "qz";
public static final int DEFAULT_LOG_SIZE = 524288;
public static final int DEFAULT_LOG_ROTATIONS = 5;

public static final int BORDER_PADDING = 10;

Expand Down Expand Up @@ -59,25 +58,6 @@ public class Constants {
public static final String PROBE_REQUEST = "getProgramName";
public static final String PROBE_RESPONSE = ABOUT_TITLE;

public static final String PREFS_NOTIFICATIONS = "tray.notifications";
public static final String PREFS_HEADLESS = "tray.headless";
public static final String PREFS_MONOCLE = "tray.monocle";
public static final String PREFS_STRICT_MODE = "tray.strictmode";
public static final String PREFS_IDLE_PRINTERS = "tray.idle.printers";
public static final String PREFS_IDLE_JFX = "tray.idle.javafx";

public static final String PREFS_FILEIO_ENABLED = "security.file.enabled";
public static final String PREFS_FILEIO_STRICT = "security.file.strict";

public static final String PREFS_LOG_DISABLE = "log.disable";
public static final String PREFS_LOG_ROTATE = "log.rotate";
public static final String PREFS_LOG_SIZE = "log.size";

public static final String PREFS_OVERRIDE_CA = "authcert.override";
public static final String PREFS_OVERRIDE_CA_CLI = "trustedRootCert";

public static final String PREFS_PRINTER_JOB_DATA = "printer.status.jobdata";

public static final String ALLOW_SITES_TEXT = "Permanently allowed \"%s\" to access local resources";
public static final String BLOCK_SITES_TEXT = "Permanently blocked \"%s\" from accessing local resources";

Expand Down
5 changes: 3 additions & 2 deletions src/qz/common/PropertyHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import qz.utils.ArgValue;

import java.io.File;
import java.io.FileInputStream;
Expand Down Expand Up @@ -53,8 +54,8 @@ public boolean getBoolean(String key, boolean defaultVal) {
}
}

public void setProperty(String key, boolean value) {
setProperty(key, "" + value);
public void setProperty(ArgValue arg, boolean value) {
setProperty(arg.getMatch(), "" + value);
}

public void load(File file) {
Expand Down
31 changes: 16 additions & 15 deletions src/qz/common/TrayManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.concurrent.TimeUnit;

import static qz.ui.component.IconCache.Icon.*;
import static qz.utils.ArgValue.*;

/**
* Manages the icons and actions associated with the TrayIcon
Expand Down Expand Up @@ -95,14 +96,14 @@ public TrayManager(boolean isHeadless) {
prefs = new PropertyHelper(FileUtilities.USER_DIR + File.separator + Constants.PREFS_FILE + ".properties");

// Set strict certificate mode preference
Certificate.setTrustBuiltIn(!getPref(Constants.PREFS_STRICT_MODE, false));
Certificate.setTrustBuiltIn(!getPref(TRAY_STRICTMODE));

// Set FileIO security
FileUtilities.setFileIoEnabled(getPref(Constants.PREFS_FILEIO_ENABLED, true));
FileUtilities.setFileIoStrict(getPref(Constants.PREFS_FILEIO_STRICT, false));
FileUtilities.setFileIoEnabled(getPref(SECURITY_FILE_ENABLED));
FileUtilities.setFileIoStrict(getPref(SECURITY_FILE_STRICT));

// Headless if turned on by user or unsupported by environment
headless = isHeadless || getPref(Constants.PREFS_HEADLESS, false) || GraphicsEnvironment.isHeadless();
headless = isHeadless || getPref(HEADLESS) || GraphicsEnvironment.isHeadless();
if (headless) {
log.info("Running in headless mode");
}
Expand Down Expand Up @@ -207,7 +208,7 @@ public TrayManager(boolean isHeadless) {

// Initialize idle actions
// Slow to start JavaFX the first time
if (getPref(Constants.PREFS_IDLE_JFX, true)) {
if (getPref(TRAY_IDLE_JAVAFX)) {
performIfIdle((int)TimeUnit.SECONDS.toMillis(60), evt -> {
log.debug("IDLE: Starting up JFX for HTML printing");
try {
Expand All @@ -220,7 +221,7 @@ public TrayManager(boolean isHeadless) {
}
// Slow to find printers the first time if a lot of printers are installed
// Must run after JavaFX per https://github.com/qzind/tray/issues/924
if (getPref(Constants.PREFS_IDLE_PRINTERS, true)) {
if (getPref(TRAY_IDLE_PRINTERS)) {
performIfIdle((int)TimeUnit.SECONDS.toMillis(120), evt -> {
log.debug("IDLE: Performing first run of find printers");
PrintServiceMatcher.getNativePrinterList(false, true);
Expand Down Expand Up @@ -279,14 +280,14 @@ private void addMenuItems() {
JCheckBoxMenuItem notificationsItem = new JCheckBoxMenuItem("Show all notifications");
notificationsItem.setToolTipText("Shows all connect/disconnect messages, useful for debugging purposes");
notificationsItem.setMnemonic(KeyEvent.VK_S);
notificationsItem.setState(getPref(Constants.PREFS_NOTIFICATIONS, false));
notificationsItem.setState(getPref(TRAY_NOTIFICATIONS));
notificationsItem.addActionListener(notificationsListener);
diagnosticMenu.add(notificationsItem);

JCheckBoxMenuItem monocleItem = new JCheckBoxMenuItem("Use Monocle for HTML");
monocleItem.setToolTipText("Use monocle platform for HTML printing (restart required)");
monocleItem.setMnemonic(KeyEvent.VK_U);
monocleItem.setState(getPref(Constants.PREFS_MONOCLE, true));
monocleItem.setState(getPref(TRAY_MONOCLE));
if(!SystemUtilities.hasMonocle()) {
log.warn("Monocle engine was not detected");
monocleItem.setEnabled(false);
Expand Down Expand Up @@ -378,15 +379,15 @@ private void addMenuItems() {
private final ActionListener notificationsListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
prefs.setProperty(Constants.PREFS_NOTIFICATIONS, ((JCheckBoxMenuItem)e.getSource()).getState());
prefs.setProperty(TRAY_NOTIFICATIONS, ((JCheckBoxMenuItem)e.getSource()).getState());
}
};

private final ActionListener monocleListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JCheckBoxMenuItem j = (JCheckBoxMenuItem)e.getSource();
prefs.setProperty(Constants.PREFS_MONOCLE, j.getState());
prefs.setProperty(TRAY_MONOCLE, j.getState());
displayWarningMessage(String.format("A restart of %s is required to ensure this feature is %sabled.",
Constants.ABOUT_TITLE, j.getState()? "en":"dis"));
}
Expand Down Expand Up @@ -470,7 +471,7 @@ public void actionPerformed(ActionEvent e) {

private final ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean showAllNotifications = getPref(Constants.PREFS_NOTIFICATIONS, false);
boolean showAllNotifications = getPref(TRAY_NOTIFICATIONS);
if (!showAllNotifications || confirmDialog.prompt("Exit " + name + "?")) { exit(0); }
}
};
Expand Down Expand Up @@ -620,7 +621,7 @@ private void displayMessage(final String caption, final String text, final TrayI
if (!headless) {
if (tray != null) {
SwingUtilities.invokeLater(() -> {
boolean showAllNotifications = getPref(Constants.PREFS_NOTIFICATIONS, false);
boolean showAllNotifications = getPref(TRAY_NOTIFICATIONS);
if (showAllNotifications || level != TrayIcon.MessageType.INFO) {
tray.displayMessage(caption, text, level);
}
Expand All @@ -640,7 +641,7 @@ public void singleInstanceCheck(java.util.List<Integer> insecurePorts, Integer i
}

public boolean isMonoclePreferred() {
return getPref(Constants.PREFS_MONOCLE, true);
return getPref(TRAY_MONOCLE);
}

public boolean isHeadless() {
Expand All @@ -650,8 +651,8 @@ public boolean isHeadless() {
/**
* Get boolean user pref: Searching "user", "app" and <code>System.getProperty(...)</code>.
*/
private boolean getPref(String name, boolean defaultVal) {
return "true".equalsIgnoreCase(PrefsSearch.get(prefs, App.getTrayProperties(), name, defaultVal + ""));
private boolean getPref(ArgValue argValue) {
return PrefsSearch.getBoolean(argValue, prefs, App.getTrayProperties());
}

private void performIfIdle(int idleQualifier, ActionListener performer) {
Expand Down
3 changes: 1 addition & 2 deletions src/qz/printer/status/StatusSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ public void enableJobDataOnPrinter(String printer, int maxJobData, PrintingUtili
if (!SystemUtilities.isWindows()) {
throw new UnsupportedOperationException("Job data listeners are only supported on Windows");
}
String spoolFileMonitoring = PrefsSearch.get(App.getTrayProperties(), Constants.PREFS_PRINTER_JOB_DATA, "false", false );
if (!Boolean.parseBoolean(spoolFileMonitoring)) {
if (!PrefsSearch.getBoolean(ArgValue.PRINTER_STATUS_JOB_DATA, false, App.getTrayProperties())) {
throw new UnsupportedOperationException("Job data listeners are currently disabled");
}
if (printerSpoolerMap.containsKey(printer)) {
Expand Down
8 changes: 3 additions & 5 deletions src/qz/ui/SiteManagerDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import qz.installer.certificate.CertificateManager;
import qz.installer.certificate.KeyPairWrapper;
import qz.ui.component.*;
import qz.utils.FileUtilities;
import qz.utils.ShellUtilities;
import qz.utils.SystemUtilities;
import qz.utils.*;

import javax.swing.*;
import javax.swing.border.Border;
Expand Down Expand Up @@ -242,15 +240,15 @@ public void mousePressed(MouseEvent e) {
readerThread = new Thread(this);
threadRunning = new AtomicBoolean(false);

strictModeCheckBox = new JCheckBox(Constants.STRICT_MODE_LABEL, prefs.getBoolean(Constants.PREFS_STRICT_MODE, false));
strictModeCheckBox = new JCheckBox(Constants.STRICT_MODE_LABEL, PrefsSearch.getBoolean(ArgValue.SECURITY_FILE_STRICT, prefs));
strictModeCheckBox.setToolTipText(Constants.STRICT_MODE_TOOLTIP);
strictModeCheckBox.addActionListener(e -> {
if (strictModeCheckBox.isSelected() && !new ConfirmDialog(null, "Please Confirm", iconCache).prompt(Constants.STRICT_MODE_CONFIRM)) {
strictModeCheckBox.setSelected(false);
return;
}
Certificate.setTrustBuiltIn(!strictModeCheckBox.isSelected());
prefs.setProperty(Constants.PREFS_STRICT_MODE, strictModeCheckBox.isSelected());
prefs.setProperty(ArgValue.SECURITY_FILE_STRICT, strictModeCheckBox.isSelected());
certTable.refreshComponents();
});
refreshStrictModeCheckbox();
Expand Down
54 changes: 49 additions & 5 deletions src/qz/utils/ArgParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import qz.installer.certificate.CertificateManager;

import java.io.File;
import java.lang.reflect.Field;
import java.util.*;
import java.util.List;

Expand All @@ -48,6 +49,7 @@ public int getCode() {
protected static final Logger log = LogManager.getLogger(ArgParser.class);

private static final String USAGE_COMMAND = String.format("java -jar %s.jar", PROPS_FILE);
private static final String USAGE_COMMAND_PARAMETER = String.format("java -Dfoo.bar=<value> -jar %s.jar", PROPS_FILE);
private static final int DESCRIPTION_COLUMN = 30;
private static final int INDENT_SIZE = 2;

Expand Down Expand Up @@ -203,7 +205,7 @@ public ExitStatus processInstallerArgs(ArgValue argValue, List<String> args) {
throw new UnsupportedOperationException("Installation type " + argValue + " is not yet supported");
}
} catch(MissingArgException e) {
log.error("Valid usage:\n {} {}", USAGE_COMMAND, argValue.getUsage());
log.error("Valid usage:{} {} {}", System.lineSeparator(), USAGE_COMMAND, argValue.getUsage());
return USAGE_ERROR;
} catch(Exception e) {
log.error("Installation step {} failed", argValue, e);
Expand All @@ -229,7 +231,7 @@ public ExitStatus processBuildArgs(ArgValue argValue) {
throw new UnsupportedOperationException("Build type " + argValue + " is not yet supported");
}
} catch(MissingArgException e) {
log.error("Valid usage:\n {} {}", USAGE_COMMAND, argValue.getUsage());
log.error("Valid usage:{} {} {}", System.lineSeparator(), USAGE_COMMAND, argValue.getUsage());
return USAGE_ERROR;
} catch(Exception e) {
log.error("Build step {} failed", argValue, e);
Expand Down Expand Up @@ -265,6 +267,15 @@ public boolean intercept() {
// Show generic help
for(ArgValue.ArgType argType : ArgValue.ArgType.values()) {
System.out.println(String.format("%s%s", System.lineSeparator(), argType));
switch(argType) {
case PREFERENCES:
System.out.println(String.format(" Preferences can be set via \"%s %s=%s\", command line via \"%s\" or via file using %s.properties" + System.lineSeparator(),
SystemUtilities.isWindows() ? "set" : "export",
"QZ_OPTS",
"-Dfoo.bar=<value>",
USAGE_COMMAND_PARAMETER,
PROPS_FILE));
}
for(ArgValue argValue : ArgValue.filter(argType)) {
printHelp(argValue);
}
Expand Down Expand Up @@ -378,11 +389,44 @@ public boolean intercept() {
return false;
}

private static void printHelp(String[] commands, String description, String usage, int indent) {
private static ArrayList<String> collectPrefs() {
ArrayList<String> opts = new ArrayList<>();
for(Field f : Constants.class.getDeclaredFields()) {
if(f.getName().startsWith("PREFS_")) {
try {
Object val = f.get(null);
if (val instanceof String) {
opts.add((String)val);
}
} catch(Exception ignore) {}
}
}
return opts;
}

private static void printHelp(String[] commands, String description, String usage, Object defaultVal, int indent) {
String text = String.format("%s%s", StringUtils.leftPad("", indent), StringUtils.join(commands, ", "));

// Try to handle overflow
String[] overflow = null;
if((text.length() > 27 + indent) && text.contains(",")) {
String[] split = text.split(",");
text = split[0] + ",";
overflow = Arrays.copyOfRange(split, 1, split.length);
}

if (description != null) {
text = StringUtils.rightPad(text, DESCRIPTION_COLUMN) + description;
if(defaultVal != null) {
text += String.format(" [%s]", defaultVal);
}
}

if(overflow != null) {
for(int i = 0; i < overflow.length; i++) {
String ending = (i == overflow.length - 1) ? "" : ",";
text += System.lineSeparator() + StringUtils.leftPad("", indent + INDENT_SIZE) + overflow[i].trim() + ending;
}
}
System.out.println(text);
if (usage != null) {
Expand All @@ -391,10 +435,10 @@ private static void printHelp(String[] commands, String description, String usag
}

private static void printHelp(ArgValue argValue) {
printHelp(argValue.getMatches(), argValue.getDescription(), argValue.getUsage(), INDENT_SIZE);
printHelp(argValue.getMatches(), argValue.getDescription(), argValue.getUsage(), argValue.getDefaultVal(), INDENT_SIZE);
}

private static void printHelp(ArgValueOption argValueOption) {
printHelp(argValueOption.getMatches(), argValueOption.getDescription(), null, INDENT_SIZE);
printHelp(argValueOption.getMatches(), argValueOption.getDescription(), null, null, INDENT_SIZE);
}
}
Loading

0 comments on commit 95db68d

Please sign in to comment.