Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4: + more detailed exceptions #8

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/org/sobotics/chatexchange/chat/ChatHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,24 @@ public enum ChatHost {
META_STACK_EXCHANGE("meta.stackexchange.com");

private final String name, baseUrl;

/**
* Host that is used for the login
*
* This might be a different host, because stackexchange.com does not have a login
*/
private final String loginHost;

private ChatHost(String name) {
this.name = name;
this.baseUrl = "https://chat." + name;

if (this.name.equalsIgnoreCase("stackexchange.com")) {
//stackexchange.com doesn't have a login, so we have to use meta
this.loginHost = "meta.stackexchange.com";
} else {
this.loginHost = this.name;
}
}

/**
Expand All @@ -33,6 +47,13 @@ public String getBaseUrl() {
}

/**
* @return Host that is used for the login
*/
public String getLoginHost() {
return this.loginHost;
}

/**
* Compares the host to another object
* @param otherHost other object
* @return true, if the name is the same
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.sobotics.chatexchange.chat;

/**
* Exception when the login fails. Contains information about the hosts
*
* @author FelixSFD
*/
public class ChatLoginException extends Exception {
private static final long serialVersionUID = 3836431112726533617L;

/**
* {@link ChatHost} that was used for the login
*/
private ChatHost host;

/**
* Initializes the exception
* @param chatHost {@link ChatHost} that was used for the login
* @param message Error-message
*/
public ChatLoginException(ChatHost chatHost, String message) {
super(message);
this.host = chatHost;
}

/**
* {@inheritDoc}
*/
@Override
public String getMessage() {
String msg = "Unable to login to " + this.host.getName();

if (!this.host.getName().equalsIgnoreCase(this.host.getLoginHost())) {
msg += " (via " + this.host.getLoginHost() + ")";
}

msg += ": " + super.getMessage();

return msg;
}

/**
* {@inheritDoc}
*/
@Override
public String getLocalizedMessage() {
return this.getMessage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,25 @@ public StackExchangeClient(String email, String password) {
* Logs in to s given site
* @param email The user's e-mail-address
* @param password The password
* @param The host of the main site (NOT the chat.*! Use ChatHost.getName())
* @param host {@link ChatHost} of the {@link Room}
* @throws ChatLoginException if the login fails
* */
private void seLogin(String email, String password, String host) throws IOException {
String originalHost = host;
private void seLogin(String email, String password, ChatHost host) throws IOException, ChatLoginException {
String originalHost = host.getName();
String loginHost = host.getLoginHost();

if (host.equalsIgnoreCase(ChatHost.STACK_EXCHANGE.getName())) {
host = ChatHost.META_STACK_EXCHANGE.getName();
}

//The login-form has a hidden field called "fkey" which needs to be sent along with the mail and password
Response response = httpClient.get("https://"+host+"/users/login", cookies);
Response response = httpClient.get("https://"+loginHost+"/users/login", cookies);
String fkey = response.parse().select("input[name='fkey']").val();

response = httpClient.post("https://"+host+"/users/login", cookies, "email", email, "password", password, "fkey", fkey);
response = httpClient.post("https://"+loginHost+"/users/login", cookies, "email", email, "password", password, "fkey", fkey);

//Create account on that site if necessary
Element formElement = response.parse().getElementById("logout-user");
if (formElement != null) {
if (!this.autoCreateAccount) {
throw new IllegalStateException("Unable to login to Stack Exchange. The user does not have an account on " + originalHost);
throw new ChatLoginException(host, "The user does not have an account on this site!");
} // if autoCreate

Elements formInputs = formElement.getElementsByTag("input");
Expand All @@ -117,21 +116,27 @@ private void seLogin(String email, String password, String host) throws IOExcept

String[] formDataArray = formData.toArray(new String[formData.size()]);

String formUrl = "https://" + host + formElement.attr("action");
String formUrl = "https://" + loginHost + formElement.attr("action");

Response formResponse = httpClient.post(formUrl, cookies, formDataArray);
if (formResponse.parse().getElementsByClass("js-inbox-button").first() == null) {
LOGGER.debug(formResponse.parse().html());
throw new IllegalStateException("Unable to create account on " + host + "! Please create the account manually.");
throw new ChatLoginException(host, "Unable to create account! Please create the account manually.");
} // if
} // if


//Check for captcha
Element captchaElement = response.parse().getElementById("nocaptcha-form");
if (captchaElement != null) {
throw new ChatLoginException(host, "Captcha found! Please wait some time before trying to login again.");
}

// check if login succeeded
Response checkResponse = httpClient.get("https://"+originalHost+"/users/current", cookies);
if (checkResponse.parse().getElementsByClass("js-inbox-button").first() == null) {
LOGGER.debug(checkResponse.parse().html());
throw new IllegalStateException("Unable to login to Stack Exchange. (Site: " + originalHost + " via " + host + ")");
throw new ChatLoginException(host, "Maybe your login credentials are wrong.");
} // if
} // seLogin

Expand Down Expand Up @@ -163,10 +168,9 @@ private void SEOpenIdLogin(String email, String password) throws IOException {
* @param host Host of the chat room to join.
* @param roomId Id of the room to join.
* @return <code>Room</code> joined.
* @throws ChatLoginException when the login failed
*/
public Room joinRoom(ChatHost host, int roomId) {
String mainSiteHost = host.getName();

public Room joinRoom(ChatHost host, int roomId) throws ChatLoginException {
boolean alreadyLoggedIn = false;

for (Room room : this.rooms) {
Expand All @@ -179,10 +183,10 @@ public Room joinRoom(ChatHost host, int roomId) {
if (!alreadyLoggedIn) {
//not logged in on that site yet
try {
this.seLogin(email, password, mainSiteHost);
this.seLogin(email, password, host);
} catch (IOException e) {
LOGGER.error("Unable to login on " + mainSiteHost + " for " + host.getBaseUrl(), e);
throw new ChatOperationException("Login to " + mainSiteHost + " failed!");
LOGGER.error("Login failed due to IOException!", e);
throw new ChatLoginException(host, "IOException: " + e.getMessage());
}
}

Expand Down