Add fields validation in mobile api login (#629)

This commit is contained in:
Mikołaj Pich 2019-12-31 17:31:26 +01:00 committed by Rafał Borcz
parent 6be801d4a8
commit 4df245755a
8 changed files with 105 additions and 14 deletions

View File

@ -122,7 +122,7 @@ configurations.all {
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:sdk:069677aa2089b5678adbcae79dc253220995f172" implementation "io.github.wulkanowy:sdk:0886d71"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0-rc01" implementation "androidx.core:core-ktx:1.2.0-rc01"

View File

@ -5,6 +5,10 @@ import android.database.sqlite.SQLiteConstraintException
import com.readystatesoftware.chuck.api.ChuckCollector import com.readystatesoftware.chuck.api.ChuckCollector
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.exception.BadCredentialsException import io.github.wulkanowy.sdk.exception.BadCredentialsException
import io.github.wulkanowy.sdk.mobile.exception.InvalidPinException
import io.github.wulkanowy.sdk.mobile.exception.InvalidSymbolException
import io.github.wulkanowy.sdk.mobile.exception.InvalidTokenException
import io.github.wulkanowy.sdk.mobile.exception.TokenDeadException
import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.base.ErrorHandler
import javax.inject.Inject import javax.inject.Inject
@ -15,12 +19,22 @@ class LoginErrorHandler @Inject constructor(
var onBadCredentials: () -> Unit = {} var onBadCredentials: () -> Unit = {}
var onInvalidToken: (String) -> Unit = {}
var onInvalidPin: (String) -> Unit = {}
var onInvalidSymbol: (String) -> Unit = {}
var onStudentDuplicate: (String) -> Unit = {} var onStudentDuplicate: (String) -> Unit = {}
override fun proceed(error: Throwable) { override fun proceed(error: Throwable) {
when (error) { when (error) {
is BadCredentialsException -> onBadCredentials() is BadCredentialsException -> onBadCredentials()
is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student)) is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student))
is TokenDeadException -> onInvalidToken(resources.getString(R.string.login_expired_token))
is InvalidTokenException -> onInvalidToken(resources.getString(R.string.login_invalid_token))
is InvalidPinException -> onInvalidPin(resources.getString(R.string.login_invalid_pin))
is InvalidSymbolException -> onInvalidSymbol(resources.getString(R.string.login_invalid_symbol))
else -> super.proceed(error) else -> super.proceed(error)
} }
} }

View File

@ -4,7 +4,9 @@ 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.inputmethod.EditorInfo
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
@ -84,6 +86,9 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
}) })
} }
loginFormPin.setOnEditorDoneSignIn()
loginFormPass.setOnEditorDoneSignIn()
loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values))) loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
with(loginFormHost) { with(loginFormHost) {
@ -92,6 +97,12 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
} }
} }
private fun AppCompatEditText.setOnEditorDoneSignIn() {
setOnEditorActionListener { _, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) loginFormSignIn.callOnClick() else false
}
}
override fun setDefaultCredentials(name: String, pass: String, symbol: String, token: String, pin: String) { override fun setDefaultCredentials(name: String, pass: String, symbol: String, token: String, pin: String) {
loginFormName.setText(name) loginFormName.setText(name)
loginFormPass.setText(pass) loginFormPass.setText(pass)
@ -101,54 +112,75 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
} }
override fun setErrorNameRequired() { override fun setErrorNameRequired() {
loginFormNameLayout.run { with(loginFormNameLayout) {
requestFocus() requestFocus()
error = getString(R.string.login_field_required) error = getString(R.string.login_field_required)
} }
} }
override fun setErrorPassRequired(focus: Boolean) { override fun setErrorPassRequired(focus: Boolean) {
loginFormPassLayout.run { with(loginFormPassLayout) {
if (focus) requestFocus() if (focus) requestFocus()
error = getString(R.string.login_field_required) error = getString(R.string.login_field_required)
} }
} }
override fun setErrorPassInvalid(focus: Boolean) { override fun setErrorPassInvalid(focus: Boolean) {
loginFormPassLayout.run { with(loginFormPassLayout) {
if (focus) requestFocus() if (focus) requestFocus()
error = getString(R.string.login_invalid_password) error = getString(R.string.login_invalid_password)
} }
} }
override fun setErrorPassIncorrect() { override fun setErrorPassIncorrect() {
loginFormPassLayout.run { with(loginFormPassLayout) {
requestFocus() requestFocus()
error = getString(R.string.login_incorrect_password) error = getString(R.string.login_incorrect_password)
} }
} }
override fun setErrorPinRequired() { override fun setErrorPinRequired() {
loginFormPinLayout.run { with(loginFormPinLayout) {
requestFocus() requestFocus()
error = getString(R.string.login_field_required) error = getString(R.string.login_field_required)
} }
} }
override fun setErrorPinInvalid(message: String) {
with(loginFormPinLayout) {
requestFocus()
error = message
}
}
override fun setErrorSymbolRequired() { override fun setErrorSymbolRequired() {
loginFormSymbolLayout.run { with(loginFormSymbolLayout) {
requestFocus() requestFocus()
error = getString(R.string.login_field_required) error = getString(R.string.login_field_required)
} }
} }
override fun setErrorSymbolInvalid(message: String) {
with(loginFormSymbolLayout) {
requestFocus()
error = message
}
}
override fun setErrorTokenRequired() { override fun setErrorTokenRequired() {
loginFormTokenLayout.run { with(loginFormTokenLayout) {
requestFocus() requestFocus()
error = getString(R.string.login_field_required) error = getString(R.string.login_field_required)
} }
} }
override fun setErrorTokenInvalid(message: String) {
with(loginFormTokenLayout) {
requestFocus()
error = message
}
}
override fun clearNameError() { override fun clearNameError() {
loginFormNameLayout.error = null loginFormNameLayout.error = null
} }

View File

@ -24,12 +24,45 @@ class LoginAdvancedPresenter @Inject constructor(
view.run { view.run {
initView() initView()
showOnlyScrapperModeInputs() showOnlyScrapperModeInputs()
loginErrorHandler.onBadCredentials = { with(loginErrorHandler) {
onBadCredentials = ::onBadCredentials
onInvalidToken = ::onInvalidToken
onInvalidSymbol = ::onInvalidSymbol
onInvalidPin = ::onInvalidPin
}
}
}
private fun onBadCredentials() {
view?.run {
setErrorPassIncorrect() setErrorPassIncorrect()
showSoftKeyboard() showSoftKeyboard()
Timber.i("Entered wrong username or password") Timber.i("Entered wrong username or password")
} }
} }
private fun onInvalidToken(message: String) {
view?.run {
setErrorTokenInvalid(message)
showSoftKeyboard()
Timber.i("Entered invalid token")
}
}
private fun onInvalidSymbol(message: String) {
view?.run {
setErrorSymbolInvalid(message)
showSoftKeyboard()
Timber.i("Entered invalid symbol")
}
}
private fun onInvalidPin(message: String) {
view?.run {
setErrorPinInvalid(message)
showSoftKeyboard()
Timber.i("Entered invalid PIN")
}
} }
fun onHostSelected() { fun onHostSelected() {

View File

@ -53,10 +53,16 @@ interface LoginAdvancedView : BaseView {
fun setErrorPinRequired() fun setErrorPinRequired()
fun setErrorPinInvalid(message: String)
fun setErrorSymbolRequired() fun setErrorSymbolRequired()
fun setErrorSymbolInvalid(message: String)
fun setErrorTokenRequired() fun setErrorTokenRequired()
fun setErrorTokenInvalid(message: String)
fun showOnlyHybridModeInputs() fun showOnlyHybridModeInputs()
fun showOnlyScrapperModeInputs() fun showOnlyScrapperModeInputs()

View File

@ -188,8 +188,6 @@
android:id="@+id/loginFormToken" android:id="@+id/loginFormToken"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeActionLabel="@string/login_sign_in"
android:imeOptions="actionDone"
android:inputType="textCapCharacters" android:inputType="textCapCharacters"
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>

View File

@ -36,6 +36,10 @@
<string name="login_sign_in">Zaloguj</string> <string name="login_sign_in">Zaloguj</string>
<string name="login_invalid_password">To hasło jest za krótkie</string> <string name="login_invalid_password">To hasło jest za krótkie</string>
<string name="login_incorrect_password">Dane logowania są niepoprawne</string> <string name="login_incorrect_password">Dane logowania są niepoprawne</string>
<string name="login_invalid_pin">Nieprawidłowy PIN</string>
<string name="login_invalid_token">Nieprawidłowy token</string>
<string name="login_expired_token">Token stracił ważność</string>
<string name="login_invalid_symbol">Niepoprawny symbol</string>
<string name="login_incorrect_symbol">Nie znaleziono ucznia. Sprawdź symbol</string> <string name="login_incorrect_symbol">Nie znaleziono ucznia. Sprawdź symbol</string>
<string name="login_field_required">To pole jest wymagane</string> <string name="login_field_required">To pole jest wymagane</string>
<string name="login_duplicate_student">Wybrany uczeń jest już zalogowany</string> <string name="login_duplicate_student">Wybrany uczeń jest już zalogowany</string>

View File

@ -36,6 +36,10 @@
<string name="login_sign_in">Sign in</string> <string name="login_sign_in">Sign in</string>
<string name="login_invalid_password">This password is too short</string> <string name="login_invalid_password">This password is too short</string>
<string name="login_incorrect_password">Login details are incorrect</string> <string name="login_incorrect_password">Login details are incorrect</string>
<string name="login_invalid_pin">Invalid PIN</string>
<string name="login_invalid_token">Invalid token</string>
<string name="login_expired_token">Token expired</string>
<string name="login_invalid_symbol">Invalid symbol</string>
<string name="login_incorrect_symbol">Student not found. Check the symbol</string> <string name="login_incorrect_symbol">Student not found. Check the symbol</string>
<string name="login_field_required">This field is required</string> <string name="login_field_required">This field is required</string>
<string name="login_duplicate_student">The selected student is already logged in</string> <string name="login_duplicate_student">The selected student is already logged in</string>