Login speed improved and network usage reduced
This commit is contained in:
@@ -2,33 +2,33 @@ package de.sebse.fuplanner;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Pair;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.sebse.fuplanner.fragments.LoginFragment;
|
||||
import de.sebse.fuplanner.fragments.ScheduleFragment;
|
||||
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
||||
import de.sebse.fuplanner.fragments.ModulesFragment;
|
||||
import de.sebse.fuplanner.fragments.ScheduleFragment;
|
||||
import de.sebse.fuplanner.fragments.StartupFragment;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.Credentials;
|
||||
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
||||
import de.sebse.fuplanner.services.KVV.KVV;
|
||||
import de.sebse.fuplanner.services.KVV.types.LoginToken;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.tools.Conversion;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
@@ -79,16 +79,16 @@ public class MainActivity extends AppCompatActivity
|
||||
this.getGoogleAuth().connect(() -> {
|
||||
getGoogleAuth().getLoginState(credentials -> {
|
||||
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
this.getKVV().endUpdate();
|
||||
toLogoutState();
|
||||
return;
|
||||
}
|
||||
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
toLoginState(credentials);
|
||||
this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
|
||||
this.getKVV().endUpdate();
|
||||
toLoginState(success);
|
||||
}, error -> {
|
||||
log.e(error);
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
this.getKVV().endUpdate();
|
||||
toLogoutState();
|
||||
});
|
||||
});
|
||||
@@ -204,11 +204,11 @@ public class MainActivity extends AppCompatActivity
|
||||
return this.mKVV;
|
||||
}
|
||||
|
||||
private void toLoginState(Credentials credentials) {
|
||||
if (credentials == null) {
|
||||
private void toLoginState(LoginToken loginToken) {
|
||||
if (loginToken == null) {
|
||||
toLogoutState();
|
||||
} else {
|
||||
toLoginState(credentials.getUsername());
|
||||
toLoginState(loginToken.getFullname(), loginToken.getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +222,7 @@ public class MainActivity extends AppCompatActivity
|
||||
View header = mNavigationView.getHeaderView(0);
|
||||
header.findViewById(R.id.imageView).setVisibility(View.GONE);
|
||||
header.findViewById(R.id.login_name).setVisibility(View.GONE);
|
||||
header.findViewById(R.id.login_mail).setVisibility(View.GONE);
|
||||
header.findViewById(R.id.btn_login_page).setVisibility(View.VISIBLE);
|
||||
header.findViewById(R.id.btn_login_page).setOnClickListener(v -> {
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
@@ -233,7 +234,7 @@ public class MainActivity extends AppCompatActivity
|
||||
mNavigationView.inflateMenu(R.menu.activity_main_drawer);
|
||||
}
|
||||
|
||||
private void toLoginState(String username) {
|
||||
private void toLoginState(String fullname, String email) {
|
||||
setTitle(R.string.courses);
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
|
||||
@@ -243,7 +244,9 @@ public class MainActivity extends AppCompatActivity
|
||||
View header = mNavigationView.getHeaderView(0);
|
||||
header.findViewById(R.id.imageView).setVisibility(View.VISIBLE);
|
||||
header.findViewById(R.id.login_name).setVisibility(View.VISIBLE);
|
||||
((TextView) header.findViewById(R.id.login_name)).setText(username);
|
||||
header.findViewById(R.id.login_mail).setVisibility(View.VISIBLE);
|
||||
((TextView) header.findViewById(R.id.login_name)).setText(fullname);
|
||||
((TextView) header.findViewById(R.id.login_mail)).setText(email);
|
||||
header.findViewById(R.id.btn_login_page).setVisibility(View.GONE);
|
||||
mNavigationView.getMenu().clear();
|
||||
mNavigationView.inflateMenu(R.menu.activity_main_drawer_login);
|
||||
@@ -275,8 +278,8 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoginFragmentInteraction(String username) {
|
||||
toLoginState(username);
|
||||
public void onLoginFragmentInteraction(LoginToken loginToken) {
|
||||
toLoginState(loginToken.getFullname(), loginToken.getEmail());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@ import de.sebse.fuplanner.MainActivity;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
||||
import de.sebse.fuplanner.services.KVV.KVV;
|
||||
import de.sebse.fuplanner.services.KVV.types.LoginToken;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
|
||||
@@ -66,8 +67,8 @@ public class LoginFragment extends Fragment {
|
||||
if (modules != null) {
|
||||
Button offline_btn = v.findViewById(R.id.btn_offline);
|
||||
offline_btn.setVisibility(View.VISIBLE);
|
||||
offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, modules.getUsername()));
|
||||
offline_btn.setOnClickListener(v1 -> mListener.onLoginFragmentInteraction(modules.getUsername()));
|
||||
offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, modules.getToken().getUsername()));
|
||||
offline_btn.setOnClickListener(v1 -> mListener.onLoginFragmentInteraction(modules.getToken()));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -100,7 +101,7 @@ public class LoginFragment extends Fragment {
|
||||
progressDialog.dismiss();
|
||||
gauth.setLoginState(username, password);
|
||||
if (mListener != null)
|
||||
mListener.onLoginFragmentInteraction(username);
|
||||
mListener.onLoginFragmentInteraction(success);
|
||||
}, error -> {
|
||||
progressDialog.dismiss();
|
||||
log.e("Error on KVV login!", error);
|
||||
@@ -142,6 +143,6 @@ public class LoginFragment extends Fragment {
|
||||
* >Communicating with Other Fragments</a> for more information.
|
||||
*/
|
||||
public interface OnLoginFragmentInteractionListener {
|
||||
void onLoginFragmentInteraction(String username);
|
||||
void onLoginFragmentInteraction(LoginToken loginToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.util.HashMap;
|
||||
|
||||
import de.sebse.fuplanner.services.KVV.types.LoginToken;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
@@ -24,10 +23,8 @@ public class KVV {
|
||||
private boolean isUpdating;
|
||||
private ArrayList<LastTokenCallback> updatingList;
|
||||
private HashMap<String, Object> addons = new HashMap<>();
|
||||
private Logger log = new Logger(this);
|
||||
|
||||
public KVV(Context context) {
|
||||
log.d("new kvv");
|
||||
this.context = context;
|
||||
this.isUpdating = false;
|
||||
this.updatingList = new ArrayList<>();
|
||||
@@ -37,12 +34,20 @@ public class KVV {
|
||||
KVVLogin login = new KVVLogin(this.context);
|
||||
login.login(username, password, success -> {
|
||||
lastToken = success;
|
||||
try {
|
||||
login.saveOffline(this.context);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.onResponse(success);
|
||||
}, error);
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
lastToken = null;
|
||||
if (lastToken != null) {
|
||||
lastToken.delete(this.context);
|
||||
lastToken = null;
|
||||
}
|
||||
KVVModuleList modules = (KVVModuleList) addons.get("modules");
|
||||
if (modules != null) {
|
||||
modules.deleteModulesOffline(this.context);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package de.sebse.fuplanner.services.KVV;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -18,23 +21,71 @@ import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
*/
|
||||
|
||||
class KVVLogin extends HTTPService {
|
||||
public KVVLogin(Context context) {
|
||||
private LoginToken loginToken;
|
||||
|
||||
KVVLogin(Context context) {
|
||||
super(context, false);
|
||||
try {
|
||||
this.loginToken = LoginToken.load(context);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void login(final String username, final String password, final NetworkCallback<LoginToken> callback, final NetworkErrorCallback error) {
|
||||
public void login(String username, String password, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
|
||||
if (this.loginToken != null) {
|
||||
if (this.loginToken.getUsername().equals(username)) {
|
||||
log.d("Old login found!");
|
||||
testLogin(this.loginToken, success -> callback.onResponse(this.loginToken), error -> {
|
||||
this.loginToken = null;
|
||||
log.d("Old login invalid! Re-login...");
|
||||
login(username, password, callback, errorCallback);
|
||||
});
|
||||
} else {
|
||||
this.loginToken = null;
|
||||
log.d("Login name no no match! Re-login...");
|
||||
login(username, password, callback, errorCallback);
|
||||
}
|
||||
} else {
|
||||
log.d("No login found! Loggin in!");
|
||||
doLogin(username, password, token -> {
|
||||
this.loginToken = token;
|
||||
log.d("Logged in successfully! Testing...");
|
||||
testLogin(this.loginToken, success -> callback.onResponse(this.loginToken), errorCallback);
|
||||
}, errorCallback);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteOffline(Context context) {
|
||||
if (this.loginToken != null)
|
||||
this.loginToken.delete(context);
|
||||
}
|
||||
|
||||
public void saveOffline(Context context) throws IOException {
|
||||
if (this.loginToken != null)
|
||||
this.loginToken.save(context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void doLogin(String username, String password, NetworkCallback<LoginToken> callback, NetworkErrorCallback error) {
|
||||
startKVVSession(success -> {
|
||||
final String kvvJSESSIONID = success.get("JSESSIONID");
|
||||
String kvvJSESSIONID = success.get("JSESSIONID");
|
||||
getSAMLRequest(kvvJSESSIONID, success1 -> startIdentSession(success1.get("Location"), success11 -> {
|
||||
final String identJSESSIONID = success11.get("JSESSIONID");
|
||||
final String ident_idp_authn_lc_key = success11.get("_idp_authn_lc_key");
|
||||
final String identROUTEID = success11.get("ROUTEID");
|
||||
String identJSESSIONID = success11.get("JSESSIONID");
|
||||
String ident_idp_authn_lc_key = success11.get("_idp_authn_lc_key");
|
||||
String identROUTEID = success11.get("ROUTEID");
|
||||
loginIdent(true, username, password, identJSESSIONID, ident_idp_authn_lc_key, identROUTEID, success111 -> loginIdent(false, username, password, identJSESSIONID, ident_idp_authn_lc_key, identROUTEID, success11112 -> {
|
||||
final String ident_idp_session = success11112.get("_idp_session");
|
||||
String ident_idp_session = success11112.get("_idp_session");
|
||||
getSAMLResponse(identJSESSIONID, ident_idp_authn_lc_key, identROUTEID, ident_idp_session, success1111 -> loginKVV(success1111.get("RelayState"), success1111.get("SAMLResponse"), kvvJSESSIONID, success111112 -> {
|
||||
final LoginToken token = new LoginToken(username, success111112.get("shibsessionKey"), success111112.get("shibsessionName"), kvvJSESSIONID);
|
||||
LoginToken token = new LoginToken(username, success111112.get("shibsessionKey"), success111112.get("shibsessionName"), kvvJSESSIONID);
|
||||
finishKVVlogin(token, success11111 -> {
|
||||
Log.d("KVVMaster", "Login worked!");
|
||||
log.d("Login worked!");
|
||||
callback.onResponse(token);
|
||||
}, error);
|
||||
}, error), error);
|
||||
@@ -43,6 +94,22 @@ class KVVLogin extends HTTPService {
|
||||
}, error);
|
||||
}
|
||||
|
||||
private void testLogin(LoginToken loginToken, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
|
||||
get(String.format("https://kvv.imp.fu-berlin.de/direct/profile/%s.json", loginToken.getUsername()), loginToken.getCookies(), response -> {
|
||||
String body = response.getParsed();
|
||||
try {
|
||||
JSONObject json = new JSONObject(body);
|
||||
String displayName = json.getString("displayName");
|
||||
String email = json.getString("email");
|
||||
loginToken.setAdditionals(displayName, email);
|
||||
callback.onResponse(loginToken);
|
||||
} catch (JSONException e) {
|
||||
errorCallback.onError(new NetworkError(100201, 403, "Cannot parse announcements!"));
|
||||
return;
|
||||
}
|
||||
}, error -> errorCallback.onError(new NetworkError(100200, error.networkResponse.statusCode, "Testing login failed!")));
|
||||
}
|
||||
|
||||
/*
|
||||
GET https://kvv.imp.fu-berlin.de/portal/login
|
||||
-> JSESSIONID 5c10406f-588c-4c16-96e9-c80d115417de.tomcat1
|
||||
@@ -253,8 +320,8 @@ class KVVLogin extends HTTPService {
|
||||
Pattern pattern = Pattern.compile(name+"=([^;]+);");
|
||||
Matcher matcher = pattern.matcher(cookies);
|
||||
if (!matcher.find()) {
|
||||
Log.d("GETcookie failed", name);
|
||||
Log.d("GETcookie failed", cookies);
|
||||
log.d("GETcookie failed", name);
|
||||
log.d("GETcookie failed", cookies);
|
||||
throw new NoSuchFieldException();
|
||||
}
|
||||
return matcher.group(1);
|
||||
|
||||
@@ -46,7 +46,7 @@ public class KVVModuleList extends HTTPService {
|
||||
this.token = token;
|
||||
try {
|
||||
Modules modules = Modules.load(context);
|
||||
if (token == null || modules.getUsername().equals(token.getUsername()))
|
||||
if (token == null || token.isSameUser(modules.getToken()))
|
||||
this.moduleList = modules;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -84,7 +84,7 @@ public class KVVModuleList extends HTTPService {
|
||||
errorCallback.onError(new NetworkError(101101, 403, "No module list retrieved!"));
|
||||
return;
|
||||
}
|
||||
Modules modules = new Modules(token.getUsername());
|
||||
Modules modules = new Modules(token);
|
||||
try {
|
||||
JSONObject json = new JSONObject(body);
|
||||
JSONArray sites = json.getJSONArray("site_collection");
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
package de.sebse.fuplanner.services.KVV.types;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by sebastian on 29.10.17.
|
||||
*/
|
||||
|
||||
public class LoginToken {
|
||||
public class LoginToken implements Serializable {
|
||||
private static final String FILE_NAME = "LoginTokenSaving";
|
||||
private final String username;
|
||||
private final String shibsessionKey;
|
||||
private final String shibsessionName;
|
||||
private String JSESSIONID;
|
||||
private String fullname;
|
||||
private String email;
|
||||
|
||||
public LoginToken(String username, String shibsessionKey, String shibsessionName, String JSESSIONID) {
|
||||
this.username = username;
|
||||
@@ -19,22 +30,56 @@ public class LoginToken {
|
||||
this.JSESSIONID = JSESSIONID;
|
||||
}
|
||||
|
||||
public static LoginToken load(Context context) throws IOException, ClassNotFoundException {
|
||||
FileInputStream fis = context.openFileInput(FILE_NAME);
|
||||
ObjectInputStream is = new ObjectInputStream(fis);
|
||||
LoginToken loginToken = (LoginToken) is.readObject();
|
||||
is.close();
|
||||
fis.close();
|
||||
return loginToken;
|
||||
}
|
||||
|
||||
public void save(Context context) throws IOException {
|
||||
FileOutputStream fos = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
|
||||
ObjectOutputStream os = new ObjectOutputStream(fos);
|
||||
os.writeObject(this);
|
||||
os.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
public void delete(Context context) {
|
||||
context.deleteFile(FILE_NAME);
|
||||
}
|
||||
|
||||
public void setAdditionals(String fullname, String email) {
|
||||
this.fullname = fullname;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getShibsessionKey() {
|
||||
private String getShibsessionKey() {
|
||||
return shibsessionKey;
|
||||
}
|
||||
|
||||
public String getShibsessionName() {
|
||||
private String getShibsessionName() {
|
||||
return shibsessionName;
|
||||
}
|
||||
|
||||
public String getJSESSIONID() {
|
||||
private String getJSESSIONID() {
|
||||
return JSESSIONID;
|
||||
}
|
||||
|
||||
public String getFullname() {
|
||||
return fullname;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getCookies() {
|
||||
HashMap<String, String> cookies = new HashMap<>();
|
||||
cookies.put("JSESSIONID", getJSESSIONID());
|
||||
@@ -43,6 +88,10 @@ public class LoginToken {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
public boolean isSameUser(LoginToken token) {
|
||||
return token != null && this.getUsername().equals(token.getUsername());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
@@ -27,12 +27,12 @@ import de.sebse.fuplanner.tools.SortedModuleList;
|
||||
public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
private final SortedModuleList list;
|
||||
private String latestSemester = null;
|
||||
private String username;
|
||||
private LoginToken token;
|
||||
//private transient Logger log = new Logger(this);
|
||||
private static final String FILE_NAME = "ModuleListSaving";
|
||||
|
||||
public Modules(String username) {
|
||||
this.username = username;
|
||||
public Modules(LoginToken loginToken) {
|
||||
this.token = loginToken;
|
||||
this.list = new SortedModuleList();
|
||||
}
|
||||
|
||||
@@ -177,8 +177,8 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
context.deleteFile(FILE_NAME);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
public LoginToken getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public class Module implements Serializable {
|
||||
|
||||
@@ -39,4 +39,13 @@
|
||||
tools:text="Android Studio"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/login_mail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
tools:text="Android Studio"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user