better error handling on failed logins
This commit is contained in:
parent
e34843c21d
commit
664136d563
@ -7,6 +7,7 @@ import java.io.InputStreamReader;
|
|||||||
|
|
||||||
import de.hsadmin.jscli.conf.CommandlineParser;
|
import de.hsadmin.jscli.conf.CommandlineParser;
|
||||||
import de.hsadmin.jscli.console.ConsoleWrapper;
|
import de.hsadmin.jscli.console.ConsoleWrapper;
|
||||||
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
import de.hsadmin.jscli.json.JSONFormatter;
|
import de.hsadmin.jscli.json.JSONFormatter;
|
||||||
|
|
||||||
|
|
||||||
@ -65,8 +66,8 @@ public class Main {
|
|||||||
try {
|
try {
|
||||||
scriptClient.execute(command);
|
scriptClient.execute(command);
|
||||||
console.println(formatter.format(scriptClient.getLastRpcResult()));
|
console.println(formatter.format(scriptClient.getLastRpcResult()));
|
||||||
} catch (Exception e) {
|
} catch (JSCliException e) {
|
||||||
console.println("Error: " + e.getLocalizedMessage() + "\n");
|
console.println(findRootException(e) + "\n");
|
||||||
}
|
}
|
||||||
command = console.readInput();
|
command = console.readInput();
|
||||||
}
|
}
|
||||||
@ -77,4 +78,12 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String findRootException(final Exception exp) {
|
||||||
|
Throwable cause = exp;
|
||||||
|
while (cause.getCause() != null && cause.getCause() != cause) {
|
||||||
|
cause = cause.getCause();
|
||||||
|
}
|
||||||
|
return "Error: " + cause.getLocalizedMessage();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ 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.conf.Config;
|
||||||
import de.hsadmin.jscli.exception.JSCliException;
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ public class RpcClient {
|
|||||||
private final List<XmlRpcClient> clientList;
|
private final List<XmlRpcClient> clientList;
|
||||||
private final Map<String, XmlRpcClient> clientMap;
|
private final Map<String, XmlRpcClient> clientMap;
|
||||||
|
|
||||||
public RpcClient(final CASTicketProvider tgt) throws JSCliException {
|
public RpcClient() throws JSCliException {
|
||||||
clientList = new ArrayList<XmlRpcClient>();
|
clientList = new ArrayList<XmlRpcClient>();
|
||||||
clientMap = new HashMap<String, XmlRpcClient>();
|
clientMap = new HashMap<String, XmlRpcClient>();
|
||||||
try {
|
try {
|
||||||
|
@ -11,7 +11,7 @@ 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.cas.TicketProviderFactory;
|
||||||
import de.hsadmin.jscli.console.ConsoleWrapper;
|
import de.hsadmin.jscli.console.ConsoleWrapper;
|
||||||
import de.hsadmin.jscli.exception.JSCliException;
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
@ -21,11 +21,9 @@ public class ScriptClient {
|
|||||||
final private Set<String> completionStrings;
|
final private Set<String> completionStrings;
|
||||||
|
|
||||||
public ScriptClient(final ConsoleWrapper console, final String user, final String runAs, final String... arguments) throws JSCliException {
|
public ScriptClient(final ConsoleWrapper console, final String user, final String runAs, final String... arguments) throws JSCliException {
|
||||||
final CASTicketProvider ticketProvider = new CASTicketProvider(console, user, runAs);
|
final RpcClient rpcClient = new RpcClient();
|
||||||
final RpcClient rpcClient = new RpcClient(ticketProvider);
|
engine = new ScriptEngineManager().getEngineByName("js");
|
||||||
final ScriptEngineManager engineManager = new ScriptEngineManager();
|
engine.put("casgrantingticket", TicketProviderFactory.getInstance(console, user, runAs));
|
||||||
engine = engineManager.getEngineByName("js");
|
|
||||||
engine.put("casgrantingticket", ticketProvider);
|
|
||||||
engine.put("xmlrpcclient", rpcClient);
|
engine.put("xmlrpcclient", rpcClient);
|
||||||
engine.put("xmlrpcLastResult", null);
|
engine.put("xmlrpcLastResult", null);
|
||||||
completionStrings = new HashSet<String>();
|
completionStrings = new HashSet<String>();
|
||||||
|
13
cli/src/main/java/de/hsadmin/jscli/TicketProvider.java
Normal file
13
cli/src/main/java/de/hsadmin/jscli/TicketProvider.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package de.hsadmin.jscli;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
|
public interface TicketProvider {
|
||||||
|
|
||||||
|
public String getTicket() throws JSCliException, FileNotFoundException;
|
||||||
|
|
||||||
|
public String getRunAs();
|
||||||
|
|
||||||
|
}
|
@ -18,14 +18,12 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import de.hsadmin.jscli.TicketProvider;
|
||||||
import de.hsadmin.jscli.conf.Config;
|
import de.hsadmin.jscli.conf.Config;
|
||||||
import de.hsadmin.jscli.console.PasswordReader;
|
import de.hsadmin.jscli.console.PasswordReader;
|
||||||
import de.hsadmin.jscli.exception.JSCliException;
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
public class CASTicketProvider {
|
public class CASTicketProvider implements TicketProvider {
|
||||||
|
|
||||||
private static final String LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
|
|
||||||
private static final String BACKEND_URL = "https://config.hostsharing.net:443/hsar/backend";
|
|
||||||
|
|
||||||
final private String loginURL;
|
final private String loginURL;
|
||||||
final private String backendURL;
|
final private String backendURL;
|
||||||
@ -35,13 +33,12 @@ public class CASTicketProvider {
|
|||||||
|
|
||||||
private String grantingTicket;
|
private String grantingTicket;
|
||||||
|
|
||||||
public CASTicketProvider(final PasswordReader console, final String user, final String runAs) throws JSCliException {
|
public CASTicketProvider(final PasswordReader console, final String user, final String runAs, final String backendURL, final String loginURL) throws JSCliException {
|
||||||
this.passwordReader = console;
|
this.passwordReader = console;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.runAs = runAs;
|
this.runAs = runAs;
|
||||||
final Config config = Config.getInstance();
|
this.backendURL = backendURL;
|
||||||
backendURL = config.getProperty("backendURL", BACKEND_URL);
|
this.loginURL = loginURL;
|
||||||
loginURL = config.getProperty("loginURL", LOGIN_URL);
|
|
||||||
if ("TestUmgebung".equals(loginURL)) {
|
if ("TestUmgebung".equals(loginURL)) {
|
||||||
grantingTicket = "ticket:" + user;
|
grantingTicket = "ticket:" + user;
|
||||||
} else {
|
} else {
|
||||||
@ -49,19 +46,39 @@ public class CASTicketProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getTicket() throws JSCliException, FileNotFoundException {
|
public String getTicket() throws JSCliException, FileNotFoundException {
|
||||||
if (grantingTicket != null && grantingTicket.startsWith("ticket:")) {
|
|
||||||
return grantingTicket.replaceFirst("ticket", "user");
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
String encodedParams = URLEncoder.encode("service", "UTF-8")
|
final String encodedParams =
|
||||||
+ "=" + URLEncoder.encode(backendURL, "UTF-8");
|
URLEncoder.encode("service", "UTF-8") + "=" + URLEncoder.encode(backendURL, "UTF-8");
|
||||||
return doHttpPost(grantingTicket, encodedParams);
|
String urlString = grantingTicket;
|
||||||
|
String result = null;
|
||||||
|
boolean grantingTicketIsValid = false;
|
||||||
|
int trails = 0;
|
||||||
|
while (!grantingTicketIsValid) {
|
||||||
|
try {
|
||||||
|
result = requestForServiceTicket(urlString, encodedParams);
|
||||||
|
grantingTicketIsValid = true;
|
||||||
|
grantingTicket = urlString;
|
||||||
|
saveProperties(grantingTicket, getTicketFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (trails > 0) {
|
||||||
|
passwordReader.println("login failed");
|
||||||
|
}
|
||||||
|
trails++;
|
||||||
|
if (trails > 3) {
|
||||||
|
throw new JSCliException("exceeded number of login attempts");
|
||||||
|
}
|
||||||
|
urlString = getGrantingTicket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new JSCliException(e);
|
throw new JSCliException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getRunAs() {
|
public String getRunAs() {
|
||||||
return runAs;
|
return runAs;
|
||||||
}
|
}
|
||||||
@ -77,7 +94,7 @@ public class CASTicketProvider {
|
|||||||
+ "=" + URLEncoder.encode(user, "UTF-8")
|
+ "=" + URLEncoder.encode(user, "UTF-8")
|
||||||
+ "&" + URLEncoder.encode("password", "UTF-8")
|
+ "&" + URLEncoder.encode("password", "UTF-8")
|
||||||
+ "=" + URLEncoder.encode(password, "UTF-8");
|
+ "=" + URLEncoder.encode(password, "UTF-8");
|
||||||
grantingTicket = doHttpPost(loginURL, encodedParams);
|
grantingTicket = requestForGrantingTicket(loginURL, encodedParams);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new JSCliException(e);
|
throw new JSCliException(e);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
@ -90,47 +107,30 @@ public class CASTicketProvider {
|
|||||||
return passwordReader.readPassword();
|
return passwordReader.readPassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String doHttpPost(final String urlString, final String encodedParams) throws JSCliException, FileNotFoundException {
|
private String requestForGrantingTicket(final String urlString, final String encodedParams) throws JSCliException, FileNotFoundException {
|
||||||
String result = null;
|
|
||||||
try {
|
try {
|
||||||
result = extractTicket(urlString, encodedParams);
|
final HttpsURLConnection connection = doConnect(urlString, encodedParams);
|
||||||
} catch (FileNotFoundException e) {
|
return connection.getHeaderField("Location");
|
||||||
grantingTicket = getGrantingTicket();
|
|
||||||
saveProperties(grantingTicket, getTicketFile());
|
|
||||||
try {
|
|
||||||
result = extractTicket(grantingTicket, encodedParams);
|
|
||||||
} catch (IOException e1) {
|
|
||||||
throw new JSCliException(e1);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new JSCliException(e);
|
throw new JSCliException(e);
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractTicket(final String urlString,
|
private String requestForServiceTicket(final String urlString, final String encodedParams)
|
||||||
final String encodedParams) throws MalformedURLException,
|
throws MalformedURLException, IOException, ProtocolException
|
||||||
IOException, ProtocolException {
|
{
|
||||||
String result;
|
|
||||||
final HttpsURLConnection connection = doConnect(urlString, encodedParams);
|
final HttpsURLConnection connection = doConnect(urlString, encodedParams);
|
||||||
final String ticket = readTicket(connection);
|
final InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream());
|
||||||
if (ticket != null && ticket.startsWith("ST-")) {
|
final BufferedReader reader = new BufferedReader(inputStreamReader);
|
||||||
result = ticket;
|
|
||||||
} else {
|
|
||||||
result = connection.getHeaderField("Location");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readTicket(final HttpsURLConnection connection)
|
|
||||||
throws IOException {
|
|
||||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
|
||||||
final String ticket = reader.readLine();
|
final String ticket = reader.readLine();
|
||||||
String readLine = null;
|
String readLine = null;
|
||||||
do {
|
do {
|
||||||
readLine = reader.readLine();
|
readLine = reader.readLine();
|
||||||
} while (readLine != null);
|
} while (readLine != null);
|
||||||
return ticket;
|
if (ticket != null && ticket.startsWith("ST-")) {
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpsURLConnection doConnect(final String urlString,
|
private HttpsURLConnection doConnect(final String urlString,
|
||||||
@ -151,15 +151,9 @@ public class CASTicketProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String readFiledGrantingTicket() throws JSCliException {
|
private String readFiledGrantingTicket() throws JSCliException {
|
||||||
String filedTicket = null;
|
|
||||||
final File file = getTicketFile();
|
final File file = getTicketFile();
|
||||||
final Properties properties = loadProperties(file);
|
final Properties properties = loadProperties(file);
|
||||||
filedTicket = properties.getProperty(user);
|
return properties.getProperty(user);
|
||||||
if (filedTicket == null) {
|
|
||||||
filedTicket = getGrantingTicket();
|
|
||||||
saveProperties(filedTicket, file);
|
|
||||||
}
|
|
||||||
return filedTicket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getTicketFile() {
|
private File getTicketFile() {
|
||||||
@ -173,7 +167,7 @@ public class CASTicketProvider {
|
|||||||
if (filedTicket != null) {
|
if (filedTicket != null) {
|
||||||
properties.setProperty(user, filedTicket);
|
properties.setProperty(user, filedTicket);
|
||||||
try {
|
try {
|
||||||
properties.store(new FileOutputStream(file), "");
|
properties.store(new FileOutputStream(file), "stored cas tickets");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new JSCliException(e);
|
throw new JSCliException(e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package de.hsadmin.jscli.cas;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
import de.hsadmin.jscli.TicketProvider;
|
||||||
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
|
public class TestTicketProvider implements TicketProvider {
|
||||||
|
|
||||||
|
private final String grantingTicket;
|
||||||
|
private final String runAs;
|
||||||
|
|
||||||
|
public TestTicketProvider(final String user, final String runAs) {
|
||||||
|
this.grantingTicket = "user:" + user;
|
||||||
|
this.runAs = runAs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTicket() throws JSCliException, FileNotFoundException {
|
||||||
|
return grantingTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRunAs() {
|
||||||
|
return runAs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package de.hsadmin.jscli.cas;
|
||||||
|
|
||||||
|
import de.hsadmin.jscli.TicketProvider;
|
||||||
|
import de.hsadmin.jscli.conf.Config;
|
||||||
|
import de.hsadmin.jscli.console.PasswordReader;
|
||||||
|
import de.hsadmin.jscli.exception.JSCliException;
|
||||||
|
|
||||||
|
public class TicketProviderFactory {
|
||||||
|
|
||||||
|
private static final String HOSTSHARING_LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
|
||||||
|
private static final String HOSTSHARING_BACKEND_URL = "https://config.hostsharing.net:443/hsar/backend";
|
||||||
|
|
||||||
|
public static TicketProvider getInstance(final PasswordReader console, final String user, final String runAs) throws JSCliException
|
||||||
|
{
|
||||||
|
final Config config = Config.getInstance();
|
||||||
|
final String backendURL = config.getProperty("backendURL", HOSTSHARING_BACKEND_URL);
|
||||||
|
final String loginURL = config.getProperty("loginURL", HOSTSHARING_LOGIN_URL);
|
||||||
|
if ("TestUmgebung".equalsIgnoreCase(loginURL)) {
|
||||||
|
return new TestTicketProvider(user, runAs);
|
||||||
|
} else {
|
||||||
|
return new CASTicketProvider(console, user, runAs, backendURL, loginURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,8 @@ import de.hsadmin.jscli.exception.JSCliException;
|
|||||||
|
|
||||||
public interface PasswordReader {
|
public interface PasswordReader {
|
||||||
|
|
||||||
String readPassword() throws JSCliException;
|
public String readPassword() throws JSCliException;
|
||||||
|
|
||||||
|
public void println(final String text) throws JSCliException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user