diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5c273b4..fb824573 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -157,6 +157,10 @@ android:configChanges="orientation|keyboardHidden" android:exported="false" android:theme="@style/Base.Theme.AppCompat" /> + diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt index 617ef5ed..10405e5f 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt @@ -205,6 +205,9 @@ const val ERROR_PODLASIE_API_OTHER = 631 const val ERROR_PODLASIE_API_DATA_MISSING = 632 const val ERROR_USOS_OAUTH_LOGIN_REQUEST = 701 +const val ERROR_USOS_OAUTH_GOT_DIFFERENT_TOKEN = 702 +const val ERROR_USOS_OAUTH_INCOMPLETE_RESPONSE = 703 +const val ERROR_USOS_NO_STUDENT_PROGRAMMES = 704 const val ERROR_TEMPLATE_WEB_OTHER = 801 diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt index f374db94..0fd1b2ba 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt @@ -16,7 +16,7 @@ class DataUsos( loginStore: LoginStore, ) : Data(app, profile, loginStore) { - fun isApiLoginValid() = oauthTokenKey != null && oauthTokenSecret != null + fun isApiLoginValid() = oauthTokenKey != null && oauthTokenSecret != null && oauthTokenIsUser override fun satisfyLoginMethods() { loginMethods.clear() @@ -25,7 +25,7 @@ class DataUsos( } } - override fun generateUserCode() = "USOS:TEST" + override fun generateUserCode() = "$schoolId:${studentNumber ?: studentId}" var schoolId: String? get() { mSchoolId = mSchoolId ?: loginStore.getLoginData("schoolId", null); return mSchoolId } @@ -62,6 +62,11 @@ class DataUsos( set(value) { loginStore.putLoginData("oauthTokenSecret", value); mOauthTokenSecret = value } private var mOauthTokenSecret: String? = null + var oauthTokenIsUser: Boolean + get() { mOauthTokenIsUser = mOauthTokenIsUser ?: loginStore.getLoginData("oauthTokenIsUser", false); return mOauthTokenIsUser ?: false } + set(value) { loginStore.putLoginData("oauthTokenIsUser", value); mOauthTokenIsUser = value } + private var mOauthTokenIsUser: Boolean? = null + var studentId: String? get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", null); return mStudentId } set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt index ac73e29a..1d3ab69c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt @@ -76,7 +76,7 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { service: String, params: Map, responseType: ResponseType, - onSuccess: (data: T) -> Unit, + onSuccess: (data: T, response: Response?) -> Unit, ) { val url = "${data.instanceUrl}services/$service" d(tag, "Request: Usos/Api - $url") @@ -123,10 +123,10 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { private fun getCallback( tag: String, responseType: ResponseType, - onSuccess: (data: T) -> Unit, + onSuccess: (data: T, response: Response?) -> Unit, ) = when (responseType) { ResponseType.OBJECT -> object : JsonCallbackHandler() { - override fun onSuccess(data: JsonObject?, response: Response?) { + override fun onSuccess(data: JsonObject?, response: Response) { processResponse(response, data as T, onSuccess) } @@ -135,7 +135,7 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { } } ResponseType.ARRAY -> object : JsonArrayCallbackHandler() { - override fun onSuccess(data: JsonArray?, response: Response?) { + override fun onSuccess(data: JsonArray?, response: Response) { processResponse(response, data as T, onSuccess) } @@ -144,7 +144,7 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { } } ResponseType.PLAIN -> object : TextCallbackHandler() { - override fun onSuccess(data: String?, response: Response?) { + override fun onSuccess(data: String?, response: Response) { processResponse(response, data as T, onSuccess) } @@ -155,11 +155,11 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { } private fun processResponse( - response: Response?, + response: Response, data: T, - onSuccess: (data: T) -> Unit, + onSuccess: (data: T, response: Response?) -> Unit, ) { - onSuccess(data) + onSuccess(data, response) } private fun processError( diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt index 3094980c..ad51cf92 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt @@ -4,9 +4,18 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.usos.firstlogin +import com.google.gson.JsonObject +import org.greenrobot.eventbus.EventBus +import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_NO_STUDENT_PROGRAMMES +import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_USOS +import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi +import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent +import pl.szczodrzynski.edziennik.data.api.models.ApiError +import pl.szczodrzynski.edziennik.data.db.entity.Profile +import pl.szczodrzynski.edziennik.ext.* class UsosFirstLogin(val data: DataUsos, val onSuccess: () -> Unit) { companion object { @@ -16,8 +25,60 @@ class UsosFirstLogin(val data: DataUsos, val onSuccess: () -> Unit) { private val api = UsosApi(data, null) init { - UsosLoginApi(data) { + val loginStoreId = data.loginStore.id + val loginStoreType = LOGIN_TYPE_USOS + var firstProfileId = loginStoreId + UsosLoginApi(data) { + api.apiRequest( + tag = TAG, + service = "users/user", + params = mapOf( + "fields" to listOf( + "id", + "first_name", + "last_name", + "student_number", + "student_programmes" to listOf( + "programme" to listOf("id"), + ), + ), + ), + responseType = UsosApi.ResponseType.OBJECT, + ) { json, response -> + val programmes = json.getJsonArray("student_programmes") + if (programmes.isNullOrEmpty()) { + data.error(ApiError(TAG, ERROR_USOS_NO_STUDENT_PROGRAMMES) + .withApiResponse(json) + .withResponse(response)) + return@apiRequest + } + + val firstName = json.getString("first_name") + val lastName = json.getString("last_name") + val studentName = buildFullName(firstName, lastName) + + val profile = Profile( + id = firstProfileId++, + loginStoreId = loginStoreId, loginStoreType = loginStoreType, + name = studentName, + subname = data.schoolId, + studentNameLong = studentName, + studentNameShort = studentName.getShortName(), + accountName = null, // student account + studentData = JsonObject( + "studentId" to json.getInt("id"), + "studentNumber" to json.getInt("student_number"), + ), + ).also { + it.studentClassName = programmes.getJsonObject(0).getJsonObject("programme").getString("id") + } + + EventBus.getDefault().postSticky( + FirstLoginFinishedEvent(listOf(profile), data.loginStore), + ) + onSuccess() + } } } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt index 3027c334..f49c0cea 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt @@ -4,9 +4,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login -import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_OAUTH_LOGIN_REQUEST -import pl.szczodrzynski.edziennik.data.api.USOS_API_OAUTH_REDIRECT_URL -import pl.szczodrzynski.edziennik.data.api.USOS_API_SCOPES +import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi import pl.szczodrzynski.edziennik.data.api.models.ApiError @@ -21,19 +19,21 @@ class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) { private const val TAG = "UsosLoginApi" } - init { run { - if (data.isApiLoginValid()) { - onSuccess() - } else if (data.oauthLoginResponse != null) { - login() - } else { - authorize() + private val api = UsosApi(data, null) + + init { + run { + if (data.isApiLoginValid()) { + onSuccess() + } else if (data.oauthLoginResponse != null) { + login() + } else { + authorize() + } } - }} + } private fun authorize() { - val api = UsosApi(data, null) - api.apiRequest( tag = TAG, service = "oauth/request_token", @@ -42,10 +42,11 @@ class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) { "scopes" to USOS_API_SCOPES, ), responseType = UsosApi.ResponseType.PLAIN, - ) { - val response = it.fromQueryString() - data.oauthTokenKey = response["oauth_token"] - data.oauthTokenSecret = response["oauth_token_secret"] + ) { text, _ -> + val authorizeData = text.fromQueryString() + data.oauthTokenKey = authorizeData["oauth_token"] + data.oauthTokenSecret = authorizeData["oauth_token_secret"] + data.oauthTokenIsUser = false val authUrl = "${data.instanceUrl}services/oauth/authorize" val authParams = mapOf( @@ -63,6 +64,42 @@ class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) { } private fun login() { - d(TAG, "Login to ${data.schoolId} with ${data.oauthLoginResponse} (${data.oauthTokenSecret})") + d(TAG, "Login to ${data.schoolId} with ${data.oauthLoginResponse}") + + val authorizeResponse = data.oauthLoginResponse?.fromQueryString() + ?: return // checked in init {} + if (authorizeResponse["oauth_token"] != data.oauthTokenKey) { + // got different token + data.error(ApiError(TAG, ERROR_USOS_OAUTH_GOT_DIFFERENT_TOKEN) + .withApiResponse(data.oauthLoginResponse)) + return + } + val verifier = authorizeResponse["oauth_verifier"] + if (verifier.isNullOrBlank()) { + data.error(ApiError(TAG, ERROR_USOS_OAUTH_INCOMPLETE_RESPONSE) + .withApiResponse(data.oauthLoginResponse)) + return + } + + api.apiRequest( + tag = TAG, + service = "oauth/access_token", + params = mapOf( + "oauth_verifier" to verifier, + ), + responseType = UsosApi.ResponseType.PLAIN, + ) { text, response -> + val accessData = text.fromQueryString() + data.oauthTokenKey = accessData["oauth_token"] + data.oauthTokenSecret = accessData["oauth_token_secret"] + data.oauthTokenIsUser = data.oauthTokenKey != null && data.oauthTokenSecret != null + + if (!data.oauthTokenIsUser) + data.error(ApiError(TAG, ERROR_USOS_OAUTH_INCOMPLETE_RESPONSE) + .withApiResponse(text) + .withResponse(response)) + else + onSuccess() + } } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ext/JsonExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ext/JsonExtensions.kt index 9f0db8ad..14d25b48 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ext/JsonExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ext/JsonExtensions.kt @@ -10,6 +10,8 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonParser import com.google.gson.JsonPrimitive +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract fun JsonObject?.get(key: String): JsonElement? = this?.get(key) @@ -93,7 +95,13 @@ fun JsonArray(vararg properties: Any?): JsonArray { } } -fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0 +@OptIn(ExperimentalContracts::class) +fun JsonArray?.isNullOrEmpty(): Boolean { + contract { + returns(false) implies (this@isNullOrEmpty != null) + } + return this == null || this.isEmpty +} operator fun JsonArray.plusAssign(o: JsonElement) = this.add(o) operator fun JsonArray.plusAssign(o: String) = this.add(o) operator fun JsonArray.plusAssign(o: Char) = this.add(o) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ext/TextExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ext/TextExtensions.kt index d7717c7b..adb6fe55 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ext/TextExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ext/TextExtensions.kt @@ -355,6 +355,7 @@ fun Map.toQueryString() = this .joinToString("&") { "${it.first}=${it.second}" } fun String.fromQueryString() = this + .substringAfter('?') .split("&") .map { it.split("=") } .associate { it[0].urlDecode() to it[1].urlDecode() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/OAuthLoginDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/OAuthLoginDialog.kt deleted file mode 100644 index b777377e..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/OAuthLoginDialog.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Kuba Szczodrzyński 2022-10-14. - */ - -package pl.szczodrzynski.edziennik.ui.dialogs - -import android.annotation.SuppressLint -import android.graphics.Bitmap -import android.view.ViewGroup -import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import android.webkit.WebView -import android.webkit.WebViewClient -import android.widget.FrameLayout -import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.updateLayoutParams -import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.ext.dp -import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog -import pl.szczodrzynski.edziennik.utils.Utils.d - -class OAuthLoginDialog( - activity: AppCompatActivity, - private val authorizeUrl: String, - private val redirectUrl: String, - private val onSuccess: (responseUrl: String) -> Unit, - private val onFailure: (() -> Unit)?, - onShowListener: ((tag: String) -> Unit)? = null, - onDismissListener: ((tag: String) -> Unit)? = null, -) : ViewDialog(activity, onShowListener, onDismissListener) { - - override val TAG = "OAuthLoginDialog" - - override fun getTitleRes() = R.string.oauth_dialog_title - override fun getPositiveButtonText() = R.string.close - - private var isSuccessful = false - - @SuppressLint("SetJavaScriptEnabled") - override fun getRootView(): WebView { - val webView = WebView(activity) - webView.webViewClient = object : WebViewClient() { - override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { - d(TAG, "Navigating to $url") - if (url.startsWith(redirectUrl)) { - isSuccessful = true - onSuccess(url) - dismiss() - } - } - } - webView.settings.javaScriptEnabled = true - return webView - } - - override suspend fun onShow() { - dialog.window?.setLayout(MATCH_PARENT, MATCH_PARENT) - root.minimumHeight = activity.windowManager.defaultDisplay?.height?.div(2) ?: 300.dp - root.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) - root.loadUrl(authorizeUrl) - } - - override fun onDismiss() { - root.stopLoading() - if (!isSuccessful) - onFailure?.invoke() - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt index 15a7021d..8b605734 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt @@ -324,7 +324,7 @@ object LoginInfo { Mode( loginMode = LOGIN_MODE_USOS_OAUTH, name = R.string.login_mode_usos_oauth, - icon = R.drawable.login_logo_usos, + icon = R.drawable.login_mode_usos_api, guideText = R.string.login_mode_usos_oauth_guide, isPlatformSelection = true, credentials = listOf(), diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginActivity.kt new file mode 100644 index 00000000..c80c3d82 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginActivity.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2022-10-15. + */ + +package pl.szczodrzynski.edziennik.ui.login.oauth + +import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.os.Bundle +import android.view.ViewGroup.LayoutParams.MATCH_PARENT +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.FrameLayout +import androidx.appcompat.app.AppCompatActivity +import org.greenrobot.eventbus.EventBus +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.utils.Utils.d + +class OAuthLoginActivity : AppCompatActivity() { + companion object { + private const val TAG = "OAuthLoginActivity" + } + + private var isSuccessful = false + + @SuppressLint("SetJavaScriptEnabled") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setTitle(R.string.oauth_dialog_title) + + val authorizeUrl = intent.getStringExtra("authorizeUrl") ?: return + val redirectUrl = intent.getStringExtra("redirectUrl") ?: return + + val webView = WebView(this) + webView.webViewClient = object : WebViewClient() { + override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { + d(TAG, "Navigating to $url") + if (url.startsWith(redirectUrl)) { + isSuccessful = true + EventBus.getDefault().post(OAuthLoginResult( + isError = false, + responseUrl = url, + )) + finish() + } + } + } + webView.settings.javaScriptEnabled = true + webView.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) + setContentView(webView) + + webView.loadUrl(authorizeUrl) + } + + override fun onDestroy() { + super.onDestroy() + if (!isSuccessful) + EventBus.getDefault().post(OAuthLoginResult( + isError = false, + responseUrl = null, + )) + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginResult.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginResult.kt new file mode 100644 index 00000000..108c0c8e --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/oauth/OAuthLoginResult.kt @@ -0,0 +1,10 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2022-10-15. + */ + +package pl.szczodrzynski.edziennik.ui.login.oauth + +data class OAuthLoginResult( + val isError: Boolean, + val responseUrl: String?, +) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/UserActionManager.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/UserActionManager.kt index c848c47a..3117c650 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/UserActionManager.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/UserActionManager.kt @@ -11,6 +11,8 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NotificationCompat import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.R @@ -21,7 +23,8 @@ import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ui.captcha.LibrusCaptchaDialog -import pl.szczodrzynski.edziennik.ui.dialogs.OAuthLoginDialog +import pl.szczodrzynski.edziennik.ui.login.oauth.OAuthLoginActivity +import pl.szczodrzynski.edziennik.ui.login.oauth.OAuthLoginResult import pl.szczodrzynski.edziennik.utils.Utils.d class UserActionManager(val app: App) { @@ -143,25 +146,35 @@ class UserActionManager(val app: App) { return false val extras = params.getBundle("extras") val storeKey = params.getString("responseStoreKey") ?: return false + params.getString("authorizeUrl") ?: return false + params.getString("redirectUrl") ?: return false - OAuthLoginDialog( - activity = activity, - authorizeUrl = params.getString("authorizeUrl") ?: return false, - redirectUrl = params.getString("redirectUrl") ?: return false, - onSuccess = { responseUrl -> - val args = Bundle( - storeKey to responseUrl, - ) - if (extras != null) - args.putAll(extras) + var listener: Any? = null + listener = object { + @Subscribe(threadMode = ThreadMode.MAIN) + fun onOAuthLoginResult(result: OAuthLoginResult) { + EventBus.getDefault().unregister(listener) + when { + result.isError -> onFailure?.invoke() + result.responseUrl != null -> { + val args = Bundle( + storeKey to result.responseUrl, + ) + if (extras != null) + args.putAll(extras) - if (onSuccess != null) - onSuccess(args) - else - EdziennikTask.syncProfile(profileId, arguments = args.toJsonObject()).enqueue(activity) - }, - onFailure = onFailure, - ).show() + if (onSuccess != null) + onSuccess(args) + else + EdziennikTask.syncProfile(profileId, arguments = args.toJsonObject()).enqueue(activity) + } + } + } + } + EventBus.getDefault().register(listener) + + val intent = Intent(activity, OAuthLoginActivity::class.java).putExtras(params) + activity.startActivity(intent) return true } } diff --git a/app/src/main/res/drawable/login_logo_usos.png b/app/src/main/res/drawable/login_logo_usos.png index 7c376bdd..98d95b34 100644 Binary files a/app/src/main/res/drawable/login_logo_usos.png and b/app/src/main/res/drawable/login_logo_usos.png differ diff --git a/app/src/main/res/drawable/login_mode_usos_api.png b/app/src/main/res/drawable/login_mode_usos_api.png new file mode 100644 index 00000000..6ec32631 Binary files /dev/null and b/app/src/main/res/drawable/login_mode_usos_api.png differ