From 79770b114f24f0c66403a4fecaaa9a3fe8398933 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 30 Apr 2014 17:05:50 -0400 Subject: [PATCH] prepend file dir with origin domain; scrub file names Signed-off-by: Bill Erickson --- src/org/evergreen_ils/hatch/FileIO.java | 65 ++++++++++++++++++++-- .../evergreen_ils/hatch/HatchWebSocketHandler.java | 16 ++++-- src/org/evergreen_ils/hatch/PrintManager.java | 11 +++- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/src/org/evergreen_ils/hatch/FileIO.java b/src/org/evergreen_ils/hatch/FileIO.java index 6b3166c..861c05c 100644 --- a/src/org/evergreen_ils/hatch/FileIO.java +++ b/src/org/evergreen_ils/hatch/FileIO.java @@ -17,6 +17,7 @@ package org.evergreen_ils.hatch; import java.io.*; import java.util.LinkedList; +import java.util.Arrays; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -24,6 +25,39 @@ public class FileIO { /** All files are read from and written to this directory */ String basePath; + String originDomain; + + // routine for scrubbing invalid chars from file names / paths + // http://stackoverflow.com/questions/1155107/is-there-a-cross-platform-java-method-to-remove-filename-special-chars + final static int[] illegalChars = { + 34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 58, 42, 63, 92, 47 + }; + + static { Arrays.sort(illegalChars); } + + public static String cleanFileName(String badFileName) { + char lastChar = 0; + StringBuilder cleanName = new StringBuilder(); + for (int i = 0; i < badFileName.length(); i++) { + int c = (int)badFileName.charAt(i); + if (Arrays.binarySearch(illegalChars, c) < 0) { + cleanName.append((char)c); + lastChar = (char) c; + } else { + // avoid dupe-ing the placeholder chars, since that + // relays no useful information (apart from the number + // of illegal characters) + // This is usefuf or things like https:// with dupe "/" chars + if (lastChar != '_') + cleanName.append('_'); + lastChar = '_'; + } + } + return cleanName.toString(); + } + // -------------------------------------------------- // logger private static final Logger logger = Log.getLogger("FileIO"); @@ -31,11 +65,14 @@ public class FileIO { /** * Constructs a new FileIO with the provided base path. * - * @param directory Directory to use as the base path for all file - * operations. + * @param directory Directory to use in conjuction with the origin + * (see below) as the base path for all file operations. + * directory is assumed to be a valid path. + * @param origin Origin domain of this request. */ - public FileIO(String directory) { - basePath = directory; + public FileIO(String directory, String origin) { + basePath = directory; + originDomain = cleanFileName(origin); } /** @@ -45,14 +82,28 @@ public class FileIO { * @return The File object if found. */ protected File getFile(String key) { + + // basePath directory File dir = new File(basePath); if (!dir.exists()) { if (!dir.mkdir()) { - logger.info("Unable to create director: " + basePath); + logger.info("Unable to create directory: " + dir.getName()); + return null; + } + } + + // basePath + originDomain directory + File subDir = new File(basePath, originDomain); + if (!subDir.exists()) { + if (!subDir.mkdir()) { + logger.info("Unable to create directory: " + subDir.getName()); return null; } } - return new File(dir, key); + + logger.info("working with directory: " + subDir.getName()); + key = cleanFileName(key); + return new File(subDir, key); } /** @@ -67,6 +118,8 @@ public class FileIO { logger.info("set => " + key); File file = getFile(key); + if (text == null) return false; + try { // delete the file if it exists diff --git a/src/org/evergreen_ils/hatch/HatchWebSocketHandler.java b/src/org/evergreen_ils/hatch/HatchWebSocketHandler.java index 3a327c3..bb2ee9c 100644 --- a/src/org/evergreen_ils/hatch/HatchWebSocketHandler.java +++ b/src/org/evergreen_ils/hatch/HatchWebSocketHandler.java @@ -40,6 +40,9 @@ public class HatchWebSocketHandler { /** A single connection to a WebSockets client */ private Session session; + /** Current origin domain */ + private String origin; + /** List of Origin domains from which we allow connections */ private static String[] trustedDomains; @@ -119,7 +122,7 @@ public class HatchWebSocketHandler { logger.info("received connection from IP " + session.getRemoteAddress().getAddress()); - String origin = session.getUpgradeRequest().getHeader("Origin"); + origin = session.getUpgradeRequest().getHeader("Origin"); if (origin == null) { logger.warn("No Origin header in request; Dropping connection"); @@ -244,10 +247,11 @@ public class HatchWebSocketHandler { Object response = null; boolean error = false; + FileIO io = new FileIO(profileDirectory, origin); switch (action) { case "keys": - response = new FileIO(profileDirectory).keys(key); + response = io.keys(key); break; case "printers": @@ -274,7 +278,7 @@ public class HatchWebSocketHandler { break; case "get": - String val = new FileIO(profileDirectory).get(key); + String val = io.get(key); if (val != null) { // set() stores bare JSON. We must pass an // Object to reply so that it may be embedded into @@ -289,15 +293,15 @@ public class HatchWebSocketHandler { break; case "remove": - response = new FileIO(profileDirectory).remove(key); + response = io.remove(key); break; case "set" : - response = new FileIO(profileDirectory).set(key, value); + response = io.set(key, value); break; case "append" : - response = new FileIO(profileDirectory).append(key, value); + response = io.append(key, value); break; default: diff --git a/src/org/evergreen_ils/hatch/PrintManager.java b/src/org/evergreen_ils/hatch/PrintManager.java index f2dea53..77a120b 100644 --- a/src/org/evergreen_ils/hatch/PrintManager.java +++ b/src/org/evergreen_ils/hatch/PrintManager.java @@ -67,13 +67,18 @@ public class PrintManager { PrinterJob job = buildPrinterJob(settings); - job.showPrintDialog(null); + boolean approved = job.showPrintDialog(null); // no printing needed job.endJob(); - // extract modifications to the settings applied within the dialog - return extractSettingsFromJob(job); + if (approved) { + // extract modifications to the settings applied within the dialog + return extractSettingsFromJob(job); + } else { + // return the unmodified settings back to the caller + return settings; + } } /** -- 2.11.0