diff options
Diffstat (limited to 'pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow')
16 files changed, 0 insertions, 4340 deletions
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java deleted file mode 100644 index b5df6ff3..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow; - -//Imports -import java.lang.reflect.Constructor; - -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindow; -import at.asit.pdfover.gui.composites.StateComposite; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.gui.workflow.states.PrepareConfigurationState; -import at.asit.pdfover.gui.workflow.states.State; - -/** - * Workflow holds logical state of signing process and updates the current - * logical state - */ -public class StateMachine { - - private static final Logger log = LoggerFactory.getLogger(StateMachine.class); - - public final Status status; - public final ConfigurationManager configProvider; - public final String[] cmdLineArgs; - - /** - * Default constructor - * - * @param cmdLineArgs - */ - public StateMachine(String[] cmdLineArgs) { - this.status = new Status(); - this.status.setCurrentState(new PrepareConfigurationState(this)); - this.configProvider = new ConfigurationManager(); - this.cmdLineArgs = cmdLineArgs; - } - - /** - * Sets the workflow state - * This method should be used to let the user jump - * around between states. This Method also resets certain properties defined - * by later states then state - * - * @param state - */ - public void jumpToState(State state) { - this.status.setCurrentState(state); - this.invokeUpdate(); - } - - /** - * Update workflow logic and let state machine do its job... - */ - public synchronized void update() { - State next = null; - while (this.status.getCurrentState() != null) { - State current = this.status.getCurrentState(); - try { - current.run(); - } catch (Exception e) { - log.error("StateMachine update: ", e); - ErrorDialog errorState = new ErrorDialog(this.getMainShell(), - Messages.getString("error.Unexpected"), BUTTONS.OK); - //errorState.setException(e); - //jumpToState(errorState); - errorState.open(); - this.exit(); - } - - if (this.exit) { - // exit request ignore - next = null; - this.status.setCurrentState(next); - } else { - - if (this.mainWindow != null && !this.mainWindow.getShell().isDisposed()) { - log.debug("Allowing MainWindow to update its state for " + current); - current.updateMainWindowBehavior(); - this.mainWindow.applyBehavior(); - this.mainWindow.doLayout(); - } - - // TODO: i really want this to be a return value from run() - next = current.nextState(); - if (next == current) { - break; - } - - if (next == null) { - log.info("Next state is null -> exit"); - this.status.setCurrentState(next); - break; - } - - log.debug("Changing state from: " - + current + " to " - + next.toString()); - this.status.setCurrentState(next); - } - } - } - - /** - * Invoke Update in UI (Main) Thread - */ - public void invokeUpdate() { - if (this.display != null) { - this.display.asyncExec(() -> { - this.update(); - }); - } - } - - private Display display = null; - - private Shell shell = null; - - private Composite container = null; - - private MainWindow mainWindow = null; - - /* - * (non-Javadoc) - * - * @see - * at.asit.pdfover.gui.workflow.StateMachine#display(org.eclipse.swt.widgets - * .Composite) - */ - public void display(StateComposite composite) { - this.mainWindow.setTopControl(composite); - } - - private void createMainWindow() { - try { - - this.display = Display.getDefault(); - - this.mainWindow = new MainWindow(this); - this.mainWindow.open(); - - this.shell = this.mainWindow.getShell(); - - this.container = this.mainWindow.getContainer(); - - this.shell.open(); - this.shell.layout(); - } catch (Exception e) { - log.warn("Main-Window creation FAILED.", e); - this.display = null; - this.mainWindow = null; - this.shell = null; - this.container = null; - throw e; - } - } - - /** - * Gets the Shell for drawing the ui - * - * @return Composite - */ - public synchronized Composite getComposite() { - // Main window will be built on first call - // returns SWT Composite container for states to draw their GUI - - if (this.container == null) { - this.createMainWindow(); - } - - return this.container; - } - - public <T> T createComposite(Class<T> compositeClass, int style, State state) { - T composite = null; - try { - Constructor<T> constructor = compositeClass.getDeclaredConstructor( - Composite.class, int.class, State.class); - composite = constructor.newInstance(getComposite(), style, state); - } catch (Exception e) { - log.error("Could not create Composite for Class " - + compositeClass.getName(), e); - } - return composite; - } - - /** - * Only returns a shell if one was already created ... - * - * @return - */ - private Shell nonCreatingGetShell() { - return this.shell; - } - - private boolean exit = false; - - /** - * Exists the Workflow - */ - public void exit() { - this.exit = true; - if (this.shell != null) { - this.shell.dispose(); - } - } - - /** - * Only returns a shell if one was already created ... - * - * @return - */ - private Display nonCreatingGetDisplay() { - return this.display; - } - - /** - * Workflow main entrance point - */ - public void start() { - - // Call update to start processing ... - update(); - - // if a user interaction is required we have a shell ... - Shell shell = nonCreatingGetShell(); - Display display = nonCreatingGetDisplay(); - - if (this.status.getCurrentState() == null) { - if (shell != null) { - this.shell.dispose(); - } - } - - if (shell != null && display != null) { - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - } - - - public synchronized Shell getMainShell() { - if(this.shell == null) { - this.createMainWindow(); - } - - return this.shell; - } - - public void reloadResources() { - this.mainWindow.reloadLocalization(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java deleted file mode 100644 index ba5e5fd5..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow; - -// Imports -import java.io.File; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.BKUs; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.workflow.states.State; -import at.asit.pdfover.signer.SignResult; -import at.asit.pdfover.signer.SignaturePosition; -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; - -public class Status { - private static final Logger log = LoggerFactory.getLogger(Status.class); - - public File document = null; - - public SignaturePosition signaturePosition = null; - - public BKUs bku = BKUs.NONE; - - private State currentState = null; - - private State previousState = null; - - public PdfAs4SigningState signingState = null; - - public SignResult signResult = null; - - public final MainWindowBehavior behavior; - - public boolean searchForPlacehoderSignature = false; - - public Status() { - this.behavior = new MainWindowBehavior(); - } - - public State getCurrentState() { - return this.currentState; - } - - public void setCurrentState(State newState) { - log.debug("Changing from " + currentState + " to " + newState); - - if ((previousState != null) && (previousState != currentState) && (previousState != newState)) - { - // Reference to previous state will be lost - perform cleanup - log.debug("Cleaning up " + previousState); - previousState.cleanUp(); - } - - this.previousState = currentState; - this.currentState = newState; - } - - public State getPreviousState() { - return this.previousState; - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java deleted file mode 100644 index adf03913..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.config; - -// Imports -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Locale; -import java.util.Objects; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -import at.asit.pdfover.commons.Profile; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.BKUs; -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.bku.mobile.MobileBKUValidator; -import at.asit.pdfover.gui.exceptions.InvalidEmblemFile; -import at.asit.pdfover.gui.exceptions.InvalidPortException; - -import static at.asit.pdfover.commons.Constants.ISNOTNULL; - -/** - * Implementation of the configuration container - */ -public class ConfigurationDataInMemory { - /** - * SLF4J Logger instance - **/ - @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(ConfigurationDataInMemory.class); - - /** the emblem size (in mm) for logo only signatures */ - public double logoOnlyTargetSize = Constants.DEFAULT_LOGO_ONLY_SIZE; - - /** the emblem File */ - protected String emblemFile = null; - public String getEmblemPath() { return this.emblemFile; } - public void setEmblem(String emblemFile) throws InvalidEmblemFile { - if (emblemFile == null || emblemFile.trim().isEmpty()) { - // Ok to set no file ... - } else { - File imageFile = new File(emblemFile); - if (!imageFile.exists()) { - throw new InvalidEmblemFile(imageFile, - new FileNotFoundException(emblemFile)); - } - - try { - Image img = new Image(Display.getDefault(), new ImageData( - emblemFile)); - - img.dispose(); - } catch (Exception ex) { - throw new InvalidEmblemFile(imageFile, ex); - } - } - - this.emblemFile = emblemFile; - } - - /** The mobile phone number */ - protected @CheckForNull String mobileNumber = null; - public @CheckForNull String getMobileNumber() { return this.mobileNumber; } - public void setMobileNumber(String number) { - if(number == null || number.trim().isEmpty()) { - this.mobileNumber = null; - return; - } - this.mobileNumber = MobileBKUValidator.normalizeMobileNumber(number); - } - - /** The mobile phone password */ - public @CheckForNull String mobilePassword = null; - - public boolean rememberPassword = false; - - /** Holds the proxy host */ - public @CheckForNull String proxyHost = null; - - /** Holds the proxy port number */ - protected int proxyPort = -1; - public int getProxyPort() { return this.proxyPort; } - public void setProxyPort(int port) throws InvalidPortException { - if(port > 0 && port <= 0xFFFF) { - this.proxyPort = port; - return; - } - if(port == -1) { - this.proxyPort = -1; - return; - } - throw new InvalidPortException(port); - } - - /** Holds the proxy username */ - public @CheckForNull String proxyUser = null; - - /** Holds the proxy password */ - public @CheckForNull String proxyPass = null; - - /** Holds the default BKU to use */ - public @Nonnull BKUs defaultBKU = BKUs.NONE; - - /** Holds the output folder */ - public @CheckForNull String outputFolder = null; - - /** Holds the signatureNote */ - public @CheckForNull String signatureNote = null; - - /** Holds the locale */ - public @CheckForNull Locale interfaceLocale = null; - - /** Holds the signature locale */ - public @CheckForNull Locale signatureLocale = null; - - /** Holds the PDF/A compatibility setting */ - public boolean signaturePDFACompat = false; - - /** Holds the default signature position */ - public boolean autoPositionSignature = false; - - /** Keystore signing options */ - public enum KeyStorePassStorageType { MEMORY, DISK }; - public @CheckForNull Boolean keystoreEnabled = null; - public @CheckForNull String keystoreFile = null; - public @CheckForNull String keystoreType = null; - public @CheckForNull String keystoreAlias = null; - public @CheckForNull KeyStorePassStorageType keystorePassStorageType = null; - public @CheckForNull String keystoreStorePass = null; - public @CheckForNull String keystoreKeyPass = null; - - /** Whether to automatically check for updates */ - public boolean updateCheck = true; - - /** Holds the main window size - * - * @IMPORTANT this must always be valid and non-null, even if configuration failed to load for whatever reason (it is used by error handlers!) - */ - public @Nonnull Point mainWindowSize = new Point(Constants.DEFAULT_MAINWINDOW_WIDTH, Constants.DEFAULT_MAINWINDOW_HEIGHT); - - /** Whether to skip the output state */ - public boolean skipFinish = false; - - /** Whether to use an existing signature marker. */ - protected boolean useMarker = false; - public boolean getUseMarker() { return this.useMarker; } - public void setUseMarker(boolean useMarker) { - this.useMarker = useMarker; - if (useMarker) setUseSignatureFields(false); - } - - /** Either QR-Code or signature fields as marker */ - protected boolean useSignatureFields = false; - public boolean getUseSignatureFields() { return this.useSignatureFields; } - public void setUseSignatureFields(boolean useFields) { - this.useSignatureFields = useFields; - if (useFields) setUseMarker(false); - } - - /** describes if the placeholder search is enabled */ - public boolean enabledPlaceholderUsage = false; - - /** The Signature Profile */ - protected @CheckForNull Profile signatureProfile = null; - public @Nonnull Profile getSignatureProfile() { - return ISNOTNULL(Objects.requireNonNullElse(this.signatureProfile, Profile.SIGNATURBLOCK_SMALL)); - } - public void setSignatureProfile(Profile profile) { this.signatureProfile = profile; } - - public @Nonnull String saveFilePostFix = Constants.DEFAULT_POSTFIX; - - /** whether fido2 authentication should be selected by default */ - public boolean fido2ByDefault = false; - -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java deleted file mode 100644 index 39071667..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java +++ /dev/null @@ -1,919 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.config; - -// Imports -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Locale; -import java.util.Properties; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -import at.asit.pdfover.commons.Profile; - -import org.apache.commons.io.FileUtils; -import org.eclipse.swt.graphics.Point; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.BKUs; -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.exceptions.InvalidEmblemFile; -import at.asit.pdfover.gui.exceptions.InvalidPortException; -import at.asit.pdfover.gui.utils.LocaleSerializer; -import at.asit.pdfover.gui.workflow.config.ConfigurationDataInMemory.KeyStorePassStorageType; -import at.asit.pdfover.commons.Messages; - -import static at.asit.pdfover.commons.Constants.ISNOTNULL; - -/** - * Implementation of the configuration provider and manipulator - */ -public class ConfigurationManager { - /** - * SLF4J Logger instance - **/ - private static final Logger log = LoggerFactory.getLogger(ConfigurationManager.class); - - private String configurationFile = Constants.DEFAULT_CONFIG_FILENAME; - - private boolean loaded = false; - - // The persistent configuration read from the config file - private ConfigurationDataInMemory configuration; - - // The configuration overlay built from the cmd line args - private ConfigurationDataInMemory configurationOverlay; - - // whether the configuration screen should crash on startup (for debugging purposes) - public boolean crashOnConfig = false; - - /** - * Constructor - */ - public ConfigurationManager() { - this.configuration = new ConfigurationDataInMemory(); - this.configurationOverlay = new ConfigurationDataInMemory(); - } - - static public void factoryResetPersistentConfig() { - // tell logback to close all file handles - ((ch.qos.logback.classic.LoggerContext)LoggerFactory.getILoggerFactory()).stop(); - - File configDirectory = new File(Constants.CONFIG_DIRECTORY); - File backupDirectory = new File(Constants.CONFIG_BACKUP_DIRECTORY); - - // delete existing backup, if any - FileUtils.deleteQuietly(backupDirectory); - - // attempt 1: try to move the old config directory to a backup location - try { - FileUtils.moveDirectory( - configDirectory, - backupDirectory - ); - } catch (Exception e) { - System.out.println("Failed move config directory to backup location:"); - e.printStackTrace(); - - // attempt 2: try to simply force delete the config directory - try { - FileUtils.forceDelete(configDirectory); - } catch (Exception e2) { - System.out.println("Failed to delete config directory:"); - e2.printStackTrace(); - - // attempt 3: try to schedule the config directory for force deletion on JVM exit - try { - FileUtils.forceDeleteOnExit(configDirectory); - } catch (Exception e3) { - System.out.println("Failed to schedule config directory for deletion:"); - e3.printStackTrace(); - } - } - } - } - - /* load from disk */ - public void loadFromDisk() throws IOException { - if (loaded) - throw new RuntimeException("ConfigProvider double load?"); - - Properties diskConfig = new Properties(); - - diskConfig.load(new FileInputStream(Constants.CONFIG_DIRECTORY + File.separator + getConfigurationFileName())); - - { /* for testing of error handlers */ - String crashProperty = diskConfig.getProperty("CRASH"); - if ("startup".equalsIgnoreCase(crashProperty)) - throw new RuntimeException("A robot must obey the orders given it by human beings except where such orders would conflict with the First Law.\n(CRASH=startup is set.)"); - else if ("config".equalsIgnoreCase(crashProperty)) - this.crashOnConfig = true; - else if (crashProperty != null) - log.warn("Unknown value '{}' for CRASH property -- you want 'startup' or 'config'.", crashProperty); - } - - setDefaultEmblemPersistent(diskConfig.getProperty(Constants.CFG_EMBLEM)); - try { - String strProp = diskConfig.getProperty(Constants.CFG_LOGO_ONLY_SIZE); - if (strProp != null) - setLogoOnlyTargetSizePersistent(Double.parseDouble(strProp)); - } catch (NumberFormatException e) { log.info("Invalid value for CFG_LOGO_ONLY_SIZE ignored.", e); } - - setDefaultMobileNumberPersistent(diskConfig.getProperty(Constants.CFG_MOBILE_NUMBER)); - setRememberMobilePasswordPersistent(Constants.TRUE.equals(diskConfig.getProperty(Constants.CFG_MOBILE_PASSWORD_REMEMBER))); - - setProxyHostPersistent(diskConfig.getProperty(Constants.CFG_PROXY_HOST)); - setProxyUserPersistent(diskConfig.getProperty(Constants.CFG_PROXY_USER)); - setProxyPassPersistent(diskConfig.getProperty(Constants.CFG_PROXY_PASS)); - - setDefaultOutputFolderPersistent(diskConfig.getProperty(Constants.CFG_OUTPUT_FOLDER)); - - String postFix = diskConfig.getProperty(Constants.CFG_POSTFIX); - if (postFix == null) - setSaveFilePostFixPersistent(Constants.DEFAULT_POSTFIX); - else - setSaveFilePostFixPersistent(postFix); - - String localeString = diskConfig.getProperty(Constants.CFG_LOCALE); - - Locale targetLocale = LocaleSerializer.parseFromString(localeString); - if (targetLocale != null) - setInterfaceLocalePersistent(targetLocale); - - String signatureLocaleString = diskConfig.getProperty(Constants.CFG_SIGNATURE_LOCALE); - - Locale signatureTargetLocale = LocaleSerializer.parseFromString(signatureLocaleString); - if (signatureTargetLocale != null) - setSignatureLocalePersistent(signatureTargetLocale); - - String useMarker = diskConfig.getProperty(Constants.CFG_USE_MARKER); - if (useMarker != null) - setUseMarkerPersistent(useMarker.equalsIgnoreCase(Constants.TRUE)); - - String useSignatureFields = diskConfig.getProperty(Constants.CFG_USE_SIGNATURE_FIELDS); - if (useSignatureFields != null) - setUseSignatureFieldsPersistent(useSignatureFields.equalsIgnoreCase(Constants.TRUE)); - - String enablePlaceholder = diskConfig.getProperty(Constants.CFG_ENABLE_PLACEHOLDER); - if (enablePlaceholder != null) - setEnablePlaceholderUsagePersistent(enablePlaceholder.equalsIgnoreCase(Constants.TRUE)); - - String signatureProfileName = diskConfig.getProperty(Constants.SIGNATURE_PROFILE); - if (signatureProfileName != null) - setSignatureProfilePersistent(Profile.getProfile(signatureProfileName)); - - if (diskConfig.containsKey(Constants.CFG_SIGNATURE_NOTE)) - setSignatureNotePersistent(diskConfig.getProperty(Constants.CFG_SIGNATURE_NOTE)); - else - setSignatureNotePersistent(getSignatureProfile().getDefaultSignatureBlockNote(getSignatureLocale())); - - String compat = diskConfig.getProperty(Constants.CFG_SIGNATURE_PDFA_COMPAT); - if (compat != null) - setSignaturePdfACompatPersistent(compat.equalsIgnoreCase(Constants.TRUE)); - - String proxyPortString = diskConfig.getProperty(Constants.CFG_PROXY_PORT); - if (proxyPortString != null && !proxyPortString.trim().isEmpty()) - { - int port = Integer.parseInt(proxyPortString); - - if (port > 0 && port <= 0xFFFF) - setProxyPortPersistent(port); - else - log.warn("Proxy port is out of range!: " + port); - } - - // Set Default BKU - String bkuString = diskConfig.getProperty(Constants.CFG_BKU); - BKUs defaultBKU = BKUs.NONE; - if (bkuString != null) { - try { - defaultBKU = BKUs.valueOf(bkuString); - } catch (IllegalArgumentException ex) { - log.error("Invalid BKU config value " + bkuString + " using none!"); - defaultBKU = BKUs.NONE; - } catch (NullPointerException ex) { - log.error("Invalid BKU config value " + bkuString + " using none!"); - defaultBKU = BKUs.NONE; - } - } - setDefaultBKUPersistent(defaultBKU); - - // Set MainWindow size - int width = Constants.DEFAULT_MAINWINDOW_WIDTH; - int height = Constants.DEFAULT_MAINWINDOW_HEIGHT; - String size = diskConfig.getProperty(Constants.CFG_MAINWINDOW_SIZE); - parse: { - if (size == null) - break parse; - int pos = size.indexOf(','); - if (pos <= 0) - break parse; - - try { - width = Integer.parseInt(size.substring(0, pos).trim()); - height = Integer.parseInt(size.substring(pos + 1).trim()); - } catch (NumberFormatException e) { - log.debug("Couldn't parse main window size", e); - // ignore parsing exception - } - } - this.configuration.mainWindowSize = new Point(width, height); - - // Set Signature Position - String signaturePositionStr = diskConfig.getProperty(Constants.CFG_SIGNATURE_POSITION); - setAutoPositionSignaturePersistent(signaturePositionStr != null && signaturePositionStr.trim().equals("auto")); - - //Set keystore stuff - String keystoreEnabled = diskConfig.getProperty(Constants.CFG_KEYSTORE_ENABLED); - if (keystoreEnabled != null) - setKeyStoreEnabledPersistent(keystoreEnabled.equalsIgnoreCase(Constants.TRUE)); - setKeyStoreFilePersistent(diskConfig.getProperty(Constants.CFG_KEYSTORE_FILE)); - setKeyStoreTypePersistent(diskConfig.getProperty(Constants.CFG_KEYSTORE_TYPE)); - setKeyStoreAliasPersistent(diskConfig.getProperty(Constants.CFG_KEYSTORE_ALIAS)); - setKeyStoreStorePassPersistent(diskConfig.getProperty(Constants.CFG_KEYSTORE_STOREPASS)); - setKeyStoreKeyPassPersistent(diskConfig.getProperty(Constants.CFG_KEYSTORE_KEYPASS)); - String storeTypeOnDisk = diskConfig.getProperty(Constants.CFG_KEYSTORE_PASSSTORETYPE); - if (storeTypeOnDisk == null) /* auto-detect based on old config */ - { - String oldKeyPass = getKeyStoreKeyPassPersistent(); - String oldStorePass = getKeyStoreStorePassPersistent(); - if ((oldKeyPass != null && !oldKeyPass.trim().isEmpty()) || (oldStorePass != null && !oldStorePass.trim().isEmpty())) /* previously stored password exists */ - storeTypeOnDisk = "disk"; - else - storeTypeOnDisk = "memory"; - } - if ("disk".equals(storeTypeOnDisk)) - setKeyStorePassStorageTypePersistent(KeyStorePassStorageType.DISK); - else if ("memory".equals(storeTypeOnDisk)) - setKeyStorePassStorageTypePersistent(KeyStorePassStorageType.MEMORY); - else - setKeyStorePassStorageTypePersistent(null); - - // Set update check - String updateCheck = diskConfig.getProperty(Constants.CFG_UPDATE_CHECK); - if (updateCheck != null) - setUpdateCheckPersistent(!updateCheck.equalsIgnoreCase(Constants.FALSE)); - - setFido2ByDefaultPersistent(Constants.TRUE.equalsIgnoreCase(diskConfig.getProperty(Constants.CFG_FIDO2_BY_DEFAULT))); - - log.info("Successfully loaded config from: " + getConfigurationFileName()); - loaded = true; - } - - private void setProperty(@Nonnull Properties props, @Nonnull String key, @Nonnull String value) { props.setProperty(key, value); } - private void setPropertyIfNotNull(@Nonnull Properties props, @Nonnull String key, @CheckForNull String value) { if (value != null) setProperty(props, key, value); } - private void setPropertyIfNotBlank(@Nonnull Properties props, @Nonnull String key, @Nonnull String value) { if (!value.isEmpty()) setProperty(props, key, value); } - /* save to file */ - public void saveToDisk() throws IOException { - String filename = this.getConfigurationFileName(); - File configFile = new File(Constants.CONFIG_DIRECTORY + File.separator + filename); - - Properties props = new Properties(); - props.clear(); - - setProperty(props, Constants.CFG_BKU, ISNOTNULL(getDefaultBKUPersistent().name())); - - setPropertyIfNotNull(props, Constants.CFG_PROXY_HOST, getProxyHostPersistent()); - int proxyPort = getProxyPortPersistent(); - if (proxyPort != -1) - setProperty(props, Constants.CFG_PROXY_PORT, ISNOTNULL(Integer.toString(proxyPort))); - setPropertyIfNotNull(props, Constants.CFG_PROXY_USER, getProxyUserPersistent()); - setPropertyIfNotNull(props, Constants.CFG_PROXY_PASS, getProxyPassPersistent()); - - setPropertyIfNotNull(props, Constants.CFG_EMBLEM, getDefaultEmblemPersistent()); - setProperty(props, Constants.CFG_LOGO_ONLY_SIZE, ISNOTNULL(Double.toString(getLogoOnlyTargetSize()))); - - setPropertyIfNotNull(props, Constants.CFG_SIGNATURE_NOTE, getSignatureNote()); - setPropertyIfNotNull(props, Constants.CFG_MOBILE_NUMBER, getDefaultMobileNumberPersistent()); - if (getRememberMobilePassword()) - setProperty(props, Constants.CFG_MOBILE_PASSWORD_REMEMBER, Constants.TRUE); - setPropertyIfNotNull(props, Constants.CFG_OUTPUT_FOLDER, getDefaultOutputFolderPersistent()); - setProperty(props, Constants.CFG_POSTFIX, getSaveFilePostFix()); - - Point size = this.configuration.mainWindowSize; - setProperty(props, Constants.CFG_MAINWINDOW_SIZE, size.x + "," + size.y); - - Locale configLocale = getInterfaceLocale(); - if(configLocale != null) { - setProperty(props, Constants.CFG_LOCALE, LocaleSerializer.getParsableString(configLocale)); - } - - Locale signatureLocale = this.getSignatureLocale(); - if(signatureLocale != null) { - setProperty(props, Constants.CFG_SIGNATURE_LOCALE, LocaleSerializer.getParsableString(signatureLocale)); - } - - if (getUseMarker()) - setProperty(props, Constants.CFG_USE_MARKER, Constants.TRUE); - - if (getUseSignatureFields()) { - setProperty(props, Constants.CFG_USE_SIGNATURE_FIELDS, Constants.TRUE); - } - - if (getEnablePlaceholderUsage()) { - setProperty(props, Constants.CFG_ENABLE_PLACEHOLDER, Constants.TRUE); - } - - if (getSignaturePdfACompat()) - setProperty(props, Constants.CFG_SIGNATURE_PDFA_COMPAT, Constants.TRUE); - - if (!getAutoPositionSignaturePersistent()) - setProperty(props, Constants.CFG_SIGNATURE_POSITION, ""); - else - setProperty(props, Constants.CFG_SIGNATURE_POSITION, "auto"); - - if (Constants.THEME != Constants.Themes.DEFAULT) - setProperty(props, Constants.CFG_THEME, ISNOTNULL(Constants.THEME.name())); - - if (getKeyStoreEnabledPersistent()) - setProperty(props, Constants.CFG_KEYSTORE_ENABLED, Constants.TRUE); - setPropertyIfNotBlank(props, Constants.CFG_KEYSTORE_FILE, getKeyStoreFilePersistent()); - setPropertyIfNotBlank(props, Constants.CFG_KEYSTORE_TYPE, getKeyStoreTypePersistent()); - setPropertyIfNotBlank(props, Constants.CFG_KEYSTORE_ALIAS, getKeyStoreAliasPersistent()); - - KeyStorePassStorageType keystorePassStorageType = getKeyStorePassStorageType(); - if (keystorePassStorageType == null) - setProperty(props, Constants.CFG_KEYSTORE_PASSSTORETYPE, "none"); - else if (keystorePassStorageType == KeyStorePassStorageType.MEMORY) - setProperty(props, Constants.CFG_KEYSTORE_PASSSTORETYPE, "memory"); - else if (keystorePassStorageType == KeyStorePassStorageType.DISK) - setProperty(props, Constants.CFG_KEYSTORE_PASSSTORETYPE, "disk"); - - if (keystorePassStorageType == KeyStorePassStorageType.DISK) - { - String keystoreStorePass = getKeyStoreStorePassPersistent(); - if (keystoreStorePass == null) - keystoreStorePass = ""; - setProperty(props, Constants.CFG_KEYSTORE_STOREPASS, keystoreStorePass); - String keystoreKeyPass = getKeyStoreKeyPassPersistent(); - if (keystoreKeyPass == null) - keystoreKeyPass = ""; - setProperty(props, Constants.CFG_KEYSTORE_KEYPASS, keystoreKeyPass); - } - - if (!getUpdateCheck()) - setProperty(props, Constants.CFG_UPDATE_CHECK, Constants.FALSE); - - if (getFido2ByDefault()) - setProperty(props, Constants.CFG_FIDO2_BY_DEFAULT, Constants.TRUE); - - setProperty(props, Constants.SIGNATURE_PROFILE, ISNOTNULL(getSignatureProfile().name())); - - - FileOutputStream outputstream = new FileOutputStream(configFile, false); - - props.store(outputstream, "Configuration file was generated!"); - - log.info("Configuration file saved to " + configFile.getAbsolutePath()); - } - - static private <T> T fallThroughOnNull(T one, T two) { return (one != null) ? one : two; } - - public void setConfigurationFileName(String configurationFile) - { - if (this.configurationFile.equals(configurationFile)) - return; - if (this.loaded) - throw new RuntimeException("Cannot change configuration file path after it has been loaded"); - this.configurationFile = configurationFile; - } - public String getConfigurationFileName() { return this.configurationFile; } - - public void setDefaultBKUPersistent(@Nonnull BKUs bku) { - this.configuration.defaultBKU = bku; - } - - public void setDefaultBKUOverlay(@Nonnull BKUs bku) { - this.configurationOverlay.defaultBKU = bku; - } - - public @Nonnull BKUs getDefaultBKU() { - BKUs bku = this.configurationOverlay.defaultBKU; - if (bku == BKUs.NONE) - bku = getDefaultBKUPersistent(); - return bku; - } - - public @Nonnull BKUs getDefaultBKUPersistent() { - return this.configuration.defaultBKU; - } - - public void setAutoPositionSignaturePersistent(boolean state) { - this.configuration.autoPositionSignature = state; - } - - public void setAutoPositionSignatureOverlay() { - this.configurationOverlay.autoPositionSignature = true; - } - - public boolean getAutoPositionSignature() { - return this.configurationOverlay.autoPositionSignature || getAutoPositionSignaturePersistent(); - } - - public boolean getAutoPositionSignaturePersistent() { - return this.configuration.autoPositionSignature; - } - - public void setDefaultMobileNumberPersistent(String number) { - if (number == null || number.trim().isEmpty()) { - this.configuration.setMobileNumber(null); - } else { - this.configuration.setMobileNumber(number); - } - } - - public void setDefaultMobileNumberOverlay(String number) { - if (number == null || number.trim().isEmpty()) { - this.configurationOverlay.setMobileNumber(null); - } else { - this.configurationOverlay.setMobileNumber(number); - } - } - - public @CheckForNull String getDefaultMobileNumber() { - return fallThroughOnNull(this.configurationOverlay.getMobileNumber(), getDefaultMobileNumberPersistent()); - } - - public @CheckForNull String getDefaultMobileNumberPersistent() { - return this.configuration.getMobileNumber(); - } - - public void setDefaultMobilePasswordOverlay(String password) { - if (password == null || password.trim().isEmpty()) { - this.configurationOverlay.mobilePassword = null; - } else { - this.configurationOverlay.mobilePassword = password; - } - } - - public @CheckForNull String getDefaultMobilePassword() { - /* this does not exist as a permanent config variable */ - return this.configurationOverlay.mobilePassword; - } - - public boolean getRememberMobilePassword() { - return this.configuration.rememberPassword; - } - - public void setRememberMobilePasswordPersistent(boolean state) { - this.configuration.rememberPassword = state; - } - - public void setDefaultEmblemPersistent(String emblem) { - try { - if (emblem == null || emblem.trim().isEmpty()) { - this.configuration.setEmblem(null); - } else { - this.configuration.setEmblem(emblem); - } - } catch (InvalidEmblemFile e) { - log.error("Error setting emblem file", e); - try { - this.configuration.setEmblem(null); - } catch (InvalidEmblemFile e1) { - // Ignore - } - } - } - - public void setDefaultEmblemOverlay(String emblem) { - try { - if (emblem == null || emblem.trim().isEmpty()) { - this.configurationOverlay.setEmblem(null); - } else { - this.configurationOverlay.setEmblem(emblem); - } - } catch (InvalidEmblemFile e) { - log.error("Error setting emblem file", e); - try { - this.configurationOverlay.setEmblem(null); - } catch (InvalidEmblemFile e1) { - // Ignore - } - } - } - - public @CheckForNull String getDefaultEmblemPath() { - return fallThroughOnNull(this.configurationOverlay.getEmblemPath(), getDefaultEmblemPersistent()); - } - - public @CheckForNull String getDefaultEmblemPersistent() { - return this.configuration.getEmblemPath(); - } - - public void setLogoOnlyTargetSizePersistent(double v) { - this.configuration.logoOnlyTargetSize = v; - } - - public double getLogoOnlyTargetSize() { - return this.configuration.logoOnlyTargetSize; - } - - public void setProxyHostPersistent(String host) { - if (host == null || host.trim().isEmpty()) { - this.configuration.proxyHost = null; - } else { - this.configuration.proxyHost = host; - } - } - - public void setProxyHostOverlay(String host) { - if (host == null || host.trim().isEmpty()) { - this.configurationOverlay.proxyHost = null; - } else { - this.configurationOverlay.proxyHost = host; - } - } - - public @CheckForNull String getProxyHost() { - return fallThroughOnNull(this.configurationOverlay.proxyHost, getProxyHostPersistent()); - } - - public @CheckForNull String getProxyHostPersistent() { - return this.configuration.proxyHost; - } - - public void setProxyPortPersistent(int port) { - try { - this.configuration.setProxyPort(port); - } catch (InvalidPortException e) { - log.error("Error setting proxy port" , e); - // ignore - } - } - - public void setProxyPortOverlay(int port) { - try { - this.configurationOverlay.setProxyPort(port); - } catch (InvalidPortException e) { - log.error("Error setting proxy port" , e); - // ignore - } - } - - public int getProxyPort() { - int port = this.configurationOverlay.getProxyPort(); - if (port == -1) // TODO -1 is a terrible, no good, very bad hack - port = getProxyPortPersistent(); - return port; - } - - public int getProxyPortPersistent() { - return this.configuration.getProxyPort(); - } - - public void setProxyUserPersistent(String user) { - if (user == null || user.trim().isEmpty()) { - this.configuration.proxyUser = null; - } else { - this.configuration.proxyUser = user; - } - } - - public void setProxyUserOverlay(String user) { - if (user == null || user.trim().isEmpty()) { - this.configurationOverlay.proxyUser = null; - } else { - this.configurationOverlay.proxyUser = user; - } - } - - public @CheckForNull String getProxyUser() { - return fallThroughOnNull(this.configurationOverlay.proxyUser, getProxyUserPersistent()); - } - - public @CheckForNull String getProxyUserPersistent() { - return this.configuration.proxyUser; - } - - public void setProxyPassPersistent(String pass) { - if (pass == null || pass.trim().isEmpty()) { - this.configuration.proxyPass = null; - } else { - this.configuration.proxyPass = pass; - } - } - - public void setProxyPassOverlay(String pass) { - if (pass == null || pass.trim().isEmpty()) { - this.configurationOverlay.proxyPass = null; - } else { - this.configurationOverlay.proxyPass = pass; - } - } - - public @CheckForNull String getProxyPass() { - return fallThroughOnNull(this.configurationOverlay.proxyPass, getProxyPassPersistent()); - } - - public @CheckForNull String getProxyPassPersistent() { - return this.configuration.proxyPass; - } - - public void setDefaultOutputFolderPersistent(String outputFolder) { - if (outputFolder == null || outputFolder.trim().isEmpty()) { - this.configuration.outputFolder = null; - } else { - this.configuration.outputFolder = outputFolder; - } - } - - public void setDefaultOutputFolderOverlay(String outputFolder) { - if (outputFolder == null || outputFolder.trim().isEmpty()) { - this.configurationOverlay.outputFolder = null; - } else { - this.configurationOverlay.outputFolder = outputFolder; - } - } - - public @CheckForNull String getDefaultOutputFolder() { - return fallThroughOnNull(this.configurationOverlay.outputFolder, getDefaultOutputFolderPersistent()); - } - - public @CheckForNull String getDefaultOutputFolderPersistent() { - return this.configuration.outputFolder; - } - - public void setSignatureNotePersistent(String note) { - if (note == null || note.trim().isEmpty()) { - this.configuration.signatureNote = null; - } else { - this.configuration.signatureNote = note; - } - } - - public @CheckForNull String getSignatureNote() { - return this.configuration.signatureNote; - } - - public void setInterfaceLocalePersistent(Locale locale) { - if(locale == null) { - this.configuration.interfaceLocale = Messages.getDefaultLocale(); - } else { - this.configuration.interfaceLocale = locale; - Locale.setDefault(locale); - Messages.setLocale(locale); - } - } - - public @Nonnull Locale getInterfaceLocale() { - Locale locale = this.configuration.interfaceLocale; - if (locale == null) - locale = Messages.getDefaultLocale(); - return locale; - } - - public void setSignatureLocalePersistent(Locale locale) { - if(locale == null) { - this.configuration.signatureLocale = Messages.getDefaultLocale(); - } else { - this.configuration.signatureLocale = locale; - } - } - - public @Nonnull Locale getSignatureLocale() { - Locale locale = this.configuration.signatureLocale; - if (locale == null) - locale = Messages.getDefaultLocale(); - return locale; - } - - public void setSignaturePdfACompatPersistent(boolean compat) { - this.configuration.signaturePDFACompat = compat; - } - - public boolean getSignaturePdfACompat() { - return this.configuration.signaturePDFACompat; - } - - public void setKeyStoreEnabledPersistent(Boolean enabled) { - this.configuration.keystoreEnabled = enabled; - } - - public void setKeyStoreEnabledOverlay(Boolean enabled) { - this.configurationOverlay.keystoreEnabled = enabled; - } - - public boolean getKeyStoreEnabled() { - return ISNOTNULL(fallThroughOnNull(this.configurationOverlay.keystoreEnabled, getKeyStoreEnabledPersistent())); - } - - public boolean getKeyStoreEnabledPersistent() { - return ISNOTNULL(fallThroughOnNull(this.configuration.keystoreEnabled, Boolean.FALSE)); - } - - public void setKeyStoreFilePersistent(@CheckForNull String file) { - if (file == null || file.trim().isEmpty()) { - this.configuration.keystoreFile = ""; - } else { - this.configuration.keystoreFile = file; - } - } - - public void setKeyStoreFileOverlay(@CheckForNull String file) { - if (file == null || file.trim().isEmpty()) { - this.configurationOverlay.keystoreFile = null; - } else { - this.configurationOverlay.keystoreFile = file; - } - } - - public @Nonnull String getKeyStoreFile() { - return ISNOTNULL(fallThroughOnNull(this.configurationOverlay.keystoreFile, getKeyStoreFilePersistent())); - } - - public @Nonnull String getKeyStoreFilePersistent() { - return ISNOTNULL(this.configuration.keystoreFile); - } - - public void setKeyStoreTypePersistent(@CheckForNull String type) { - if (type == null || type.trim().isEmpty()) { - this.configuration.keystoreType = ""; - } else { - this.configuration.keystoreType = type; - } - } - - public void setKeyStoreTypeOverlay(@CheckForNull String type) { - if (type == null || type.trim().isEmpty()) { - this.configurationOverlay.keystoreType = null; - } else { - this.configurationOverlay.keystoreType = type; - } - } - - public @Nonnull String getKeyStoreType() { - return ISNOTNULL(fallThroughOnNull(this.configurationOverlay.keystoreType, getKeyStoreTypePersistent())); - } - - public @Nonnull String getKeyStoreTypePersistent() { - return ISNOTNULL(this.configuration.keystoreType); - } - - public void setKeyStoreAliasPersistent(@CheckForNull String alias) { - if (alias == null || alias.trim().isEmpty()) { - this.configuration.keystoreAlias = ""; - } else { - this.configuration.keystoreAlias = alias; - } - } - - public void setKeyStoreAliasOverlay(@CheckForNull String alias) { - if (alias == null || alias.trim().isEmpty()) { - this.configurationOverlay.keystoreAlias = null; - } else { - this.configurationOverlay.keystoreAlias = alias; - } - } - - public @Nonnull String getKeyStoreAlias() { - return ISNOTNULL(fallThroughOnNull(this.configurationOverlay.keystoreAlias, getKeyStoreAliasPersistent())); - } - - public @Nonnull String getKeyStoreAliasPersistent() { - return ISNOTNULL(this.configuration.keystoreAlias); - } - - public void setKeyStorePassStorageTypePersistent(@CheckForNull KeyStorePassStorageType type) { - this.configuration.keystorePassStorageType = type; - } - - public @CheckForNull KeyStorePassStorageType getKeyStorePassStorageType() { - return this.configuration.keystorePassStorageType; - } - - public void setKeyStoreStorePassPersistent(@CheckForNull String storePass) { - this.configuration.keystoreStorePass = storePass; - } - - public void setKeyStoreStorePassOverlay(@CheckForNull String storePass) { - this.configurationOverlay.keystoreStorePass = storePass; - } - - public @CheckForNull String getKeyStoreStorePass() { - String storePass = this.configurationOverlay.keystoreStorePass; - if (storePass != null) - return storePass; - if (getKeyStorePassStorageType() != KeyStorePassStorageType.DISK) - return null; - return getKeyStoreStorePassPersistent(); - } - - public @CheckForNull String getKeyStoreStorePassPersistent() { - return this.configuration.keystoreStorePass; - } - - public void setKeyStoreKeyPassPersistent(@CheckForNull String keyPass) { - this.configuration.keystoreKeyPass = keyPass; - } - - public void setKeyStoreKeyPassOverlay(@CheckForNull String keyPass) { - this.configurationOverlay.keystoreKeyPass = keyPass; - } - - public @CheckForNull String getKeyStoreKeyPass() { - String keyPass = this.configurationOverlay.keystoreKeyPass; - if (keyPass != null) - return keyPass; - if (getKeyStorePassStorageType() != KeyStorePassStorageType.DISK) - return null; - return getKeyStoreKeyPassPersistent(); - } - - public @CheckForNull String getKeyStoreKeyPassPersistent() { - return this.configuration.keystoreKeyPass; - } - - public void setUpdateCheckPersistent(boolean checkUpdate) { - this.configuration.updateCheck = checkUpdate; - } - - public boolean getUpdateCheck() { - return this.configuration.updateCheck; - } - - public void setMainWindowSizePersistent(@Nonnull Point size) { - this.configuration.mainWindowSize = size; - } - - public @Nonnull Point getMainWindowSize() { - return this.configuration.mainWindowSize; - } - - public boolean getSkipFinish() { - return this.configurationOverlay.skipFinish; - } - - public void setSkipFinishOverlay(boolean skipFinish) { - this.configurationOverlay.skipFinish = skipFinish; - } - - public boolean getUseSignatureFields() { - return this.configuration.getUseSignatureFields(); - } - - public void setUseSignatureFieldsPersistent(boolean useFields) { - this.configuration.setUseSignatureFields(useFields); - if (useFields) setUseMarkerPersistent(false); - } - - public boolean getUseMarker() { - return this.configuration.getUseMarker(); - } - - public void setUseMarkerPersistent(boolean useMarker) { - this.configuration.setUseMarker(useMarker); - if (useMarker) setUseSignatureFieldsPersistent(false); - } - - public void setSaveFilePostFixPersistent(@Nonnull String postFix) { - this.configuration.saveFilePostFix = postFix; - } - - public @Nonnull String getSaveFilePostFix(){ - return this.configuration.saveFilePostFix; - } - - public @Nonnull Profile getSignatureProfile() { - return ISNOTNULL(fallThroughOnNull(this.configuration.signatureProfile, Profile.SIGNATURBLOCK_SMALL)); - } - - public void setSignatureProfilePersistent(Profile profile) { - this.configuration.signatureProfile = profile; - } - - public void setEnablePlaceholderUsagePersistent(boolean bool) { - this.configuration.enabledPlaceholderUsage = bool; - } - - public boolean getEnablePlaceholderUsage() { - return this.configuration.enabledPlaceholderUsage; - } - - public void setFido2ByDefaultPersistent(boolean bool) { - this.configuration.fido2ByDefault = bool; - } - - public boolean getFido2ByDefault() { - return this.configuration.fido2ByDefault; - } - -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/BKUSelectionState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/BKUSelectionState.java deleted file mode 100644 index d1bdfe0d..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/BKUSelectionState.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.io.File; - -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.bku.LocalBKUConnector; -import at.asit.pdfover.commons.BKUs; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.composites.BKUSelectionComposite; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; - -/** - * Decides which BKU to use (preconfigured or let user choose) - */ -public class BKUSelectionState extends State { - - /** - * @param stateMachine - */ - public BKUSelectionState(StateMachine stateMachine) { - super(stateMachine); - } - - /** - * SLF4J Logger instance - **/ - @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(BKUSelectionState.class); - - private BKUSelectionComposite selectionComposite = null; - private BKUSelectionComposite getSelectionComposite() { - if (this.selectionComposite == null) { - this.selectionComposite = - getStateMachine().createComposite(BKUSelectionComposite.class, SWT.RESIZE, this); - } - - return this.selectionComposite; - } - - private boolean isKeystoreEnabled() { - if (getStateMachine().configProvider.getKeyStoreEnabled()) { - File ks = new File(getStateMachine().configProvider.getKeyStoreFile()); - return ks.exists(); - } else - return false; - } - - @Override - public void run() { - Status status = getStateMachine().status; - State previousState = status.getPreviousState(); - - final boolean hasLocalBKU = LocalBKUConnector.IsAvailable(); - final boolean hasKeystore = isKeystoreEnabled(); - if ( - (previousState instanceof OpenState) || - (previousState instanceof PositioningState) - ) { - if (!hasLocalBKU && !hasKeystore) - status.bku = BKUs.MOBILE; - } else if (!(previousState instanceof BKUSelectionState)) { - status.bku = BKUs.NONE; - } - - if(status.bku == BKUs.NONE) { - BKUSelectionComposite selection = this.getSelectionComposite(); - selection.setLocalBKUEnabled(hasLocalBKU); - selection.setKeystoreEnabled(hasKeystore); - - getStateMachine().display(selection); - selection.layout(); - - status.bku = selection.getSelected(); - - if(status.bku == BKUs.NONE) { - return; - } - } - this.setNextState(new PrepareSigningState(getStateMachine())); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - if (this.selectionComposite != null) - this.selectionComposite.dispose(); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setEnabled(Buttons.CONFIG, true); - behavior.setEnabled(Buttons.OPEN, true); - behavior.setEnabled(Buttons.POSITION, true); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ConfigurationUIState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ConfigurationUIState.java deleted file mode 100644 index 7393f13e..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ConfigurationUIState.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -// Imports -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.composites.ConfigurationComposite; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; - -/** - * - */ -public class ConfigurationUIState extends State { - private static final Logger log = LoggerFactory.getLogger(ConfigurationUIState.class); - - private ConfigurationComposite configurationComposite = null; - - private ConfigurationComposite getConfigurationComposite() { - if (this.configurationComposite == null) { - this.configurationComposite = - getStateMachine().createComposite(ConfigurationComposite.class, SWT.RESIZE, this); - this.configurationComposite.setConfigProvider(getStateMachine().configProvider); - } - - return this.configurationComposite; - } - - /** - * @param stateMachine - */ - public ConfigurationUIState(StateMachine stateMachine) { - super(stateMachine); - } - - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#run() - */ - @Override - public void run() { - Status status = getStateMachine().status; - - ConfigurationComposite config; - try { - config = this.getConfigurationComposite(); - getStateMachine().display(config); - } catch (Exception e) { - log.error("Failed to initialize config UI", e); - ErrorDialog error = new ErrorDialog( - getStateMachine().getMainShell(), - Messages.getString("error.ConfigInitialization"), - BUTTONS.YES_NO - ); - - int selection = error.open(); - if (selection == SWT.YES) - { - ConfigurationManager.factoryResetPersistentConfig(); - getStateMachine().exit(); - return; - } - - throw e; - } - - if(config.isUserDone()) - { - this.reloadResources(); - State previousState = status.getPreviousState(); - if (previousState instanceof OutputState) - this.setNextState(new OpenState(getStateMachine())); - else - this.setNextState(previousState); // TODO do we need to tell a previous state to refresh from config settings? (positioning preview) - } - } - - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - if(this.configurationComposite != null) - this.configurationComposite.dispose(); - } - - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#updateMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - // Leave the state as it is - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.setEnabled(Buttons.CONFIG, false); - behavior.setMainBarVisible(false); - } - - /** - * Triggers to reload the resources - */ - public void reloadResources() { - getStateMachine().reloadResources(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/KSState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/KSState.java deleted file mode 100644 index 42a2f605..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/KSState.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -// Imports -import java.io.File; -import java.security.Key; -import java.security.KeyStore; -import java.security.UnrecoverableKeyException; - -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.keystore.KeystoreUtils; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.gui.controls.PasswordInputDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.gui.workflow.config.ConfigurationDataInMemory.KeyStorePassStorageType; -import at.asit.pdfover.signer.SignatureException; -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; - -/** - * Logical state for performing the BKU Request to a local BKU - */ -public class KSState extends State { - - /** - * SLF4J Logger instance - **/ - static final Logger log = LoggerFactory.getLogger(KSState.class); - - /** - * Constructor - * @param stateMachine the StateMachine - */ - public KSState(StateMachine stateMachine) { - super(stateMachine); - } - - private void showError(String messageKey, Object... args) - { - new ErrorDialog(getStateMachine().getMainShell(), Messages.formatString(messageKey, args), BUTTONS.OK).open(); - } - - private boolean askShouldRetry(String messageKey, Object... args) - { - return SWT.RETRY == (new ErrorDialog(getStateMachine().getMainShell(), Messages.formatString(messageKey, args), BUTTONS.RETRY_CANCEL).open()); - } - - /* - * (non-Javadoc) - * - * @see - * at.asit.pdfover.gui.workflow.WorkflowState#update(at.asit.pdfover.gui - * .workflow.Workflow) - */ - @Override - public void run() { - Status status = getStateMachine().status; - - PdfAs4SigningState signingState = status.signingState; - ConfigurationManager config = getStateMachine().configProvider; - - try { - String file = config.getKeyStoreFile(); - File f = new File(file); - if (!f.isFile()) { - log.error("Keystore not found"); - if (askShouldRetry("error.KeyStoreFileNotExist", f.getName())) - this.run(); - else - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - String type = config.getKeyStoreType(); - KeyStore keyStore = null; - String storePass = config.getKeyStoreStorePass(); - while (keyStore == null) { - if (storePass == null) - { - storePass = new PasswordInputDialog( - getStateMachine().getMainShell(), - Messages.getString("keystore_config.KeystoreStorePass"), - Messages.getString("keystore.KeystoreStorePassEntry")).open(); - - if (storePass == null) - { - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - } - - try { - keyStore = KeystoreUtils.tryLoadKeystore(f, type, storePass); - } catch (UnrecoverableKeyException e) { - showError("error.KeyStoreStorePass"); - storePass = null; - } catch (Exception e) { - throw new SignatureException("Failed to load keystore", e); - } - } - - /* we've successfully unlocked the key store, save the entered password if requested */ - if (config.getKeyStorePassStorageType() == KeyStorePassStorageType.DISK) - { - /* only save to disk if the current keystore file is the one saved to disk */ - /* (might not be true if overridden from CLI) */ - if (file.equals(config.getKeyStoreFilePersistent())) - config.setKeyStoreStorePassPersistent(storePass); - else - config.setKeyStoreStorePassOverlay(storePass); - } - else if (config.getKeyStorePassStorageType() == KeyStorePassStorageType.MEMORY) - config.setKeyStoreStorePassOverlay(storePass); - - /* next, try to load the key from the now-unlocked keystore */ - String alias = config.getKeyStoreAlias(); - Key key = null; - String keyPass = config.getKeyStoreKeyPass(); - while (key == null) { - if (keyPass == null) { - keyPass = new PasswordInputDialog( - getStateMachine().getMainShell(), - Messages.getString("keystore_config.KeystoreKeyPass"), - Messages.getString("keystore.KeystoreKeyPassEntry")).open(); - - if (keyPass == null) - { - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - } - - try { - key = keyStore.getKey(alias, keyPass.toCharArray()); - if (key == null) /* alias does not exist */ - { - if (!askShouldRetry("error.KeyStoreAliasExist", alias)) - { - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - continue; - } - } catch (UnrecoverableKeyException e) { - showError("error.KeyStoreKeyPass"); - keyPass = null; - } catch (Exception e) { - throw new SignatureException("Failed to load key from store", e); - } - } - - if (config.getKeyStorePassStorageType() == KeyStorePassStorageType.DISK) - { - if (file.equals(config.getKeyStoreFilePersistent())) - config.setKeyStoreKeyPassPersistent(keyPass); - else - config.setKeyStoreKeyPassOverlay(keyPass); - } - else if (config.getKeyStorePassStorageType() == KeyStorePassStorageType.MEMORY) - config.setKeyStoreKeyPassOverlay(keyPass); - - signingState.setKeystoreSigner(file, alias, storePass, keyPass, type); - } catch (SignatureException e) { - log.error("Error loading keystore", e); - if (askShouldRetry("error.KeyStore")) - this.run(); /* recurse */ - else - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - - // OK - this.setNextState(new at.asit.pdfover.gui.workflow.states.SigningState(getStateMachine())); - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - // No composite - no cleanup necessary - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java deleted file mode 100644 index f1bfa5b9..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -// Imports -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.methods.PostMethod; -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.bku.BKUHelper; -import at.asit.pdfover.gui.bku.LocalBKUConnector; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; - -/** - * Logical state for performing the BKU Request to a local BKU - */ -public class LocalBKUState extends State { - - /** - * SLF4J Logger instance - **/ - static final Logger log = LoggerFactory.getLogger(LocalBKUState.class); - - /** - * HTTP Response server HEADER - */ - public final static String BKU_RESPONSE_HEADER_SERVER = "server"; - - /** - * HTTP Response user-agent HEADER - */ - public final static String BKU_RESPONSE_HEADER_USERAGENT = "user-agent"; - - /** - * HTTP Response SignatureLayout HEADER - */ - public final static String BKU_RESPONSE_HEADER_SIGNATURE_LAYOUT = "SignatureLayout"; - - Exception threadException = null; - - /** Whether to use Base64 or FileUpload Request */ - boolean useBase64Request = false; - - /** - * Null-Operation SL-Request - */ - private final static String NULL_OPERATION_REQUEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<sl:NullOperationRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\"/>"; - - /** - * Constructor - * @param stateMachine the StateMachine - */ - public LocalBKUState(StateMachine stateMachine) { - super(stateMachine); - } - - /** - * - */ - private final class SignLocalBKUThread implements Runnable { - - private LocalBKUState state; - private PdfAs4SigningState signingState; - - - /** - * @param localBKUState - * @param signingState - */ - public SignLocalBKUThread(LocalBKUState localBKUState, PdfAs4SigningState signingState) { - this.state = localBKUState; - this.signingState = signingState; - } - - @Override - public void run() { - try { - - HttpClient client = (HttpClient) BKUHelper.getHttpClient(); - - PostMethod method = new PostMethod(Constants.LOCAL_BKU_URL); - - String sl_request = NULL_OPERATION_REQUEST; - method.addParameter("XMLRequest", sl_request); - int returnCode = client.executeMethod(method); - - if (returnCode != HttpStatus.SC_OK) { - this.state.threadException = new HttpException( - method.getResponseBodyAsString()); - } else { - String server = getResponseHeader(method, BKU_RESPONSE_HEADER_SERVER); - if ((server != null) && (server.contains("trustDeskbasic") || server.contains("asignSecurityLayer"))) - LocalBKUState.this.useBase64Request = true; - - this.signingState.signatureResponse = method.getResponseBodyAsString(); - this.signingState.useBase64Request = LocalBKUState.this.useBase64Request; - } - } catch (Exception e) { - log.error("SignLocalBKUThread: ", e); - - this.state.threadException = e; - } finally { - this.state.updateStateMachine(); - } - } - - /** - * Returns the value corresponding to the given header name - * @param method the HTTP method - * @param headerName the header name - * @return the header value (or null if not found) - */ - private String getResponseHeader(HttpMethod method, String headerName) { - if (method.getResponseHeader(headerName) == null) - return null; - return method.getResponseHeader(headerName).getValue(); - } - } - - /* - * (non-Javadoc) - * - * @see - * at.asit.pdfover.gui.workflow.WorkflowState#update(at.asit.pdfover.gui - * .workflow.Workflow) - */ - @Override - public void run() { - Status status = getStateMachine().status; - - PdfAs4SigningState signingState = status.signingState; - - if ((signingState.signatureResponse == null) - && this.threadException == null) { - Thread t = new Thread(new SignLocalBKUThread(this, signingState)); - t.start(); - return; - } - signingState.bkuConnector = new LocalBKUConnector(); - - if (this.threadException != null) { - ErrorDialog dialog = new ErrorDialog( - getStateMachine().getMainShell(), - Messages.getString("error.LocalBKU"), - BUTTONS.RETRY_CANCEL); - if (dialog.open() != SWT.RETRY) { - //getStateMachine().exit(); - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - this.threadException = null; - this.run(); - return; - } - - // OK - this.setNextState(new at.asit.pdfover.gui.workflow.states.SigningState(getStateMachine())); - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - // No composite - no cleanup necessary - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java deleted file mode 100644 index d858c067..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java +++ /dev/null @@ -1,668 +0,0 @@ -/*
- * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package at.asit.pdfover.gui.workflow.states;
-
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.URI;
-import java.net.UnknownHostException;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-// Imports
-import at.asit.pdfover.signer.UserCancelledException;
-import at.asit.pdfover.signer.pdfas.PdfAs4SigningState;
-import at.asit.webauthn.PublicKeyCredential;
-import at.asit.webauthn.responsefields.AuthenticatorAssertionResponse;
-
-import org.apache.hc.client5.http.classic.methods.HttpGet;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import at.asit.pdfover.gui.MainWindow.Buttons;
-import at.asit.pdfover.gui.MainWindowBehavior;
-import at.asit.pdfover.gui.bku.MobileBKUConnector;
-import at.asit.pdfover.gui.composites.WaitingComposite;
-import at.asit.pdfover.gui.composites.mobilebku.MobileBKUEnterNumberComposite;
-import at.asit.pdfover.gui.composites.mobilebku.MobileBKUEnterTANComposite;
-import at.asit.pdfover.gui.composites.mobilebku.MobileBKUFido2Composite;
-import at.asit.pdfover.gui.composites.mobilebku.MobileBKUFingerprintComposite;
-import at.asit.pdfover.gui.composites.mobilebku.MobileBKUQRComposite;
-import at.asit.pdfover.gui.composites.mobilebku.WaitingForAppComposite;
-import at.asit.pdfover.gui.controls.Dialog.BUTTONS;
-import at.asit.pdfover.gui.controls.Dialog.ICON;
-import at.asit.pdfover.gui.controls.Dialog;
-import at.asit.pdfover.gui.controls.ErrorDialog;
-import at.asit.pdfover.commons.Messages;
-import at.asit.pdfover.gui.workflow.StateMachine;
-
-import static at.asit.pdfover.commons.Constants.ISNOTNULL;
-
-/**
- * Logical state for performing the BKU Request to the A-Trust Mobile BKU
- */
-public class MobileBKUState extends State {
- static final Logger log = LoggerFactory.getLogger(MobileBKUState.class);
-
- PdfAs4SigningState signingState;
-
- public Exception threadException = null;
-
- public MobileBKUState(StateMachine stateMachine) {
- super(stateMachine);
- }
-
- MobileBKUEnterTANComposite mobileBKUEnterTANComposite = null;
-
- WaitingForAppComposite waitingForAppComposite = null;
- WaitingForAppComposite getWaitingForAppComposite() {
- if (this.waitingForAppComposite == null) {
- this.waitingForAppComposite = getStateMachine()
- .createComposite(WaitingForAppComposite.class, SWT.RESIZE, this);
- }
-
- return this.waitingForAppComposite;
- }
-
- WaitingComposite waitingComposite = null;
- WaitingComposite getWaitingComposite() {
- if (this.waitingComposite == null) {
- this.waitingComposite = getStateMachine()
- .createComposite(WaitingComposite.class, SWT.RESIZE, this);
- }
-
- return this.waitingComposite;
- }
-
- MobileBKUEnterTANComposite getMobileBKUEnterTANComposite() {
- if (this.mobileBKUEnterTANComposite == null) {
- this.mobileBKUEnterTANComposite = getStateMachine()
- .createComposite(MobileBKUEnterTANComposite.class, SWT.RESIZE, this);
- }
-
- return this.mobileBKUEnterTANComposite;
- }
-
- MobileBKUQRComposite mobileBKUQRComposite = null;
- MobileBKUQRComposite getMobileBKUQRComposite() {
- if (this.mobileBKUQRComposite == null) {
- this.mobileBKUQRComposite = getStateMachine()
- .createComposite(MobileBKUQRComposite.class, SWT.RESIZE, this);
- }
-
- return this.mobileBKUQRComposite;
- }
-
- MobileBKUEnterNumberComposite mobileBKUEnterNumberComposite = null;
- MobileBKUEnterNumberComposite getMobileBKUEnterNumberComposite() {
- if (this.mobileBKUEnterNumberComposite == null) {
- this.mobileBKUEnterNumberComposite = getStateMachine()
- .createComposite(MobileBKUEnterNumberComposite.class, SWT.RESIZE, this);
- }
-
- return this.mobileBKUEnterNumberComposite;
- }
-
- MobileBKUFingerprintComposite mobileBKUFingerprintComposite = null;
- MobileBKUFingerprintComposite getMobileBKUFingerprintComposite() {
- if (this.mobileBKUFingerprintComposite == null) {
- this.mobileBKUFingerprintComposite = getStateMachine()
- .createComposite(MobileBKUFingerprintComposite.class, SWT.RESIZE, this);
- }
-
- return this.mobileBKUFingerprintComposite;
- }
-
- MobileBKUFido2Composite mobileBKUFido2Composite = null;
- MobileBKUFido2Composite getMobileBKUFido2Composite() {
- if (this.mobileBKUFido2Composite == null) {
- this.mobileBKUFido2Composite = getStateMachine()
- .createComposite(MobileBKUFido2Composite.class, SWT.RESIZE, this);
- }
-
- return this.mobileBKUFido2Composite;
- }
-
- /**
- * @return the signingState
- */
- public PdfAs4SigningState getSigningState() {
- return this.signingState;
- }
-
- /**
- * Display an error message
- *
- * @param e
- * the exception
- */
- public void displayError(Exception e) {
- String message = null;
- if (e instanceof UnknownHostException)
- {
- log.error("Failed to resolve hostname", e);
- message = Messages.formatString("error.CouldNotResolveHostname", e.getMessage());
- } else if (e instanceof ConnectException) {
- log.error("Failed to connect", e);
- message = Messages.formatString("error.FailedToConnect", e.getMessage());
- } else {
- message = Messages.getString("error.Unexpected");
- log.error(message, e);
- String errormsg = e.getLocalizedMessage();
- if (errormsg != null && !errormsg.isEmpty())
- message += ": " + errormsg;
- }
- displayError(message);
- }
-
- /**
- * Display an error message
- *
- * @param message
- * the error message
- */
- public void displayError(final String message) {
- log.error(message);
- Display.getDefault().syncExec(() -> {
- ErrorDialog error = new ErrorDialog(getStateMachine().getMainShell(), message, BUTTONS.OK);
- error.open();
- });
- }
-
- public void showInformationMessage(final @Nonnull String message) throws UserCancelledException {
- Display.getDefault().syncCall(() -> {
- Dialog dialog = new Dialog(getStateMachine().getMainShell(), Messages.getString("common.info"), message, BUTTONS.OK, ICON.INFORMATION);
- int result = dialog.open();
- if (result == SWT.CANCEL)
- throw new UserCancelledException();
- return true; /* dummy return to keep java happy */
- });
- }
-
- /**
- * Show an error message to the user with "retry" or "cancel" as options
- * returns normally on "retry", throws UserCancelledException on "cancel"
- */
- public void showRecoverableError(final @Nonnull String errorMessage) throws UserCancelledException {
- Display.getDefault().syncCall(() -> {
- ErrorDialog error = new ErrorDialog(getStateMachine().getMainShell(), errorMessage, BUTTONS.RETRY_CANCEL);
- int result = error.open();
- if (result == SWT.CANCEL)
- throw new UserCancelledException();
- return true; /* dummy return */
- });
- }
-
- /**
- * Show an error message to the user with only an "ok" option;
- * throws UserCancelledException afterwards
- */
- public void showUnrecoverableError(final @Nonnull String errorMessage) throws UserCancelledException {
- Display.getDefault().syncCall(() -> {
- ErrorDialog error = new ErrorDialog(getStateMachine().getMainShell(), errorMessage, BUTTONS.OK);
- error.open();
- throw new UserCancelledException();
- });
- }
-
- public static class UsernameAndPassword {
- public @CheckForNull String username;
- public @CheckForNull String password;
- public UsernameAndPassword() {}
- public UsernameAndPassword(@Nullable String u, @Nullable String p) { this.username = u; this.password = p; }
- }
- public @Nonnull UsernameAndPassword getRememberedCredentials() {
- UsernameAndPassword r = new UsernameAndPassword();
- storeRememberedCredentialsTo(r);
- return r;
- }
- public void storeRememberedCredentialsTo(@Nonnull UsernameAndPassword output) {
- output.username = getStateMachine().configProvider.getDefaultMobileNumber();
- output.password = getStateMachine().configProvider.getDefaultMobilePassword();
- }
-
- public void rememberCredentialsIfNecessary(@Nullable String username, @Nullable String password) {
- if (getStateMachine().configProvider.getRememberMobilePassword())
- {
- getStateMachine().configProvider.setDefaultMobileNumberPersistent(username);
- getStateMachine().configProvider.setDefaultMobilePasswordOverlay(password);
- }
- }
- public void rememberCredentialsIfNecessary(@Nonnull UsernameAndPassword credentials) {
- rememberCredentialsIfNecessary(credentials.username, credentials.password);
- }
-
- public void clearRememberedPassword() {
- getStateMachine().configProvider.setDefaultMobilePasswordOverlay(null);
- }
-
- public @Nonnull UsernameAndPassword getCredentialsFromUser(@Nullable String currentUsername, @Nullable String errorMessage) throws UserCancelledException {
- UsernameAndPassword r = new UsernameAndPassword(currentUsername, null);
- getCredentialsFromUserTo(r, errorMessage);
- return r;
- }
-
- private void updateRememberPasswordSetting(boolean enabled, boolean allowEnabling) {
- final var config = getStateMachine().configProvider;
- if (enabled == config.getRememberMobilePassword()) /* nothing to do here */
- return;
- if (enabled && !allowEnabling) /* do not allow "cancel" to set the remember checkbox */
- return;
- config.setRememberMobilePasswordPersistent(enabled);
- if (!enabled) { /* clear remembered info */
- config.setDefaultMobileNumberPersistent(null);
- config.setDefaultMobilePasswordOverlay(null);
- }
- }
-
- public void getCredentialsFromUserTo(@Nonnull UsernameAndPassword credentials, @Nullable String errorMessage) throws UserCancelledException {
- Display.getDefault().syncCall(() -> {
- MobileBKUEnterNumberComposite ui = this.getMobileBKUEnterNumberComposite();
-
- if (!ui.userAck) { // We need number and password => show UI!
-
- if (errorMessage != null)
- ui.setErrorMessage(errorMessage);
- else
- ui.setErrorMessage(Messages.getString("mobileBKU.aTrustDisclaimer"));
-
- if ((ui.getMobileNumber() == null) || ui.getMobileNumber().isEmpty()) {
- // set possible phone number
- ui.setMobileNumber(credentials.username);
- }
-
- ui.setRememberPassword(getStateMachine().configProvider.getRememberMobilePassword());
-
- ui.enableButton();
- getStateMachine().display(ui);
-
- Display display = getStateMachine().getMainShell().getDisplay();
- while (!ui.userAck && !ui.userCancel) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
- }
-
- updateRememberPasswordSetting(ui.isRememberPassword(), !ui.userCancel);
-
- if (ui.userCancel) {
- ui.userCancel = false;
- throw new UserCancelledException();
- }
-
- // user hit ok
- ui.userAck = false;
-
- // get number and password from UI
- credentials.username = ui.getMobileNumber();
- credentials.password = ui.getMobilePassword();
-
- // show waiting composite
- getStateMachine().display(this.getWaitingComposite());
-
- return true; /* dummy return for lambda type deduction */
- });
- }
-
- public static class SMSTanResult {
- public static enum ResultType { TO_FIDO2, SMSTAN };
- public final @Nonnull ResultType type;
- public final @CheckForNull String smsTan;
-
- private SMSTanResult(@Nullable String smsTan) { this.type = ResultType.SMSTAN; this.smsTan = smsTan; }
- private SMSTanResult(@Nonnull ResultType type) { this.type = type; this.smsTan = null; }
- }
-
- public @Nonnull SMSTanResult getSMSTanFromUser(final @Nonnull String referenceValue, final @Nullable URI signatureDataURI, final boolean showFido2, final @Nullable String errorMessage) throws UserCancelledException {
- return ISNOTNULL(Display.getDefault().syncCall(() -> {
- MobileBKUEnterTANComposite tan = getMobileBKUEnterTANComposite();
-
- tan.reset();
- tan.setRefVal(referenceValue);
- tan.setSignatureDataURI(signatureDataURI);
- tan.setErrorMessage(errorMessage);
- tan.setFIDO2Enabled(showFido2);
- getStateMachine().display(tan);
-
- Display display = getStateMachine().getMainShell().getDisplay();
- while (!tan.isDone()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
- getStateMachine().display(getWaitingComposite());
-
- if (tan.isUserCancel())
- throw new UserCancelledException();
-
- if (tan.isUserFido2())
- return new SMSTanResult(SMSTanResult.ResultType.TO_FIDO2);
-
- return new SMSTanResult(tan.getTan());
- }));
- }
-
- /**
- * start showing the QR code at the indicated URI
- * this method will return immediately */
- public void showQRCode(final @Nonnull String referenceValue, @Nonnull URI qrCodeURI, @Nullable URI signatureDataURI, final boolean showSmsTan, final boolean showFido2, final @Nullable String errorMessage) {
- byte[] qrCode;
- try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
- try (final CloseableHttpResponse response = httpClient.execute(new HttpGet(qrCodeURI))) {
- qrCode = EntityUtils.toByteArray(response.getEntity());
- }
- } catch (IOException e) {
- log.warn("Failed to load QR code.");
- qrCode = null;
- }
-
- final byte[] qrCodeCopy = qrCode; /* because java is silly */
- Display.getDefault().syncExec(() -> {
- MobileBKUQRComposite qr = getMobileBKUQRComposite();
- qr.reset();
-
- qr.setRefVal(referenceValue);
- qr.setSignatureDataURI(signatureDataURI);
- qr.setErrorMessage(errorMessage);
- qr.setQR(qrCodeCopy);
- qr.setSMSEnabled(showSmsTan);
- qr.setFIDO2Enabled(showFido2);
- getStateMachine().display(qr);
- });
- }
-
- public enum QRResult {
- /* the user has pressed the FIDO2 button */
- TO_FIDO2,
- /* the user has pressed the SMS button */
- TO_SMS,
- /* signalQRScanned has been called; this indicates that we should refresh the page */
- UPDATE
- };
-
- public @Nonnull QRResult waitForQRCodeResult() throws UserCancelledException {
- return ISNOTNULL(Display.getDefault().syncCall(() -> {
- MobileBKUQRComposite qr = getMobileBKUQRComposite();
-
- Display display = getStateMachine().getMainShell().getDisplay();
- while (!qr.isDone()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- getStateMachine().display(this.getWaitingComposite());
-
- if (qr.wasCancelClicked()) {
- clearRememberedPassword();
- throw new UserCancelledException();
- }
-
- if (qr.wasSMSClicked())
- return QRResult.TO_SMS;
-
- if (qr.wasFIDO2Clicked())
- return QRResult.TO_FIDO2;
-
- return QRResult.UPDATE;
- }));
- }
-
- /**
- * indicate that the long polling operation completed
- * (any ongoing waitForQRCodeResult call will then return)
- */
- public void signalQRScanned() {
- getMobileBKUQRComposite().signalPollingDone();
- }
-
- /**
- * start showing the "waiting for app" screen
- * this method will return immediately */
- public void showWaitingForAppOpen(final @Nonnull String referenceValue, @Nullable URI signatureDataURI, final boolean showSmsTan, final boolean showFido2) {
- Display.getDefault().syncExec(() -> {
- WaitingForAppComposite wfa = getWaitingForAppComposite();
- wfa.reset();
-
- // TODO composite does not currently support: refval, signature data
- wfa.setSMSEnabled(showSmsTan);
- wfa.setFIDO2Enabled(showFido2);
- getStateMachine().display(wfa);
- });
- }
-
- public enum AppOpenResult {
- /* the user has pressed the FIDO2 button */
- TO_FIDO2,
- /* the user has pressed the SMS button */
- TO_SMS,
- /* signalAppOpened has been called; this indicates that we should refresh the page */
- UPDATE
- };
-
- public @Nonnull AppOpenResult waitForAppOpen() throws UserCancelledException {
- return ISNOTNULL(Display.getDefault().syncCall(() -> {
- WaitingForAppComposite wfa = getWaitingForAppComposite();
-
- Display display = wfa.getDisplay();
- while (!wfa.isDone()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
-
- getStateMachine().display(this.getWaitingComposite());
-
- if (wfa.wasCancelClicked()) {
- clearRememberedPassword();
- throw new UserCancelledException();
- }
-
- if (wfa.wasSMSClicked())
- return AppOpenResult.TO_SMS;
-
- if (wfa.wasFIDO2Clicked())
- return AppOpenResult.TO_FIDO2;
-
- return AppOpenResult.UPDATE;
- }));
- }
-
- /**
- * indicate that the long polling operation completed
- * (any ongoing waitForAppOpen call will then return)
- */
- public void signalAppOpened() {
- getWaitingForAppComposite().signalPollingDone();
- }
-
- public void showWaitingForAppBiometry(final @Nonnull String referenceValue, @Nullable URI signatureDataURI, final boolean showSmsTan, final boolean showFido2) {
- Display.getDefault().syncExec(() -> {
- MobileBKUFingerprintComposite bio = getMobileBKUFingerprintComposite();
- bio.reset();
-
- bio.setRefVal(referenceValue);
- bio.signatureDataURI = signatureDataURI;
- bio.setErrorMessage(null); // TODO
- bio.setSMSEnabled(showSmsTan);
- bio.setFIDO2Enabled(showFido2);
- getStateMachine().display(bio);
- });
- }
-
- // TODO can we maybe deduplicate the various waiting screens' logic?
-
- public enum AppBiometryResult {
- /* the user has pressed the FIDO2 button */
- TO_FIDO2,
- /* the user has pressed the SMS button */
- TO_SMS,
- /* signalAppBiometryDone has been called; this indicates that we should refresh the page */
- UPDATE
- };
-
- public @Nonnull AppBiometryResult waitForAppBiometry() throws UserCancelledException {
- return ISNOTNULL(Display.getDefault().syncCall(() -> {
- MobileBKUFingerprintComposite bio = getMobileBKUFingerprintComposite();
-
- Display display = bio.getDisplay();
- while (!bio.isDone()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
-
- getStateMachine().display(this.getWaitingComposite());
-
- if (bio.wasCancelClicked()) {
- clearRememberedPassword();
- throw new UserCancelledException();
- }
-
- if (bio.wasSMSClicked())
- return AppBiometryResult.TO_SMS;
-
- if (bio.wasFIDO2Clicked())
- return AppBiometryResult.TO_FIDO2;
-
- return AppBiometryResult.UPDATE;
- }));
- }
-
- public void signalAppBiometryDone() {
- getMobileBKUFingerprintComposite().signalPollingDone();
- }
-
- public static class FIDO2Result {
- public static enum ResultType { TO_SMS, CREDENTIAL };
- public final @Nonnull ResultType type;
- public final @Nullable PublicKeyCredential<AuthenticatorAssertionResponse> credential;
-
- private FIDO2Result(@Nonnull ResultType type) { this.type = type; this.credential = null; }
- private FIDO2Result(@Nonnull PublicKeyCredential<AuthenticatorAssertionResponse> cred) { this.type = ResultType.CREDENTIAL; this.credential = cred; }
- }
-
- /**
- * prompts user for fido2 auth and blocks until result is available
- * @param fido2Options JSON data from A-Trust
- * @return
- * @throws UserCancelledException
- */
- public @Nonnull FIDO2Result promptUserForFIDO2Auth(final @Nonnull String fido2Options, @Nullable URI signatureDataURI, final boolean showSmsTan) throws UserCancelledException {
- return ISNOTNULL(Display.getDefault().syncCall(() -> {
- MobileBKUFido2Composite fido2 = getMobileBKUFido2Composite();
- fido2.initialize(fido2Options);
- fido2.setSMSEnabled(showSmsTan);
- fido2.setSignatureDataURI(signatureDataURI);
-
- getStateMachine().display(fido2);
-
- Display display = fido2.getDisplay();
- while (!fido2.isDone()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
-
- getStateMachine().display(this.getWaitingComposite());
-
- if (fido2.wasUserCancelClicked())
- throw new UserCancelledException();
-
- if (fido2.wasUserSMSClicked())
- return new FIDO2Result(FIDO2Result.ResultType.TO_SMS);
-
- return new FIDO2Result(ISNOTNULL(fido2.getResultingCredential()));
- }));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * at.asit.pdfover.gui.workflow.WorkflowState#update(at.asit.pdfover.gui
- * .workflow.Workflow)
- */
- @Override
- public void run() {
- this.signingState = getStateMachine().status.signingState;
-
- this.signingState.bkuConnector = new MobileBKUConnector(this);
- this.signingState.useBase64Request = false;
-
- if (this.threadException != null) {
- displayError(this.threadException);
- return;
- }
-
- getStateMachine().display(
- this.getWaitingComposite());
-
- this.setNextState(new SigningState(getStateMachine()));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see at.asit.pdfover.gui.workflow.states.State#cleanUp()
- */
- @Override
- public void cleanUp() {
- if (this.mobileBKUEnterNumberComposite != null)
- this.mobileBKUEnterNumberComposite.dispose();
- if (this.mobileBKUEnterTANComposite != null)
- this.mobileBKUEnterTANComposite.dispose();
- if (this.waitingComposite != null)
- this.waitingComposite.dispose();
- if (this.waitingForAppComposite != null)
- this.waitingForAppComposite.dispose();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior()
- */
- @Override
- public void updateMainWindowBehavior() {
- MainWindowBehavior behavior = getStateMachine().status.behavior;
- behavior.reset();
- behavior.setActive(Buttons.OPEN, true);
- behavior.setActive(Buttons.POSITION, true);
- behavior.setActive(Buttons.SIGN, true);
- behavior.setEnabled(Buttons.OPEN, true);
- behavior.setEnabled(Buttons.POSITION, true);
- //behavior.setEnabled(Buttons.SIGN, true);
- }
-
- @Override
- public String toString() {
- return this.getClass().getName();
- }
-
- /**
- * invoke state machine update in main thread
- */
- public void invokeUpdate() {
- getStateMachine().invokeUpdate();
- }
-}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OpenState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OpenState.java deleted file mode 100644 index 12b16da7..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OpenState.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; - -import at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder.SignatureFieldsAndPlaceHolderExtractor; - -import org.apache.pdfbox.pdmodel.PDDocument; - -//Imports -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.MessageBox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.bku.LocalBKUConnector; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.PlaceholderSelectionGui; -import at.asit.pdfover.gui.composites.DataSourceSelectComposite; -import at.asit.pdfover.gui.utils.SWTUtils; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.commons.Profile; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.signer.SignaturePosition; -import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData; - - - -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.configuration.PropertiesConfigurationLayout; - - -/** - * Selects the data source for the signature process. - */ -public class OpenState extends State { - - /** - * @param stateMachine - */ - public OpenState(StateMachine stateMachine) { - super(stateMachine); - } - - /** - * SLF4J Logger instance - **/ - private static final Logger log = LoggerFactory.getLogger(OpenState.class); - private static final String advancedConfig = Constants.CONFIG_DIRECTORY + File.separator + "/cfg/advancedconfig.properties"; - - private DataSourceSelectComposite selectionComposite = null; - - private DataSourceSelectComposite getSelectionComposite() { - if (this.selectionComposite == null) { - this.selectionComposite = - getStateMachine().createComposite(DataSourceSelectComposite.class, SWT.RESIZE, this); - } - return this.selectionComposite; - } - - @Override - public void run() { - ConfigurationManager config = getStateMachine().configProvider; - Status status = getStateMachine().status; - if (!(status.getPreviousState() instanceof PrepareConfigurationState) - && !(status.getPreviousState() instanceof OpenState)) { - status.bku = config.getDefaultBKU(); - status.document = null; - status.signaturePosition = ((config.getSignatureProfile() == Profile.INVISIBLE) || config.getAutoPositionSignature()) ? (new SignaturePosition()) : null; - - /* ensure that files get closed */ - status.getPreviousState().cleanUp(); - } - - /* force static initialization and start polling */ - LocalBKUConnector.IsAvailable(); - - if (status.document == null) { - DataSourceSelectComposite selection = this.getSelectionComposite(); - - getStateMachine().display(selection); - selection.layout(); - - status.document = selection.getSelected(); - - if (status.document == null) { - // Not selected yet - return; - } - } - log.debug("Got Datasource: " + getStateMachine().status.document.getAbsolutePath()); - - // scan for signature placeholders - // - see if we want to scan for placeholders in the settings - if (config.getEnablePlaceholderUsage()) { - try (PDDocument pddocument = PDDocument.load(getStateMachine().status.document)) { - // - scan for placeholders - boolean useSignatureFields = config.getUseSignatureFields(); - boolean useMarker = config.getUseMarker(); - log.debug("Placeholder usage enabled. Signature fields: {}, QR Markers: {}", useSignatureFields, useMarker); - //first check the signature fields placeholder - if (useSignatureFields) { - - List<String> fields = SignatureFieldsAndPlaceHolderExtractor.findEmptySignatureFields(pddocument); - - if (fields.size() > 0) { - while (true) - { - // create a dialog with ok and cancel buttons and a question - // icon - MessageBox dialog = new MessageBox(getStateMachine().getMainShell(), - SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); - SWTUtils.setLocalizedText(dialog, "dataSourceSelection.usePlaceholderTitle"); - dialog.setMessage(Messages.getString("dataSourceSelection.usePlaceholderText")); - - // open dialog and await user selection - int result = dialog.open(); - if (result == SWT.YES) { - - if (fields.size() == 1) { - addPlaceholderSelectionToConfig(fields.get(0)); - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - - } else if (fields.size() > 1) { - - PlaceholderSelectionGui gui = new PlaceholderSelectionGui( - getStateMachine().getMainShell(), 65570, "text", - "select the fields", fields); - int res = gui.open(); - if (res != -1) { - getStateMachine().status.searchForPlacehoderSignature = true; - addPlaceholderSelectionToConfig(fields.get(res)); - this.setNextState(new BKUSelectionState(getStateMachine())); - } - else - continue; - } - - } else if (result == SWT.NO) { - getStateMachine().status.searchForPlacehoderSignature = false; - } else { - status.document = null; - return; - } - break; - } - } - // second check if qr code placeholder search is enabled - } else if (useMarker) { - - SignaturePlaceholderData signaturePlaceholderData = SignatureFieldsAndPlaceHolderExtractor.getNextUnusedSignaturePlaceHolder(pddocument); - - if (null != signaturePlaceholderData) { - - // create a dialog with ok and cancel buttons and a question icon - MessageBox dialog = new MessageBox(getStateMachine().getMainShell(), - SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); - SWTUtils.setLocalizedText(dialog, "dataSourceSelection.usePlaceholderTitle"); - dialog.setMessage(Messages.getString("dataSourceSelection.usePlaceholderText")); - - // open dialog and await user selection - int result = dialog.open(); - if (result == SWT.YES) { - - // if the user chooses to use the signature placeholder - // - fill the position information so that we skip to - // the - // next stages without breaking stuff - status.signaturePosition = new SignaturePosition( - signaturePlaceholderData.getTablePos().getPosX(), - signaturePlaceholderData.getTablePos().getPosY(), - signaturePlaceholderData.getTablePos().getPage()); - - getStateMachine().status.searchForPlacehoderSignature = true; - - } else if (result == SWT.NO) { - getStateMachine().status.searchForPlacehoderSignature = false; - } else { - status.document = null; - return; - } - // TODO: why does this use a different logic (via PositioningState) than the signature placeholders? - } - - } else { - // Do nothing - } - - } catch (IOException e) { - // fail silently. In case we got here no dialog has been shown. - // Just - // proceed with the usual process. - } - } - - this.setNextState(new PositioningState(getStateMachine())); - } - - /** - * The selected placeholder is added to the configuration file - * @param selection - */ - private void addPlaceholderSelectionToConfig(String selection) { - try { - PropertiesConfiguration config = new PropertiesConfiguration(); - PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config); - layout.load(new InputStreamReader(new FileInputStream(advancedConfig))); - - config.setProperty(Constants.SIGNATURE_FIELD_NAME_CONF, selection); - layout.save(new FileWriter(advancedConfig, false)); - - } catch (Exception e) { - log.error("Failed to add placeholder selection to config", e); - } - - } - - /** - * Open the input document selection dialog - */ - public void openFileDialog() { - if (this.selectionComposite != null) - this.selectionComposite.openFileDialog(); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - if (this.selectionComposite != null) - this.selectionComposite.dispose(); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setEnabled(Buttons.CONFIG, true); - behavior.setEnabled(Buttons.OPEN, true); - behavior.setActive(Buttons.OPEN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java deleted file mode 100644 index 308b7d5a..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.io.File; - -import org.eclipse.swt.SWT; - -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.composites.OutputComposite; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; - -/** - * Produces the output of the signature process. (save file, open file) - */ -public class OutputState extends State { - - private OutputComposite outputComposite = null; - - /** - * @param stateMachine - */ - public OutputState(StateMachine stateMachine) { - super(stateMachine); - } - - private OutputComposite getOutputComposite() { - if (this.outputComposite == null) { - this.outputComposite = getStateMachine() - .createComposite(OutputComposite.class, SWT.RESIZE, this); - - ConfigurationManager config = getStateMachine().configProvider; - Status status = getStateMachine().status; - - File tmpDir = new File(Constants.CONFIG_DIRECTORY + File.separator + "tmp"); - - if(!tmpDir.exists()) { - tmpDir.mkdir(); - } - - this.outputComposite.setOutputDir(config.getDefaultOutputFolder()); - this.outputComposite.setSaveFilePostFix(config.getSaveFilePostFix()); - this.outputComposite.setTempDir(tmpDir.getAbsolutePath()); - this.outputComposite.setInputFile(status.document); - - this.outputComposite.setSignedDocument(status.signResult.getSignedDocument()); - - // Save signed document - this.outputComposite.saveDocument(); - - if (config.getSkipFinish() && this.outputComposite.getSaveSuccessful()) { - getStateMachine().exit(); - } - } - - return this.outputComposite; - } - - @Override - public void run() { - Status status = getStateMachine().status; - - if (status.signResult == null) { - ErrorDialog error = new ErrorDialog(getStateMachine().getMainShell(), - Messages.getString("error.Signatur"), BUTTONS.RETRY_CANCEL); - if(error.open() == SWT.RETRY) { - this.setNextState(new PrepareSigningState(getStateMachine())); - } else { - this.setNextState(new BKUSelectionState(getStateMachine())); - } - return; - } - - OutputComposite outputComposite = this.getOutputComposite(); - - // Display dialog - getStateMachine().display(outputComposite); - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - - getStateMachine().status.signResult = null; - - if (this.outputComposite != null) - this.outputComposite.dispose(); - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setEnabled(Buttons.CONFIG, true); - behavior.setEnabled(Buttons.OPEN, true); - behavior.setEnabled(Buttons.POSITION, true); - behavior.setEnabled(Buttons.SIGN, true); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - behavior.setActive(Buttons.FINAL, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java deleted file mode 100644 index b56fb6d7..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.io.File; -import java.io.IOException; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException; -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.composites.PositioningComposite; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.signer.Emblem; -import at.asit.pdfover.signer.SignaturePosition; -import at.asit.pdfover.signer.pdfas.PdfAs4SignatureParameter; -import at.asit.pdfover.signer.pdfas.PdfAs4SignaturePlaceholder; - -/** - * Decides where to position the signature block - */ -public class PositioningState extends State { - - /** - * @param stateMachine - */ - public PositioningState(StateMachine stateMachine) { - super(stateMachine); - } - - /** - * SLF4J Logger instance - **/ - private static final Logger log = LoggerFactory.getLogger(PositioningState.class); - - private PositioningComposite positionComposite = null; - - private SignaturePosition previousPosition = null; - - - private File loadedDocumentPath = null; - private PDDocument document = null; - - private void closePDFDocument() { - - if (this.document != null) - { - try { this.document.close(); } catch (IOException e) { log.warn("Failed to close PDF", e); } - this.document = null; - } - this.loadedDocumentPath = null; - } - - private void openPDFDocument() throws IOException { - closePDFDocument(); - File documentPath = getStateMachine().status.document; - PDDocument pdf = null; - try - { - pdf = PDDocument.load(documentPath); - if (pdf.getNumberOfPages() > 0) - pdf.getPage(0); - else - throw new IOException(); - } - catch (InvalidPasswordException e) { - throw new IOException(Messages.getString("error.PDFPwdProtected"), e); - } - catch (IOException e) { - throw new IOException(Messages.getString("error.MayNotBeAPDF"), e); - } - this.document = pdf; - this.loadedDocumentPath = documentPath; - } - - private PositioningComposite getPositioningComposite(PDDocument document) { - StateMachine stateMachine = getStateMachine(); - if (this.positionComposite == null) { - this.positionComposite = - stateMachine.createComposite(PositioningComposite.class, SWT.RESIZE, this); - log.debug("Displaying " + stateMachine.status.document); - this.positionComposite.displayDocument(document); - } - - ConfigurationManager config = stateMachine.configProvider; - - PdfAs4SignatureParameter param = new PdfAs4SignatureParameter(); - param.signatureProfile = config.getSignatureProfile(); - - String emblemPath = config.getDefaultEmblemPath(); - if (emblemPath != null && !emblemPath.trim().isEmpty()) - param.emblem = new Emblem(emblemPath); - if (config.getSignatureNote() != null && !config.getSignatureNote().isEmpty()) - param.signatureNote = config.getSignatureNote(); - - param.signatureLanguage = config.getSignatureLocale().getLanguage(); - param.enablePDFACompat = config.getSignaturePdfACompat(); - param.targetLogoSize = Math.min(120.0, config.getLogoOnlyTargetSize()); // TODO WORKAROUND FOR #117 - - PdfAs4SignaturePlaceholder.For(param, (p) -> { - if (p.hasImage()) - this.positionComposite.setPlaceholder(p.getAWTImage()); - }); - - if (this.previousPosition != null && !this.previousPosition.useAutoPositioning()) - { - this.positionComposite.setPosition( - this.previousPosition.getX(), - this.previousPosition.getY(), - this.previousPosition.getPage()); - } - - return this.positionComposite; - } - - @Override - public void run() { - Status status = getStateMachine().status; - if (!(status.getPreviousState() instanceof PositioningState) && - !(status.getPreviousState() instanceof OpenState)) - { - this.previousPosition = status.signaturePosition; - status.signaturePosition = null; - } - - if ((this.document == null) || - (this.loadedDocumentPath != getStateMachine().status.document)) { - log.debug("Checking PDF document for encryption"); - try { - openPDFDocument(); - } catch (IOException e) { - this.positionComposite = null; - log.error("Failed to display PDF document", e); - String message = e.getLocalizedMessage(); - if (message == null) - message = Messages.getString("error.IOError"); - ErrorDialog dialog = new ErrorDialog( - getStateMachine().getMainShell(), - message, BUTTONS.RETRY_CANCEL); - if(dialog.open() == SWT.RETRY) { - run(); - } else { - setNextState(new OpenState(getStateMachine())); - } - return; - } - } - - if (status.signaturePosition == null) { - PositioningComposite position = null; - try { - position = this.getPositioningComposite(this.document); - } catch(Exception ex) { - log.error("Failed to create composite (probably a mac...)", ex); - ErrorDialog dialog = new ErrorDialog( - getStateMachine().getMainShell(), - Messages.getString("error.PositioningNotPossible"), BUTTONS.OK); - dialog.open(); - status.signaturePosition = new SignaturePosition(); - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - - getStateMachine().display(position); - - status.signaturePosition = position.getPosition(); - - if(status.signaturePosition != null) { - this.setNextState(new BKUSelectionState(getStateMachine())); - } - - this.positionComposite.requestFocus(); - } else { - this.setNextState(new BKUSelectionState(getStateMachine())); - } - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - if (this.positionComposite != null) - this.positionComposite.dispose(); - closePDFDocument(); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setEnabled(Buttons.CONFIG, true); - behavior.setEnabled(Buttons.OPEN, true); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java deleted file mode 100644 index 87693c19..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - - -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.cliarguments.*; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.gui.exceptions.InitializationException; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.utils.UpdateCheckManager; -import at.asit.pdfover.gui.utils.VersionComparator; -import at.asit.pdfover.gui.utils.Zipper; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.signer.SignaturePosition; - -/** - * Starting state of workflow proccess - * - * Reads configuration, command arguments and initializes configured variables - */ -public class PrepareConfigurationState extends State { - - /** SLF4J Logger instance **/ - static final Logger log = LoggerFactory.getLogger(PrepareConfigurationState.class); - - private ArgumentHandler handler; - - private ArgumentHandler configFileHandler; - - /** - * @param stateMachine - */ - public PrepareConfigurationState(StateMachine stateMachine) { - super(stateMachine); - this.handler = new ArgumentHandler(getStateMachine()); - this.handler.addCLIArgument(HelpArgument.class); - this.handler.addCLIArgument(InputDocumentArgument.class); - this.handler.addCLIArgument(OutputFolderArgument.class); - this.handler.addCLIArgument(BKUArgument.class); - this.handler.addCLIArgument(PhoneNumberArgument.class); - this.handler.addCLIArgument(PasswordArgument.class); - this.handler.addCLIArgument(KeystoreFileArgument.class); - this.handler.addCLIArgument(KeystoreTypeArgument.class); - this.handler.addCLIArgument(KeystoreStorePassArgument.class); - this.handler.addCLIArgument(KeystoreAliasArgument.class); - this.handler.addCLIArgument(KeystoreKeyPassArgument.class); - this.handler.addCLIArgument(ProxyHostArgument.class); - this.handler.addCLIArgument(ProxyPortArgument.class); - this.handler.addCLIArgument(ProxyUserArgument.class); - this.handler.addCLIArgument(ProxyPassArgument.class); - this.handler.addCLIArgument(EmblemArgument.class); - this.handler.addCLIArgument(AutomaticPositioningArgument.class); - this.handler.addCLIArgument(SkipFinishArgument.class); - // adding config file argument to this handler so it appears in help - this.handler.addCLIArgument(ConfigFileArgument.class); - this.handler.addCLIArgument(InvisibleProfile.class); - - this.configFileHandler = new ArgumentHandler(getStateMachine()); - this.configFileHandler.addCLIArgument(ConfigFileArgument.class); - } - - private void initializeFromConfigurationFile() throws InitializationException { - try { - getStateMachine().configProvider.loadFromDisk(); - } catch (IOException ex) { - throw new InitializationException("Failed to read configuration from config file", ex); - } - } - - private void initializeFromArguments(String[] args, ArgumentHandler handler) throws InitializationException { - handler.handleArguments(args); - - if (handler.doesRequireExit()) { - getStateMachine().exit(); - } - } - - private void ensurePdfOverConfigExists() throws InitializationException { - try { - File pdfOverConfig = new File(Constants.CONFIG_DIRECTORY + File.separator + Constants.DEFAULT_CONFIG_FILENAME); - if (!pdfOverConfig.exists()) - pdfOverConfig.createNewFile(); - } catch (Exception e) { - log.error("Failed to create PDF-Over config file", e); - throw new InitializationException("Failed to create PDF-Over config file", e); - } - } - - private void unzipPdfAsConfig(File configDir) throws InitializationException { - InputStream is = getClass().getResourceAsStream(Constants.RES_CFG_ZIP); - - try { - Zipper.unzip(is, configDir.getAbsolutePath()); - } catch (IOException e) { - log.error( - "Failed to create local configuration directory!", e); - throw new InitializationException( - "Failed to create local configuration directory!", - e); - } - } - - private static void updateVersionFile(File configDir) throws InitializationException { - File versionFile = new File(configDir, Constants.CONFIG_VERSION_FILENAME); - try { - BufferedWriter versionWriter = new BufferedWriter(new FileWriter(versionFile)); - String version = Constants.APP_VERSION == null ? "Unknown" : Constants.APP_VERSION; - versionWriter.write(version); - versionWriter.close(); - } catch (IOException e) { - log.error( - "Failed to create configuration version file!", e); - throw new InitializationException( - "Failed to create configuration version file!", - e); - } - } - - private void createConfiguration(File configDir) throws InitializationException { - boolean allOK = false; - - log.info("Creating configuration directory"); - if (!configDir.exists()) { - configDir.mkdir(); - } - - try { - ensurePdfOverConfigExists(); - unzipPdfAsConfig(configDir); - updateVersionFile(configDir); - - allOK = true; - } finally { - if (!allOK) { - configDir.delete(); - } - } - } - - /** - * @return The first valid (not empty, non comment) line of the version file - * or null if version file cannot be read or does not contain - * such a line. - */ - private static String getVersion(File versionFile) { - if (versionFile.exists() && versionFile.canRead()) { - BufferedReader versionReader = null; - try { - versionReader = new BufferedReader(new FileReader(versionFile)); - String version; - while ((version = versionReader.readLine()) != null) { - version = version.trim(); - if (version.length() > 0 && !version.startsWith("#")) { - log.trace("configuration version from " + versionFile - + ": " + version); - return version; - } - } - } catch (IOException ex) { - log.error("failed to read configuration version from " - + versionFile, ex); - } finally { - try { - if (versionReader != null) - versionReader.close(); - } catch (IOException ex) { - // ignore - } - } - } - log.debug("unknown configuration version"); - return null; - } - - /** - * Backup old configuration, create new - * @param configDir - * @throws InitializationException - */ - private void backupAndCreatePdfAsConfiguration(File configDir) throws InitializationException { - try { - File backup = File.createTempFile(Constants.PDF_AS_CONFIG_BACKUP_FILENAME, ".zip"); - OutputStream os = new FileOutputStream(backup); - Zipper.zip(configDir + File.separator + "cfg", os, true); - os.close(); - unzipPdfAsConfig(configDir); - File b = new File(configDir, Constants.PDF_AS_CONFIG_BACKUP_FILENAME + ".zip"); - int i = 1; - while (b.exists()) { - b = new File(configDir, Constants.PDF_AS_CONFIG_BACKUP_FILENAME + i++ + ".zip"); - } - backup.renameTo(b); - updateVersionFile(configDir); - } catch (FileNotFoundException e) { - log.error("Backup file not found", e); - throw new InitializationException("Backup file not found", e); - } catch (IOException e) { - log.error("Error creating configuration backup", e); - throw new InitializationException("Error creating configuration backup", e); - } - } - - @Override - public void run() { - // Read config file - try { - StateMachine stateMachine = getStateMachine(); - ConfigurationManager config = stateMachine.configProvider; - File configDir = new File(Constants.CONFIG_DIRECTORY); - File configFile = new File(configDir, Constants.DEFAULT_CONFIG_FILENAME); - if (!configDir.exists() || !configFile.exists()) { - log.debug("Creating configuration file"); - createConfiguration(configDir); - } else { - log.debug("Configuration directory exists!"); - // Check PDF-AS config version - File versionFile = new File(configDir, Constants.CONFIG_VERSION_FILENAME); - String configVersion = getVersion(versionFile); - if (configVersion == null || VersionComparator.before(configVersion, Constants.MIN_PDF_AS_CONFIG_VERSION)) - backupAndCreatePdfAsConfiguration(configDir); - } - - - // Read cli arguments for config file location first - try { - initializeFromArguments(stateMachine.cmdLineArgs, this.configFileHandler); - } catch (InitializationException e) { - log.error("Error in cmd line arguments: ", e); - ErrorDialog error = new ErrorDialog(stateMachine.getMainShell(), - Messages.getString("error.CmdLineArgs") + "\n" + - e.getMessage(), - BUTTONS.OK); - error.open(); - stateMachine.exit(); - } - - // initialize from config file - initializeFromConfigurationFile(); - - // Read cli arguments - try { - initializeFromArguments(stateMachine.cmdLineArgs, this.handler); - } catch (InitializationException e) { - log.error("Error in cmd line arguments: ", e); - ErrorDialog error; - - if (e.getCause() instanceof FileNotFoundException) { - error = new ErrorDialog(stateMachine.getMainShell(), - String.format( - Messages.getString("error.FileNotExist"), - e.getCause().getMessage()), - BUTTONS.OK); - } else { - error = new ErrorDialog(stateMachine.getMainShell(), - Messages.getString("error.CmdLineArgs") + "\n" + - e.getMessage(), - BUTTONS.OK); - } - error.open(); - stateMachine.exit(); - } - - // Check for updates - if (config.getUpdateCheck()) - UpdateCheckManager.checkNow(stateMachine.getMainShell()); - - // Create PDF Signer - Status status = stateMachine.status; - status.bku = getStateMachine().configProvider.getDefaultBKU(); - status.signaturePosition = getStateMachine().configProvider.getAutoPositionSignature() ? (new SignaturePosition()) : null; - - setNextState(new OpenState(stateMachine)); - - } catch (Exception e) { - log.error("Failed to initialize: ", e); - ErrorDialog error = new ErrorDialog( - getStateMachine().getMainShell(), - Messages.getString("error.Initialization"), - BUTTONS.YES_NO - ); - // error.setException(e); - // setNextState(error); - int selection = error.open(); - if (selection == SWT.YES) - ConfigurationManager.factoryResetPersistentConfig(); - - getStateMachine().exit(); - } - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - // No composite - no cleanup necessary - } - - /* - * (non-Javadoc) - * - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - // no behavior necessary yet - } - - @Override - public String toString() { - return getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java deleted file mode 100644 index 1669f2f8..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.net.Authenticator; -import java.net.PasswordAuthentication; - -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.composites.WaitingComposite; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; -import at.asit.pdfover.signer.Emblem; -import at.asit.pdfover.signer.PDFFileDocumentSource; -import at.asit.pdfover.signer.pdfas.PdfAs4SignatureParameter; -import at.asit.pdfover.signer.pdfas.PdfAs4Signer; -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; - -/** - * User waiting state, wait for PDF Signator library to prepare document for - * signing. - */ -public class PrepareSigningState extends State { - - /** - * @param stateMachine - */ - public PrepareSigningState(StateMachine stateMachine) { - super(stateMachine); - } - - private final class PrepareDocumentThread implements Runnable { - - private PrepareSigningState state; - - /** - * Default constructor - * - * @param state - */ - public PrepareDocumentThread(PrepareSigningState state) { - this.state = state; - } - - @Override - public void run() { - try { - - Status status = this.state.getStateMachine().status; - - ConfigurationManager configuration = this.state.getStateMachine().configProvider; - - // SET PROXY HOST and PORT settings - final String proxyHost = configuration.getProxyHost(); - final int proxyPort = configuration.getProxyPort(); - final String proxyUser = configuration.getProxyUser(); - final String proxyPass = configuration.getProxyPass(); - - if (proxyHost != null && !proxyHost.isEmpty()) { - log.debug("Setting proxy host to " + proxyHost); - System.setProperty("http.proxyHost", proxyHost); - System.setProperty("https.proxyHost", proxyHost); - } - - if (proxyPort > 0 && proxyPort <= 0xFFFF) { - String port = Integer.toString(proxyPort); - log.debug("Setting proxy port to " + port); - System.setProperty("http.proxyPort", port); - System.setProperty("https.proxyPort", port); - } - - if (proxyUser != null && !proxyUser.isEmpty()) { - log.debug("Setting proxy username to " + proxyUser); - System.setProperty("http.proxyUser", proxyUser); - System.setProperty("https.proxyUser", proxyUser); - } - - if (proxyPass != null) { - log.debug("Setting proxy password"); - System.setProperty("http.proxyPassword", proxyPass); - System.setProperty("https.proxyPassword", proxyPass); - } - - if (proxyUser != null && !proxyUser.isEmpty() && - proxyPass != null && !proxyPass.isEmpty()) { - log.debug("Enabling proxy authentication"); - Authenticator.setDefault(new Authenticator() { - /* (non-Javadoc) - * @see java.net.Authenticator#getPasswordAuthentication() - */ - @Override - protected PasswordAuthentication getPasswordAuthentication() { - if (getRequestorType() == RequestorType.PROXY) { - if (getRequestingHost().equalsIgnoreCase(proxyHost) && - (getRequestingPort() == proxyPort)) { - return new PasswordAuthentication(proxyUser, - proxyPass.toCharArray()); - } - } - return super.getPasswordAuthentication(); - } - }); - } - - if (this.state.signatureParameter == null) { - this.state.signatureParameter = new PdfAs4SignatureParameter(); - } - - this.state.signatureParameter.inputDocument = new PDFFileDocumentSource(status.document); - this.state.signatureParameter.signatureDevice = status.bku; - if (status.signaturePosition != null) { - this.state.signatureParameter.signaturePosition = status.signaturePosition; - } - - if (configuration.getDefaultEmblemPath() != null && !configuration.getDefaultEmblemPath().isEmpty()) { - this.state.signatureParameter.emblem = new Emblem(configuration.getDefaultEmblemPath()); - } - - if (configuration.getSignatureNote() != null && !configuration.getSignatureNote().isEmpty()) { - this.state.signatureParameter.signatureNote = configuration.getSignatureNote(); - } - - this.state.signatureParameter.searchForPlaceholderSignatures = getStateMachine().status.searchForPlacehoderSignature; - this.state.signatureParameter.signatureLanguage = configuration.getSignatureLocale().getLanguage(); - this.state.signatureParameter.enablePDFACompat = configuration.getSignaturePdfACompat(); - this.state.signatureParameter.signatureProfile = configuration.getSignatureProfile(); - this.state.signatureParameter.targetLogoSize = configuration.getLogoOnlyTargetSize(); - - this.state.signingState = PdfAs4Signer.prepare(this.state.signatureParameter); - - } catch (Exception e) { - log.error("PrepareDocumentThread: ", e); - this.state.threadException = e; - } finally { - this.state.updateStateMachine(); - } - } - } - - /** - * SLF4J Logger instance - **/ - static final Logger log = LoggerFactory.getLogger(PrepareSigningState.class); - - PdfAs4SignatureParameter signatureParameter; - - private WaitingComposite waitingComposite = null; - - private WaitingComposite getSelectionComposite() { - if (this.waitingComposite == null) { - this.waitingComposite = getStateMachine() - .createComposite(WaitingComposite.class, SWT.RESIZE, this); - } - - return this.waitingComposite; - } - - PdfAs4SigningState signingState = null; - - Exception threadException = null; - - @Override - public void run() { - WaitingComposite waiting = this.getSelectionComposite(); - - getStateMachine().display(waiting); - - Status status = getStateMachine().status; - - if (this.signatureParameter == null) { - this.signatureParameter = new PdfAs4SignatureParameter(); - } - - if (this.signingState == null && this.threadException == null) { - Thread t = new Thread(new PrepareDocumentThread(this)); - t.start(); - return; - } - - if (this.threadException != null) { - ErrorDialog error = new ErrorDialog(getStateMachine() - .getMainShell(), - Messages.getString("error.PrepareDocument"), - BUTTONS.RETRY_CANCEL); - this.threadException = null; - if (error.open() == SWT.RETRY) { - run(); - } else { - this.setNextState(new BKUSelectionState(getStateMachine())); - } - return; - } - - // We got the Request set it into status and move on to next state ... - status.signingState = this.signingState; - - switch (status.bku) - { - case LOCAL: - this.setNextState(new LocalBKUState(getStateMachine())); - break; - case MOBILE: - this.setNextState(new MobileBKUState(getStateMachine())); - break; - case KS: - this.setNextState(new KSState(getStateMachine())); - break; - default: - log.error("Invalid selected BKU Value \"{}\" in PrepareSigningState!", status.bku.name()); - this.setNextState(new BKUSelectionState(getStateMachine())); - } - } - - /* - * (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - if (this.waitingComposite != null) - this.waitingComposite.dispose(); - } - - /* - * (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java deleted file mode 100644 index cf4d6d37..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import java.net.ConnectException; - -import org.eclipse.swt.SWT; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.MainWindowBehavior; -import at.asit.pdfover.gui.MainWindow.Buttons; -import at.asit.pdfover.gui.controls.Dialog.BUTTONS; -import at.asit.pdfover.gui.controls.ErrorDialog; -import at.asit.pdfover.commons.Messages; -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.Status; -import at.asit.pdfover.signer.SignatureException; -import at.asit.pdfover.signer.UserCancelledException; -import at.asit.pdfover.signer.pdfas.PdfAs4Signer; - -/** - * Logical state for signing process, usually show BKU Dialog during this state. - */ -public class SigningState extends State { - - /** - * - */ - private final class FinishSignThread implements Runnable { - - private SigningState state; - - /** - * @param signingState - */ - public FinishSignThread(SigningState signingState) { - this.state = signingState; - } - - @Override - public void run() { - try { - Status status = this.state.getStateMachine().status; - status.signResult = PdfAs4Signer.sign(status.signingState); - } catch(Exception e) { - this.state.threadException = e; - } finally { - this.state.updateStateMachine(); - } - } - } - - /** - * @param stateMachine - */ - public SigningState(StateMachine stateMachine) { - super(stateMachine); - } - - /** - * SLF4J Logger instance - **/ - static final Logger log = LoggerFactory.getLogger(SigningState.class); - - Exception threadException = null; - - @Override - public void run() { - Status status = getStateMachine().status; - - if(status.signResult == null && - this.threadException == null) { - Thread t = new Thread(new FinishSignThread(this)); - t.start(); - return; - } - - if(this.threadException != null) { - String message = Messages.getString("error.Signatur"); - if (this.threadException instanceof SignatureException) { - Throwable cause = this.threadException; - while (cause.getCause() != null) - cause = cause.getCause(); - if (cause instanceof ConnectException) - message += ": " + cause.getMessage(); - if (cause instanceof IllegalStateException) { - // TODO legacy hack - this.threadException = new UserCancelledException(); - } - } - if (this.threadException instanceof UserCancelledException) { - // don't display error, clear remembered password and go back to BKU Selection - if (this.getConfig().getRememberMobilePassword()) - this.getConfig().setDefaultMobilePasswordOverlay(null); - this.setNextState(new BKUSelectionState(getStateMachine())); - return; - } - - // if we have gotten to this point, this is an actual exception - log.error("FinishSignThread: ", this.threadException); - - ErrorDialog error = new ErrorDialog(getStateMachine().getMainShell(), - message, BUTTONS.RETRY_CANCEL); - this.threadException = null; - if(error.open() == SWT.RETRY) { - this.setNextState(new PrepareSigningState(getStateMachine())); - } else { - this.setNextState(new BKUSelectionState(getStateMachine())); - } - return; - } - - this.setNextState(new OutputState(getStateMachine())); - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#cleanUp() - */ - @Override - public void cleanUp() { - // No composite - no cleanup necessary - } - - /* (non-Javadoc) - * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior() - */ - @Override - public void updateMainWindowBehavior() { - MainWindowBehavior behavior = getStateMachine().status.behavior; - behavior.reset(); - behavior.setActive(Buttons.OPEN, true); - behavior.setActive(Buttons.POSITION, true); - behavior.setActive(Buttons.SIGN, true); - //behavior.setEnabled(Buttons.OPEN, true); - //behavior.setEnabled(Buttons.POSITION, true); - //behavior.setEnabled(Buttons.SIGN, true); - } - - @Override - public String toString() { - return this.getClass().getName(); - } -} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/State.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/State.java deleted file mode 100644 index c039f21a..00000000 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/State.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.workflow.states; - -//Imports -import at.asit.pdfover.gui.workflow.StateMachine; -import at.asit.pdfover.gui.workflow.config.ConfigurationManager; - -/** - * Base state class - */ -public abstract class State { - - /** - * The StateMachine - */ - private StateMachine stateMachine; - - private State nextState = null; - - /** - * Default Workflow State constructor - * @param stateMachine the State Machine - */ - public State(StateMachine stateMachine) { - this.stateMachine = stateMachine; - this.nextState = this; - } - - public ConfigurationManager getConfig() { return this.stateMachine.configProvider; } - - /** - * Gets the next logical state or null if this their is no state transition - * @return the next state (or null) - */ - public State nextState() { - return this.nextState; - } - - /** - * Sets the next logical state - * @param state - */ - protected void setNextState(State state) { - this.nextState = state; - } - - /** - * Perform main logic for this state - */ - public abstract void run(); - - /** - * Perform status cleanup - */ - public abstract void cleanUp(); - - /** - * Update the state machine - */ - public void updateStateMachine() - { - this.stateMachine.invokeUpdate(); - } - - /** - * Get the state machine - * @return the StateMachine - */ - protected StateMachine getStateMachine() - { - return this.stateMachine; - } - - /** - * Update the main window behavior of this state if necessary - * Should update this.stateMachine.status.getBehavior() - */ - public abstract void updateMainWindowBehavior(); -} |