From 2070ced5a252b11ae7e19be1bb2430fa8e9220d9 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 26 Nov 2017 18:02:34 +0100 Subject: [PATCH] Remote: now with a pin code --- src/be/nikiroo/fanfix/Main.java | 23 ++++--- .../fanfix/bundles/resources.properties | 10 +-- .../nikiroo/fanfix/library/RemoteLibrary.java | 22 ++++--- .../fanfix/library/RemoteLibraryServer.java | 66 ++++++++++++------- 4 files changed, 76 insertions(+), 45 deletions(-) diff --git a/src/be/nikiroo/fanfix/Main.java b/src/be/nikiroo/fanfix/Main.java index 6a8a4a5a..a133de78 100644 --- a/src/be/nikiroo/fanfix/Main.java +++ b/src/be/nikiroo/fanfix/Main.java @@ -62,9 +62,10 @@ public class Main { *
  • --set-reader [reader type]: set the reader type to CLI, TUI or LOCAL * for this command
  • *
  • --version: get the version of the program
  • - *
  • --server [port]: start a server on this port
  • - *
  • --stop-server [port]: stop the running server on this port if any
  • - *
  • --remote [host] [port]: use a the given remote library
  • + *
  • --server [key] [port]: start a server on this port
  • + *
  • --stop-server [key] [port]: stop the running server on this port if + * any
  • + *
  • --remote [key] [host] [port]: use a the given remote library
  • * * * @param args @@ -76,6 +77,7 @@ public class Main { String sourceString = null; String chapString = null; String target = null; + String key = null; MainAction action = MainAction.START; Boolean plusInfo = null; String host = null; @@ -179,20 +181,24 @@ public class Main { break; case SERVER: case STOP_SERVER: - if (port == null) { + if (key == null) { + key = args[i]; + } else if (port == null) { port = Integer.parseInt(args[i]); } else { exitCode = 255; } break; case REMOTE: - if (host == null) { + if (key == null) { + key = args[i]; + } else if (host == null) { host = args[i]; } else if (port == null) { port = Integer.parseInt(args[i]); File remoteCacheDir = Instance.getRemoteDir(host); - BasicLibrary lib = new RemoteLibrary(host, port); + BasicLibrary lib = new RemoteLibrary(key, host, port); lib = new CacheLibrary(remoteCacheDir, lib); BasicReader.setDefaultLibrary(lib); @@ -319,7 +325,7 @@ public class Main { break; } try { - Server server = new RemoteLibraryServer(port); + Server server = new RemoteLibraryServer(key, port); server.start(); System.out.println("Remote server started on: " + port); } catch (IOException e) { @@ -333,12 +339,13 @@ public class Main { } try { + final String fkey = key; new ConnectActionClient(host, port, true) { @Override public void action(Version serverVersion) throws Exception { try { - send(new Object[] { "EXIT" }); + send(new Object[] { fkey, "EXIT" }); } catch (Exception e) { Instance.syserr(e); } diff --git a/src/be/nikiroo/fanfix/bundles/resources.properties b/src/be/nikiroo/fanfix/bundles/resources.properties index fba6355a..cd80b3aa 100644 --- a/src/be/nikiroo/fanfix/bundles/resources.properties +++ b/src/be/nikiroo/fanfix/bundles/resources.properties @@ -19,10 +19,12 @@ HELP_SYNTAX = Valid options:\n\ \t--list: list the stories present in the library\n\ \t--set-reader [reader type]: set the reader type to CLI, TUI or GUI for \n\ \t\tthis command\n\ -\t--server [port]: start a remote server on this port\n\ -\t--stop-server [port]: stop the remote server running on this port if any\n\ -\t--remote [host] [port]: select this remote server to get \n\ -\t\t(or update or...) the stories from\n\ +\t--server [key] [port]: start a remote server on this port\n\ +\t--stop-server [key] [port]: stop the remote server running on this port\n\ +\t\tif any (key must be set to the same value)\n\ +\t--remote [key] [host] [port]: select this remote server to get \n\ +\t\t(or update or...) the stories from (key must be set to the \n\ +\t\tsame value)\n\ \t--help: this help message\n\ \t--version: return the version of the program\n\ \n\ diff --git a/src/be/nikiroo/fanfix/library/RemoteLibrary.java b/src/be/nikiroo/fanfix/library/RemoteLibrary.java index 29d2bcda..0a747bdc 100644 --- a/src/be/nikiroo/fanfix/library/RemoteLibrary.java +++ b/src/be/nikiroo/fanfix/library/RemoteLibrary.java @@ -23,16 +23,21 @@ import be.nikiroo.utils.serial.ConnectActionClient; public class RemoteLibrary extends BasicLibrary { private String host; private int port; + private final String key; /** * Create a {@link RemoteLibrary} linked to the given server. * + * @param key + * the key that will allow us to exchange information with the + * server * @param host * the host to contact or NULL for localhost * @param port * the port to contact it on */ - public RemoteLibrary(String host, int port) { + public RemoteLibrary(String key, String host, int port) { + this.key = key; this.host = host; this.port = port; } @@ -47,7 +52,7 @@ public class RemoteLibrary extends BasicLibrary { // TODO: progress final List metas = new ArrayList(); MetaData[] fromNetwork = this. getRemoteObject( // - new Object[] { "GET_METADATA", "*" }); + new Object[] { key, "GET_METADATA", "*" }); if (fromNetwork != null) { for (MetaData meta : fromNetwork) { @@ -61,18 +66,19 @@ public class RemoteLibrary extends BasicLibrary { @Override public BufferedImage getCover(final String luid) { return this. getRemoteObject( // - new Object[] { "GET_COVER", luid }); + new Object[] { key, "GET_COVER", luid }); } @Override public BufferedImage getSourceCover(final String source) { return this. getRemoteObject( // - new Object[] { "GET_SOURCE_COVER", source }); + new Object[] { key, "GET_SOURCE_COVER", source }); } @Override public synchronized Story getStory(final String luid, Progress pg) { - return this. getRemoteObject(new Object[] { "GET_STORY", luid }); + return this. getRemoteObject( // + new Object[] { key, "GET_STORY", luid }); } @Override @@ -82,7 +88,7 @@ public class RemoteLibrary extends BasicLibrary { @Override public synchronized Story save(Story story, String luid, Progress pg) throws IOException { - getRemoteObject(new Object[] { "SAVE_STORY", story, luid }); + getRemoteObject(new Object[] { key, "SAVE_STORY", story, luid }); // because the meta changed: clearCache(); @@ -93,13 +99,13 @@ public class RemoteLibrary extends BasicLibrary { @Override public synchronized void delete(String luid) throws IOException { - getRemoteObject(new Object[] { "DELETE_STORY", luid }); + getRemoteObject(new Object[] { key, "DELETE_STORY", luid }); } @Override public void setSourceCover(String source, String luid) { this. getRemoteObject( // - new Object[] { "SET_SOURCE_COVER", source, luid }); + new Object[] { key, "SET_SOURCE_COVER", source, luid }); } @Override diff --git a/src/be/nikiroo/fanfix/library/RemoteLibraryServer.java b/src/be/nikiroo/fanfix/library/RemoteLibraryServer.java index 1fe182b8..5bbe4cdd 100644 --- a/src/be/nikiroo/fanfix/library/RemoteLibraryServer.java +++ b/src/be/nikiroo/fanfix/library/RemoteLibraryServer.java @@ -14,80 +14,96 @@ import be.nikiroo.utils.serial.Server; /** * Create a new remote server that will listen for order on the given port. *

    - * The available commands are given as String arrays (first item is the command, - * the rest are the arguments): + * The available commands are given as String arrays (first item is the key, + * second is the command, the rest are the arguments): *

      - *
    • GET_METADATA *: will return the metadata of all the stories in the + *
    • KEY GET_METADATA *: will return the metadata of all the stories in the * library
    • - *
    • GET_STORY [luid]: will return the given story if it exists (or NULL if - * not)
    • - *
    • SAVE_STORY [story] [luid]: save the story with the given LUID
    • - *
    • DELETE_STORY [luid]: delete the story of LUID luid
    • - *
    • GET_COVER [luid]: return the cover of the story
    • - *
    • GET_SOURCE_COVER [source]: return the cover for this source
    • - *
    • SET_SOURCE_COVER [source], [luid]: set the default cover for the given - * source to the cover of the story denoted by luid
    • - *
    • EXIT: stop the server
    • + *
    • KEY GET_STORY [luid]: will return the given story if it exists (or NULL + * if not)
    • + *
    • KEY SAVE_STORY [story] [luid]: save the story with the given LUID
    • + *
    • KEY DELETE_STORY [luid]: delete the story of LUID luid
    • + *
    • KEY GET_COVER [luid]: return the cover of the story
    • + *
    • KEY GET_SOURCE_COVER [source]: return the cover for this source
    • + *
    • KEY SET_SOURCE_COVER [source], [luid]: set the default cover for the + * given source to the cover of the story denoted by luid
    • + *
    • KEY EXIT: stop the server
    • *
    * * @author niki */ public class RemoteLibraryServer extends Server { + private final String key; /** * Create a new remote server (will not be active until * {@link RemoteLibraryServer#start()} is called). * + * @param key + * the key that will restrict access to this server * @param port * the port to listen on * * @throws IOException * in case of I/O error */ - public RemoteLibraryServer(int port) throws IOException { + public RemoteLibraryServer(String key, int port) throws IOException { super(port, true); + this.key = key; } @Override protected Object onRequest(ConnectActionServer action, Version clientVersion, Object data) throws Exception { + String key = ""; String command = ""; Object[] args = new Object[0]; if (data instanceof Object[]) { - args = (Object[]) data; - if (args.length > 0) { - command = "" + args[0]; + Object[] dataArray = (Object[]) data; + if (dataArray.length >= 2) { + args = new Object[dataArray.length - 2]; + for (int i = 2; i < dataArray.length; i++) { + args[i] = dataArray[i]; + } + + key = "" + dataArray[0]; + command = "" + dataArray[1]; } } - System.out.print("COMMAND: "); + System.out.print("[" + command + "] "); for (Object arg : args) { System.out.print(arg + " "); } System.out.println(""); + if (!key.equals(this.key)) { + System.out.println("Key rejected."); + throw new SecurityException("Invalid key"); + } + // TODO: progress (+send name + %age info back to client) if ("GET_METADATA".equals(command)) { - if (args[1].equals("*")) { + if (args[0].equals("*")) { List metas = Instance.getLibrary().getMetas(null); return metas.toArray(new MetaData[] {}); } throw new InvalidParameterException( - "only * is valid here, but you passed: " + args[1]); + "only * is valid here, but you passed: " + args[0]); } else if ("GET_STORY".equals(command)) { - return Instance.getLibrary().getStory("" + args[1], null); + return Instance.getLibrary().getStory("" + args[0], null); } else if ("SAVE_STORY".equals(command)) { - Instance.getLibrary().save((Story) args[1], "" + args[2], null); + Instance.getLibrary().save((Story) args[0], "" + args[1], null); } else if ("DELETE_STORY".equals(command)) { - Instance.getLibrary().delete("" + args[1]); + Instance.getLibrary().delete("" + args[0]); } else if ("GET_COVER".equals(command)) { - return Instance.getLibrary().getCover("" + args[1]); + return Instance.getLibrary().getCover("" + args[0]); } else if ("GET_SOURCE_COVER".equals(command)) { - return Instance.getLibrary().getSourceCover("" + args[1]); + return Instance.getLibrary().getSourceCover("" + args[0]); } else if ("SET_SOURCE_COVER".equals(command)) { - Instance.getLibrary().setSourceCover("" + args[1], "" + args[2]); + Instance.getLibrary().setSourceCover("" + args[0], "" + args[1]); } else if ("EXIT".equals(command)) { stop(0, false); } -- 2.27.0