better error handling on failed logins

This commit is contained in:
Peter Hormanns 2016-08-31 16:53:03 +02:00
parent e34843c21d
commit 664136d563
8 changed files with 131 additions and 63 deletions

View File

@ -7,6 +7,7 @@ import java.io.InputStreamReader;
import de.hsadmin.jscli.conf.CommandlineParser;
import de.hsadmin.jscli.console.ConsoleWrapper;
import de.hsadmin.jscli.exception.JSCliException;
import de.hsadmin.jscli.json.JSONFormatter;
@ -65,8 +66,8 @@ public class Main {
try {
scriptClient.execute(command);
console.println(formatter.format(scriptClient.getLastRpcResult()));
} catch (Exception e) {
console.println("Error: " + e.getLocalizedMessage() + "\n");
} catch (JSCliException e) {
console.println(findRootException(e) + "\n");
}
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();
}
}

View File

@ -11,7 +11,6 @@ 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;
@ -22,7 +21,7 @@ public class RpcClient {
private final List<XmlRpcClient> clientList;
private final Map<String, XmlRpcClient> clientMap;
public RpcClient(final CASTicketProvider tgt) throws JSCliException {
public RpcClient() throws JSCliException {
clientList = new ArrayList<XmlRpcClient>();
clientMap = new HashMap<String, XmlRpcClient>();
try {

View File

@ -11,7 +11,7 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
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.exception.JSCliException;
@ -21,11 +21,9 @@ public class ScriptClient {
final private Set<String> completionStrings;
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(ticketProvider);
final ScriptEngineManager engineManager = new ScriptEngineManager();
engine = engineManager.getEngineByName("js");
engine.put("casgrantingticket", ticketProvider);
final RpcClient rpcClient = new RpcClient();
engine = new ScriptEngineManager().getEngineByName("js");
engine.put("casgrantingticket", TicketProviderFactory.getInstance(console, user, runAs));
engine.put("xmlrpcclient", rpcClient);
engine.put("xmlrpcLastResult", null);
completionStrings = new HashSet<String>();

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

View File

@ -18,14 +18,12 @@ import java.util.Properties;
import javax.net.ssl.HttpsURLConnection;
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 CASTicketProvider {
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";
public class CASTicketProvider implements TicketProvider {
final private String loginURL;
final private String backendURL;
@ -35,13 +33,12 @@ public class CASTicketProvider {
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.user = user;
this.runAs = runAs;
final Config config = Config.getInstance();
backendURL = config.getProperty("backendURL", BACKEND_URL);
loginURL = config.getProperty("loginURL", LOGIN_URL);
this.backendURL = backendURL;
this.loginURL = loginURL;
if ("TestUmgebung".equals(loginURL)) {
grantingTicket = "ticket:" + user;
} else {
@ -49,19 +46,39 @@ public class CASTicketProvider {
}
}
@Override
public String getTicket() throws JSCliException, FileNotFoundException {
if (grantingTicket != null && grantingTicket.startsWith("ticket:")) {
return grantingTicket.replaceFirst("ticket", "user");
}
try {
String encodedParams = URLEncoder.encode("service", "UTF-8")
+ "=" + URLEncoder.encode(backendURL, "UTF-8");
return doHttpPost(grantingTicket, encodedParams);
final String encodedParams =
URLEncoder.encode("service", "UTF-8") + "=" + URLEncoder.encode(backendURL, "UTF-8");
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) {
throw new JSCliException(e);
}
}
@Override
public String getRunAs() {
return runAs;
}
@ -77,7 +94,7 @@ public class CASTicketProvider {
+ "=" + URLEncoder.encode(user, "UTF-8")
+ "&" + URLEncoder.encode("password", "UTF-8")
+ "=" + URLEncoder.encode(password, "UTF-8");
grantingTicket = doHttpPost(loginURL, encodedParams);
grantingTicket = requestForGrantingTicket(loginURL, encodedParams);
} catch (UnsupportedEncodingException e) {
throw new JSCliException(e);
} catch (FileNotFoundException e) {
@ -90,48 +107,31 @@ public class CASTicketProvider {
return passwordReader.readPassword();
}
private String doHttpPost(final String urlString, final String encodedParams) throws JSCliException, FileNotFoundException {
String result = null;
private String requestForGrantingTicket(final String urlString, final String encodedParams) throws JSCliException, FileNotFoundException {
try {
result = extractTicket(urlString, encodedParams);
} catch (FileNotFoundException e) {
grantingTicket = getGrantingTicket();
saveProperties(grantingTicket, getTicketFile());
try {
result = extractTicket(grantingTicket, encodedParams);
} catch (IOException e1) {
throw new JSCliException(e1);
}
final HttpsURLConnection connection = doConnect(urlString, encodedParams);
return connection.getHeaderField("Location");
} catch (IOException e) {
throw new JSCliException(e);
}
return result;
}
private String extractTicket(final String urlString,
final String encodedParams) throws MalformedURLException,
IOException, ProtocolException {
String result;
private String requestForServiceTicket(final String urlString, final String encodedParams)
throws MalformedURLException, IOException, ProtocolException
{
final HttpsURLConnection connection = doConnect(urlString, encodedParams);
final String ticket = readTicket(connection);
if (ticket != null && ticket.startsWith("ST-")) {
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 InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream());
final BufferedReader reader = new BufferedReader(inputStreamReader);
final String ticket = reader.readLine();
String readLine = null;
do {
readLine = reader.readLine();
} while (readLine != null);
if (ticket != null && ticket.startsWith("ST-")) {
return ticket;
}
return null;
}
private HttpsURLConnection doConnect(final String urlString,
final String encodedParams) throws MalformedURLException,
@ -151,15 +151,9 @@ public class CASTicketProvider {
}
private String readFiledGrantingTicket() throws JSCliException {
String filedTicket = null;
final File file = getTicketFile();
final Properties properties = loadProperties(file);
filedTicket = properties.getProperty(user);
if (filedTicket == null) {
filedTicket = getGrantingTicket();
saveProperties(filedTicket, file);
}
return filedTicket;
return properties.getProperty(user);
}
private File getTicketFile() {
@ -173,7 +167,7 @@ public class CASTicketProvider {
if (filedTicket != null) {
properties.setProperty(user, filedTicket);
try {
properties.store(new FileOutputStream(file), "");
properties.store(new FileOutputStream(file), "stored cas tickets");
} catch (IOException e) {
throw new JSCliException(e);
}

View File

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

View File

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

View File

@ -4,6 +4,8 @@ import de.hsadmin.jscli.exception.JSCliException;
public interface PasswordReader {
String readPassword() throws JSCliException;
public String readPassword() throws JSCliException;
public void println(final String text) throws JSCliException;
}