/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.tool; import java.io.File; import java.util.Scanner; import divconq.hub.Clock; import divconq.lang.op.FuncResult; import divconq.lang.op.OperationResult; import divconq.util.FileUtil; import divconq.util.ISettingsObfuscator; import divconq.util.StringUtil; import divconq.xml.XAttribute; import divconq.xml.XElement; import divconq.xml.XmlReader; import divconq.xml.XmlWriter; /** * TODO out of date, replace * * Utility to construct a Project from a local (developer) repository. Allows the user * to pick the packages to use and to setup the database connection. Should only be run * by developer using a local repository, will not work otherwise. * * A Project is required both by developers running in developer mode and by deployed * production Hubs. Projects hold configuration, server keys and other project specific * resources. * * @author Andy * */ public class Configure { /* * Install Developer * * hub/ * bin/ * run.bat [configure, sync, testdb or run which takes developers class name as 2nd argument] * run.sh * * lib/ * third party*.jar * divconq.core.jar * * licenses/ * *.txt * * packages/ * dcCore/ * m/ * dcConn.m * dcShema.m * dcInstall.m * dcUninstall.m * dcStrUtil.m * dcTimeUtil.m * all/ * dictionary/ * dictionary.xml * schema/ * schema.xml * lib/ * divconq.core.jar * * dcTest/ * m/ * dcTest.m * dcToyTest.m * all/ * dictionary/ * dictionary.xml * schema/ * schema.xml * * LICENSE.txt * NOTICE.txt * README.txt * * * --------------------------------------------------- * * Configure adds: * * project/ * packages.xml [if not present, prompt for packages to use] * * private/ * config.xml [if not present, create and init Id and Feed - prompt for database connection details] * * resource/ [if using a ssh client key] * [dbclientkey].pem * * public/ * config.xml * * TODO, copy libs, upload routines, start install - create repo * * TODO local/remote repo - where to get files * * TODO configure for deployment - not just devmode * */ /** * Utility must be run from the application base directory (parent to "bin") * * @param args ignored */ public static void main(String[] args) { File pkgs = new File("./packages"); if (!pkgs.exists()) { System.out.println("This deployment does not have any local repository, unable to configure."); return; } Scanner scan = new Scanner(System.in); boolean running = true; while(running) { try { System.out.println(); System.out.println("-----------------------------------------------"); System.out.println(" DivConq Configure Menu"); System.out.println("-----------------------------------------------"); System.out.println("0) Exit"); System.out.println("1) Install Project"); System.out.println("2) Configure Database"); System.out.println("3) Encrypt Setting"); System.out.println("4) Hash Value"); String opt = scan.nextLine(); Long mopt = StringUtil.parseInt(opt); if (mopt == null) continue; switch (mopt.intValue()) { case 0: running = false; break; case 1: Configure.install(scan); break; case 2: Configure.db(scan); break; case 3: Configure.encrypt(scan); break; case 4: Configure.hash(scan); break; } } catch(Exception x) { System.out.println("CLI error: " + x); } } } /** * Assemble the packages and config file. * * @param scan user input scanner */ private static void install(Scanner scan) { File config = new File("./project/private/config.xml"); if (config.exists()) { System.out.println("Installing will wipe out previous project, are you sure you want to continue?"); System.out.print("[yes/no]: "); if (!"yes".equals(scan.nextLine().toLowerCase())) return; } File proj = new File("./project"); FileUtil.deleteDirectory(proj.toPath()); proj.mkdirs(); System.out.println(); System.out.println("Adding packages, type 'yes' for packages you wish to include: "); File pkgs = new File("./packages"); XElement xpkgs = new XElement("Packages"); // TODO order the packages, not just in order found for (File pkg : pkgs.listFiles()) { if (pkg.isDirectory() || pkg.getName().endsWith(".zip")) { String name = pkg.getName(); if (name.endsWith(".zip")) name = name.substring(0, name.length() - 4); System.out.println("Found: " + name); System.out.print("[yes/no]: "); if ("yes".equals(scan.nextLine().toLowerCase())) xpkgs.add(new XElement("Package", new XAttribute("Name", name))); } } XmlWriter.writeToFile(xpkgs, "./project/packages.xml"); File priv = new File("./project/private"); priv.mkdirs(); File pub = new File("./project/public"); pub.mkdirs(); XElement conf = new XElement("Config"); XElement clock = new XElement("Clock"); // TODO prompt for custom "TimerClass" - add that class name to clock OperationResult or = new OperationResult(); Clock tclock = new Clock(); tclock.init(or, clock); // TODO check "or" result ISettingsObfuscator crypto1 = tclock.getObfuscator(); crypto1.configure(clock); conf.add(clock); XmlWriter.writeToFile(conf, "./project/private/config.xml"); XmlWriter.writeToFile(conf, "./project/public/config.xml"); Configure.db(scan); } /** * configure the database settings (only for private safety area) * * @param scan user input scanner */ private static void db(Scanner scan) { File config = new File("./project/private/config.xml"); if (!config.exists()) { System.out.println("Missing project config, please install first."); return; } FuncResult<XElement> xres = XmlReader.loadFile(config, false); if (xres.hasErrors()) { System.out.println("Project config is not well formed Xml, please re-install."); System.out.println("Errors: " + xres.getMessages()); return; } XElement conf = xres.getResult(); XElement clock = conf.find("Clock"); if ((clock == null) || !clock.hasAttribute("Id")) { System.out.println("Project config is invlaid, missing Clock, please re-install."); return; } OperationResult or = new OperationResult(); Clock tclock = new Clock(); tclock.init(or, clock); // TODO check "or" errors ISettingsObfuscator crypto1 = tclock.getObfuscator(); // remove old database settings - TODO support more than one connection and support editing instead of simple replace XElement xdb1 = conf.find("Database"); if (xdb1 == null) { xdb1 = new XElement("Database"); conf.add(xdb1); } XElement xdb = xdb1.find("Connect"); if (xdb == null) { xdb = new XElement("Connect", new XAttribute("Method", "Ssh")); xdb1.add(xdb); } System.out.println(); System.out.println("Enter database connection settings."); System.out.print("Host: "); String host = scan.nextLine(); if (StringUtil.isEmpty(host)) return; xdb.setAttribute("Host", host); System.out.print("Port [enter for 22]: "); String port = scan.nextLine(); if (StringUtil.isNotEmpty(port)) xdb.setAttribute("Port", port); System.out.print("User: "); String user = scan.nextLine(); if (StringUtil.isEmpty(user)) return; xdb.setAttribute("User", user); System.out.print("Name of ssh key file [leave blank if not using client ssh key]: "); String keyfilename = scan.nextLine(); if (StringUtil.isNotEmpty(keyfilename)) { xdb.removeAttribute("Password"); xdb.removeAttribute("Passphrase"); if (!keyfilename.endsWith(".pem")) keyfilename = keyfilename + ".pem"; System.out.println("Place the ssh key file in the correct project resource path."); System.out.println("./project/private/resource/" + keyfilename); while (true) { System.out.println("Press enter after placing the file and we'll confirm the file"); scan.nextLine(); File keyf = new File("./project/private/resource/" + keyfilename); if (keyf.exists()) break; } System.out.println("Key file confirmed."); System.out.println(); xdb.setAttribute("KeyFile", keyfilename); System.out.print("Client Key Passphrase [leave blank if none]: "); String passphrase = scan.nextLine(); if (StringUtil.isNotEmpty(passphrase)) xdb.setAttribute("Passphrase", crypto1.encryptStringToHex(passphrase)); } else { xdb.removeAttribute("Passphrase"); xdb.removeAttribute("KeyFile"); System.out.print("Password: "); String password = scan.nextLine(); if (StringUtil.isNotEmpty(password)) xdb.setAttribute("Password", crypto1.encryptStringToHex(password)); } XmlWriter.writeToFile(conf, "./project/private/config.xml"); } private static void encrypt(Scanner scan) { File config = new File("./project/private/config.xml"); if (!config.exists()) { System.out.println("Missing project config, please install first."); return; } FuncResult<XElement> xres = XmlReader.loadFile(config, false); if (xres.hasErrors()) { System.out.println("Project config is not well formed Xml, please re-install."); System.out.println("Errors: " + xres.getMessages()); return; } XElement conf = xres.getResult(); XElement clock = conf.find("Clock"); if ((clock == null) || !clock.hasAttribute("Id")) { System.out.println("Project config is invlaid, missing Clock, please re-install."); return; } OperationResult or = new OperationResult(); Clock tclock = new Clock(); tclock.init(or, clock); // TODO check "or" results ISettingsObfuscator crypto1 = tclock.getObfuscator(); System.out.print("Value: "); String password = scan.nextLine(); System.out.println("Result: " + crypto1.encryptStringToHex(password)); } private static void hash(Scanner scan) { File config = new File("./project/private/config.xml"); if (!config.exists()) { System.out.println("Missing project config, please install first."); return; } FuncResult<XElement> xres = XmlReader.loadFile(config, false); if (xres.hasErrors()) { System.out.println("Project config is not well formed Xml, please re-install."); System.out.println("Errors: " + xres.getMessages()); return; } XElement conf = xres.getResult(); XElement clock = conf.find("Clock"); if ((clock == null) || !clock.hasAttribute("Id")) { System.out.println("Project config is invlaid, missing Clock, please re-install."); return; } OperationResult or = new OperationResult(); Clock tclock = new Clock(); tclock.init(or, clock); // TODO check "or" results ISettingsObfuscator crypto1 = tclock.getObfuscator(); System.out.print("Value: "); String password = scan.nextLine(); System.out.println("Result: " + crypto1.hashStringToHex(password)); } }