From cd7b17015df1b1aa0766b4350c16bcfb85fb2a00 Mon Sep 17 00:00:00 2001 From: Peter Hormanns Date: Mon, 16 Jun 2014 19:22:07 +0200 Subject: [PATCH] refactorings, removed old cli-client --- hsarjcli/.classpath | 1 + hsarjcli/build.xml | 23 +- hsarjcli/resource/js/functions.js | 84 ++++ hsarjcli/src/de/hsadmin/cli/Base64.java | 244 ---------- hsarjcli/src/de/hsadmin/cli/HSadmin.java | 458 ------------------ hsarjcli/src/de/hsadmin/cli/Scripting.java | 25 - hsarjcli/src/de/hsadmin/jscli/Main.java | 19 +- hsarjcli/src/de/hsadmin/jscli/RpcClient.java | 26 +- .../src/de/hsadmin/jscli/ScriptClient.java | 121 ++--- .../CASTicketProvider.java} | 16 +- .../jscli/{ => conf}/CommandlineParser.java | 4 +- .../de/hsadmin/jscli/{ => conf}/Config.java | 2 +- .../jscli/{ => console}/ConsoleWrapper.java | 11 +- .../hsadmin/jscli/console/PasswordReader.java | 9 + .../jscli/{ => exception}/JSCliException.java | 2 +- .../jscli/{ => json}/JSONFormatter.java | 2 +- 16 files changed, 201 insertions(+), 846 deletions(-) create mode 100644 hsarjcli/resource/js/functions.js delete mode 100644 hsarjcli/src/de/hsadmin/cli/Base64.java delete mode 100644 hsarjcli/src/de/hsadmin/cli/HSadmin.java delete mode 100644 hsarjcli/src/de/hsadmin/cli/Scripting.java rename hsarjcli/src/de/hsadmin/jscli/{CASTicket.java => cas/CASTicketProvider.java} (90%) rename hsarjcli/src/de/hsadmin/jscli/{ => conf}/CommandlineParser.java (95%) rename hsarjcli/src/de/hsadmin/jscli/{ => conf}/Config.java (97%) rename hsarjcli/src/de/hsadmin/jscli/{ => console}/ConsoleWrapper.java (77%) create mode 100644 hsarjcli/src/de/hsadmin/jscli/console/PasswordReader.java rename hsarjcli/src/de/hsadmin/jscli/{ => exception}/JSCliException.java (85%) rename hsarjcli/src/de/hsadmin/jscli/{ => json}/JSONFormatter.java (98%) diff --git a/hsarjcli/.classpath b/hsarjcli/.classpath index 20e5ff1..387d152 100644 --- a/hsarjcli/.classpath +++ b/hsarjcli/.classpath @@ -1,6 +1,7 @@ + diff --git a/hsarjcli/build.xml b/hsarjcli/build.xml index 5918e01..5cdf7bd 100644 --- a/hsarjcli/build.xml +++ b/hsarjcli/build.xml @@ -5,6 +5,7 @@ + @@ -15,15 +16,25 @@ + + + + + + + + + - + + @@ -31,7 +42,15 @@ - + diff --git a/hsarjcli/resource/js/functions.js b/hsarjcli/resource/js/functions.js new file mode 100644 index 0000000..e7a8781 --- /dev/null +++ b/hsarjcli/resource/js/functions.js @@ -0,0 +1,84 @@ +importClass(java.util.ArrayList); +importClass(java.util.HashMap); + +function hsaParseParam(val) { + if (val instanceof java.util.List) { + return val; + } + if (val instanceof java.util.Map) { + return val; + } + if (typeof val === 'object' && val.constructor === Array) { + return hsaParseParamArray(val); + } + if (typeof val === 'object') { + return hsaParseParamObject(val); + } +} + +function hsaParseParamArray(o) { + var lst = new ArrayList(); + var val = ''; + for (var idx=0; idx < o.length; idx++) { + val = o[idx]; + if (typeof val === 'object' && val.constructor === Array) { + val = hsaParseParamArray(val); + } + else if (typeof val === 'object') { + val = hsaParseParamObject(val); + }; + lst.add(val); + }; + return lst; +} + +function hsaParseParamObject(o) { + var hsh = new HashMap(); + for (var key in o) { + var val = o[key]; + if (typeof val === 'object' && val.constructor === Array) { + val = hsaParseParamArray(val); + } + else if (typeof val === 'object') { + val = hsaParseParamObject(val); + }; + hsh.put(key, val); + }; + return hsh; +} + +function hsaToNativeJSObject(val) { + if (val instanceof java.util.List) { + var res = []; + for (i = 0; i < val.size(); i++) { + res[i] = hsaToNativeJSObject(val.get(i)); + } + return res; + } + if (val instanceof java.util.Map) { + var res = {}; + var iter = val.keySet().iterator(); + while (iter.hasNext()) { + var key = iter.next(); + res[key] = hsaToNativeJSObject(val.get(key)); + } + return res; + } +} + +function hsaModuleCall(mod, fct, json) { + var params = new ArrayList(); + params.add(casgrantingticket.getRunAs()); + params.add(casgrantingticket.getTicket()); + if (typeof json === "undefined") { + json = {where:{}, set:{}}; + } + if (fct == "update" || fct == "add") { + params.add(hsaParseParamObject(json["set"])); + } + if (fct == "update" || fct == "delete" || fct == "search") { + params.add(hsaParseParamObject(json["where"])); + } + xmlrpcLastResult = xmlrpcclient.execute(mod + "." + fct, params); + return hsaToNativeJSObject(xmlrpcLastResult); +} diff --git a/hsarjcli/src/de/hsadmin/cli/Base64.java b/hsarjcli/src/de/hsadmin/cli/Base64.java deleted file mode 100644 index afa5cc1..0000000 --- a/hsarjcli/src/de/hsadmin/cli/Base64.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * @(#)Base64.java 1.5 03/12/19 - * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -package de.hsadmin.cli; - -/** - * Static methods for translating Base64 encoded strings to byte arrays - * and vice-versa. - * - * @author Josh Bloch - * @version 1.5, 12/19/03 - * @see Preferences - * @since 1.4 - */ -class Base64 { - /** - * Translates the specified byte array into a Base64 string as per - * Preferences.put(byte[]). - */ - static String byteArrayToBase64(byte[] a) { - return byteArrayToBase64(a, false); - } - - /** - * Translates the specified byte array into an "aternate representation" - * Base64 string. This non-standard variant uses an alphabet that does - * not contain the uppercase alphabetic characters, which makes it - * suitable for use in situations where case-folding occurs. - */ - static String byteArrayToAltBase64(byte[] a) { - return byteArrayToBase64(a, true); - } - - private static String byteArrayToBase64(byte[] a, boolean alternate) { - int aLen = a.length; - int numFullGroups = aLen/3; - int numBytesInPartialGroup = aLen - 3*numFullGroups; - int resultLen = 4*((aLen + 2)/3); - StringBuffer result = new StringBuffer(resultLen); - char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); - - // Translate all full groups from byte array elements to Base64 - int inCursor = 0; - for (int i=0; i> 2]); - result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]); - result.append(intToAlpha[byte2 & 0x3f]); - } - - // Translate partial group if present - if (numBytesInPartialGroup != 0) { - int byte0 = a[inCursor++] & 0xff; - result.append(intToAlpha[byte0 >> 2]); - if (numBytesInPartialGroup == 1) { - result.append(intToAlpha[(byte0 << 4) & 0x3f]); - result.append("=="); - } else { - // assert numBytesInPartialGroup == 2; - int byte1 = a[inCursor++] & 0xff; - result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2)&0x3f]); - result.append('='); - } - } - // assert inCursor == a.length; - // assert result.length() == resultLen; - return result.toString(); - } - - /** - * This array is a lookup table that translates 6-bit positive integer - * index values into their "Base64 Alphabet" equivalents as specified - * in Table 1 of RFC 2045. - */ - private static final char intToBase64[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - /** - * This array is a lookup table that translates 6-bit positive integer - * index values into their "Alternate Base64 Alphabet" equivalents. - * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045. - * This alternate alphabet does not use the capital letters. It is - * designed for use in environments where "case folding" occurs. - */ - private static final char intToAltBase64[] = { - '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':', - ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?' - }; - - /** - * Translates the specified Base64 string (as per Preferences.get(byte[])) - * into a byte array. - * - * @throw IllegalArgumentException if s is not a valid Base64 - * string. - */ - static byte[] base64ToByteArray(String s) { - return base64ToByteArray(s, false); - } - - /** - * Translates the specified "aternate representation" Base64 string - * into a byte array. - * - * @throw IllegalArgumentException or ArrayOutOfBoundsException - * if s is not a valid alternate representation - * Base64 string. - */ - static byte[] altBase64ToByteArray(String s) { - return base64ToByteArray(s, true); - } - - private static byte[] base64ToByteArray(String s, boolean alternate) { - byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); - int sLen = s.length(); - int numGroups = sLen/4; - if (4*numGroups != sLen) - throw new IllegalArgumentException( - "String length must be a multiple of four."); - int missingBytesInLastGroup = 0; - int numFullGroups = numGroups; - if (sLen != 0) { - if (s.charAt(sLen-1) == '=') { - missingBytesInLastGroup++; - numFullGroups--; - } - if (s.charAt(sLen-2) == '=') - missingBytesInLastGroup++; - } - byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; - - // Translate all full groups from base64 to byte array elements - int inCursor = 0, outCursor = 0; - for (int i=0; i> 4)); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - result[outCursor++] = (byte) ((ch2 << 6) | ch3); - } - - // Translate partial group, if present - if (missingBytesInLastGroup != 0) { - int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); - - if (missingBytesInLastGroup == 1) { - int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - } - } - // assert inCursor == s.length()-missingBytesInLastGroup; - // assert outCursor == result.length; - return result; - } - - /** - * Translates the specified character, which is assumed to be in the - * "Base 64 Alphabet" into its equivalent 6-bit positive integer. - * - * @throw IllegalArgumentException or ArrayOutOfBoundsException if - * c is not in the Base64 Alphabet. - */ - private static int base64toInt(char c, byte[] alphaToInt) { - int result = alphaToInt[c]; - if (result < 0) - throw new IllegalArgumentException("Illegal character " + c); - return result; - } - - /** - * This array is a lookup table that translates unicode characters - * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) - * into their 6-bit positive integer equivalents. Characters that - * are not in the Base64 alphabet but fall within the bounds of the - * array are translated to -1. - */ - private static final byte base64ToInt[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - }; - - /** - * This array is the analogue of base64ToInt, but for the nonstandard - * variant that avoids the use of uppercase alphabetic characters. - */ - private static final byte altBase64ToInt[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, - 2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 22, 23, 24, 25 - }; - - public static void main(String args[]) { - int numRuns = Integer.parseInt(args[0]); - int numBytes = Integer.parseInt(args[1]); - java.util.Random rnd = new java.util.Random(); - for (int i=0; i> responseHeaders; - private StringBuilder requestData; - private StringBuilder responseData; - private String password; - private String username; - private String responseMessage; - - public HttpRequest(String url) throws MalformedURLException { - this.url = new URL(url); - } - - public int post() throws IOException { - return doRequest("POST"); - } - - public int put() throws IOException { - return doRequest("PUT"); - } - - public int doRequest(String method) throws IOException { - echoVerbose(method + ": " + url.toString()); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setDoOutput(true); - conn.setDoInput(true); - conn.setUseCaches(false); - conn.setAllowUserInteraction(false); - conn.setRequestProperty("Content-type", - "application/x-www-form-urlencoded; charset=" + "UTF-8"); - if (username != null) - conn.setRequestProperty("Authorization", - createAuthorizationHeader(username, password)); - conn.setRequestMethod(method); - OutputStreamWriter wr = new OutputStreamWriter(conn - .getOutputStream(), "UTF-8"); - if (requestData == null) { - if (username != null) - addParam("username", username); - if (password != null) - addParam("password", password); - } - if (requestData != null) - wr.write(requestData.toString()); - wr.flush(); - - responseHeaders = conn.getHeaderFields(); - if (verbosity > 1) - echoResponseHeaders(conn); - - responseData = new StringBuilder(); - try { - BufferedReader rd = new BufferedReader(new InputStreamReader( - conn.getInputStream(), "ISO-8859-1")); - String line; - while ((line = rd.readLine()) != null) { - responseData.append(line + "\n"); - } - rd.close(); - } catch (IOException exc) { - } - wr.close(); - responseMessage = conn.getResponseMessage(); - return conn.getResponseCode(); - } - - private String createAuthorizationHeader(String username, - String password) throws IOException { - if (password == null) - password = getPassWord(); - String authValue = username + ":" + password; - String encodedAuth = Base64.byteArrayToBase64(authValue.getBytes()); - return "Basic " + encodedAuth; - } - - /** - * printing the response header. - */ - private void echoResponseHeaders(HttpURLConnection conn) - throws IOException { - // TODO: just for debugging - remove - System.out.println("ResponseCode: " + conn.getResponseCode()); - System.out.println("ResponseMessage: " + conn.getResponseMessage()); - for (String key : responseHeaders.keySet()) { - System.out.println(key + ": " + responseHeaders.get(key)); - } - } - - public void addParam(String name, String value) - throws UnsupportedEncodingException { - if (requestData == null) { - requestData = new StringBuilder(); - } else { - requestData.append("&"); - } - requestData.append(URLEncoder.encode(name, "UTF-8") + "=" - + URLEncoder.encode(value, "UTF-8")); - } - - public String getResponseData() { - return responseData.toString(); - } - - public void setUsername(String username) { - this.username = username; - } - - public void setPassword(String password) { - this.password = password; - } - - public List getResponseHeader(String key) { - return responseHeaders.get(key); - } - - public void setRequestData(String data) { - requestData = new StringBuilder(data); - } - - public String getResponseMessage() { - return responseMessage; - } - } - - /** - * returns the TGT, either from a special user config file or from stdin - */ - private static String getTGT() throws IOException { - HttpRequest postReq = new HttpRequest(loginURL); - echoVerbose("using userName=" + authenticatedUserName + " for login"); - postReq.setUsername(authenticatedUserName); - String pw = getPassWord(); - postReq.setPassword(pw); - if (201 == postReq.post()) { - String tgt = postReq.getResponseHeader("Location").get(0); - echoVerbose("TGT: " + tgt); - return tgt; - } else { - return null; - } - } - - /** - * retrieves a new session ticket using the given ticket granting ticket - */ - private static String getST(String tgt) { - String st = null; - try { - HttpRequest httpReq = new HttpRequest(tgt); - httpReq.setRequestData("service=" + backendURL); - if (200 == httpReq.post()) { - st = httpReq.getResponseData(); - } - } catch (Exception exc) { /* ignore */ - } - echoVerbose("ST: " + st); - return st; - } - - /** - * returns the password, either from parameter, user config file or from - * stdin. - */ - private static String getPassWord() throws IOException { - if (passWord == null) - passWord = config.getProperty("passWord." + authenticatedUserName, - config.getProperty("passWord")); - if (passWord == null) { - Console console = System.console(); - if (console != null) { - char[] input = console.readPassword("Password: "); - passWord = new String(input); - } else { - System.out.print("Password: "); - System.out.flush(); - BufferedReader reader = new BufferedReader( - new InputStreamReader(System.in)); - - PasswordMaskingThread thread = new PasswordMaskingThread(); - thread.start(); - passWord = reader.readLine(); - thread.interrupt(); - } - } - return passWord; - } - - /** - * calls the remote service using the given service ticket 'st'. - */ - private static String exec(String st, String[] args) throws IOException { - HttpRequest httpReq = new HttpRequest(servletURL); - if (runAsUserName == null) { - runAsUserName = authenticatedUserName; - } - echoVerbose("using userName=" + runAsUserName + " for exec"); - httpReq.setUsername(runAsUserName); - httpReq.setPassword(st); - StringBuilder argsAsString = new StringBuilder(); - for (String arg : args) { - argsAsString.append(arg + "\n"); - } - echoVerbose("--- remote args: ---\n" + argsAsString.toString() - + "\n--- end of args. ---"); - httpReq.setRequestData(argsAsString.toString()); - int code = httpReq.put(); - List hsadminErrors = httpReq.getResponseHeader("X-hsadmin-error"); - if (hsadminErrors != null && hsadminErrors.size() > 0 && hsadminErrors.get(0) != null) { - throw new RuntimeException(hsadminErrors.get(0)); - } - else { - if (200 == code) return httpReq.getResponseData(); - } - throw new RuntimeException("HTTP error #" + code + ": " - + httpReq.getResponseMessage()); - } - - /** - * reads session information (in users home dir). - */ - private static String loadTGT(String user, String fileName) - throws IOException { - Properties properties = new Properties(); - try { - properties.load(new FileInputStream(new File(System - .getProperty("user.home"), fileName))); - return properties.getProperty(user); - } catch (FileNotFoundException exc) { - return null; - } - } - - /** - * stores session information (in users home dir). - */ - private static void storeTGT(String fileName, String user, String tgt) - throws IOException { - Properties properties = new Properties(); - try { - properties.load(new FileInputStream(new File(System - .getProperty("user.home"), fileName))); - } catch (Exception exc) { /* ignore */ - } - properties.setProperty(user, tgt); - properties.store(new FileOutputStream(new File(System - .getProperty("user.home"), fileName)), ""); - } - - /** - * reads the settings from the given config file (looked up in users home - * dir). - */ - private static void readUserConfig(String string) throws IOException { - // Read properties file. - config = new Properties(); - try { - config.load( - new FileInputStream( - new File(System.getProperty("user.home"), ".hsadmin.conf"))); - } catch (FileNotFoundException e) { - try { - config.load( - new FileInputStream( - new File("/etc/hsadmin.conf"))); - } catch (FileNotFoundException ee) { - } - } - authenticatedUserName = config.getProperty("userName", System.getenv("USER")); - loginURL = config.getProperty("loginURL", loginURL); - servletURL = config.getProperty("servletURL", servletURL); - backendURL = config.getProperty("backendURL", backendURL); - verbosity = Integer.parseInt(config.getProperty("verbosity", "0")); - } - - /** - * echoes the string to stdout depending on verbosity level. - */ - private static void echoVerbose(String string) { - if (verbosity > 0) { - System.out.println("]" + string); - } - } - - private static void printHelp() { - System.out.println("syntax: hsadmin [-h|--help] [-V (0|1|2)|--verbosity=(0|1|2)] [-v|--version]\n" - + " [-u USER|--user=USER] [-|REMOTE-ARGUMENTS]"); - System.out.println("sample: hsadmin -V 0 -u xyz00 -c user.search"); - System.out.println("version: " + version); - System.out.println(""); - System.out.println("REMOTE-ARGUMENTS ('-' on command line => read from stdin):"); - } - - /** - * reads remote arguments from stdin into 'remoteArgs'. - */ - private static void readArgsFromStdIn(ArrayList remoteArgs) - throws IOException { - echoVerbose("READING ARGS FROM STDIN"); - BufferedReader rd = new BufferedReader(new InputStreamReader(System.in)); - String line; - while ((line = rd.readLine()) != null) { - echoVerbose("ADDING REMOTE ARG:" + line); - remoteArgs.add(line); - } - rd.close(); - } - - private static String createSessionTicket() throws IOException { - String tgt = loadTGT(authenticatedUserName, ".hsadmin.tgt"); - String st = getST(tgt); - if (st == null) { - tgt = getTGT(); - if (tgt == null) { - System.err.println("ERROR: login failure - cannot get ticket granting ticket"); - System.exit(1); - } - storeTGT(".hsadmin.tgt", authenticatedUserName, tgt); - st = getST(tgt); - } - return st; - } - - private static ArrayList createRemoteArgs(String[] args) - throws IOException { - ArrayList remoteArgs = new ArrayList(); - for (int n = 0; n < args.length; ++n) { - String arg = args[n]; - if (arg.equals("-u")) { - // TODO: out of bounds error - authenticatedUserName = args[++n]; - } else if (arg.startsWith("--user=") || arg.startsWith("--user:")) { - authenticatedUserName = args[n].substring(7); - } else if (arg.equals("-r")) { - // TODO: out of bounds error - runAsUserName = args[++n]; - } else if (arg.toLowerCase().startsWith("--runas=") || arg.toLowerCase().startsWith("--runas:")) { - runAsUserName = args[n].substring(8); - } else if (arg.equals("-V")) { - // TODO: out of bounds error - verbosity = Integer.parseInt(args[++n]); - } else if (arg.startsWith("--verbosity:") - || arg.startsWith("--verbosity=")) { - verbosity = Integer.parseInt(args[n].substring(12)); - } else if (arg.equals("-v")) { - System.out.println(version); - remoteArgs = new ArrayList(); - break; - } else if (arg.startsWith("--version")) { - System.out.println(version); - remoteArgs = new ArrayList(); - break; - } else if (arg.equals("-h")) { - // TODO: out of bounds error - printHelp(); - remoteArgs = new ArrayList(); - remoteArgs.add("-h"); - break; - } else if (arg.startsWith("--help")) { - printHelp(); - remoteArgs = new ArrayList(); - remoteArgs.add("-h"); - break; - } else if (arg.equals("-")) - readArgsFromStdIn(remoteArgs); - else { - echoVerbose("ADDING REMOTE ARG:" + args[n]); - remoteArgs.add(args[n]); - } - } - return remoteArgs; - } - - /** - * main program. - */ - public static void main(String[] args) throws IOException { - readUserConfig(".hsadmin.conf"); - ArrayList remoteArgs = createRemoteArgs(args); - if (remoteArgs.size() > 0) { - try { - String st = createSessionTicket(); - String response = exec(st, remoteArgs.toArray(new String[remoteArgs.size()])); - if (response != null) - System.out.print(response); - } catch (Exception exc) { - System.err.println(exc.getMessage()); - System.exit(1); // TODO: be more specific, - // like: 1=unknown, 2=remoting, 3=functional - } - } - } - -} diff --git a/hsarjcli/src/de/hsadmin/cli/Scripting.java b/hsarjcli/src/de/hsadmin/cli/Scripting.java deleted file mode 100644 index 4555066..0000000 --- a/hsarjcli/src/de/hsadmin/cli/Scripting.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.hsadmin.cli; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; - -public class Scripting { - - public static void main(String[] args) { - ScriptEngineManager engineManager = new ScriptEngineManager(); - ScriptEngine engine = engineManager.getEngineByName("js"); - try { - engine.eval("if (typeof user === 'undefined') { user = { }; };"); - engine.eval("user['name'] = 'Klaus-Dieter';"); - engine.eval("if (typeof user === 'undefined') { user = { }; };"); - engine.eval("user['age'] = 44;"); - engine.eval("print(user.name + '\\n');"); - engine.eval("print(user.age + '\\n');"); - engine.eval("print(user + '\\n');"); - } catch (ScriptException e) { - System.err.println(e.getMessage()); - } - } - -} diff --git a/hsarjcli/src/de/hsadmin/jscli/Main.java b/hsarjcli/src/de/hsadmin/jscli/Main.java index 3452ee5..26a4f93 100644 --- a/hsarjcli/src/de/hsadmin/jscli/Main.java +++ b/hsarjcli/src/de/hsadmin/jscli/Main.java @@ -5,19 +5,22 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.InputStreamReader; +import de.hsadmin.jscli.conf.CommandlineParser; +import de.hsadmin.jscli.console.ConsoleWrapper; +import de.hsadmin.jscli.json.JSONFormatter; + public class Main { public static void main(String[] args) { - ConsoleWrapper console = null; + final ConsoleWrapper console = new ConsoleWrapper(); + final JSONFormatter formatter = new JSONFormatter(); try { - CommandlineParser cmdParser = new CommandlineParser(args); - String runAs = cmdParser.getRunAs(); - console = new ConsoleWrapper(); + final CommandlineParser cmdParser = new CommandlineParser(args); + final String runAs = cmdParser.getRunAs(); console.open(runAs + "@hsadmin> "); - JSONFormatter formatter = new JSONFormatter(); - ScriptClient scriptClient = new ScriptClient(console, cmdParser.getUser(), runAs); - String file = cmdParser.getFile(); + final ScriptClient scriptClient = new ScriptClient(console, cmdParser.getUser(), runAs); + final String file = cmdParser.getFile(); if (file != null && file.length() > 0) { if ("-".equals(file)) { scriptClient.execute(new InputStreamReader(System.in)); @@ -32,7 +35,7 @@ public class Main { } } } - String expr = cmdParser.getExpression(); + final String expr = cmdParser.getExpression(); if (expr != null && expr.length() > 0) { scriptClient.execute(expr); console.println(formatter.format(scriptClient.getLastRpcResult())); diff --git a/hsarjcli/src/de/hsadmin/jscli/RpcClient.java b/hsarjcli/src/de/hsadmin/jscli/RpcClient.java index e8aead4..d6c6c71 100644 --- a/hsarjcli/src/de/hsadmin/jscli/RpcClient.java +++ b/hsarjcli/src/de/hsadmin/jscli/RpcClient.java @@ -9,14 +9,18 @@ import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; +import de.hsadmin.jscli.cas.CASTicketProvider; +import de.hsadmin.jscli.conf.Config; +import de.hsadmin.jscli.exception.JSCliException; + public class RpcClient { private static final String XMLRPC_URL = "https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin"; - private String xmlrpcURL; - private XmlRpcClient client; + private final String xmlrpcURL; + private final XmlRpcClient client; - public RpcClient(CASTicket tgt) throws JSCliException { + public RpcClient(final CASTicketProvider tgt) throws JSCliException { try { xmlrpcURL = Config.getInstance().getProperty("xmlrpcURL", XMLRPC_URL); XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); @@ -30,24 +34,24 @@ public class RpcClient { } public List listMethods() throws JSCliException { - List methodList = new ArrayList(); - List execute = execute("system.listMethods"); - for (Object obj : execute) { + final List methodList = new ArrayList(); + final List execute = execute("system.listMethods"); + for (final Object obj : execute) { methodList.add(obj.toString()); } return methodList; } - private List execute(String method) throws JSCliException { + private List execute(final String method) throws JSCliException { return execute(method, new ArrayList()); } - public List execute(String method, List params) throws JSCliException { + public List execute(final String method, final List params) throws JSCliException { try { - Object execute = client.execute(method, params); - ArrayList list = new ArrayList(); + final Object execute = client.execute(method, params); + final ArrayList list = new ArrayList(); if (execute instanceof Object[]) { - Object[] resArray = (Object[]) execute; + final Object[] resArray = (Object[]) execute; for (int idx=0; idx < resArray.length; idx++) { list.add(resArray[idx]); } diff --git a/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java b/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java index 6bb0540..4acc603 100644 --- a/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java +++ b/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java @@ -1,5 +1,7 @@ package de.hsadmin.jscli; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.Reader; import java.util.HashSet; import java.util.List; @@ -9,99 +11,52 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import de.hsadmin.jscli.cas.CASTicketProvider; +import de.hsadmin.jscli.console.ConsoleWrapper; +import de.hsadmin.jscli.exception.JSCliException; + public class ScriptClient { final private ScriptEngine engine; final private Set completionStrings; - public ScriptClient(ConsoleWrapper console, String user, String runAs) throws JSCliException { + public ScriptClient(final ConsoleWrapper console, final String user, final String runAs) throws JSCliException { + final CASTicketProvider ticketProvider = new CASTicketProvider(console, user, runAs); + final RpcClient rpcClient = new RpcClient(ticketProvider); + final ScriptEngineManager engineManager = new ScriptEngineManager(); completionStrings = new HashSet(); - CASTicket grantingTicket = new CASTicket(console, user, runAs); - RpcClient rpcClient = new RpcClient(grantingTicket); - ScriptEngineManager engineManager = new ScriptEngineManager(); engine = engineManager.getEngineByName("js"); + engine.put("casgrantingticket", ticketProvider); + engine.put("xmlrpcclient", rpcClient); + engine.put("xmlrpcLastResult", null); try { - engine.put("casgrantingticket", grantingTicket); - engine.put("xmlrpcclient", rpcClient); - engine.put("xmlrpcLastResult", null); - engine.eval("importClass(java.util.ArrayList);"); - engine.eval("importClass(java.util.HashMap);"); - engine.eval("function hsaParseParam(val) { " + - "if (val instanceof java.util.List) return val;" + - "if (val instanceof java.util.Map) return val;" + - "if (typeof val === 'object' && val.constructor === Array) { res = hsaParseParamArray(val); } " + - "else if (typeof val === 'object') { res = hsaParseParamObject(val); }; " + - "return res; " + - "}"); - engine.eval("function hsaParseParamArray(o) { " + - "var lst = new ArrayList(); " + - "var val = ''; " + - "for (var idx=0; idx < o.length; idx++) { " + - " val = o[idx]; " + - " if (typeof val === 'object' && val.constructor === Array) { val = hsaParseParamArray(val); } " + - " else if (typeof val === 'object') { val = hsaParseParamObject(val); }; " + - " lst.add(val); " + - "}; " + - "return lst; " + - "}"); - engine.eval("function hsaParseParamObject(o) { " + - "var hsh = new HashMap(); " + - "for (var key in o) { " + - " var val = o[key]; " + - " if (typeof val === 'object' && val.constructor === Array) { val = hsaParseParamArray(val); } " + - " else if (typeof val === 'object') { val = hsaParseParamObject(val); }; " + - " hsh.put(key, val); " + - "}; " + - "return hsh; " + - "}"); - engine.eval("function hsaToNativeJSObject(val) { " + - "if (val instanceof java.util.List) {" + - " var res = [];" + - " for (i = 0; i < val.size(); i++) {" + - " res[i] = hsaToNativeJSObject(val.get(i));" + - " }" + - " return res;" + - "}" + - "if (val instanceof java.util.Map) {" + - " var res = {};" + - " var iter = val.keySet().iterator();" + - " while (iter.hasNext()) {" + - " var key = iter.next();" + - " res[key] = hsaToNativeJSObject(val.get(key));" + - " }" + - " return res;" + - "}" + - "return val;" + - "};"); + final InputStream inputResource = getClass().getClassLoader().getResourceAsStream("js/functions.js"); + engine.eval(new InputStreamReader(inputResource)); } catch (ScriptException e) { throw new JSCliException(e); } - List methods = rpcClient.listMethods(); - for (String method : methods) { - String[] parts = method.split("\\."); + final List methods = rpcClient.listMethods(); + for (final String method : methods) { + final String[] parts = method.split("\\."); if (parts.length == 2) { - String module = parts[0]; - String function = parts[1]; - if ("delete".equals(function)) { - function = "remove"; - } + final String module = parts[0]; completionStrings.add(module); - completionStrings.add(module + "." + function); + final String function = parts[1]; + final String jsFunctionIdent; + if ("delete".equals(function)) { + jsFunctionIdent = module + "['remove']"; + completionStrings.add(module + ".remove"); + } else { + jsFunctionIdent = module + "['" + function + "']"; + completionStrings.add(module + "." + function); + } try { - engine.eval("if (typeof " + module + " === 'undefined') " + - "{ var " + module + " = { }; };\n" + - module + "['" + function + "'] = function(json) { " + - "var mod = '" + module + "'; " + - ("remove".equals(function) ? "var fct = 'delete'; " : "var fct = '" + function + "'; ") + - "var params = new ArrayList(); " + - "params.add(casgrantingticket.getRunAs()); " + - "params.add(casgrantingticket.getTicket()); " + - "if (typeof json === 'undefined') { json = { where:{}, set:{} } };" + - "if (fct == 'update' || fct == 'add') { params.add(hsaParseParamObject(json['set'])); }; " + - "if (fct == 'update' || fct == 'delete' || fct == 'search') { params.add(hsaParseParamObject(json['where'])); }; " + - "xmlrpcLastResult = xmlrpcclient.execute(mod + '.' + fct, params);" + - "return hsaToNativeJSObject(xmlrpcLastResult); " + - "};"); + engine.eval( + "if (typeof " + module + " === 'undefined')" + + " { var " + module + " = { }; };\n" + + jsFunctionIdent + + " = function(json) { hsaModuleCall('" + module + "', '" + function + "', json); }" + ); } catch (ScriptException e) { e.printStackTrace(); } @@ -111,16 +66,16 @@ public class ScriptClient { } public String[] getCodeCompletionStrings() { - String[] codeCompletionStrings = new String[completionStrings.size()]; + final String[] codeCompletionStrings = new String[completionStrings.size()]; int idx = 0; - for (String s : completionStrings) { + for (final String s : completionStrings) { codeCompletionStrings[idx] = s; idx++; } return codeCompletionStrings; } - public Object execute(String snippet) throws JSCliException { + public Object execute(final String snippet) throws JSCliException { try { engine.put("xmlrpcLastResult", null); return engine.eval(snippet); @@ -129,7 +84,7 @@ public class ScriptClient { } } - public Object execute(Reader rd) throws JSCliException { + public Object execute(final Reader rd) throws JSCliException { try { engine.put("xmlrpcLastResult", null); return engine.eval(rd); diff --git a/hsarjcli/src/de/hsadmin/jscli/CASTicket.java b/hsarjcli/src/de/hsadmin/jscli/cas/CASTicketProvider.java similarity index 90% rename from hsarjcli/src/de/hsadmin/jscli/CASTicket.java rename to hsarjcli/src/de/hsadmin/jscli/cas/CASTicketProvider.java index 9dabcf3..f0db01a 100644 --- a/hsarjcli/src/de/hsadmin/jscli/CASTicket.java +++ b/hsarjcli/src/de/hsadmin/jscli/cas/CASTicketProvider.java @@ -1,4 +1,4 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.cas; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -15,7 +15,11 @@ import java.util.Properties; import javax.net.ssl.HttpsURLConnection; -public class CASTicket { +import de.hsadmin.jscli.conf.Config; +import de.hsadmin.jscli.console.PasswordReader; +import de.hsadmin.jscli.exception.JSCliException; + +public class CASTicketProvider { private static final String LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets"; private static final String BACKEND_URL = "https://admin.hostsharing.net:443/hsar/backend"; @@ -24,12 +28,12 @@ public class CASTicket { final private String backendURL; final private String runAs; final private String user; - final private ConsoleWrapper cons; + final private PasswordReader passwordReader; private String grantingTicket; - public CASTicket(ConsoleWrapper console, String user, String runAs) throws JSCliException { - this.cons = console; + public CASTicketProvider(final PasswordReader console, final String user, final String runAs) throws JSCliException { + this.passwordReader = console; this.user = user; this.runAs = runAs; Config config = Config.getInstance(); @@ -78,7 +82,7 @@ public class CASTicket { } private String readPasswordFromConsole() throws JSCliException { - return cons.readPassword(); + return passwordReader.readPassword(); } private String doHttpPost(String urlString, String encodedParams) throws JSCliException { diff --git a/hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java b/hsarjcli/src/de/hsadmin/jscli/conf/CommandlineParser.java similarity index 95% rename from hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java rename to hsarjcli/src/de/hsadmin/jscli/conf/CommandlineParser.java index 706f35f..2fe573f 100644 --- a/hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java +++ b/hsarjcli/src/de/hsadmin/jscli/conf/CommandlineParser.java @@ -1,4 +1,4 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.conf; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; @@ -6,6 +6,8 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; +import de.hsadmin.jscli.exception.JSCliException; + public class CommandlineParser { diff --git a/hsarjcli/src/de/hsadmin/jscli/Config.java b/hsarjcli/src/de/hsadmin/jscli/conf/Config.java similarity index 97% rename from hsarjcli/src/de/hsadmin/jscli/Config.java rename to hsarjcli/src/de/hsadmin/jscli/conf/Config.java index f082065..5b24a65 100644 --- a/hsarjcli/src/de/hsadmin/jscli/Config.java +++ b/hsarjcli/src/de/hsadmin/jscli/conf/Config.java @@ -1,4 +1,4 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.conf; import java.io.File; import java.io.FileReader; diff --git a/hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java b/hsarjcli/src/de/hsadmin/jscli/console/ConsoleWrapper.java similarity index 77% rename from hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java rename to hsarjcli/src/de/hsadmin/jscli/console/ConsoleWrapper.java index 57d59f4..b7cff04 100644 --- a/hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java +++ b/hsarjcli/src/de/hsadmin/jscli/console/ConsoleWrapper.java @@ -1,11 +1,12 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.console; import java.io.IOException; +import de.hsadmin.jscli.exception.JSCliException; import jline.ConsoleReader; import jline.SimpleCompletor; -public class ConsoleWrapper { +public class ConsoleWrapper implements PasswordReader { private ConsoleReader cons; private String prompt; @@ -32,7 +33,7 @@ public class ConsoleWrapper { } } - public void println(String text) throws JSCliException { + public void println(final String text) throws JSCliException { try { if (cons != null) { cons.printString(text); @@ -47,7 +48,7 @@ public class ConsoleWrapper { public String readPassword() throws JSCliException { try { - String pw = cons.readLine("Password: ", new Character('*')); + final String pw = cons.readLine("Password: ", new Character('*')); cons.setDefaultPrompt(prompt); return pw; } catch (IOException e) { @@ -55,7 +56,7 @@ public class ConsoleWrapper { } } - public void codeCompletion(String[] candidateStrings) { + public void codeCompletion(final String[] candidateStrings) { cons.addCompletor(new SimpleCompletor(candidateStrings)); } diff --git a/hsarjcli/src/de/hsadmin/jscli/console/PasswordReader.java b/hsarjcli/src/de/hsadmin/jscli/console/PasswordReader.java new file mode 100644 index 0000000..4a42f3c --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/console/PasswordReader.java @@ -0,0 +1,9 @@ +package de.hsadmin.jscli.console; + +import de.hsadmin.jscli.exception.JSCliException; + +public interface PasswordReader { + + String readPassword() throws JSCliException; + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/JSCliException.java b/hsarjcli/src/de/hsadmin/jscli/exception/JSCliException.java similarity index 85% rename from hsarjcli/src/de/hsadmin/jscli/JSCliException.java rename to hsarjcli/src/de/hsadmin/jscli/exception/JSCliException.java index c511317..ab3cb10 100644 --- a/hsarjcli/src/de/hsadmin/jscli/JSCliException.java +++ b/hsarjcli/src/de/hsadmin/jscli/exception/JSCliException.java @@ -1,4 +1,4 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.exception; public class JSCliException extends Exception { diff --git a/hsarjcli/src/de/hsadmin/jscli/JSONFormatter.java b/hsarjcli/src/de/hsadmin/jscli/json/JSONFormatter.java similarity index 98% rename from hsarjcli/src/de/hsadmin/jscli/JSONFormatter.java rename to hsarjcli/src/de/hsadmin/jscli/json/JSONFormatter.java index 2f221fb..3b77639 100644 --- a/hsarjcli/src/de/hsadmin/jscli/JSONFormatter.java +++ b/hsarjcli/src/de/hsadmin/jscli/json/JSONFormatter.java @@ -1,4 +1,4 @@ -package de.hsadmin.jscli; +package de.hsadmin.jscli.json; import java.util.List; import java.util.Map;