refactorings, removed old cli-client

This commit is contained in:
Peter Hormanns 2014-06-16 19:22:07 +02:00
parent c3f5a5b248
commit cd7b17015d
16 changed files with 201 additions and 846 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resource"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/> <classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
<classpathentry kind="lib" path="lib/xmlrpc-client-3.1.jar"/> <classpathentry kind="lib" path="lib/xmlrpc-client-3.1.jar"/>

View File

@ -5,6 +5,7 @@
<property name="lib.home" value="${basedir}/lib" /> <property name="lib.home" value="${basedir}/lib" />
<property name="conf.home" value="${basedir}/conf" /> <property name="conf.home" value="${basedir}/conf" />
<property name="src.home" value="${basedir}/src" /> <property name="src.home" value="${basedir}/src" />
<property name="resource.home" value="${basedir}/resource" />
<property name="test.home" value="${basedir}/test" /> <property name="test.home" value="${basedir}/test" />
<property name="dist.home" value="${basedir}/dist" /> <property name="dist.home" value="${basedir}/dist" />
@ -15,15 +16,25 @@
<property name="compile.deprecation" value="true" /> <property name="compile.deprecation" value="true" />
<property name="compile.optimize" value="true" /> <property name="compile.optimize" value="true" />
<path id="cp">
<fileset dir="${lib.home}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="clean" description="aufräumen"> <target name="clean" description="aufräumen">
<delete dir="${build.home}" /> <delete dir="${build.home}" />
<delete dir="${dist.home}" /> <delete dir="${dist.home}" />
</target> </target>
<target name="jar" depends="compile"> <target name="jar" depends="compile">
<copy todir="${build.home}/cls">
<fileset dir="${resource.home}" />
</copy>
<jar destfile="build/hsadmin.jar" basedir="build/cls"> <jar destfile="build/hsadmin.jar" basedir="build/cls">
<manifest> <manifest>
<attribute name="Main-Class" value="de.hsadmin.cli.HSadmin"/> <attribute name="Main-Class" value="de.hsadmin.jscli.Main"/>
<attribute name="Class-Path" value="../lib/commons-cli-1.2.jar ../lib/jline-1.0.jar ../lib/ws-commons-util-1.0.1.jar ../lib/xmlrpc-client-3.1.jar ../lib/xmlrpc-common-3.1.jar"/>
</manifest> </manifest>
</jar> </jar>
</target> </target>
@ -31,7 +42,15 @@
<target name="compile" description="compilieren"> <target name="compile" description="compilieren">
<mkdir dir="${build.home}" /> <mkdir dir="${build.home}" />
<mkdir dir="${build.home}/cls" /> <mkdir dir="${build.home}/cls" />
<javac srcdir="${src.home}" destdir="${build.home}/cls" debug="${compile.debug}" deprecation="${compile.deprecation}" optimize="${compile.optimize}" encoding="UTF8" includeantruntime="false" /> <javac
srcdir="${src.home}"
destdir="${build.home}/cls"
classpathref="cp"
debug="${compile.debug}"
deprecation="${compile.deprecation}"
optimize="${compile.optimize}"
encoding="UTF8"
includeantruntime="false" />
</target> </target>
</project> </project>

View File

@ -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);
}

View File

@ -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<numFullGroups; i++) {
int byte0 = a[inCursor++] & 0xff;
int byte1 = a[inCursor++] & 0xff;
int byte2 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 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 <tt>s</tt> 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 <tt>s</tt> 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<numFullGroups; i++) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 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<numRuns; i++) {
for (int j=0; j<numBytes; j++) {
byte[] arr = new byte[j];
for (int k=0; k<j; k++)
arr[k] = (byte)rnd.nextInt();
String s = byteArrayToBase64(arr);
byte [] b = base64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Dismal failure!");
s = byteArrayToAltBase64(arr);
b = altBase64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Alternate dismal failure!");
}
}
}
}

View File

@ -1,458 +0,0 @@
package de.hsadmin.cli;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* command line client for hsadmin.
*/
public class HSadmin {
private static String version = "CLI Client 2.0.0 (2011/May/21 09:00 MEST)";
private static String loginURL = "https://login.hostsharing.net/cas/v1/tickets";
private static String servletURL = "https://admin.hostsharing.net/hsar/hsadmin/cli-interface/";
private static String backendURL = "https://admin.hostsharing.net:443/hsar/backend";
private static Properties config;
private static String authenticatedUserName;
private static String passWord;
private static String runAsUserName;
private static int verbosity = 0;
private static class PasswordMaskingThread extends Thread {
private boolean stop = false;
public void interrupt() {
stop = true;
super.interrupt();
}
public void run() {
while (!stop) {
try {
Thread.sleep(50); // rate at which attempts to mask
} catch (InterruptedException ie) {
}
// in case I was sleeping while stop was changed, don't print
// I might be on the next line because of enter key being
// pressed
if (!stop) {
System.out.print("\rPassword: "
+ "\rPassword: ");
}
System.out.flush();
}
}
}
private static class HttpRequest {
private URL url;
private Map<String, List<String>> 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<String> 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<String> 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<String> 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<String> createRemoteArgs(String[] args)
throws IOException {
ArrayList<String> remoteArgs = new ArrayList<String>();
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<String>();
break;
} else if (arg.startsWith("--version")) {
System.out.println(version);
remoteArgs = new ArrayList<String>();
break;
} else if (arg.equals("-h")) {
// TODO: out of bounds error
printHelp();
remoteArgs = new ArrayList<String>();
remoteArgs.add("-h");
break;
} else if (arg.startsWith("--help")) {
printHelp();
remoteArgs = new ArrayList<String>();
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<String> 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
}
}
}
}

View File

@ -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());
}
}
}

View File

@ -5,19 +5,22 @@ import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.InputStreamReader; 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 class Main {
public static void main(String[] args) { public static void main(String[] args) {
ConsoleWrapper console = null; final ConsoleWrapper console = new ConsoleWrapper();
final JSONFormatter formatter = new JSONFormatter();
try { try {
CommandlineParser cmdParser = new CommandlineParser(args); final CommandlineParser cmdParser = new CommandlineParser(args);
String runAs = cmdParser.getRunAs(); final String runAs = cmdParser.getRunAs();
console = new ConsoleWrapper();
console.open(runAs + "@hsadmin> "); console.open(runAs + "@hsadmin> ");
JSONFormatter formatter = new JSONFormatter(); final ScriptClient scriptClient = new ScriptClient(console, cmdParser.getUser(), runAs);
ScriptClient scriptClient = new ScriptClient(console, cmdParser.getUser(), runAs); final String file = cmdParser.getFile();
String file = cmdParser.getFile();
if (file != null && file.length() > 0) { if (file != null && file.length() > 0) {
if ("-".equals(file)) { if ("-".equals(file)) {
scriptClient.execute(new InputStreamReader(System.in)); 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) { if (expr != null && expr.length() > 0) {
scriptClient.execute(expr); scriptClient.execute(expr);
console.println(formatter.format(scriptClient.getLastRpcResult())); console.println(formatter.format(scriptClient.getLastRpcResult()));

View File

@ -9,14 +9,18 @@ import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; 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 { public class RpcClient {
private static final String XMLRPC_URL = "https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin"; private static final String XMLRPC_URL = "https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin";
private String xmlrpcURL; private final String xmlrpcURL;
private XmlRpcClient client; private final XmlRpcClient client;
public RpcClient(CASTicket tgt) throws JSCliException { public RpcClient(final CASTicketProvider tgt) throws JSCliException {
try { try {
xmlrpcURL = Config.getInstance().getProperty("xmlrpcURL", XMLRPC_URL); xmlrpcURL = Config.getInstance().getProperty("xmlrpcURL", XMLRPC_URL);
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
@ -30,24 +34,24 @@ public class RpcClient {
} }
public List<String> listMethods() throws JSCliException { public List<String> listMethods() throws JSCliException {
List<String> methodList = new ArrayList<String>(); final List<String> methodList = new ArrayList<String>();
List<Object> execute = execute("system.listMethods"); final List<Object> execute = execute("system.listMethods");
for (Object obj : execute) { for (final Object obj : execute) {
methodList.add(obj.toString()); methodList.add(obj.toString());
} }
return methodList; return methodList;
} }
private List<Object> execute(String method) throws JSCliException { private List<Object> execute(final String method) throws JSCliException {
return execute(method, new ArrayList<Object>()); return execute(method, new ArrayList<Object>());
} }
public List<Object> execute(String method, List<?> params) throws JSCliException { public List<Object> execute(final String method, final List<?> params) throws JSCliException {
try { try {
Object execute = client.execute(method, params); final Object execute = client.execute(method, params);
ArrayList<Object> list = new ArrayList<Object>(); final ArrayList<Object> list = new ArrayList<Object>();
if (execute instanceof Object[]) { if (execute instanceof Object[]) {
Object[] resArray = (Object[]) execute; final Object[] resArray = (Object[]) execute;
for (int idx=0; idx < resArray.length; idx++) { for (int idx=0; idx < resArray.length; idx++) {
list.add(resArray[idx]); list.add(resArray[idx]);
} }

View File

@ -1,5 +1,7 @@
package de.hsadmin.jscli; package de.hsadmin.jscli;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -9,99 +11,52 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import javax.script.ScriptException; 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 { public class ScriptClient {
final private ScriptEngine engine; final private ScriptEngine engine;
final private Set<String> completionStrings; final private Set<String> 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<String>(); completionStrings = new HashSet<String>();
CASTicket grantingTicket = new CASTicket(console, user, runAs);
RpcClient rpcClient = new RpcClient(grantingTicket);
ScriptEngineManager engineManager = new ScriptEngineManager();
engine = engineManager.getEngineByName("js"); engine = engineManager.getEngineByName("js");
engine.put("casgrantingticket", ticketProvider);
engine.put("xmlrpcclient", rpcClient);
engine.put("xmlrpcLastResult", null);
try { try {
engine.put("casgrantingticket", grantingTicket); final InputStream inputResource = getClass().getClassLoader().getResourceAsStream("js/functions.js");
engine.put("xmlrpcclient", rpcClient); engine.eval(new InputStreamReader(inputResource));
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;" +
"};");
} catch (ScriptException e) { } catch (ScriptException e) {
throw new JSCliException(e); throw new JSCliException(e);
} }
List<String> methods = rpcClient.listMethods(); final List<String> methods = rpcClient.listMethods();
for (String method : methods) { for (final String method : methods) {
String[] parts = method.split("\\."); final String[] parts = method.split("\\.");
if (parts.length == 2) { if (parts.length == 2) {
String module = parts[0]; final String module = parts[0];
String function = parts[1];
if ("delete".equals(function)) {
function = "remove";
}
completionStrings.add(module); 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 { try {
engine.eval("if (typeof " + module + " === 'undefined') " + engine.eval(
"{ var " + module + " = { }; };\n" + "if (typeof " + module + " === 'undefined')" +
module + "['" + function + "'] = function(json) { " + " { var " + module + " = { }; };\n" +
"var mod = '" + module + "'; " + jsFunctionIdent +
("remove".equals(function) ? "var fct = 'delete'; " : "var fct = '" + function + "'; ") + " = function(json) { hsaModuleCall('" + module + "', '" + function + "', 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); " +
"};");
} catch (ScriptException e) { } catch (ScriptException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -111,16 +66,16 @@ public class ScriptClient {
} }
public String[] getCodeCompletionStrings() { public String[] getCodeCompletionStrings() {
String[] codeCompletionStrings = new String[completionStrings.size()]; final String[] codeCompletionStrings = new String[completionStrings.size()];
int idx = 0; int idx = 0;
for (String s : completionStrings) { for (final String s : completionStrings) {
codeCompletionStrings[idx] = s; codeCompletionStrings[idx] = s;
idx++; idx++;
} }
return codeCompletionStrings; return codeCompletionStrings;
} }
public Object execute(String snippet) throws JSCliException { public Object execute(final String snippet) throws JSCliException {
try { try {
engine.put("xmlrpcLastResult", null); engine.put("xmlrpcLastResult", null);
return engine.eval(snippet); 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 { try {
engine.put("xmlrpcLastResult", null); engine.put("xmlrpcLastResult", null);
return engine.eval(rd); return engine.eval(rd);

View File

@ -1,4 +1,4 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.cas;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedWriter;
@ -15,7 +15,11 @@ import java.util.Properties;
import javax.net.ssl.HttpsURLConnection; 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 LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
private static final String BACKEND_URL = "https://admin.hostsharing.net:443/hsar/backend"; 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 backendURL;
final private String runAs; final private String runAs;
final private String user; final private String user;
final private ConsoleWrapper cons; final private PasswordReader passwordReader;
private String grantingTicket; private String grantingTicket;
public CASTicket(ConsoleWrapper console, String user, String runAs) throws JSCliException { public CASTicketProvider(final PasswordReader console, final String user, final String runAs) throws JSCliException {
this.cons = console; this.passwordReader = console;
this.user = user; this.user = user;
this.runAs = runAs; this.runAs = runAs;
Config config = Config.getInstance(); Config config = Config.getInstance();
@ -78,7 +82,7 @@ public class CASTicket {
} }
private String readPasswordFromConsole() throws JSCliException { private String readPasswordFromConsole() throws JSCliException {
return cons.readPassword(); return passwordReader.readPassword();
} }
private String doHttpPost(String urlString, String encodedParams) throws JSCliException { private String doHttpPost(String urlString, String encodedParams) throws JSCliException {

View File

@ -1,4 +1,4 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.conf;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter; 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.ParseException;
import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.PosixParser;
import de.hsadmin.jscli.exception.JSCliException;
public class CommandlineParser { public class CommandlineParser {

View File

@ -1,4 +1,4 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.conf;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;

View File

@ -1,11 +1,12 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.console;
import java.io.IOException; import java.io.IOException;
import de.hsadmin.jscli.exception.JSCliException;
import jline.ConsoleReader; import jline.ConsoleReader;
import jline.SimpleCompletor; import jline.SimpleCompletor;
public class ConsoleWrapper { public class ConsoleWrapper implements PasswordReader {
private ConsoleReader cons; private ConsoleReader cons;
private String prompt; 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 { try {
if (cons != null) { if (cons != null) {
cons.printString(text); cons.printString(text);
@ -47,7 +48,7 @@ public class ConsoleWrapper {
public String readPassword() throws JSCliException { public String readPassword() throws JSCliException {
try { try {
String pw = cons.readLine("Password: ", new Character('*')); final String pw = cons.readLine("Password: ", new Character('*'));
cons.setDefaultPrompt(prompt); cons.setDefaultPrompt(prompt);
return pw; return pw;
} catch (IOException e) { } 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)); cons.addCompletor(new SimpleCompletor(candidateStrings));
} }

View File

@ -0,0 +1,9 @@
package de.hsadmin.jscli.console;
import de.hsadmin.jscli.exception.JSCliException;
public interface PasswordReader {
String readPassword() throws JSCliException;
}

View File

@ -1,4 +1,4 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.exception;
public class JSCliException extends Exception { public class JSCliException extends Exception {

View File

@ -1,4 +1,4 @@
package de.hsadmin.jscli; package de.hsadmin.jscli.json;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;