mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-11 05:00:46 +02:00
[Login/Librus] Implement Librus JST login form.
This commit is contained in:
@ -148,16 +148,16 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
*/
|
||||
private var mApiCode: String? = null
|
||||
var apiCode: String?
|
||||
get() { mApiCode = mApiCode ?: profile?.getStudentData("accountCode", null); return mApiCode }
|
||||
set(value) { profile?.putStudentData("accountCode", value) ?: return; mApiCode = value }
|
||||
get() { mApiCode = mApiCode ?: loginStore.getLoginData("accountCode", null); return mApiCode }
|
||||
set(value) { loginStore.putLoginData("accountCode", value) ?: return; mApiCode = value }
|
||||
/**
|
||||
* A JST login PIN.
|
||||
* Used only during first login in JST mode.
|
||||
*/
|
||||
private var mApiPin: String? = null
|
||||
var apiPin: String?
|
||||
get() { mApiPin = mApiPin ?: profile?.getStudentData("accountPin", null); return mApiPin }
|
||||
set(value) { profile?.putStudentData("accountPin", value) ?: return; mApiPin = value }
|
||||
get() { mApiPin = mApiPin ?: loginStore.getLoginData("accountPin", null); return mApiPin }
|
||||
set(value) { loginStore.putLoginData("accountPin", value) ?: return; mApiPin = value }
|
||||
|
||||
/**
|
||||
* A Synergia API access token.
|
||||
@ -168,7 +168,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
private var mApiAccessToken: String? = null
|
||||
var apiAccessToken: String?
|
||||
get() { mApiAccessToken = mApiAccessToken ?: profile?.getStudentData("accountToken", null); return mApiAccessToken }
|
||||
set(value) { profile?.putStudentData("accountToken", value) ?: return; mApiAccessToken = value }
|
||||
set(value) { mApiAccessToken = value; profile?.putStudentData("accountToken", value) ?: return; }
|
||||
/**
|
||||
* A Synergia API refresh token.
|
||||
* Used when refreshing the [apiAccessToken] in JST, Synergia modes.
|
||||
@ -176,7 +176,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
private var mApiRefreshToken: String? = null
|
||||
var apiRefreshToken: String?
|
||||
get() { mApiRefreshToken = mApiRefreshToken ?: profile?.getStudentData("accountRefreshToken", null); return mApiRefreshToken }
|
||||
set(value) { profile?.putStudentData("accountRefreshToken", value) ?: return; mApiRefreshToken = value }
|
||||
set(value) { mApiRefreshToken = value; profile?.putStudentData("accountRefreshToken", value) ?: return; }
|
||||
/**
|
||||
* The expiry time for [apiAccessToken], as a UNIX timestamp.
|
||||
* Used when refreshing the [apiAccessToken] in JST, Synergia modes.
|
||||
@ -185,7 +185,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
private var mApiTokenExpiryTime: Long? = null
|
||||
var apiTokenExpiryTime: Long
|
||||
get() { mApiTokenExpiryTime = mApiTokenExpiryTime ?: profile?.getStudentData("accountTokenTime", 0L); return mApiTokenExpiryTime ?: 0L }
|
||||
set(value) { profile?.putStudentData("accountTokenTime", value) ?: return; mApiTokenExpiryTime = value }
|
||||
set(value) { mApiTokenExpiryTime = value; profile?.putStudentData("accountTokenTime", value) ?: return; }
|
||||
|
||||
/* _____ _
|
||||
/ ____| (_)
|
||||
|
@ -85,6 +85,36 @@ class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||
LibrusLoginApi(data) {
|
||||
api.apiGet(TAG, "Me") { json ->
|
||||
|
||||
val profile = Profile()
|
||||
|
||||
val me = json.getJsonObject("Me")
|
||||
val account = me?.getJsonObject("Account")
|
||||
val user = me?.getJsonObject("User")
|
||||
|
||||
profile.putStudentData("isPremium", account?.getBoolean("IsPremium") == true || account?.getBoolean("IsPremiumDemo") == true)
|
||||
|
||||
val isParent = account?.getInt("GroupId") == 5
|
||||
profile.accountNameLong =
|
||||
if (isParent)
|
||||
buildFullName(account?.getString("FirstName"), account?.getString("LastName"))
|
||||
else null
|
||||
|
||||
profile.studentNameLong =
|
||||
buildFullName(user?.getString("FirstName"), user?.getString("LastName"))
|
||||
|
||||
profile.studentNameShort = profile.studentNameLong?.getShortName()
|
||||
profile.name = profile.studentNameLong
|
||||
profile.subname = account.getString("Login")
|
||||
profile.empty = true
|
||||
profile.putStudentData("accountId", account.getInt("Id") ?: 0)
|
||||
profile.putStudentData("accountLogin", profile.subname)
|
||||
profile.putStudentData("accountToken", data.apiAccessToken)
|
||||
profile.putStudentData("accountRefreshToken", data.apiRefreshToken)
|
||||
profile.putStudentData("accountTokenTime", data.apiTokenExpiryTime)
|
||||
profileList.add(profile)
|
||||
|
||||
EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore))
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||
AttendanceType.class,
|
||||
pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson.class,
|
||||
ConfigEntry.class,
|
||||
Metadata.class}, version = 68)
|
||||
Metadata.class}, version = 69)
|
||||
@TypeConverters({
|
||||
ConverterTime.class,
|
||||
ConverterDate.class,
|
||||
@ -823,6 +823,12 @@ public abstract class AppDb extends RoomDatabase {
|
||||
database.execSQL("DELETE FROM metadata WHERE thingType=7");
|
||||
}
|
||||
};
|
||||
private static final Migration MIGRATION_68_69 = new Migration(68, 69) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("ALTER TABLE loginStores ADD COLUMN loginStoreMode INTEGER NOT NULL DEFAULT 0");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static AppDb getDatabase(final Context context) {
|
||||
@ -888,7 +894,8 @@ public abstract class AppDb extends RoomDatabase {
|
||||
MIGRATION_64_65,
|
||||
MIGRATION_65_66,
|
||||
MIGRATION_66_67,
|
||||
MIGRATION_67_68
|
||||
MIGRATION_67_68,
|
||||
MIGRATION_68_69
|
||||
)
|
||||
.allowMainThreadQueries()
|
||||
//.fallbackToDestructiveMigration()
|
||||
|
@ -5,7 +5,6 @@ import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
@ -28,7 +27,7 @@ public class LoginStore {
|
||||
@ColumnInfo(name = "loginStoreData")
|
||||
public JsonObject data;
|
||||
|
||||
@Ignore
|
||||
@ColumnInfo(name = "loginStoreMode")
|
||||
public int mode = 0;
|
||||
public static final int LOGIN_MODE_LIBRUS_EMAIL = 0;
|
||||
public static final int LOGIN_MODE_LIBRUS_SYNERGIA = 1;
|
||||
|
@ -51,6 +51,7 @@ public class LoginChooserFragment extends Fragment {
|
||||
|
||||
b.loginMobidziennikLogo.setOnClickListener((v) -> nav.navigate(R.id.loginMobidziennikFragment, null, LoginActivity.navOptions));
|
||||
b.loginLibrusLogo.setOnClickListener((v) -> nav.navigate(R.id.loginLibrusFragment, null, LoginActivity.navOptions));
|
||||
b.loginLibrusJstLogo.setOnClickListener((v) -> nav.navigate(R.id.loginLibrusJstFragment, null, LoginActivity.navOptions));
|
||||
b.loginVulcanLogo.setOnClickListener((v) -> nav.navigate(R.id.loginVulcanFragment, null, LoginActivity.navOptions));
|
||||
b.loginIuczniowieLogo.setOnClickListener((v) -> nav.navigate(R.id.loginIuczniowieFragment, null, LoginActivity.navOptions));
|
||||
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-12-13.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.login;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentLoginLibrusJstBinding;
|
||||
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.api.v2.ErrorsKt.ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN;
|
||||
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_MODE_LIBRUS_JST;
|
||||
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_LIBRUS;
|
||||
|
||||
public class LoginLibrusJstFragment extends Fragment {
|
||||
|
||||
private App app;
|
||||
private NavController nav;
|
||||
private FragmentLoginLibrusJstBinding b;
|
||||
private static final String TAG = "LoginLibrus";
|
||||
private ErrorSnackbar errorSnackbar;
|
||||
|
||||
public LoginLibrusJstFragment() { }
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
if (getActivity() != null) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
|
||||
errorSnackbar = ((LoginActivity) getActivity()).errorSnackbar;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_login_librus_jst, container, false);
|
||||
return b.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
assert getContext() != null;
|
||||
assert getActivity() != null;
|
||||
|
||||
view.postDelayed(() -> {
|
||||
ApiError error = LoginActivity.error;
|
||||
if (error != null) {
|
||||
switch (error.getErrorCode()) {
|
||||
case ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN:
|
||||
b.loginCodeLayout.setError(getString(R.string.login_error_incorrect_code_or_pin));
|
||||
break;
|
||||
}
|
||||
errorSnackbar.addError(error).show();
|
||||
LoginActivity.error = null;
|
||||
}
|
||||
}, 100);
|
||||
|
||||
b.helpButton.setOnClickListener((v) -> nav.navigate(R.id.loginLibrusHelpFragment, null, LoginActivity.navOptions));
|
||||
b.backButton.setOnClickListener((v) -> nav.navigateUp());
|
||||
|
||||
b.loginButton.setOnClickListener((v) -> {
|
||||
boolean errors = false;
|
||||
|
||||
b.loginCodeLayout.setError(null);
|
||||
b.loginPinLayout.setError(null);
|
||||
|
||||
Editable codeEditable = b.loginCode.getText();
|
||||
Editable pinEditable = b.loginPin.getText();
|
||||
if (codeEditable == null || codeEditable.length() == 0) {
|
||||
b.loginCodeLayout.setError(getString(R.string.login_error_no_code));
|
||||
errors = true;
|
||||
}
|
||||
if (pinEditable == null || pinEditable.length() == 0) {
|
||||
b.loginPinLayout.setError(getString(R.string.login_error_no_pin));
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return;
|
||||
errors = false;
|
||||
|
||||
String code = codeEditable.toString().toUpperCase();
|
||||
String pin = pinEditable.toString();
|
||||
b.loginCode.setText(code);
|
||||
if (!code.matches("[A-Z0-9_]+")) {
|
||||
b.loginCodeLayout.setError(getString(R.string.login_error_incorrect_code));
|
||||
errors = true;
|
||||
}
|
||||
if (!pin.matches("[a-z0-9_]+")) {
|
||||
b.loginPinLayout.setError(getString(R.string.login_error_incorrect_pin));
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return;
|
||||
errors = false;
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("loginType", LOGIN_TYPE_LIBRUS);
|
||||
args.putInt("loginMode", LOGIN_MODE_LIBRUS_JST);
|
||||
args.putString("accountCode", code);
|
||||
args.putString("accountPin", pin);
|
||||
nav.navigate(R.id.loginProgressFragment, args, LoginActivity.navOptions);
|
||||
});
|
||||
}
|
||||
}
|
@ -85,8 +85,10 @@ public class LoginProgressFragment extends Fragment {
|
||||
}
|
||||
|
||||
int loginType = args.getInt("loginType", -1);
|
||||
int loginMode = args.getInt("loginMode", 0);
|
||||
|
||||
LoginStore loginStore = new LoginStore(-1, loginType, new JsonObject());
|
||||
loginStore.mode = loginMode;
|
||||
loginStore.copyFrom(args);
|
||||
|
||||
if (App.devMode && LoginChooserFragment.fakeLogin) {
|
||||
|
Reference in New Issue
Block a user