[Login] Add QR scanner to Vulcan & Librus JST login. Implement incorrect token error in Librus JST.

This commit is contained in:
Kuba Szczodrzyński 2020-03-15 21:46:46 +01:00
parent 9bac239f77
commit 1b2bdc0580
8 changed files with 102 additions and 24 deletions

View File

@ -125,6 +125,7 @@ const val ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM = 183
const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED = 184 const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED = 184
const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185 const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185
const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186 const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186
const val ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST = 187
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201 const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202 const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202

View File

@ -42,7 +42,7 @@ class LibrusApiAttendances(override val data: DataLibrus,
val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id") val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id")
val semester = attendance.getInt("Semester") ?: return@forEach val semester = attendance.getInt("Semester") ?: return@forEach
val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
val typeObject = data.attendanceTypes.get(type) val typeObject = data.attendanceTypes[type] ?: null
val topic = typeObject?.name ?: "" val topic = typeObject?.name ?: ""
val startTime = data.lessonRanges.get(lessonNo).startTime val startTime = data.lessonRanges.get(lessonNo).startTime
@ -60,13 +60,13 @@ class LibrusApiAttendances(override val data: DataLibrus,
topic, topic,
lessonDate, lessonDate,
startTime, startTime,
typeObject.type typeObject?.type ?: Attendance.TYPE_CUSTOM
) )
val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach) val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach)
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if(typeObject.type != Attendance.TYPE_PRESENT) { if(typeObject?.type != Attendance.TYPE_PRESENT) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,

View File

@ -137,6 +137,7 @@ class LibrusLoginApi {
"librus_change_password_error" -> ERROR_LOGIN_LIBRUS_API_CHANGE_PASSWORD_ERROR "librus_change_password_error" -> ERROR_LOGIN_LIBRUS_API_CHANGE_PASSWORD_ERROR
"librus_password_change_required" -> ERROR_LOGIN_LIBRUS_API_PASSWORD_CHANGE_REQUIRED "librus_password_change_required" -> ERROR_LOGIN_LIBRUS_API_PASSWORD_CHANGE_REQUIRED
"invalid_grant" -> ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN "invalid_grant" -> ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN
"invalid_request" -> ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST
else -> ERROR_LOGIN_LIBRUS_API_OTHER else -> ERROR_LOGIN_LIBRUS_API_OTHER
}.let { errorCode -> }.let { errorCode ->
data.error(ApiError(TAG, errorCode) data.error(ApiError(TAG, errorCode)

View File

@ -40,7 +40,7 @@ class QrScannerDialog(
onShowListener?.invoke(TAG) onShowListener?.invoke(TAG)
app = activity.applicationContext as App app = activity.applicationContext as App
scannerView = ZXingScannerView(activity) scannerView = ZXingScannerView(activity)
scannerView.setPadding(0, 16.dp, 4.dp, 0) scannerView.setPadding(0, 16.dp, 2.dp, 0)
dialog = MaterialAlertDialogBuilder(activity) dialog = MaterialAlertDialogBuilder(activity)
.setTitle(R.string.qr_scanner_dialog_title) .setTitle(R.string.qr_scanner_dialog_title)
.setView(scannerView) .setView(scannerView)

View File

@ -4,19 +4,27 @@
package pl.szczodrzynski.edziennik.ui.modules.login package pl.szczodrzynski.edziennik.ui.modules.login
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST
import pl.szczodrzynski.edziennik.data.api.LOGIN_MODE_LIBRUS_JST import pl.szczodrzynski.edziennik.data.api.LOGIN_MODE_LIBRUS_JST
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
import pl.szczodrzynski.edziennik.databinding.FragmentLoginLibrusJstBinding import pl.szczodrzynski.edziennik.databinding.FragmentLoginLibrusJstBinding
import pl.szczodrzynski.edziennik.ui.dialogs.QrScannerDialog
import java.util.* import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -47,12 +55,26 @@ class LoginLibrusJstFragment : Fragment(), CoroutineScope {
activity.lastError = null activity.lastError = null
startCoroutineTimer(delayMillis = 100) { startCoroutineTimer(delayMillis = 100) {
when (error.errorCode) { when (error.errorCode) {
ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN -> ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN,
ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST ->
b.loginCodeLayout.error = getString(R.string.login_error_incorrect_code_or_pin) b.loginCodeLayout.error = getString(R.string.login_error_incorrect_code_or_pin)
} }
} }
} }
b.loginQrScan.setImageDrawable(IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_qrcode_scan)
.colorInt(Color.BLACK)
.sizeDp(72))
b.loginQrScan.onClick {
QrScannerDialog(activity, { code ->
b.loginCode.setText(code)
if (b.loginPin.requestFocus()) {
activity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
})
}
b.helpButton.onClick { nav.navigate(R.id.loginLibrusHelpFragment, null, LoginActivity.navOptions) } b.helpButton.onClick { nav.navigate(R.id.loginLibrusHelpFragment, null, LoginActivity.navOptions) }
b.backButton.onClick { nav.navigateUp() } b.backButton.onClick { nav.navigateUp() }

View File

@ -4,17 +4,25 @@
package pl.szczodrzynski.edziennik.ui.modules.login package pl.szczodrzynski.edziennik.ui.modules.login
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.databinding.FragmentLoginVulcanBinding import pl.szczodrzynski.edziennik.databinding.FragmentLoginVulcanBinding
import pl.szczodrzynski.edziennik.ui.dialogs.QrScannerDialog
import pl.szczodrzynski.edziennik.utils.Utils
import java.util.* import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -57,6 +65,26 @@ class LoginVulcanFragment : Fragment(), CoroutineScope {
} }
} }
b.loginQrScan.setImageDrawable(IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_qrcode_scan)
.colorInt(Color.BLACK)
.sizeDp(72))
b.loginQrScan.onClick {
QrScannerDialog(activity, { code ->
try {
val data = Utils.VulcanQrEncryptionUtils.decode(code)
"CERT#https?://.+?/([A-z]+)/mobile-api#([A-z0-9]+)#ENDCERT".toRegex().find(data)?.let {
b.loginToken.setText(it[2])
b.loginSymbol.setText(it[1])
if (b.loginPin.requestFocus()) {
activity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
}
catch (_: Exception) {}
})
}
b.helpButton.onClick { nav.navigate(R.id.loginVulcanHelpFragment, null, LoginActivity.navOptions) } b.helpButton.onClick { nav.navigate(R.id.loginVulcanHelpFragment, null, LoginActivity.navOptions) }
b.backButton.onClick { nav.navigateUp() } b.backButton.onClick { nav.navigateUp() }

View File

@ -67,24 +67,48 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="16dp" /> android:layout_height="16dp" />
<com.google.android.material.textfield.TextInputLayout <LinearLayout
android:id="@+id/login_code_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginLeft="16dp" android:orientation="horizontal">
android:layout_marginRight="16dp"
android:hint="@string/login_hint_token"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_code" android:id="@+id/login_code_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inputType="textNoSuggestions|textEmailAddress" /> android:layout_marginLeft="16dp"
</com.google.android.material.textfield.TextInputLayout> android:layout_weight="1"
android:hint="@string/login_hint_token"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/login_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textNoSuggestions|textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/loginQrScan"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:layout_marginBottom="16dp"
android:layout_weight="1"
android:background="@android:color/transparent"
android:padding="4dp"
android:layout_marginRight="16dp"
android:layout_marginLeft="8dp"
android:scaleType="centerInside"
tools:srcCompat="@tools:sample/avatars"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:contentDescription="@string/login_vulcan_qr" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginPinLayout" android:id="@+id/loginPinLayout"

View File

@ -97,6 +97,7 @@
<string name="error_184" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED</string> <string name="error_184" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED</string>
<string name="error_185" translatable="false">ERROR_LIBRUS_API_DEVICE_REGISTERED</string> <string name="error_185" translatable="false">ERROR_LIBRUS_API_DEVICE_REGISTERED</string>
<string name="error_186" translatable="false">ERROR_LIBRUS_MESSAGES_NOT_FOUND</string> <string name="error_186" translatable="false">ERROR_LIBRUS_MESSAGES_NOT_FOUND</string>
<string name="error_187" translatable="false">ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST</string>
<string name="error_201" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN</string> <string name="error_201" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN</string>
<string name="error_202" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD</string> <string name="error_202" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD</string>
@ -245,7 +246,7 @@
<string name="error_159_reason">API Portalu Librus wyłączone</string> <string name="error_159_reason">API Portalu Librus wyłączone</string>
<string name="error_160_reason">Konto Synergia zostało rozłączone</string> <string name="error_160_reason">Konto Synergia zostało rozłączone</string>
<string name="error_161_reason">Inny błąd Portalu Librus</string> <string name="error_161_reason">Inny błąd Portalu Librus</string>
<string name="error_162_reason">Nie znaleziono konta Synergia</string> <string name="error_162_reason">Nie znaleziono konta Synergia. Zaloguj się na stronie portal.librus.pl, a następnie powiąż swoje konto Synergia do konta Librus Portal.</string>
<string name="error_163_reason">Inny błąd logowania do Portalu Librus</string> <string name="error_163_reason">Inny błąd logowania do Portalu Librus</string>
<string name="error_164_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED</string> <string name="error_164_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED</string>
<string name="error_165_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED</string> <string name="error_165_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED</string>
@ -260,8 +261,8 @@
<string name="error_174_reason">ERROR_LIBRUS_SYNERGIA_OTHER</string> <string name="error_174_reason">ERROR_LIBRUS_SYNERGIA_OTHER</string>
<string name="error_175_reason">Librus Synergia: przerwa techniczna</string> <string name="error_175_reason">Librus Synergia: przerwa techniczna</string>
<string name="error_176_reason">Librus Wiadomości: przerwa techniczna</string> <string name="error_176_reason">Librus Wiadomości: przerwa techniczna</string>
<string name="error_177_reason">ERROR_LIBRUS_MESSAGES_ERROR</string> <string name="error_177_reason">Librus Wiadomości: serwer zwrócił błąd. Prześlij zgłoszenie błędu.</string>
<string name="error_178_reason">ERROR_LIBRUS_MESSAGES_OTHER</string> <string name="error_178_reason">Librus Wiadomości: serwer zwrócił nieznany błąd. Prześlij zgłoszenie błędu.</string>
<string name="error_179_reason">Librus Wiadomości: nieprawidłowe dane logowania</string> <string name="error_179_reason">Librus Wiadomości: nieprawidłowe dane logowania</string>
<string name="error_180_reason">Librus Portal: nieprawidłowe dane logowania</string> <string name="error_180_reason">Librus Portal: nieprawidłowe dane logowania</string>
<string name="error_181_reason">Librus API: przerwa techniczna</string> <string name="error_181_reason">Librus API: przerwa techniczna</string>
@ -270,6 +271,7 @@
<string name="error_184_reason">Librus: Sesja logowania wygasła. Zaloguj się ponownie.</string> <string name="error_184_reason">Librus: Sesja logowania wygasła. Zaloguj się ponownie.</string>
<string name="error_185_reason">Urządzenie jest już zarejestrowane</string> <string name="error_185_reason">Urządzenie jest już zarejestrowane</string>
<string name="error_186_reason">Nie znaleziono wiadomości. Mogła zostać usunięta.</string> <string name="error_186_reason">Nie znaleziono wiadomości. Mogła zostać usunięta.</string>
<string name="error_187_reason">Nieprawidłowe dane dostępu. Sprawdź poprawność wprowadzonych danych.</string>
<string name="error_201_reason">Nieprawidłowy login lub hasło</string> <string name="error_201_reason">Nieprawidłowy login lub hasło</string>
<string name="error_202_reason">Podano stare hasło</string> <string name="error_202_reason">Podano stare hasło</string>
@ -334,7 +336,7 @@
<string name="error_901_reason">EXCEPTION_LOGIN_LIBRUS_API_TOKEN</string> <string name="error_901_reason">EXCEPTION_LOGIN_LIBRUS_API_TOKEN</string>
<string name="error_902_reason">EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN</string> <string name="error_902_reason">EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN</string>
<string name="error_903_reason">EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN</string> <string name="error_903_reason">EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN</string>
<string name="error_904_reason">EXCEPTION_LIBRUS_API_REQUEST</string> <string name="error_904_reason">Zgłoś błąd: wyjątek w API Librus</string>
<string name="error_905_reason">EXCEPTION_LIBRUS_SYNERGIA_REQUEST</string> <string name="error_905_reason">EXCEPTION_LIBRUS_SYNERGIA_REQUEST</string>
<string name="error_906_reason">EXCEPTION_MOBIDZIENNIK_WEB_REQUEST</string> <string name="error_906_reason">EXCEPTION_MOBIDZIENNIK_WEB_REQUEST</string>
<string name="error_907_reason">EXCEPTION_VULCAN_API_REQUEST</string> <string name="error_907_reason">EXCEPTION_VULCAN_API_REQUEST</string>