Remote: now with a pin code
authorNiki Roo <niki@nikiroo.be>
Sun, 26 Nov 2017 17:02:34 +0000 (18:02 +0100)
committerNiki Roo <niki@nikiroo.be>
Sun, 26 Nov 2017 17:02:34 +0000 (18:02 +0100)
src/be/nikiroo/fanfix/Main.java
src/be/nikiroo/fanfix/bundles/resources.properties
src/be/nikiroo/fanfix/library/RemoteLibrary.java
src/be/nikiroo/fanfix/library/RemoteLibraryServer.java

index 6a8a4a5af7542dccb07e8ffd5ba97dccd1abb05a..a133de789cf3de776e0a8519ffd1ec5b5d3536f9 100644 (file)
@@ -62,9 +62,10 @@ public class Main {
         * <li>--set-reader [reader type]: set the reader type to CLI, TUI or LOCAL
         * for this command</li>
         * <li>--version: get the version of the program</li>
-        * <li>--server [port]: start a server on this port</li>
-        * <li>--stop-server [port]: stop the running server on this port if any</li>
-        * <li>--remote [host] [port]: use a the given remote library</li>
+        * <li>--server [key] [port]: start a server on this port</li>
+        * <li>--stop-server [key] [port]: stop the running server on this port if
+        * any</li>
+        * <li>--remote [key] [host] [port]: use a the given remote library</li>
         * </ul>
         * 
         * @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);
                                                        }
index fba6355a437b1ec6ecf610c8a603cf73bd08dda8..cd80b3aa68b77ff38885afe5beee2730954dc8d9 100644 (file)
@@ -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\
index 29d2bcda594f353afc882436438d071686db2dc0..0a747bdc11adc3d208f4011c74f4deff6be25f16 100644 (file)
@@ -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<MetaData> metas = new ArrayList<MetaData>();
                MetaData[] fromNetwork = this.<MetaData[]> 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.<BufferedImage> getRemoteObject( //
-                               new Object[] { "GET_COVER", luid });
+                               new Object[] { key, "GET_COVER", luid });
        }
 
        @Override
        public BufferedImage getSourceCover(final String source) {
                return this.<BufferedImage> 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.<Story> getRemoteObject(new Object[] { "GET_STORY", luid });
+               return this.<Story> 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.<BufferedImage> getRemoteObject( //
-               new Object[] { "SET_SOURCE_COVER", source, luid });
+               new Object[] { key, "SET_SOURCE_COVER", source, luid });
        }
 
        @Override
index 1fe182b87980c01e44844b34a1916d40bda6a97e..5bbe4cdd1f33b77bb67e609b91b7770aa886a35e 100644 (file)
@@ -14,80 +14,96 @@ import be.nikiroo.utils.serial.Server;
 /**
  * Create a new remote server that will listen for order on the given port.
  * <p>
- * 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):
  * <ul>
- * <li>GET_METADATA *: will return the metadata of all the stories in the
+ * <li>KEY GET_METADATA *: will return the metadata of all the stories in the
  * library</li>
- * <li>GET_STORY [luid]: will return the given story if it exists (or NULL if
- * not)</li>
- * <li>SAVE_STORY [story] [luid]: save the story with the given LUID</li>
- * <li>DELETE_STORY [luid]: delete the story of LUID luid</li>
- * <li>GET_COVER [luid]: return the cover of the story</li>
- * <li>GET_SOURCE_COVER [source]: return the cover for this source</li>
- * <li>SET_SOURCE_COVER [source], [luid]: set the default cover for the given
- * source to the cover of the story denoted by luid</li>
- * <li>EXIT: stop the server</li>
+ * <li>KEY GET_STORY [luid]: will return the given story if it exists (or NULL
+ * if not)</li>
+ * <li>KEY SAVE_STORY [story] [luid]: save the story with the given LUID</li>
+ * <li>KEY DELETE_STORY [luid]: delete the story of LUID luid</li>
+ * <li>KEY GET_COVER [luid]: return the cover of the story</li>
+ * <li>KEY GET_SOURCE_COVER [source]: return the cover for this source</li>
+ * <li>KEY SET_SOURCE_COVER [source], [luid]: set the default cover for the
+ * given source to the cover of the story denoted by luid</li>
+ * <li>KEY EXIT: stop the server</li>
  * </ul>
  * 
  * @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<MetaData> 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);
                }