diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt index b34b6900..ef594568 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt @@ -14,6 +14,14 @@ val SYSTEM_USER_AGENT = System.getProperty("http.agent") ?: "Dalvik/2.1.0 Androi val SERVER_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME} $SYSTEM_USER_AGENT" +const val FAKE_LIBRUS_API = "http://librus.szkolny.eu/api" +const val FAKE_LIBRUS_PORTAL = "http://librus.szkolny.eu" +const val FAKE_LIBRUS_AUTHORIZE = "http://librus.szkolny.eu/authorize.php" +const val FAKE_LIBRUS_LOGIN = "http://librus.szkolny.eu/login_action.php" +const val FAKE_LIBRUS_TOKEN = "http://librus.szkolny.eu/access_token.php" +const val FAKE_LIBRUS_ACCOUNT = "/synergia_accounts_fresh.php?login=" +const val FAKE_LIBRUS_ACCOUNTS = "/synergia_accounts.php" + val LIBRUS_USER_AGENT = "$SYSTEM_USER_AGENT LibrusMobileApp" const val SYNERGIA_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/62.0" const val LIBRUS_CLIENT_ID = "wmSyUMo8llDAs4y9tJVYY92oyZ6h4lAt7KCuy0Gv" diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt index 6dd2ffb9..1d4b6288 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt @@ -66,13 +66,13 @@ val librusLoginMethods = listOf( }, LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, LibrusLoginSynergia::class.java) - .withIsPossible { _, _ -> true } + .withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") } .withRequiredLoginMethod { profile, _ -> if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED }, LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, LibrusLoginMessages::class.java) - .withIsPossible { _, _ -> true } + .withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") } .withRequiredLoginMethod { profile, _ -> if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt index d913e303..4f8d12eb 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt @@ -28,7 +28,7 @@ open class LibrusApi(open val data: DataLibrus) { fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject) -> Unit) { - d(tag, "Request: Librus/Api - $LIBRUS_API_URL/$endpoint") + d(tag, "Request: Librus/Api - ${if (data.fakeLogin) FAKE_LIBRUS_API else LIBRUS_API_URL}/$endpoint") val callback = object : JsonCallbackHandler() { override fun onSuccess(json: JsonObject?, response: Response?) { @@ -90,7 +90,7 @@ open class LibrusApi(open val data: DataLibrus) { } Request.builder() - .url("$LIBRUS_API_URL/$endpoint") + .url("${if (data.fakeLogin) FAKE_LIBRUS_API else LIBRUS_API_URL}/$endpoint") .userAgent(LIBRUS_USER_AGENT) .addHeader("Authorization", "Bearer ${data.apiAccessToken}") .apply { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusPortal.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusPortal.kt index b86a6956..97fdf33d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusPortal.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusPortal.kt @@ -24,7 +24,7 @@ open class LibrusPortal(open val data: DataLibrus) { fun portalGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject, response: Response?) -> Unit) { - d(tag, "Request: Librus/Portal - $LIBRUS_PORTAL_URL$endpoint") + d(tag, "Request: Librus/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_PORTAL else LIBRUS_PORTAL_URL}$endpoint") val callback = object : JsonCallbackHandler() { override fun onSuccess(json: JsonObject?, response: Response?) { @@ -81,7 +81,7 @@ open class LibrusPortal(open val data: DataLibrus) { } Request.builder() - .url(LIBRUS_PORTAL_URL + endpoint) + .url((if (data.fakeLogin) FAKE_LIBRUS_PORTAL else LIBRUS_PORTAL_URL) + endpoint) .userAgent(LIBRUS_USER_AGENT) .addHeader("Authorization", "Bearer ${data.portalAccessToken}") .apply { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/firstlogin/LibrusFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/firstlogin/LibrusFirstLogin.kt index 08daf09a..41d77921 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/firstlogin/LibrusFirstLogin.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/firstlogin/LibrusFirstLogin.kt @@ -3,6 +3,7 @@ package pl.szczodrzynski.edziennik.api.v2.librus.firstlogin import org.greenrobot.eventbus.EventBus import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.api.v2.ERROR_NO_STUDENTS_IN_ACCOUNT +import pl.szczodrzynski.edziennik.api.v2.FAKE_LIBRUS_ACCOUNTS import pl.szczodrzynski.edziennik.api.v2.LIBRUS_ACCOUNTS_URL import pl.szczodrzynski.edziennik.api.v2.LOGIN_MODE_LIBRUS_EMAIL import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent @@ -29,7 +30,7 @@ class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) { if (data.loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL) { // email login: use Portal for account list LibrusLoginPortal(data) { - portal.portalGet(TAG, LIBRUS_ACCOUNTS_URL) { json, response -> + portal.portalGet(TAG, if (data.fakeLogin) FAKE_LIBRUS_ACCOUNTS else LIBRUS_ACCOUNTS_URL) { json, response -> val accounts = json.getJsonArray("accounts") if (accounts == null || accounts.size() < 1) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LibrusLoginPortal.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LibrusLoginPortal.kt index 67730e01..dc129626 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LibrusLoginPortal.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LibrusLoginPortal.kt @@ -7,14 +7,15 @@ import im.wangchao.mhttp.Response import im.wangchao.mhttp.body.MediaTypeUtils import im.wangchao.mhttp.callback.JsonCallbackHandler import im.wangchao.mhttp.callback.TextCallbackHandler -import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.DataLibrus import pl.szczodrzynski.edziennik.api.v2.models.ApiError -import pl.szczodrzynski.edziennik.utils.Utils +import pl.szczodrzynski.edziennik.getInt +import pl.szczodrzynski.edziennik.getString +import pl.szczodrzynski.edziennik.getUnixDate import pl.szczodrzynski.edziennik.utils.Utils.d import java.net.HttpURLConnection.HTTP_UNAUTHORIZED -import java.util.ArrayList +import java.util.* import java.util.regex.Pattern class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) { @@ -42,7 +43,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) { } else { data.app.cookieJar.clearForDomain("portal.librus.pl") - authorize(LIBRUS_AUTHORIZE_URL) + authorize(if (data.fakeLogin) FAKE_LIBRUS_AUTHORIZE else LIBRUS_AUTHORIZE_URL) } }} @@ -86,10 +87,10 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) { } private fun login(csrfToken: String) { - d(TAG, "Request: Librus/Login/Portal - $LIBRUS_LOGIN_URL") + d(TAG, "Request: Librus/Login/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_LOGIN else LIBRUS_LOGIN_URL}") Request.builder() - .url(LIBRUS_LOGIN_URL) + .url(if (data.fakeLogin) FAKE_LIBRUS_LOGIN else LIBRUS_LOGIN_URL) .userAgent(LIBRUS_USER_AGENT) .addParameter("email", data.portalEmail) .addParameter("password", data.portalPassword) @@ -135,7 +136,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) { private var refreshTokenFailed = false private fun accessToken(code: String?, refreshToken: String?) { - d(TAG, "Request: Librus/Login/Portal - $LIBRUS_TOKEN_URL") + d(TAG, "Request: Librus/Login/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_TOKEN else LIBRUS_TOKEN_URL}") val onSuccess = { json: JsonObject, response: Response? -> data.portalAccessToken = json.getString("access_token") @@ -204,7 +205,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) { } Request.builder() - .url(LIBRUS_TOKEN_URL) + .url(if (data.fakeLogin) FAKE_LIBRUS_TOKEN else LIBRUS_TOKEN_URL) .userAgent(LIBRUS_USER_AGENT) .addParams(params) .post() diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt index 27fdbe6a..0d80cd65 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt @@ -43,7 +43,7 @@ class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () -> val accountLogin = data.apiLogin ?: return false data.portalAccessToken ?: return false - d(TAG, "Request: Librus/SynergiaTokenExtractor - $LIBRUS_ACCOUNT_URL$accountLogin") + d(TAG, "Request: Librus/SynergiaTokenExtractor - ${if (data.fakeLogin) FAKE_LIBRUS_ACCOUNT else LIBRUS_ACCOUNT_URL}$accountLogin") val onSuccess = { json: JsonObject, response: Response? -> // synergiaAccount is executed when a synergia token needs a refresh @@ -67,7 +67,7 @@ class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () -> } } - portalGet(TAG, LIBRUS_ACCOUNT_URL+accountLogin, onSuccess = onSuccess) + portalGet(TAG, (if (data.fakeLogin) FAKE_LIBRUS_ACCOUNT else LIBRUS_ACCOUNT_URL)+accountLogin, onSuccess = onSuccess) return true } } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt index bac36618..2db316d3 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt @@ -5,7 +5,7 @@ import android.util.SparseArray import androidx.core.util.size import com.google.gson.JsonObject import im.wangchao.mhttp.Response -import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.api.v2.DataNotifications import pl.szczodrzynski.edziennik.api.v2.EXCEPTION_NOTIFY_AND_SYNC import pl.szczodrzynski.edziennik.api.v2.ServerSync @@ -38,11 +38,8 @@ import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsence import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsenceType import pl.szczodrzynski.edziennik.data.db.modules.teams.Team -import pl.szczodrzynski.edziennik.singleOrNull -import pl.szczodrzynski.edziennik.toSparseArray import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.models.Date -import pl.szczodrzynski.edziennik.values import java.io.InterruptedIOException import java.net.SocketTimeoutException import java.net.UnknownHostException @@ -167,6 +164,9 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) val db: AppDb by lazy { app.db } init { + if (BuildConfig.DEBUG) { + fakeLogin = loginStore.hasLoginData("fakeLogin") + } clear() if (profile != null) { endpointTimers = db.endpointTimerDao().getAllNow(profile.id).toMutableList() diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java index 7f5a2c49..2aff483c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java @@ -14,6 +14,7 @@ import androidx.navigation.NavController; import androidx.navigation.Navigation; import pl.szczodrzynski.edziennik.App; +import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.databinding.FragmentLoginChooserBinding; import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackActivity; @@ -26,6 +27,7 @@ public class LoginChooserFragment extends Fragment { private NavController nav; private FragmentLoginChooserBinding b; private static final String TAG = "LoginTemplate"; + public static boolean fakeLogin = false; public LoginChooserFragment() { } @@ -71,6 +73,10 @@ public class LoginChooserFragment extends Fragment { b.cancelButton.setVisibility(View.GONE); } + b.fakeLogin.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); + b.fakeLogin.setChecked(fakeLogin); + b.fakeLogin.setOnCheckedChangeListener((v, isChecked) -> fakeLogin = isChecked); + b.helpButton.setOnClickListener((v -> { startActivity(new Intent(getActivity(), FeedbackActivity.class)); })); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java index f7b84db8..08c7e919 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java @@ -19,6 +19,7 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import pl.szczodrzynski.edziennik.App; +import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent; import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent; @@ -89,6 +90,10 @@ public class LoginProgressFragment extends Fragment { LoginStore loginStore = new LoginStore(-1, loginType, new JsonObject()); loginStore.copyFrom(args); + if (BuildConfig.DEBUG && LoginChooserFragment.fakeLogin) { + loginStore.putLoginData("fakeLogin", true); + } + EdziennikTask.Companion.firstLogin(loginStore).enqueue(getContext()); } diff --git a/app/src/main/res/layout/fragment_login_chooser.xml b/app/src/main/res/layout/fragment_login_chooser.xml index 78201b71..9b7937fa 100644 --- a/app/src/main/res/layout/fragment_login_chooser.xml +++ b/app/src/main/res/layout/fragment_login_chooser.xml @@ -151,6 +151,16 @@ + + + diff --git a/app/src/main/res/layout/timetable_lesson.xml b/app/src/main/res/layout/timetable_lesson.xml index 5fadc319..47892c39 100644 --- a/app/src/main/res/layout/timetable_lesson.xml +++ b/app/src/main/res/layout/timetable_lesson.xml @@ -3,6 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> + + @@ -89,12 +91,13 @@ android:layout_gravity="center_vertical" android:fontFamily="sans-serif-condensed-light" android:includeFontPadding="false" - android:layout_marginTop="@{annotationVisible ? -4 : 4}" - android:layout_marginBottom="@{annotationVisible ? -4 : 0}" + android:paddingStart="4dp" android:paddingEnd="4dp" android:text="9" tools:textSize="28sp"/> +