From 06a27199eeef0bb867b012689462840bcfa02a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Studzi=C5=84ski?= <48914870+studzinskik@users.noreply.github.com> Date: Wed, 3 Mar 2021 22:37:58 +0100 Subject: [PATCH] Add early validation for special mail domains (#1000) (#1176) --- .../modules/login/form/LoginFormFragment.kt | 7 +++++ .../modules/login/form/LoginFormPresenter.kt | 19 ++++++++++++-- .../ui/modules/login/form/LoginFormView.kt | 2 ++ app/src/main/res/values/strings.xml | 1 + .../login/form/LoginFormPresenterTest.kt | 26 +++++++++++++------ 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index c6d0209da..4e09bd4d6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -150,6 +150,13 @@ class LoginFormFragment : BaseFragment(R.layout.fragme } } + override fun setErrorEmailInvalid(domain: String) { + with(binding.loginFormUsernameLayout) { + requestFocus() + error = getString(R.string.login_invalid_custom_email,domain) + } + } + override fun clearUsernameError() { binding.loginFormUsernameLayout.error = null } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index f6a528ae3..70b468990 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -11,6 +11,7 @@ import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.ifNullOrBlank import kotlinx.coroutines.flow.onEach import timber.log.Timber +import java.net.URL import javax.inject.Inject class LoginFormPresenter @Inject constructor( @@ -87,7 +88,14 @@ class LoginFormPresenter @Inject constructor( if (!validateCredentials(email, password, host)) return - flowWithResource { studentRepository.getStudentsScrapper(email, password, host, symbol) }.onEach { + flowWithResource { + studentRepository.getStudentsScrapper( + email, + password, + host, + symbol + ) + }.onEach { when (it.status) { Status.LOADING -> view?.run { Timber.i("Login started") @@ -150,11 +158,18 @@ class LoginFormPresenter @Inject constructor( view?.setErrorLoginRequired() isCorrect = false } - if ("@" !in login && "email" in host) { view?.setErrorEmailRequired() isCorrect = false } + if ("@" in login && "login" !in host && "email" !in host) { + val emailHost = login.substringAfter("@") + val emailDomain = URL(host).host + if (emailHost != emailDomain) { + view?.setErrorEmailInvalid(domain = emailDomain) + isCorrect = false + } + } } if (password.isEmpty()) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 31f8a6217..079629ef6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -39,6 +39,8 @@ interface LoginFormView : BaseView { fun setErrorPassIncorrect() + fun setErrorEmailInvalid(domain: String) + fun clearUsernameError() fun clearPassError() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c95bbc557..a7b7004da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,6 +50,7 @@ Token expired Invalid email Use the assigned login instead of email + Use the assigned login or email in @%1$s Invalid symbol Student not found. Validate the symbol and the chosen variation of the UONET+ register This field is required diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt index 31e3e198b..67d3e6266 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt @@ -65,7 +65,7 @@ class LoginFormPresenterTest { fun emptyNicknameLoginTest() { every { loginFormView.formUsernameValue } returns "" every { loginFormView.formPassValue } returns "test123" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" presenter.onSignInClick() verify { loginFormView.setErrorUsernameRequired() } @@ -73,11 +73,21 @@ class LoginFormPresenterTest { verify(exactly = 0) { loginFormView.setErrorPassInvalid(false) } } + @Test + fun invalidEmailLoginTest() { + every { loginFormView.formUsernameValue } returns "@" + every { loginFormView.formPassValue } returns "123456" + every { loginFormView.formHostValue } returns "https://fakelog.cf/" + presenter.onSignInClick() + + verify { loginFormView.setErrorEmailInvalid("fakelog.cf") } + } + @Test fun emptyPassLoginTest() { every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" presenter.onSignInClick() verify(exactly = 0) { loginFormView.setErrorUsernameRequired() } @@ -89,7 +99,7 @@ class LoginFormPresenterTest { fun invalidPassLoginTest() { every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "123" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" presenter.onSignInClick() verify(exactly = 0) { loginFormView.setErrorUsernameRequired() } @@ -102,7 +112,7 @@ class LoginFormPresenterTest { val studentTest = Student( email = "test@", password = "123", - scrapperBaseUrl = "https://fakelog.cf/", + scrapperBaseUrl = "https://fakelog.cf/?email", loginType = "AUTO", studentName = "", schoolSymbol = "", @@ -128,7 +138,7 @@ class LoginFormPresenterTest { every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "123456" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" every { loginFormView.formHostSymbol } returns "Default" presenter.onSignInClick() @@ -144,7 +154,7 @@ class LoginFormPresenterTest { coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } returns listOf() every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "123456" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" every { loginFormView.formHostSymbol } returns "Default" presenter.onSignInClick() @@ -160,7 +170,7 @@ class LoginFormPresenterTest { coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } returns listOf() every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "123456" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" every { loginFormView.formHostSymbol } returns "Default" presenter.onSignInClick() presenter.onSignInClick() @@ -178,7 +188,7 @@ class LoginFormPresenterTest { coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } throws testException every { loginFormView.formUsernameValue } returns "@" every { loginFormView.formPassValue } returns "123456" - every { loginFormView.formHostValue } returns "https://fakelog.cf/?standard" + every { loginFormView.formHostValue } returns "https://fakelog.cf/?email" every { loginFormView.formHostSymbol } returns "Default" every { loginFormView.showProgress(any()) } just Runs every { loginFormView.showProgress(any()) } just Runs