Added Blackboard Courses to List

This commit is contained in:
Caesar2011
2019-01-28 02:01:43 +01:00
parent 72234d2439
commit c15fc1339f
18 changed files with 700 additions and 130 deletions

View File

@@ -45,7 +45,7 @@ import de.sebse.fuplanner.services.fulogin.AccountGeneral;
import de.sebse.fuplanner.services.kvv.KVV;
import de.sebse.fuplanner.services.kvv.KVVListener;
import de.sebse.fuplanner.services.kvv.sync.KVVContentProvider;
import de.sebse.fuplanner.services.kvv.types.LoginToken;
import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV;
import de.sebse.fuplanner.services.kvv.types.Modules;
import de.sebse.fuplanner.services.news.NewsManager;
import de.sebse.fuplanner.tools.CustomAccountManager;
@@ -658,7 +658,7 @@ public class MainActivity extends AppCompatActivity
@Override
public void onLogin(LoginToken token, boolean isOnlyRefresh) {
public void onLogin(LoginTokenKVV token, boolean isOnlyRefresh) {
toLoginState(token.getFullName(), token.getEmail(), getDefaultFragmentAfterLogin());
if (!isOnlyRefresh) {
registerSync();

View File

@@ -4,5 +4,4 @@ public class AccountGeneral {
public static final String ACCOUNT_TYPE = "de.sebse.fuplanner.fuauth";
public static final String AUTHTOKEN_TYPE_KVV = "KVV";
public static final String AUTHTOKEN_TYPE_BLACKBOARD = "Blackboard";
public static final long SYNC_INTERVAL = 6 * 60 * 60; // defined in seconds
}

View File

@@ -14,9 +14,10 @@ import java.util.concurrent.atomic.AtomicReference;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.kvv.sync.Login;
import de.sebse.fuplanner.services.kvv.types.LoginToken;
import de.sebse.fuplanner.services.kvv.sync.BBLogin;
import de.sebse.fuplanner.services.kvv.sync.KVVLogin;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
/**
@@ -34,20 +35,22 @@ public class UserLoginTask extends AsyncTask<Void, Void, String> {
};*/
static final String PARAM_USER_PASS = "PARAM_USER_PASS";
private final String mEmail;
private final String mUsername;
private final String mPassword;
private final Login mVolleyLogin;
private final KVVLogin mKVVLogin;
private final BBLogin mBBLogin;
private String mTokenType;
private Logger log = new Logger(this);
@SuppressLint("StaticFieldLeak")
@Nullable
private FUAuthenticatorActivity mActivity;
UserLoginTask(String email, String password, String tokenType, @NotNull Context context) {
mEmail = email;
UserLoginTask(String username, String password, String tokenType, @NotNull Context context) {
mUsername = username;
mPassword = password;
mTokenType = tokenType;
mVolleyLogin = new Login(context);
mKVVLogin = new KVVLogin(context);
mBBLogin = new BBLogin(context);
if (context instanceof FUAuthenticatorActivity)
mActivity = (FUAuthenticatorActivity) context;
}
@@ -57,30 +60,38 @@ public class UserLoginTask extends AsyncTask<Void, Void, String> {
// TODO: attempt authentication against a network service.
CountDownLatch latch = new CountDownLatch(1);
AtomicReference<LoginToken> login = new AtomicReference<>();
mVolleyLogin.doLogin(mEmail, mPassword, success -> {
mVolleyLogin.testLoginToken(success, success1 -> {
login.set(success);
latch.countDown();
}, error -> {
log.e(error);
latch.countDown();
});
}, error -> {
AtomicReference<String> login = new AtomicReference<>();
NetworkErrorCallback errorFunc = error -> {
log.e(error);
latch.countDown();
});
};
switch (mTokenType) {
case AccountGeneral.AUTHTOKEN_TYPE_KVV:
mKVVLogin.doLogin(mUsername, mPassword, success -> {
mKVVLogin.testLoginToken(success, success1 -> {
login.set(success1.toJsonString());
latch.countDown();
}, errorFunc);
}, errorFunc);
break;
case AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD:
mBBLogin.doLogin(mUsername, mPassword, success -> {
mBBLogin.testLoginToken(success, success1 -> {
login.set(success1.toJsonString());
latch.countDown();
}, errorFunc);
}, errorFunc);
break;
default:
return null;
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (login.get() == null) {
return null;
} else {
return login.get().toJsonString();
}
return login.get();
}
@Override
@@ -94,7 +105,7 @@ public class UserLoginTask extends AsyncTask<Void, Void, String> {
if (success != null) {
final Intent res = new Intent();
res.putExtra(AccountManager.KEY_ACCOUNT_NAME, mEmail);
res.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);
res.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE);
res.putExtra(AccountManager.KEY_AUTHTOKEN, success);
res.putExtra(PARAM_USER_PASS, mPassword);

View File

@@ -2,11 +2,11 @@ package de.sebse.fuplanner.services.kvv;
import com.android.volley.NetworkResponse;
import de.sebse.fuplanner.services.kvv.types.LoginToken;
import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV;
import de.sebse.fuplanner.tools.CustomAccountManager;
public interface KVVListener {
default void onLogin(LoginToken token, boolean isOnlyRefresh) {}
default void onLogin(LoginTokenKVV token, boolean isOnlyRefresh) {}
default void onLogout() {}

View File

@@ -1,12 +1,16 @@
package de.sebse.fuplanner.services.kvv;
import android.content.Context;
import android.util.Pair;
import org.jetbrains.annotations.NotNull;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
import de.sebse.fuplanner.services.kvv.types.LoginToken;
import de.sebse.fuplanner.services.kvv.sync.BBLogin;
import de.sebse.fuplanner.services.kvv.sync.KVVLogin;
import de.sebse.fuplanner.services.kvv.types.LoginTokenBB;
import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV;
import de.sebse.fuplanner.tools.CustomAccountManager;
import de.sebse.fuplanner.tools.NetworkCallbackCollector;
import de.sebse.fuplanner.tools.network.HTTPService;
@@ -16,9 +20,10 @@ import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
public class Login extends HTTPService {
private final KVVListener mListener;
@Nullable private LoginToken mToken;
@Nullable private LoginTokenKVV mTokenKVV;
@Nullable private LoginTokenBB mTokenBB;
private boolean mLoginPending = false;
private final NetworkCallbackCollector<LoginToken> mRefreshCallbacks = new NetworkCallbackCollector<>();
private final NetworkCallbackCollector<Pair<LoginTokenKVV, LoginTokenBB>> mRefreshCallbacks = new NetworkCallbackCollector<>();
Login(KVVListener listener, Context context) {
super(context);
@@ -31,27 +36,33 @@ public class Login extends HTTPService {
return;
}
mLoginPending = true;
LoginToken.load(mListener.getAccountManager(), token -> {
boolean result = setToken(token);
mLoginPending = false;
callback.run(result);
LoginTokenKVV.load(mListener.getAccountManager(), tokenKVV -> {
LoginTokenBB.load(mListener.getAccountManager(), tokenBB -> {
boolean result = setToken(tokenKVV, tokenBB);
mLoginPending = false;
callback.run(result);
});
});
}
public void isOfflineStoredAvailable(BooleanInterface callback) {
LoginToken.load(mListener.getAccountManager(), token -> {
callback.run(token != null);
LoginTokenKVV.load(mListener.getAccountManager(), tokenKVV -> {
LoginTokenBB.load(mListener.getAccountManager(), tokenBB -> {
callback.run(tokenKVV != null && tokenBB != null);
});
});
}
public boolean logout(boolean delete) {
if (mLoginPending)
return false;
if (mToken == null)
if (mTokenKVV == null || mTokenBB == null)
return true;
if (delete)
mToken.delete(mListener.getAccountManager());
mToken = null;
if (delete) {
mTokenKVV.delete(mListener.getAccountManager());
mTokenBB.delete(mListener.getAccountManager());
}
mTokenKVV = null;
return handleCallbacks(false);
}
@@ -60,43 +71,57 @@ public class Login extends HTTPService {
}
public boolean isLoggedIn() {
return mToken != null;
return mTokenKVV != null && mTokenBB != null;
}
public boolean isInOnlineMode() {
return isLoggedIn();
}
void testLoginToken(@NotNull NetworkCallback<LoginToken> callback, @NotNull NetworkErrorCallback errorCallback) {
if (mToken == null) {
void testLoginToken(@NotNull NetworkCallback<Pair<LoginTokenKVV, LoginTokenBB>> callback, @NotNull NetworkErrorCallback errorCallback) {
if (mTokenKVV == null) {
errorCallback.onError(new NetworkError(100173, -1, "Not logged in!"));
return;
}
testLoginToken(mToken, callback, errorCallback);
if (mTokenBB == null) {
errorCallback.onError(new NetworkError(100174, -1, "Not logged in!"));
return;
}
testLoginToken(mTokenKVV, mTokenBB, callback, errorCallback);
}
private void testLoginToken(@NotNull LoginToken token, @NotNull NetworkCallback<LoginToken> callback, @NotNull NetworkErrorCallback errorCallback) {
new de.sebse.fuplanner.services.kvv.sync.Login(getContext()).testLoginToken(token, callback, errorCallback);
private void testLoginToken(@NotNull LoginTokenKVV tokenKVV, @NotNull LoginTokenBB tokenBB, @NotNull NetworkCallback<Pair<LoginTokenKVV, LoginTokenBB>> callback, @NotNull NetworkErrorCallback errorCallback) {
new KVVLogin(getContext()).testLoginToken(tokenKVV, tokenKVV1 -> {
new BBLogin(getContext()).testLoginToken(tokenBB, tokenBB1 -> {
callback.onResponse(new Pair<>(tokenKVV1, tokenBB1));
}, errorCallback);
}, errorCallback);
}
@Nullable public LoginToken getLoginToken() {
return mToken;
@Nullable public LoginTokenKVV getLoginTokenKVV() {
return mTokenKVV;
}
void refreshLogin(NetworkCallback<LoginToken> success, NetworkErrorCallback error) {
@Nullable public LoginTokenBB getLoginTokenBB() {
return mTokenBB;
}
void refreshLogin(NetworkCallback<Pair<LoginTokenKVV, LoginTokenBB>> success, NetworkErrorCallback error) {
boolean isFirst = mRefreshCallbacks.isEmpty();
mRefreshCallbacks.add(success, error);
if (!isFirst)
return;
CustomAccountManager manager = mListener.getAccountManager();
manager.doInvalidateToken(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, ignored -> {
restoreOnlineLogin(isRestored -> {
if (isRestored)
testLoginToken(mRefreshCallbacks::responseResponse, mRefreshCallbacks::responseError);
else {
logout(true);
mRefreshCallbacks.responseError(new NetworkError(100180, 403, "Re-login failed!"));
}
manager.doInvalidateToken(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD, ignored2 -> {
restoreOnlineLogin(isRestored -> {
if (isRestored)
testLoginToken(mRefreshCallbacks::responseResponse, mRefreshCallbacks::responseError);
else {
logout(true);
mRefreshCallbacks.responseError(new NetworkError(100180, 403, "Re-login failed!"));
}
});
});
});
}
@@ -104,8 +129,8 @@ public class Login extends HTTPService {
private boolean handleCallbacks(boolean isOnlyRefresh) {
if (mToken != null) {
mListener.onLogin(mToken, isOnlyRefresh);
if (mTokenKVV != null) {
mListener.onLogin(mTokenKVV, isOnlyRefresh);
return true;
} else {
mListener.onLogout();
@@ -113,11 +138,12 @@ public class Login extends HTTPService {
}
}
private boolean setToken(@Nullable LoginToken token) {
if (token == null)
private boolean setToken(@Nullable LoginTokenKVV tokenKVV, @Nullable LoginTokenBB tokenBB) {
if (tokenKVV == null || tokenBB == null)
return false;
boolean isOnlyRefresh = mToken != null;
mToken = token;
boolean isOnlyRefresh = mTokenKVV != null && tokenBB != null;
mTokenKVV = tokenKVV;
mTokenBB = tokenBB;
return isOnlyRefresh || handleCallbacks(isOnlyRefresh);
}

View File

@@ -33,12 +33,12 @@ public class ModulesAnnouncements extends PartModules<ArrayList<Announcement>> {
}
@Override
protected void upgrade(final String ID, final NetworkCallback<ArrayList<Announcement>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
protected void upgradeKVV(final String ID, final NetworkCallback<ArrayList<Announcement>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101204, 500, "Currently running in offline mode!"));
return;
}
super.get(String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID), mLogin.getLoginToken().getCookies(), response -> {
super.get(String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID), mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101201, 403, "No announcements retrieved!"));
@@ -88,4 +88,9 @@ public class ModulesAnnouncements extends PartModules<ArrayList<Announcement>> {
callback.onResponse(announcements);
}, error -> errorCallback.onError(new NetworkError(101203, error.networkResponse.statusCode, "Cannot get announcements!")));
}
@Override
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Announcement>> callback, NetworkErrorCallback errorCallback) {
callback.onResponse(new ArrayList<>());
}
}

View File

@@ -34,12 +34,12 @@ public class ModulesAssignments extends PartModules<AssignmentList> {
}
@Override
protected void upgrade(final String ID, final NetworkCallback<AssignmentList> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
protected void upgradeKVV(final String ID, final NetworkCallback<AssignmentList> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101304, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/assignment/site/%s.json", ID), mLogin.getLoginToken().getCookies(), response -> {
get(String.format("https://kvv.imp.fu-berlin.de/direct/assignment/site/%s.json", ID), mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101301, 403, "No assignments retrieved!"));
@@ -87,4 +87,9 @@ public class ModulesAssignments extends PartModules<AssignmentList> {
callback.onResponse(assignments);
}, error -> errorCallback.onError(new NetworkError(101303, error.networkResponse.statusCode, "Cannot get assignments!")));
}
@Override
protected void upgradeBB(String ID, NetworkCallback<AssignmentList> callback, NetworkErrorCallback errorCallback) {
callback.onResponse(new AssignmentList());
}
}

View File

@@ -32,12 +32,12 @@ public class ModulesEvents extends PartModules<EventList> {
}
@Override
protected void upgrade(final String ID, final NetworkCallback<EventList> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
protected void upgradeKVV(final String ID, final NetworkCallback<EventList> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101404, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/calendar/site/%s.json?detailed=true", ID), mLogin.getLoginToken().getCookies(), response -> {
get(String.format("https://kvv.imp.fu-berlin.de/direct/calendar/site/%s.json?detailed=true", ID), mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101401, 403, "No events retrieved!"));
@@ -80,4 +80,9 @@ public class ModulesEvents extends PartModules<EventList> {
callback.onResponse(events);
}, error -> errorCallback.onError(new NetworkError(101403, error.networkResponse.statusCode, "Cannot get events!")));
}
@Override
protected void upgradeBB(String ID, NetworkCallback<EventList> callback, NetworkErrorCallback errorCallback) {
callback.onResponse(new EventList());
}
}

View File

@@ -33,12 +33,12 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
}
@Override
protected void upgrade(final String ID, final NetworkCallback<ArrayList<Grade>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
protected void upgradeKVV(final String ID, final NetworkCallback<ArrayList<Grade>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101504, 500, "Currently running in offline mode!"));
return;
}
super.get(String.format("https://kvv.imp.fu-berlin.de/direct/gradebook/site/%s.json", ID), mLogin.getLoginToken().getCookies(), response -> {
super.get(String.format("https://kvv.imp.fu-berlin.de/direct/gradebook/site/%s.json", ID), mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101501, 403, "No gradebook retrieved!"));
@@ -73,4 +73,9 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
callback.onResponse(gradebook);
}, error -> errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook!")));
}
@Override
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Grade>> callback, NetworkErrorCallback errorCallback) {
callback.onResponse(new ArrayList<>());
}
}

View File

@@ -9,8 +9,10 @@ import org.json.JSONObject;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.concurrent.CountDownLatch;
import java.util.regex.MatchResult;
import de.sebse.fuplanner.services.kvv.types.Lecturer;
@@ -61,7 +63,10 @@ public class ModulesList extends HTTPService {
}
private void find(String moduleID, NetworkCallback<Modules.Module> moduleNetworkCallback, NetworkErrorCallback errorCallback, int retries) {
if (mModules != null && mLogin.getLoginToken() != null && mLogin.getLoginToken().isOtherUser(mModules.getUsername()))
if (mModules != null &&
mLogin.getLoginTokenKVV() != null && mLogin.getLoginTokenKVV().isOtherUser(mModules.getUsername()) &&
mLogin.getLoginTokenBB() != null && mLogin.getLoginTokenBB().isOtherUser(mModules.getUsername())
)
delete();
if (retries < 0) {
errorCallback.onError(new NetworkError(101107, -1, "Too many retries!"));
@@ -114,7 +119,10 @@ public class ModulesList extends HTTPService {
}
private void recv(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh, final int retries) {
if (mModules != null && mLogin.getLoginToken() != null && mLogin.getLoginToken().isOtherUser(mModules.getUsername()))
if (mModules != null &&
mLogin.getLoginTokenKVV() != null && mLogin.getLoginTokenKVV().isOtherUser(mModules.getUsername()) &&
mLogin.getLoginTokenBB() != null && mLogin.getLoginTokenBB().isOtherUser(mModules.getUsername())
)
delete();
mQueue.add(() -> {
if (this.mModules != null && !forceRefresh) {
@@ -122,19 +130,10 @@ public class ModulesList extends HTTPService {
mQueue.next();
return;
}
this.upgrade(success -> {
if (this.mModules == null)
this.mModules = success;
else if(this.mModules.updateList(success)) {
mListener.onModuleListChange();
store();
}
callback.onResponse(this.mModules);
mQueue.next();
}, error -> {
NetworkErrorCallback errorFunc = (error -> {
if (retries > 0 && (error.getHttpStatus() == 401 || error.getHttpStatus() == 403)) {
mLogin.refreshLogin(success -> {
recv(callback, errorCallback, forceRefresh, retries-1);
recv(callback, errorCallback, forceRefresh, retries - 1);
mQueue.next();
}, error1 -> {
errorCallback.onError(error1);
@@ -145,28 +144,40 @@ public class ModulesList extends HTTPService {
errorCallback.onError(error);
mQueue.next();
});
this.upgradeKVV(successKVV -> {
this.upgradeBlackboard(successKVV, success -> {
if (this.mModules == null)
this.mModules = success;
else if (this.mModules.updateList(success)) {
mListener.onModuleListChange();
store();
}
callback.onResponse(this.mModules);
mQueue.next();
}, errorFunc);
}, errorFunc);
});
}
private void upgrade(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
errorCallback.onError(new NetworkError(101105, 500, "Currently running in offline mode!"));
private void upgradeKVV(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101110, 500, "Currently running in offline mode!"));
return;
}
get("https://kvv.imp.fu-berlin.de/direct/site.json", mLogin.getLoginToken().getCookies(), response -> {
get("https://kvv.imp.fu-berlin.de/direct/site.json", mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101101, 403, "No module list retrieved!"));
errorCallback.onError(new NetworkError(101111, 403, "No module list retrieved!"));
return;
}
Modules modules = new Modules(mLogin.getLoginToken().getUsername());
Modules modules = new Modules(mLogin.getLoginTokenKVV().getUsername());
JSONArray sites;
try {
JSONObject json = new JSONObject(body);
sites = json.getJSONArray("site_collection");
} catch (JSONException e) {
e.printStackTrace();
errorCallback.onError(new NetworkError(101102, 403, "Cannot parse module list!"));
errorCallback.onError(new NetworkError(101112, 403, "Cannot parse module list!"));
return;
}
for (int i = 0; i < sites.length(); i++) {
@@ -192,13 +203,13 @@ public class ModulesList extends HTTPService {
String description = site.optString("description", "");
description = String.valueOf(PartModules.fromHtml(description));
String id = site.getString("id");
modules.addModule(semester, lvNumbers, title, lecturers, type, description, id);
modules.addModule(semester, lvNumbers, title, lecturers, type, description, id, Modules.TYPE_KVV);
} catch (JSONException e) {
log.e(new NetworkError(101103, 403, "Cannot parse module list!"));
log.e(new NetworkError(101113, 403, "Cannot parse module list!"));
log.e("ID:", i, "JSON:", sites);
e.printStackTrace();
} catch (NoSuchFieldException e) {
log.e(new NetworkError(101106, 403, "Cannot parse module list!"));
log.e(new NetworkError(101114, 403, "Cannot parse module list!"));
log.e("ID:", i, "JSON:", sites);
e.printStackTrace();
}
@@ -208,6 +219,76 @@ public class ModulesList extends HTTPService {
mLogin.testLoginToken(token -> callback.onResponse(modules), errorCallback);
else
callback.onResponse(modules);
}, error -> errorCallback.onError(new NetworkError(101104, error.networkResponse.statusCode, "Cannot get module list!")));
}, error -> errorCallback.onError(new NetworkError(101115, error.networkResponse.statusCode, "Cannot get module list!")));
}
private void upgradeBlackboard(final Modules modulesKVV, final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null) {
errorCallback.onError(new NetworkError(101120, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://lms.fu-berlin.de/learn/api/public/v1/users/%s/courses", mLogin.getLoginTokenBB().getId()), mLogin.getLoginTokenBB().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101121, 403, "No module list retrieved!"));
return;
}
final JSONArray[] sites = new JSONArray[1];
try {
JSONObject json = new JSONObject(body);
sites[0] = json.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
errorCallback.onError(new NetworkError(101122, 403, "Cannot parse module list!"));
return;
}
final int[] latch = {sites[0].length()};
for (int i = 0; i < sites[0].length(); i++) {
try {
JSONObject site = sites[0].getJSONObject(i);
String courseId = site.getString("courseId");
get(String.format("https://lms.fu-berlin.de/learn/api/v1/courses/%s", courseId), mLogin.getLoginTokenBB().getCookies(), response1 -> {
String body1 = response1.getParsed();
if (body1 == null) {
errorCallback.onError(new NetworkError(101124, 403, "No module list retrieved!"));
return;
}
try {
JSONObject json = new JSONObject(body1);
String name = json.getString("name");
String type = Regex.regex("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]*)([A-Z]*)", json.getString("courseId"), 1);
String lvNumber = Regex.regex("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]*)([A-Z]*)", json.getString("courseId"), 2);
String semYear = Regex.regex("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]*)([A-Z]*)", json.getString("courseId"), 3);
String semType = Regex.regex("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]*)([A-Z]*)", json.getString("courseId"), 4);
boolean found = false;
for (Modules.Module module: modulesKVV) {
if (module.lvNumber.contains(lvNumber)) {
found = true;
break;
}
}
if (!found)
modulesKVV.addModule(new Semester(semType.equals("W") ? Semester.SEM_WS : Semester.SEM_SS, Integer.valueOf(semYear)), new HashSet<>(), name, new LinkedHashSet<>(), type, "", courseId, Modules.TYPE_BB);
latch[0]--;
if (latch[0] == 0)
callback.onResponse(modulesKVV);
} catch (JSONException e) {
e.printStackTrace();
errorCallback.onError(new NetworkError(101125, 403, "Cannot parse module list!"));
return;
} catch (NoSuchFieldException e) {
e.printStackTrace();
errorCallback.onError(new NetworkError(101127, 403, "Cannot parse module list!"));
return;
}
}, error -> errorCallback.onError(new NetworkError(101126, error.networkResponse.statusCode, "Cannot get module list!")));
} catch (JSONException e) {
log.e(new NetworkError(101123, 403, "Cannot parse module list!"));
log.e("ID:", i, "JSON:", sites[0]);
e.printStackTrace();
}
}
}, error -> errorCallback.onError(new NetworkError(101125, error.networkResponse.statusCode, "Cannot get module list!")));
}
}

View File

@@ -42,12 +42,12 @@ public class ModulesResources extends PartModules<ArrayList<Resource>> {
}
@Override
protected void upgrade(final String ID, final NetworkCallback<ArrayList<Resource>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
protected void upgradeKVV(final String ID, final NetworkCallback<ArrayList<Resource>> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101604, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/content/site/%s.json", ID), mLogin.getLoginToken().getCookies(), response -> {
get(String.format("https://kvv.imp.fu-berlin.de/direct/content/site/%s.json", ID), mLogin.getLoginTokenKVV().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101601, 403, "No resources retrieved!"));
@@ -124,6 +124,10 @@ public class ModulesResources extends PartModules<ArrayList<Resource>> {
}, error -> errorCallback.onError(new NetworkError(101603, error.networkResponse.statusCode, "Cannot get resources!")));
}
@Override
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Resource>> callback, NetworkErrorCallback errorCallback) {
callback.onResponse(new ArrayList<>());
}
@@ -160,11 +164,11 @@ public class ModulesResources extends PartModules<ArrayList<Resource>> {
}
private void fileUpgrade(String filename, String url, String modulename, final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginToken() == null) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) {
errorCallback.onError(new NetworkError(101604, 500, "Currently running in offline mode!"));
return;
}
get(url, mLogin.getLoginToken().getCookies(), response -> {
get(url, mLogin.getLoginTokenKVV().getCookies(), response -> {
if (Regex.has("\\.[Uu][Rr][Ll]$", url)){
// Return redirected URL
String path = response.getHeaders().get("Location");

View File

@@ -25,7 +25,7 @@ abstract class PartModules<T> extends Part<Modules.Module> {
mQueue.next();
return;
}
upgrade(module.getID(), success -> {
upgrade(module.getModuleType(), module.getID(), success -> {
if (setPart(module, success)) {
this.mList.store();
}
@@ -61,5 +61,18 @@ abstract class PartModules<T> extends Part<Modules.Module> {
protected abstract boolean setPart(Modules.Module module, T part);
protected abstract void upgrade(final String ID, final NetworkCallback<T> callback, final NetworkErrorCallback errorCallback);
protected void upgrade(final int moduleType, final String ID, final NetworkCallback<T> callback, final NetworkErrorCallback errorCallback) {
switch (moduleType) {
case Modules.TYPE_KVV:
upgradeKVV(ID, callback, errorCallback);
break;
case Modules.TYPE_BB:
upgradeBB(ID, callback, errorCallback);
break;
}
}
protected abstract void upgradeKVV(final String ID, final NetworkCallback<T> callback, final NetworkErrorCallback errorCallback);
protected abstract void upgradeBB(final String ID, final NetworkCallback<T> callback, final NetworkErrorCallback errorCallback);
}

View File

@@ -0,0 +1,266 @@
package de.sebse.fuplanner.services.kvv.sync;
import android.content.Context;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.sebse.fuplanner.services.kvv.types.LoginTokenBB;
import de.sebse.fuplanner.tools.network.HTTPService;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
public class BBLogin extends HTTPService {
public BBLogin(Context context) {
super(context);
}
public void testLoginToken(@NotNull LoginTokenBB token, @NotNull NetworkCallback<LoginTokenBB> callback, @NotNull NetworkErrorCallback errorCallback) {
get(String.format("https://lms.fu-berlin.de/learn/api/public/v1/users/?userName=%s", token.getUsername()), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(100272, 403, "Testing login failed!"));
return;
}
try {
JSONObject json = new JSONObject(body);
json = json.getJSONArray("results").getJSONObject(0);
String id = json.getString("id");
String studentId = json.getString("studentId");
token.setAdditionals(id, studentId);
callback.onResponse(token);
} catch (JSONException e) {
errorCallback.onError(new NetworkError(100271, 403, "Cannot parse profile!"));
}
}, error -> errorCallback.onError(new NetworkError(100270, error.networkResponse.statusCode, "Testing login failed!")));
}
public void doLogin(String username, String password, NetworkCallback<LoginTokenBB> callback, NetworkErrorCallback error) {
step1(success1 -> {
String samlLocation = success1.get("Location");
step2(samlLocation, success2 -> {
String fuJSESSIONID = success2.get("JSESSIONID");
step3(fuJSESSIONID, success3 -> {
step4(username, password, fuJSESSIONID, success4 -> {
String samlResponse = success4.get("SAMLResponse");
step5(samlResponse, success5 -> {
String shibsessionKey = success5.get("shibsessionKey");
String shibsessionName = success5.get("shibsessionName");
step6(shibsessionKey, shibsessionName, success6 -> {
String s_session_id = success6.get("s_session_id");
String session_id = success6.get("session_id");
LoginTokenBB token = new LoginTokenBB(username, s_session_id, session_id);
callback.onResponse(token);
}, error);
}, error);
}, error);
}, error);
}, error);
}, error);
}
/*
1= GET https://lms.fu-berlin.de/lms-apps/login/sso/index.php
-> Location-Header: https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?SAMLResponse=[SAMLResponse]&RelayState=[RelayState]
*/
private void step1(final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
get("https://lms.fu-berlin.de/lms-apps/login/sso/index.php", null, response -> {
String location = response.getHeaders().get("Location");
if (location==null) {
errorCallback.onError(new NetworkError(100211, -1, "Error on getting SAML request!"));
return;
}
HashMap<String, String> object = new HashMap<>();
object.put("Location", location);
callback.onResponse(object);
}, error -> errorCallback.onError(new NetworkError(100210, error.networkResponse.statusCode, "Error on getting SAML request!")));
}
/*
2= GET [Location-Header 1]
-> Set-Cookie: JSESSIONID=[JSESSION-FU]
-> Location: /idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1
*/
private void step2(String url, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
get(url, null, response -> {
String cookies = response.getHeaders().get("Set-Cookie");
if (cookies==null) {
errorCallback.onError(new NetworkError(100221, -1, "Error on starting FU session!"));
return;
}
HashMap<String, String> object;
try {
object = getCookie(cookies, new String[]{"JSESSIONID"});
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(100222, -1, "Error on starting FU session!"));
return;
}
callback.onResponse(object);
}, error -> errorCallback.onError(new NetworkError(100220, error.networkResponse.statusCode, "Error on starting FU session!")));
}
/*
3= GET [Location-Header 2]
+ Cookie: JSESSIONID=[JSESSION-FU]
*/
private void step3(String JSESSIONID_FU, final NetworkCallback<Boolean> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> cookies = new HashMap<>();
cookies.put("JSESSIONID", JSESSIONID_FU);
head("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1", cookies, response -> {
callback.onResponse(true);
}, error -> errorCallback.onError(new NetworkError(100230, error.networkResponse.statusCode, "Error starting login page!")));
}
/*
4= POST [Location-Header 2]
+ Body: j_username=[USERNAME]&j_password=[PASSWORD]&_eventId_proceed=
+ Header: Content-Type: application/x-www-form-urlencoded
+ Header: Referer: [Location-Header 2]
+ Cookie: JSESSIONID=[JSESSION-FU]
-> Set-Cookie: shib_idp_session=[SHIB-IDP-SESSION]
-> Body SAMLResponse-Input-value
*/
private void step4(String username, String password, String JSESSIONID_FU, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> cookies = new HashMap<>();
cookies.put("JSESSIONID", JSESSIONID_FU);
HashMap<String, String> body = new HashMap<>();
body.put("j_username", username);
body.put("j_password", password);
body.put("_eventId_proceed", "");
post("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1", cookies, body, response -> {
String cookies1 = response.getHeaders().get("Set-Cookie");
if (cookies1 ==null) {
errorCallback.onError(new NetworkError(100241, -1, "Error on logging in to FU Identity Server!"));
return;
}
HashMap<String, String> object;
try {
object = getCookie(cookies1, new String[]{"shib_idp_session"});
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(100242, -1, "Error on logging in to FU Identity Server!"));
return;
}
String content = response.getParsed();
if (content == null) {
errorCallback.onError(new NetworkError(100243, -1, "Error on getting SAML response!"));
return;
}
Pattern pattern = Pattern.compile("name=\"SAMLResponse\" value=\"([0-9a-zA-Z+]+=*)");
Matcher matcher = pattern.matcher(content);
if (!matcher.find()) {
errorCallback.onError(new NetworkError(100244, -1, "Error on getting SAML response!"));
return;
}
object.put("SAMLResponse", matcher.group(1));
callback.onResponse(object);
}, error -> errorCallback.onError(new NetworkError(100245, error.networkResponse.statusCode, "Error on logging in to FU Identity Server!")));
}
/*
5= POST https://lms.fu-berlin.de/Shibboleth.sso/SAML2/POST
+ Body: SAMLResponse=[SAML-RESPONSE]
+ Header: Content-Type: application/x-www-form-urlencoded
-> Set-Cookie: _shibsession_[SESS-NR]: [SESS-VALUE]
*/
private void step5(String SAMLResponse, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> body = new HashMap<>();
body.put("SAMLResponse", SAMLResponse);
post("https://lms.fu-berlin.de/Shibboleth.sso/SAML2/POST", null, body, response -> {
String cookies = response.getHeaders().get("Set-Cookie");
if (cookies ==null) {
errorCallback.onError(new NetworkError(100251, -1, "Error on starting KVV session!"));
return;
}
HashMap<String, String> object = new HashMap<>();
Pattern pattern = Pattern.compile("(_shibsession_[0-9a-f]+)=([^;]+);");
Matcher matcher = pattern.matcher(cookies);
if (!matcher.find()) {
errorCallback.onError(new NetworkError(100252, -1, "Error on starting KVV session!"));
}
object.put("shibsessionKey", matcher.group(1));
object.put("shibsessionName", matcher.group(2));
callback.onResponse(object);
}, error -> errorCallback.onError(new NetworkError(100250, error.networkResponse.statusCode, "Error on starting KVV session!")));
}
/*
6= https://lms.fu-berlin.de/webapps/bb-auth-provider-shibboleth-bb_bb60/execute/shibbolethLogin?returnUrl=https://lms.fu-berlin.de/webapps/portal/execute/defaultTab&authProviderId=_3_1
+ Cookie: _shibsession_[SESS-NR]: [SESS-VALUE]
-> Set-Cookie: JSESSIONID: [JSESSION-KVV]
*/
private void step6(String shibsessionKey, String shibsessionName, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> cookies = new HashMap<>();
cookies.put(shibsessionKey, shibsessionName);
log.d(shibsessionKey, shibsessionName);
get("https://lms.fu-berlin.de/webapps/bb-auth-provider-shibboleth-bb_bb60/execute/shibbolethLogin?returnUrl=https://lms.fu-berlin.de/webapps/portal/execute/defaultTab&authProviderId=_3_1", cookies, response -> {
String cookies1 = response.getHeaders().get("Set-Cookie");
if (cookies1 ==null) {
errorCallback.onError(new NetworkError(100261, -1, "Cannot finish login process!"));
return;
}
HashMap<String, String> object;
try {
object = getCookie(cookies1, new String[]{"session_id", "s_session_id"});
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(100262, -1, "Cannot finish login process!"));
return;
}
callback.onResponse(object);
}, error -> errorCallback.onError(new NetworkError(100260, error.networkResponse.statusCode, "Cannot finish login process!")));
}
private String getCookie(String cookies, String name) throws NoSuchFieldException {
Pattern pattern = Pattern.compile(name+"=([^;]+);");
Matcher matcher = pattern.matcher(cookies);
if (!matcher.find()) {
log.e("GETcookie failed", name);
log.e("GETcookie failed", cookies);
throw new NoSuchFieldException();
}
return matcher.group(1);
}
private HashMap<String, String> getCookie(String cookies, String[] names) throws NoSuchFieldException {
HashMap<String, String> result = new HashMap<>();
for (String name: names) {
result.put(name,this.getCookie(cookies, name));
}
return result;
}
}

View File

@@ -10,19 +10,19 @@ import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.sebse.fuplanner.services.kvv.types.LoginToken;
import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV;
import de.sebse.fuplanner.tools.network.HTTPService;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
public class Login extends HTTPService {
public Login(Context context) {
public class KVVLogin extends HTTPService {
public KVVLogin(Context context) {
super(context);
}
public void testLoginToken(@NotNull LoginToken token, @NotNull NetworkCallback<LoginToken> callback, @NotNull NetworkErrorCallback errorCallback) {
public void testLoginToken(@NotNull LoginTokenKVV token, @NotNull NetworkCallback<LoginTokenKVV> callback, @NotNull NetworkErrorCallback errorCallback) {
get(String.format("https://kvv.imp.fu-berlin.de/direct/profile/%s.json", token.getUsername()), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -55,7 +55,7 @@ public class Login extends HTTPService {
public void doLogin(String username, String password, NetworkCallback<LoginToken> callback, NetworkErrorCallback error) {
public void doLogin(String username, String password, NetworkCallback<LoginTokenKVV> callback, NetworkErrorCallback error) {
step1(success1 -> {
String samlLocation = success1.get("Location");
step2(samlLocation, success2 -> {
@@ -68,7 +68,7 @@ public class Login extends HTTPService {
String shibsessionName = success5.get("shibsessionName");
step6(shibsessionKey, shibsessionName, success6 -> {
String kvvJSESSIONID = success6.get("JSESSIONID");
LoginToken token = new LoginToken(username, kvvJSESSIONID);
LoginTokenKVV token = new LoginTokenKVV(username, kvvJSESSIONID);
callback.onResponse(token);
}, error);
}, error);
@@ -80,7 +80,7 @@ public class Login extends HTTPService {
/*
1= GET https://kvv.imp.fu-berlin.de/Shibboleth.sso/Login?entityID=https://identity.fu-berlin.de/idp-fub
-> Location-Header: https://identity.fu-berlin.de:9443/idp-fub-qa/profile/SAML2/Redirect/SSO?SAMLResponse=[SAMLResponse]&RelayState=[RelayState]
-> Location-Header: https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?SAMLResponse=[SAMLResponse]&RelayState=[RelayState]
*/
private void step1(final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
get("https://kvv.imp.fu-berlin.de/Shibboleth.sso/Login?entityID=https://identity.fu-berlin.de/idp-fub", null, response -> {
@@ -98,7 +98,7 @@ public class Login extends HTTPService {
/*
2= GET [Location-Header 1]
-> Set-Cookie: JSESSIONID=[JSESSION-FU]
-> Location: /idp-fub-qa/profile/SAML2/Redirect/SSO?execution=e1s1
-> Location: /idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1
*/
private void step2(String url, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
get(url, null, response -> {
@@ -125,7 +125,7 @@ public class Login extends HTTPService {
private void step3(String JSESSIONID_FU, final NetworkCallback<Boolean> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> cookies = new HashMap<>();
cookies.put("JSESSIONID", JSESSIONID_FU);
get("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1", cookies, response -> {
head("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO?execution=e1s1", cookies, response -> {
callback.onResponse(true);
}, error -> errorCallback.onError(new NetworkError(100130, error.networkResponse.statusCode, "Error starting login page!")));
}

View File

@@ -0,0 +1,133 @@
package de.sebse.fuplanner.services.kvv.types;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
import de.sebse.fuplanner.tools.CustomAccountManager;
/**
* Created by sebastian on 29.10.17.
*/
public class LoginTokenBB {
private final String s_session_id;
private final String session_id;
private final String username;
@Nullable private String id;
@Nullable private String studentId;
public LoginTokenBB(String username, String s_session_id, String session_id) {
this.username = username;
this.s_session_id = s_session_id;
this.session_id = session_id;
}
public static void load(CustomAccountManager manager, LoginTokenInterface callback) {
if (!manager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) {
callback.run(null);
return;
}
manager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD, tokenString -> {
if (tokenString == null) {
callback.run(null);
return;
}
callback.run(LoginTokenBB.fromJsonString(tokenString));
});
}
public void delete(CustomAccountManager manager) {
manager.deleteAccount(AccountGeneral.ACCOUNT_TYPE);
}
public void setAdditionals(String id, String studentId) {
this.id = id;
this.studentId = studentId;
}
public String getUsername() {
return username;
}
private String getSessionId() {
return session_id;
}
public String getSSessionId() {
return s_session_id;
}
@Nullable
public String getId() {
return id;
}
@Nullable
public String getStudentId() {
return studentId;
}
public HashMap<String, String> getCookies() {
HashMap<String, String> cookies = new HashMap<>();
cookies.put("session_id", getSessionId());
cookies.put("s_session_id", getSSessionId());
return cookies;
}
public boolean isOtherUser(String username) {
return !this.getUsername().equals(username);
}
@NonNull
@Override
public String toString() {
StringBuilder result = new StringBuilder();
HashMap<String, String> cookies = this.getCookies();
for (String header: cookies.keySet()) {
result.append(header).append("=").append(cookies.get(header)).append(";");
}
return result.substring(0, result.length()-1);
}
public String toJsonString() {
JSONObject json = new JSONObject();
try {
json.put("s_session_id", s_session_id);
json.put("session_id", session_id);
json.put("username", username);
json.put("id", id);
json.put("studentId", studentId);
} catch (JSONException e) {
return null;
}
return json.toString();
}
private static LoginTokenBB fromJsonString(String tokenString) {
try {
JSONObject json = new JSONObject(tokenString);
LoginTokenBB token = new LoginTokenBB(
json.getString("username"),
json.getString("s_session_id"),
json.getString("session_id"));
if (!json.isNull("id"))
token.setAdditionals(
json.getString("id"),
json.getString("studentId")
);
return token;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public interface LoginTokenInterface {
void run(LoginTokenBB token);
}
}

View File

@@ -3,26 +3,24 @@ package de.sebse.fuplanner.services.kvv.types;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.util.HashMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
import de.sebse.fuplanner.tools.CustomAccountManager;
import de.sebse.fuplanner.tools.logging.Logger;
/**
* Created by sebastian on 29.10.17.
*/
public class LoginToken implements Serializable {
public class LoginTokenKVV {
private final String username;
private final String JSESSIONID;
@Nullable private String fullName;
@Nullable private String email;
public LoginToken(String username, String JSESSIONID) {
public LoginTokenKVV(String username, String JSESSIONID) {
this.username = username;
this.JSESSIONID = JSESSIONID;
}
@@ -37,7 +35,7 @@ public class LoginToken implements Serializable {
callback.run(null);
return;
}
callback.run(LoginToken.fromJsonString(tokenString));
callback.run(LoginTokenKVV.fromJsonString(tokenString));
});
}
@@ -103,10 +101,10 @@ public class LoginToken implements Serializable {
return json.toString();
}
private static LoginToken fromJsonString(String tokenString) {
private static LoginTokenKVV fromJsonString(String tokenString) {
try {
JSONObject json = new JSONObject(tokenString);
LoginToken token = new LoginToken(
LoginTokenKVV token = new LoginTokenKVV(
json.getString("username"),
json.getString("JSESSIONID"));
if (!json.isNull("fullName"))
@@ -122,6 +120,6 @@ public class LoginToken implements Serializable {
}
public interface LoginTokenInterface {
void run(LoginToken token);
void run(LoginTokenKVV token);
}
}

View File

@@ -25,6 +25,9 @@ import androidx.annotation.Nullable;
*/
public class Modules implements Iterable<Modules.Module>, Serializable {
public static final int TYPE_KVV = 1;
public static final int TYPE_BB = 2;
private SortedListModule list;
private final String mUsername;
private transient long mLastTimestamp = 0;
@@ -37,8 +40,8 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
this.list = new SortedListModule();
}
public void addModule(@Nullable Semester semester, HashSet<String> lvNumber, String title, LinkedHashSet<Lecturer> lecturer, String type, String description, String ID) {
Module m = new Module(semester, lvNumber, title, lecturer, type, description, ID);
public void addModule(@Nullable Semester semester, HashSet<String> lvNumber, String title, LinkedHashSet<Lecturer> lecturer, String type, String description, String ID, int moduleType) {
Module m = new Module(semester, lvNumber, title, lecturer, type, description, ID, moduleType);
this.list.add(m);
}
@@ -154,14 +157,16 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
}
public class Module implements Serializable {
@Nullable public final Semester semester;
@NotNull final HashSet<String> lvNumber;
@NotNull public final HashSet<String> lvNumber;
@NotNull public final String title;
@NotNull
public final ArrayList<Lecturer> lecturer;
@Nullable public final String type;
@Nullable public final String description;
@NotNull private final String ID;
@NotNull private final int moduleType;
@Nullable public ArrayList<Announcement> announcements;
@Nullable public AssignmentList assignments;
@Nullable public EventList events;
@@ -182,7 +187,7 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
return userPoint/maxPoint;
}
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull LinkedHashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID) {
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull LinkedHashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID, @NotNull int moduleType) {
title = title.replaceAll("(.*?) (S[0-9]{2}|W[0-9/]{5})", "$1");
@@ -193,6 +198,7 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
this.type = type;
this.description = description;
this.ID = ID;
this.moduleType = moduleType;
}
@NonNull
@@ -213,7 +219,11 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
@Override
public int hashCode() {
return Objects.hashCode(semester, lvNumber, title, lecturer, type, description, ID);
return Objects.hashCode(semester, lvNumber, title, lecturer, type, description, ID, moduleType);
}
public int getModuleType() {
return moduleType;
}
}
}

View File

@@ -52,8 +52,17 @@ public class HTTPService {
successResponseListener.remove(id);
}
protected void head(String url, @Nullable final HashMap<String, String> cookies, Response.Listener<Result> response, Response.ErrorListener error) {
get(url, cookies, response, error, true);
}
protected void get(String url, @Nullable final HashMap<String, String> cookies, Response.Listener<Result> response, Response.ErrorListener error) {
HttpRequest request = new HttpRequest(Request.Method.GET, url, response, error) {
get(url, cookies, response, error, false);
}
protected void get(String url, @Nullable final HashMap<String, String> cookies, Response.Listener<Result> response, Response.ErrorListener error, boolean noBody) {
int requestMethod = noBody ? Request.Method.HEAD : Request.Method.GET;
HttpRequest request = new HttpRequest(requestMethod, url, response, error) {
@Override
public void deliverError(VolleyError error) {
if (error == null) {