|
@ -27,11 +27,10 @@ import okhttp3.RequestBody; |
|
|
import okhttp3.Response; |
|
|
import okhttp3.Response; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
This class handles all session related operations (e.g. login, logout) |
|
|
* This class handles all session related operations (e.g. login, logout) |
|
|
and stores data to SharedPreferences (session information and cookies). |
|
|
* and stores data to SharedPreferences (session information and cookies). |
|
|
*/ |
|
|
*/ |
|
|
public class SessionManager |
|
|
public class SessionManager { |
|
|
{ |
|
|
|
|
|
//Class TAG
|
|
|
//Class TAG
|
|
|
private static final String TAG = "SessionManager"; |
|
|
private static final String TAG = "SessionManager"; |
|
|
|
|
|
|
|
@ -66,27 +65,25 @@ public class SessionManager |
|
|
|
|
|
|
|
|
//Constructor
|
|
|
//Constructor
|
|
|
public SessionManager(OkHttpClient client, PersistentCookieJar cookieJar, |
|
|
public SessionManager(OkHttpClient client, PersistentCookieJar cookieJar, |
|
|
SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs) |
|
|
SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs) { |
|
|
{ |
|
|
|
|
|
this.client = client; |
|
|
this.client = client; |
|
|
this.cookiePersistor=cookiePersistor; |
|
|
this.cookiePersistor = cookiePersistor; |
|
|
this.cookieJar = cookieJar; |
|
|
this.cookieJar = cookieJar; |
|
|
this.sharedPrefs = sharedPrefs; |
|
|
this.sharedPrefs = sharedPrefs; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//------------------------------------AUTH BEGINS----------------------------------------------
|
|
|
//------------------------------------AUTH BEGINS----------------------------------------------
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Login function with two options: (username, password) or nothing (using saved cookies). |
|
|
* Login function with two options: (username, password) or nothing (using saved cookies). |
|
|
* Always call it in a separate thread. |
|
|
* Always call it in a separate thread. |
|
|
*/ |
|
|
*/ |
|
|
public int login(String... strings) |
|
|
public int login(String... strings) { |
|
|
{ |
|
|
|
|
|
Report.i(TAG, "Logging in..."); |
|
|
Report.i(TAG, "Logging in..."); |
|
|
|
|
|
|
|
|
//Build the login request for each case
|
|
|
//Build the login request for each case
|
|
|
Request request; |
|
|
Request request; |
|
|
if (strings.length == 2) |
|
|
if (strings.length == 2) { |
|
|
{ |
|
|
|
|
|
clearSessionData(); |
|
|
clearSessionData(); |
|
|
|
|
|
|
|
|
String loginName = strings[0]; |
|
|
String loginName = strings[0]; |
|
@ -101,9 +98,7 @@ public class SessionManager |
|
|
.url(loginUrl) |
|
|
.url(loginUrl) |
|
|
.post(formBody) |
|
|
.post(formBody) |
|
|
.build(); |
|
|
.build(); |
|
|
} |
|
|
} else { |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
request = new Request.Builder() |
|
|
request = new Request.Builder() |
|
|
.url(loginUrl) |
|
|
.url(loginUrl) |
|
|
.build(); |
|
|
.build(); |
|
@ -125,20 +120,16 @@ public class SessionManager |
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); |
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); |
|
|
sharedPrefs.edit().putString(USERNAME, extractUserName(document)).apply(); |
|
|
sharedPrefs.edit().putString(USERNAME, extractUserName(document)).apply(); |
|
|
String avatar = extractAvatarLink(document); |
|
|
String avatar = extractAvatarLink(document); |
|
|
if (avatar!=null) |
|
|
if (avatar != null) { |
|
|
{ |
|
|
sharedPrefs.edit().putBoolean(HAS_AVATAR, true).apply(); |
|
|
sharedPrefs.edit().putBoolean(HAS_AVATAR,true).apply(); |
|
|
|
|
|
sharedPrefs.edit().putString(AVATAR_LINK, extractAvatarLink(document)).apply(); |
|
|
sharedPrefs.edit().putString(AVATAR_LINK, extractAvatarLink(document)).apply(); |
|
|
} |
|
|
} else |
|
|
else |
|
|
sharedPrefs.edit().putBoolean(HAS_AVATAR, false).apply(); |
|
|
sharedPrefs.edit().putBoolean(HAS_AVATAR,false).apply(); |
|
|
|
|
|
|
|
|
|
|
|
sharedPrefs.edit().putString(LOGOUT_LINK, HttpUrl.parse(logoutButton.attr("href")).toString()).apply(); |
|
|
sharedPrefs.edit().putString(LOGOUT_LINK, HttpUrl.parse(logoutButton.attr("href")).toString()).apply(); |
|
|
|
|
|
|
|
|
return SUCCESS; |
|
|
return SUCCESS; |
|
|
} |
|
|
} else { |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
Report.i(TAG, "Login failed."); |
|
|
Report.i(TAG, "Login failed."); |
|
|
|
|
|
|
|
|
//Investigate login failure
|
|
|
//Investigate login failure
|
|
@ -159,41 +150,35 @@ public class SessionManager |
|
|
return FAILURE; |
|
|
return FAILURE; |
|
|
} |
|
|
} |
|
|
//Handle exception
|
|
|
//Handle exception
|
|
|
} |
|
|
} catch (InterruptedIOException e) { |
|
|
catch (InterruptedIOException e){ |
|
|
|
|
|
Report.i(TAG, "Login InterruptedIOException"); //users cancels LoginTask
|
|
|
Report.i(TAG, "Login InterruptedIOException"); //users cancels LoginTask
|
|
|
return CANCELLED; |
|
|
return CANCELLED; |
|
|
} |
|
|
} catch (IOException e) { |
|
|
catch (IOException e) { |
|
|
|
|
|
Report.w(TAG, "Login IOException", e); |
|
|
Report.w(TAG, "Login IOException", e); |
|
|
return CONNECTION_ERROR; |
|
|
return CONNECTION_ERROR; |
|
|
} |
|
|
} catch (Exception e) { |
|
|
catch (Exception e) { |
|
|
|
|
|
Report.w(TAG, "Login Exception (other)", e); |
|
|
Report.w(TAG, "Login Exception (other)", e); |
|
|
return EXCEPTION; |
|
|
return EXCEPTION; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* A function that checks the validity of the current saved session (if it exists). |
|
|
* A function that checks the validity of the current saved session (if it exists). |
|
|
* If isLoggedIn() is true, it will call login() with cookies. On failure, this can only return |
|
|
* If isLoggedIn() is true, it will call login() with cookies. On failure, this can only return |
|
|
* the code FAILURE. CANCELLED, CONNECTION_ERROR and EXCEPTION are simply considered a SUCCESS |
|
|
* the code FAILURE. CANCELLED, CONNECTION_ERROR and EXCEPTION are simply considered a SUCCESS |
|
|
* (e.g. no internet connection), at least until a more thorough handling of different |
|
|
* (e.g. no internet connection), at least until a more thorough handling of different |
|
|
* exceptions is implemented (if considered mandatory). |
|
|
* exceptions is implemented (if considered mandatory). |
|
|
* Always call it in a separate thread in a way that won't hinder performance (e.g. after |
|
|
* Always call it in a separate thread in a way that won't hinder performance (e.g. after |
|
|
* fragments' data are retrieved). |
|
|
* fragments' data are retrieved). |
|
|
*/ |
|
|
*/ |
|
|
public void validateSession() |
|
|
public void validateSession() { |
|
|
{ |
|
|
|
|
|
Report.i(TAG, "Validating session..."); |
|
|
Report.i(TAG, "Validating session..."); |
|
|
|
|
|
|
|
|
if(isLoggedIn()) |
|
|
if (isLoggedIn()) { |
|
|
{ |
|
|
|
|
|
int loginResult = login(); |
|
|
int loginResult = login(); |
|
|
if(loginResult != FAILURE) |
|
|
if (loginResult != FAILURE) |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} else if (isLoginScreenDefault()) |
|
|
else if(isLoginScreenDefault()) |
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, true).apply(); |
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, true).apply(); |
|
@ -201,10 +186,9 @@ public class SessionManager |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Call this function when user explicitly chooses to continue as a guest (UI thread). |
|
|
* Call this function when user explicitly chooses to continue as a guest (UI thread). |
|
|
*/ |
|
|
*/ |
|
|
public void guestLogin() |
|
|
public void guestLogin() { |
|
|
{ |
|
|
|
|
|
Report.i("TAG", "Continuing as a guest, as chosen by the user."); |
|
|
Report.i("TAG", "Continuing as a guest, as chosen by the user."); |
|
|
clearSessionData(); |
|
|
clearSessionData(); |
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); |
|
|
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); |
|
@ -212,14 +196,13 @@ public class SessionManager |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Logout function. Always call it in a separate thread. |
|
|
* Logout function. Always call it in a separate thread. |
|
|
*/ |
|
|
*/ |
|
|
public int logout() |
|
|
public int logout() { |
|
|
{ |
|
|
|
|
|
Report.i(TAG, "Logging out..."); |
|
|
Report.i(TAG, "Logging out..."); |
|
|
|
|
|
|
|
|
Request request = new Request.Builder() |
|
|
Request request = new Request.Builder() |
|
|
.url(sharedPrefs.getString(LOGOUT_LINK,"LogoutLink")) |
|
|
.url(sharedPrefs.getString(LOGOUT_LINK, "LogoutLink")) |
|
|
.build(); |
|
|
.build(); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
@ -271,15 +254,18 @@ public class SessionManager |
|
|
return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true); |
|
|
return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//TODO FIX METHOD, THIS MIGHT BE A SECURITY FLAW!! SEE ISSUE #2 MERGED WITH #16
|
|
|
|
|
|
public String getCookieHeader() { |
|
|
|
|
|
return cookiePersistor.loadAll().get(0).toString(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//--------------------------------------GETTERS END---------------------------------------------
|
|
|
//--------------------------------------GETTERS END---------------------------------------------
|
|
|
|
|
|
|
|
|
//------------------------------------OTHER FUNCTIONS-------------------------------------------
|
|
|
//------------------------------------OTHER FUNCTIONS-------------------------------------------
|
|
|
private void setPersistentCookieSession() |
|
|
private void setPersistentCookieSession() { |
|
|
{ |
|
|
|
|
|
List<Cookie> cookieList = cookieJar.loadForRequest(indexUrl); |
|
|
List<Cookie> cookieList = cookieJar.loadForRequest(indexUrl); |
|
|
|
|
|
|
|
|
if (cookieList.size() == 2) |
|
|
if (cookieList.size() == 2) { |
|
|
{ |
|
|
|
|
|
if ((cookieList.get(0).name().equals("THMMYgrC00ki3")) |
|
|
if ((cookieList.get(0).name().equals("THMMYgrC00ki3")) |
|
|
&& (cookieList.get(1).name().equals("PHPSESSID"))) { |
|
|
&& (cookieList.get(1).name().equals("PHPSESSID"))) { |
|
|
Cookie.Builder builder = new Cookie.Builder(); |
|
|
Cookie.Builder builder = new Cookie.Builder(); |
|
@ -295,18 +281,16 @@ public class SessionManager |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void clearSessionData() |
|
|
private void clearSessionData() { |
|
|
{ |
|
|
|
|
|
cookieJar.clear(); |
|
|
cookieJar.clear(); |
|
|
sharedPrefs.edit().clear().apply(); //Clear session data
|
|
|
sharedPrefs.edit().clear().apply(); //Clear session data
|
|
|
sharedPrefs.edit().putString(USERNAME, guestName).apply(); |
|
|
sharedPrefs.edit().putString(USERNAME, guestName).apply(); |
|
|
sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
|
|
|
sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
|
|
|
Report.i(TAG,"Session data cleared."); |
|
|
Report.i(TAG, "Session data cleared."); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Nullable |
|
|
@Nullable |
|
|
private String extractUserName(Document doc) |
|
|
private String extractUserName(Document doc) { |
|
|
{ |
|
|
|
|
|
if (doc != null) { |
|
|
if (doc != null) { |
|
|
Elements user = doc.select("div[id=myuser] > h3"); |
|
|
Elements user = doc.select("div[id=myuser] > h3"); |
|
|
|
|
|
|
|
@ -319,13 +303,12 @@ public class SessionManager |
|
|
return matcher.group(1); |
|
|
return matcher.group(1); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
Report.w(TAG,"Extracting username failed!"); |
|
|
Report.w(TAG, "Extracting username failed!"); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Nullable |
|
|
@Nullable |
|
|
private String extractAvatarLink(Document doc) |
|
|
private String extractAvatarLink(Document doc) { |
|
|
{ |
|
|
|
|
|
if (doc != null) { |
|
|
if (doc != null) { |
|
|
Elements avatar = doc.select("#ava img"); |
|
|
Elements avatar = doc.select("#ava img"); |
|
|
|
|
|
|
|
@ -333,7 +316,7 @@ public class SessionManager |
|
|
return avatar.attr("src"); |
|
|
return avatar.attr("src"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
Report.w(TAG,"Extracting avatar's link failed!"); |
|
|
Report.w(TAG, "Extracting avatar's link failed!"); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
//----------------------------------OTHER FUNCTIONS END-----------------------------------------
|
|
|
//----------------------------------OTHER FUNCTIONS END-----------------------------------------
|
|
|