mirror of https://github.com/ThmmyNoLife/mTHMMY
Apostolos Fanakis
8 years ago
25 changed files with 542 additions and 543 deletions
@ -1,61 +1,281 @@ |
|||
package gr.thmmy.mthmmy.activities; |
|||
|
|||
import android.content.SharedPreferences; |
|||
import android.os.Bundle; |
|||
import android.support.v7.app.AppCompatActivity; |
|||
import android.util.Log; |
|||
|
|||
import com.franmontiel.persistentcookiejar.PersistentCookieJar; |
|||
import com.franmontiel.persistentcookiejar.cache.SetCookieCache; |
|||
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; |
|||
|
|||
import gr.thmmy.mthmmy.utils.Thmmy; |
|||
import org.jsoup.Jsoup; |
|||
import org.jsoup.nodes.Document; |
|||
import org.jsoup.nodes.Element; |
|||
import org.jsoup.select.Elements; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.List; |
|||
import java.util.Objects; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
import javax.net.ssl.SSLHandshakeException; |
|||
|
|||
import okhttp3.Cookie; |
|||
import okhttp3.CookieJar; |
|||
import okhttp3.FormBody; |
|||
import okhttp3.HttpUrl; |
|||
import okhttp3.OkHttpClient; |
|||
import okhttp3.Request; |
|||
import okhttp3.RequestBody; |
|||
import okhttp3.Response; |
|||
|
|||
public class BaseActivity extends AppCompatActivity { |
|||
|
|||
//Shared preferences
|
|||
static final String SHARED_PREFS_NAME = "thmmySharedPrefs"; |
|||
//----------------------------------------CLASS VARIABLES-----------------------------------------
|
|||
/* --Response Codes-- */ |
|||
static final int LOGGED_OUT = 0; |
|||
static final int LOGGED_IN = 1; |
|||
static final int WRONG_USER = 2; |
|||
static final int WRONG_PASSWORD = 3; |
|||
static final int FAILED = 4; |
|||
static final int CERTIFICATE_ERROR = 5; |
|||
static final int OTHER_ERROR = 6; |
|||
/* --Response Codes End-- */ |
|||
/* --Shared Preferences-- */ |
|||
static final String USER_NAME = "userNameKey"; |
|||
static final String GUEST_PREF_USERNAME = "GUEST"; |
|||
static final String IS_LOGGED_IN = "isLoggedIn"; |
|||
static final String LOG_STATUS = "isLoggedIn"; |
|||
private static final String SHARED_PREFS_NAME = "thmmySharedPrefs"; |
|||
static SharedPreferences _prefs; |
|||
/* --Shared Preferences End-- */ |
|||
|
|||
/* --Client Stuff-- */ |
|||
static OkHttpClient client; |
|||
static Thmmy.LoginData loginData; |
|||
private static CookieJar cookieJar; |
|||
private static SharedPrefsCookiePersistor sharedPrefsCookiePersistor; |
|||
private static boolean init =false; //To initialize stuff only once per app start
|
|||
/* --Client Stuff End-- */ |
|||
|
|||
//Other variables
|
|||
private static boolean init = false; //To initialize stuff only once per app start
|
|||
private static final String TAG = "BaseActivity"; |
|||
//--------------------------------------CLASS VARIABLES END---------------------------------------
|
|||
|
|||
public static CookieJar getCookieJar() |
|||
{ |
|||
//-------------------------------------CLIENT AND COOKIES-----------------------------------------
|
|||
private static CookieJar getCookieJar() { |
|||
return cookieJar; |
|||
} |
|||
|
|||
public static SharedPrefsCookiePersistor getSharedPrefsCookiePersistor() { |
|||
private static SharedPrefsCookiePersistor getSharedPrefsCookiePersistor() { |
|||
return sharedPrefsCookiePersistor; |
|||
} |
|||
|
|||
public static OkHttpClient getClient() { |
|||
return client; |
|||
} |
|||
//-----------------------------------CLIENT AND COOKIES END---------------------------------------
|
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
|
|||
if(!init) |
|||
{ |
|||
if (!init) { |
|||
_prefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); |
|||
sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(BaseActivity.this); |
|||
cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor); |
|||
client = new OkHttpClient.Builder() |
|||
.cookieJar(cookieJar) |
|||
.build(); |
|||
loginData = new Thmmy.LoginData(); |
|||
loginData.setStatus(0); |
|||
init =true; |
|||
init = true; |
|||
} |
|||
|
|||
} |
|||
|
|||
void setLoginData(Thmmy.LoginData loginData) { |
|||
BaseActivity.loginData = loginData; |
|||
/* |
|||
THMMY CLASS |
|||
-- inner class of BaseActivity |
|||
|
|||
This class handles all session related operations (e.g. login, logout) |
|||
Also stores data to SharedPreferences file. |
|||
*/ |
|||
|
|||
//---------------------------------------INNER CLASS BEGINS---------------------------------------
|
|||
public static class Thmmy { |
|||
//Class variables
|
|||
private static final HttpUrl loginUrl = HttpUrl |
|||
.parse("https://www.thmmy.gr/smf/index.php?action=login2"); |
|||
private static final HttpUrl indexUrl = HttpUrl |
|||
.parse("https://www.thmmy.gr/smf/index.php"); |
|||
|
|||
|
|||
//-------------------------------------------LOGIN------------------------------------------------
|
|||
//Two options: (username, password, duration) or nothing - cookies
|
|||
static void login(String... strings) { |
|||
Log.d("Login", "Logging in..."); |
|||
Request request; |
|||
|
|||
if (strings.length == 3) { //Actual login
|
|||
String loginName = strings[0]; |
|||
String password = strings[1]; |
|||
String duration = strings[2]; |
|||
|
|||
((PersistentCookieJar) getCookieJar()).clear(); |
|||
|
|||
RequestBody formBody = new FormBody.Builder() //Build login form
|
|||
.add("user", loginName) |
|||
.add("passwrd", password) |
|||
.add("cookielength", duration) //Forever is -1
|
|||
.build(); |
|||
request = new Request.Builder() //Build the request
|
|||
.url(loginUrl) |
|||
.post(formBody) |
|||
.build(); |
|||
} else { //Already logged in, just get cookies
|
|||
request = new Request.Builder() //Build the request
|
|||
.url(loginUrl) |
|||
.build(); |
|||
} |
|||
|
|||
try { |
|||
Response response = client.newCall(request).execute(); //Make the request
|
|||
/* --Handle response-- */ |
|||
Document document = Jsoup.parse(response.body().string()); |
|||
Element logout = document.getElementById("logoutbtn"); //Get logout button
|
|||
|
|||
if (logout != null) { //If there is a logout button, then I successfully logged in
|
|||
Log.i("Login", "Login successful"); |
|||
setPersistentCookieSession(); |
|||
|
|||
//Edit SharedPreferences, save session's data
|
|||
_prefs.edit().putString(USER_NAME, extractUserName(document)).apply(); |
|||
_prefs.edit().putInt(LOG_STATUS, LOGGED_IN).apply(); |
|||
} else { //I am not logged in, what went wrong?
|
|||
Log.w("Login", "Login failed"); |
|||
_prefs.edit().putInt(LOG_STATUS, FAILED).apply(); //Request failed
|
|||
|
|||
//Making error more specific
|
|||
|
|||
Elements error = document.select("b:contains(That username does not exist.)"); |
|||
if (error.size() == 1) { //Wrong username
|
|||
_prefs.edit().putInt(LOG_STATUS, WRONG_USER).apply(); |
|||
Log.d("Login", "Wrong Username"); |
|||
} |
|||
|
|||
error = document.select("body:contains(Password incorrect)"); |
|||
if (error.size() == 1) { //Wrong password
|
|||
_prefs.edit().putInt(LOG_STATUS, WRONG_PASSWORD).apply(); |
|||
Log.d("Login", "Wrong Password"); |
|||
} |
|||
|
|||
((PersistentCookieJar) getCookieJar()).clear(); |
|||
|
|||
} |
|||
//Request exception handling
|
|||
} catch (SSLHandshakeException e) { |
|||
_prefs.edit().putInt(LOG_STATUS, CERTIFICATE_ERROR).apply(); |
|||
Log.w("Login", "Certificate problem"); |
|||
|
|||
} catch (Exception e) { |
|||
_prefs.edit().putInt(LOG_STATUS, OTHER_ERROR).apply(); |
|||
Log.e("Login", "Error", e); |
|||
} |
|||
} |
|||
//--------------------------------------LOGIN ENDS------------------------------------------------
|
|||
|
|||
//---------------------------------------LOGOUT---------------------------------------------------
|
|||
static int logout() { |
|||
String _logout_link = ""; |
|||
{ //Find current logout link
|
|||
try { |
|||
//Build and make a request for the index (home) page
|
|||
Request request = new Request.Builder() |
|||
.url(indexUrl) |
|||
.build(); |
|||
Response response = client.newCall(request).execute(); |
|||
Document document = Jsoup.parse(response.body().string()); |
|||
Element logout = document.getElementById("logoutbtn"); //Find the logout button
|
|||
_logout_link = HttpUrl.parse(logout.attr("href")).toString(); //Get the url
|
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
if (Objects.equals(_logout_link, "")) { //If logout button wasn't found
|
|||
return OTHER_ERROR; //Something went wrong
|
|||
} |
|||
|
|||
//Attempt logout
|
|||
OkHttpClient client = getClient(); |
|||
Request request = new Request.Builder() |
|||
.url(_logout_link) |
|||
.build(); |
|||
|
|||
try { |
|||
Response response = client.newCall(request).execute(); |
|||
Document document = Jsoup.parse(response.body().string()); |
|||
|
|||
Elements login = document.select("[value=Login]"); //Find login button
|
|||
((PersistentCookieJar) getCookieJar()).clear(); |
|||
if (!login.isEmpty()) { //If found, logout was successful
|
|||
Log.i("Logout", "Logout successful"); |
|||
_prefs.edit().clear().apply(); //Clear session data
|
|||
//User is now guest
|
|||
_prefs.edit().putString(USER_NAME, GUEST_PREF_USERNAME).apply(); |
|||
_prefs.edit().putInt(LOG_STATUS, LOGGED_IN).apply(); |
|||
return LOGGED_OUT; |
|||
} else { |
|||
Log.w("Logout", "Logout failed"); |
|||
return FAILED; |
|||
} |
|||
} catch (SSLHandshakeException e) { |
|||
Log.w("Logout", "Certificate problem (please switch to unsafe connection)."); |
|||
return CERTIFICATE_ERROR; |
|||
|
|||
} catch (Exception e) { |
|||
Log.d("Logout", "ERROR", e); |
|||
return OTHER_ERROR; |
|||
} |
|||
} |
|||
//----------------------------------------LOGOUT ENDS---------------------------------------------
|
|||
|
|||
//-------------------------------------------MISC-------------------------------------------------
|
|||
private static String extractUserName(Document doc) { |
|||
if (doc != null) { |
|||
Elements user = doc.select("div[id=myuser] > h3"); |
|||
|
|||
if (user.size() == 1) { |
|||
String txt = user.first().ownText(); |
|||
|
|||
Pattern pattern = Pattern.compile(", (.*?),"); |
|||
Matcher matcher = pattern.matcher(txt); |
|||
if (matcher.find()) |
|||
return matcher.group(1); |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static void setPersistentCookieSession() { |
|||
List<Cookie> cookieList = getCookieJar().loadForRequest(HttpUrl |
|||
.parse("https://www.thmmy.gr")); |
|||
|
|||
if (cookieList.size() == 2) { |
|||
if ((cookieList.get(0).name().equals("THMMYgrC00ki3")) |
|||
&& (cookieList.get(1).name().equals("PHPSESSID"))) { |
|||
Cookie.Builder builder = new Cookie.Builder(); |
|||
builder.name(cookieList.get(1).name()) |
|||
.value(cookieList.get(1).value()) |
|||
.domain(cookieList.get(1).domain()) |
|||
.expiresAt(cookieList.get(0).expiresAt()); |
|||
cookieList.remove(1); |
|||
cookieList.add(builder.build()); |
|||
getSharedPrefsCookiePersistor().clear(); |
|||
getSharedPrefsCookiePersistor().saveAll(cookieList); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//----------------------------------------INNER CLASS ENDS----------------------------------------
|
|||
} |
|||
|
@ -1,249 +0,0 @@ |
|||
package gr.thmmy.mthmmy.utils; |
|||
|
|||
import android.os.Parcel; |
|||
import android.os.Parcelable; |
|||
import android.util.Log; |
|||
|
|||
import com.franmontiel.persistentcookiejar.PersistentCookieJar; |
|||
|
|||
import org.jsoup.Jsoup; |
|||
import org.jsoup.nodes.Document; |
|||
import org.jsoup.nodes.Element; |
|||
import org.jsoup.select.Elements; |
|||
|
|||
import java.util.List; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
import javax.net.ssl.SSLHandshakeException; |
|||
|
|||
import gr.thmmy.mthmmy.activities.BaseActivity; |
|||
import okhttp3.Cookie; |
|||
import okhttp3.FormBody; |
|||
import okhttp3.HttpUrl; |
|||
import okhttp3.OkHttpClient; |
|||
import okhttp3.Request; |
|||
import okhttp3.RequestBody; |
|||
import okhttp3.Response; |
|||
|
|||
|
|||
public class Thmmy { |
|||
public static final int LOGGED_OUT = 0; |
|||
public static final int LOGGED_IN = 1; |
|||
public static final int WRONG_USER = 2; |
|||
public static final int WRONG_PASSWORD = 3; |
|||
public static final int FAILED = 4; |
|||
public static final int CERTIFICATE_ERROR = 5; |
|||
public static final int OTHER_ERROR = 6; |
|||
private static final HttpUrl loginUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=login2"); |
|||
|
|||
//-------------------------------------------LOGIN--------------------------------------------------
|
|||
//Two options: (username, password, duration) or nothing - cookies
|
|||
public static LoginData login(String... strings) { |
|||
Log.d("Login", "Logging in..."); |
|||
LoginData loginData = new LoginData(); |
|||
Request request; |
|||
|
|||
if (strings.length == 3) { |
|||
String loginName = strings[0]; |
|||
String password = strings[1]; |
|||
String duration = strings[2]; |
|||
|
|||
((PersistentCookieJar) BaseActivity.getCookieJar()).clear(); |
|||
|
|||
RequestBody formBody = new FormBody.Builder() |
|||
.add("user", loginName) |
|||
.add("passwrd", password) |
|||
.add("cookielength", duration) //Forever is -1
|
|||
.build(); |
|||
request = new Request.Builder() |
|||
.url(loginUrl) |
|||
.post(formBody) |
|||
.build(); |
|||
} else { |
|||
request = new Request.Builder() |
|||
.url(loginUrl) |
|||
.build(); |
|||
} |
|||
|
|||
OkHttpClient client = BaseActivity.getClient(); |
|||
|
|||
try { |
|||
Response response = client.newCall(request).execute(); |
|||
Document document = Jsoup.parse(response.body().string()); |
|||
|
|||
Element logout = document.getElementById("logoutbtn"); |
|||
|
|||
if (logout != null) { |
|||
Log.i("Login", "Login successful"); |
|||
setPersistentCookieSession(); |
|||
loginData.setUsername(extractUserName(document)); |
|||
loginData.setLogoutLink(HttpUrl.parse(logout.attr("href"))); |
|||
loginData.setStatus(LOGGED_IN); |
|||
} else { |
|||
Log.w("Login", "Login failed"); |
|||
loginData.setStatus(FAILED); |
|||
|
|||
//Making error more specific
|
|||
Elements error = document.select("b:contains(That username does not exist.)"); |
|||
|
|||
if (error.size() == 1) { |
|||
loginData.setStatus(WRONG_USER); |
|||
Log.d("Login", "Wrong Username"); |
|||
} |
|||
|
|||
error = document.select("body:contains(Password incorrect)"); |
|||
if (error.size() == 1) { |
|||
Log.d("Login", "Wrong Password"); |
|||
loginData.setStatus(WRONG_PASSWORD); |
|||
} |
|||
|
|||
((PersistentCookieJar) BaseActivity.getCookieJar()).clear(); |
|||
|
|||
} |
|||
} catch (SSLHandshakeException e) { |
|||
Log.w("Login", "Certificate problem"); |
|||
loginData.setStatus(CERTIFICATE_ERROR); |
|||
|
|||
} catch (Exception e) { |
|||
Log.e("Login", "Error", e); |
|||
loginData.setStatus(OTHER_ERROR); |
|||
} |
|||
|
|||
return loginData; |
|||
} |
|||
|
|||
private static void setPersistentCookieSession() { |
|||
List<Cookie> cookieList = BaseActivity.getCookieJar().loadForRequest(HttpUrl.parse("https://www.thmmy.gr")); |
|||
|
|||
if (cookieList.size() == 2) { |
|||
if ((cookieList.get(0).name().equals("THMMYgrC00ki3")) && (cookieList.get(1).name().equals("PHPSESSID"))) { |
|||
Cookie.Builder builder = new Cookie.Builder(); |
|||
builder.name(cookieList.get(1).name()) |
|||
.value(cookieList.get(1).value()) |
|||
.domain(cookieList.get(1).domain()) |
|||
.expiresAt(cookieList.get(0).expiresAt()); |
|||
cookieList.remove(1); |
|||
cookieList.add(builder.build()); |
|||
BaseActivity.getSharedPrefsCookiePersistor().clear(); |
|||
BaseActivity.getSharedPrefsCookiePersistor().saveAll(cookieList); |
|||
} |
|||
} |
|||
} |
|||
|
|||
//--------------------------------------LOGOUT--------------------------------------------------
|
|||
public static int logout(LoginData loginData) { |
|||
OkHttpClient client = BaseActivity.getClient(); |
|||
Request request = new Request.Builder() |
|||
.url(loginData.getLogoutLink()) |
|||
.build(); |
|||
|
|||
try { |
|||
Response response = client.newCall(request).execute(); |
|||
Document document = Jsoup.parse(response.body().string()); |
|||
|
|||
Elements login = document.select("[value=Login]"); |
|||
((PersistentCookieJar) BaseActivity.getCookieJar()).clear(); |
|||
if (!login.isEmpty()) { |
|||
Log.i("Logout", "Logout successful"); |
|||
loginData.setStatus(LOGGED_OUT); |
|||
return LOGGED_OUT; |
|||
} else { |
|||
Log.w("Logout", "Logout failed"); |
|||
return FAILED; |
|||
} |
|||
} catch (SSLHandshakeException e) { |
|||
Log.w("Logout", "Certificate problem (please switch to unsafe connection)."); |
|||
return CERTIFICATE_ERROR; |
|||
|
|||
} catch (Exception e) { |
|||
Log.d("Logout", "ERROR", e); |
|||
return OTHER_ERROR; |
|||
} |
|||
|
|||
|
|||
} |
|||
//-------------------------------------LOGIN ENDS-----------------------------------------------
|
|||
|
|||
//-------------------------------------------MISC---------------------------------------------------
|
|||
private static String extractUserName(Document doc) { |
|||
if (doc != null) { |
|||
Elements user = doc.select("div[id=myuser] > h3"); |
|||
|
|||
if (user.size() == 1) { |
|||
String txt = user.first().ownText(); |
|||
|
|||
Pattern pattern = Pattern.compile(", (.*?),"); |
|||
Matcher matcher = pattern.matcher(txt); |
|||
if (matcher.find()) |
|||
return matcher.group(1); |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
|
|||
//----------------------------------------LOGOUT ENDS-----------------------------------------------
|
|||
|
|||
//To maintain data between activities/ between activity state change (possibly temporary solution)
|
|||
public static class LoginData implements Parcelable { |
|||
public static final Parcelable.Creator<LoginData> CREATOR |
|||
= new Parcelable.Creator<LoginData>() { |
|||
public LoginData createFromParcel(Parcel in) { |
|||
return new LoginData(in); |
|||
} |
|||
|
|||
public LoginData[] newArray(int size) { |
|||
return new LoginData[size]; |
|||
} |
|||
}; |
|||
private int status; |
|||
private String username; |
|||
private HttpUrl logoutLink; |
|||
|
|||
public LoginData() { |
|||
} |
|||
|
|||
private LoginData(Parcel in) { |
|||
status = in.readInt(); |
|||
username = in.readString(); |
|||
logoutLink = HttpUrl.parse(in.readString()); |
|||
} |
|||
|
|||
public String getUsername() { |
|||
return username; |
|||
} |
|||
|
|||
void setUsername(String username) { |
|||
this.username = username; |
|||
} |
|||
|
|||
public int getStatus() { |
|||
return status; |
|||
} |
|||
|
|||
public void setStatus(int status) { |
|||
this.status = status; |
|||
} |
|||
|
|||
HttpUrl getLogoutLink() { |
|||
return logoutLink; |
|||
} |
|||
|
|||
void setLogoutLink(HttpUrl logoutLink) { |
|||
this.logoutLink = logoutLink; |
|||
} |
|||
|
|||
public int describeContents() { |
|||
return 0; |
|||
} |
|||
|
|||
public void writeToParcel(Parcel out, int flags) { |
|||
out.writeInt(status); |
|||
out.writeString(username); |
|||
out.writeString(logoutLink.toString()); |
|||
} |
|||
} |
|||
|
|||
} |
@ -1,8 +1,8 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<translate |
|||
android:duration="500" |
|||
android:fromXDelta="100%p" |
|||
android:toXDelta="0" /> |
|||
<translate |
|||
android:duration="500" |
|||
android:fromXDelta="100%p" |
|||
android:toXDelta="0"/> |
|||
|
|||
</set> |
@ -1,7 +1,7 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<translate |
|||
android:duration="500" |
|||
android:fromXDelta="0" |
|||
android:toXDelta="-100%p" /> |
|||
<translate |
|||
android:duration="500" |
|||
android:fromXDelta="0" |
|||
android:toXDelta="-100%p"/> |
|||
</set> |
@ -1,22 +1,22 @@ |
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|||
xmlns:tools="http://schemas.android.com/tools" |
|||
tools:context=".activities.MainActivity"> |
|||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|||
xmlns:tools="http://schemas.android.com/tools" |
|||
tools:context=".activities.MainActivity"> |
|||
<item |
|||
android:id="@+id/action_login" |
|||
android:orderInCategory="100" |
|||
android:title="@string/login" |
|||
android:visible="false" |
|||
app:showAsAction="never" /> |
|||
app:showAsAction="never"/> |
|||
<item |
|||
android:id="@+id/action_logout" |
|||
android:orderInCategory="200" |
|||
android:title="@string/logout" |
|||
android:visible="false" |
|||
app:showAsAction="never" /> |
|||
app:showAsAction="never"/> |
|||
<item |
|||
android:id="@+id/action_about" |
|||
android:orderInCategory="300" |
|||
android:title="@string/about" |
|||
app:showAsAction="never" /> |
|||
app:showAsAction="never"/> |
|||
</menu> |
|||
|
Loading…
Reference in new issue