-
-
Save hlnstepanova/1dabb07ce34d9d927be54074ad701b8c to your computer and use it in GitHub Desktop.
LoginModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.comp.proj.shared.models | |
import co.touchlab.kermit.Kermit | |
import co.touchlab.stately.ensureNeverFrozen | |
import com.russhwolf.settings.Settings | |
import de.comp.proj.shared.* | |
import de.comp.proj.shared.resources.MR | |
import de.comp.proj.shared.cache.DatabaseHelper | |
import de.comp.proj.shared.entity.Email | |
import de.comp.proj.shared.entity.LoginResult | |
import de.comp.proj.shared.entity.User | |
import de.comp.proj.shared.ktor.KtorApi | |
import dev.icerock.moko.mvvm.dispatcher.EventsDispatcher | |
import dev.icerock.moko.mvvm.dispatcher.EventsDispatcherOwner | |
import dev.icerock.moko.mvvm.livedata.LiveData | |
import dev.icerock.moko.mvvm.livedata.MutableLiveData | |
import dev.icerock.moko.mvvm.viewmodel.ViewModel | |
import org.koin.core.KoinComponent | |
import org.koin.core.inject | |
import org.koin.core.parameter.parametersOf | |
import dev.icerock.moko.resources.StringResource | |
import dev.icerock.moko.resources.desc.ResourceFormatted | |
import dev.icerock.moko.resources.desc.StringDesc | |
import dev.icerock.moko.resources.desc.Resource | |
import dev.icerock.moko.resources.desc.desc | |
import kotlinx.coroutines.launch | |
class LoginModel(override val eventsDispatcher: EventsDispatcher<EventsListener>) : ViewModel(), | |
EventsDispatcherOwner<LoginModel.EventsListener>, KoinComponent { | |
private val dbHelper: DatabaseHelper by inject() | |
private val settings: Settings by inject() | |
private val ktorApi: KtorApi by inject() | |
private val log: Kermit by inject { parametersOf("LoginModel") } | |
private val _cloudLogin = MutableLiveData(false) | |
private val _logged = MutableLiveData(false) | |
private val _loading = MutableLiveData(false) | |
val username = MutableLiveData("") | |
val password = MutableLiveData("") | |
val url = MutableLiveData("") | |
val logged: LiveData<Boolean> | |
get() = _logged | |
val loading: LiveData<Boolean> | |
get() = _loading | |
val cloudLogin: LiveData<Boolean> | |
get() = _cloudLogin | |
companion object { | |
internal const val EXPIRATION_TIME_KEY = "tokenExpiredKey" | |
internal const val ACCESS_TOKEN_KEY = "accessTokenKey" | |
} | |
init { | |
ensureNeverFrozen() | |
} | |
fun onLogin() { | |
val user = User(username.value, password.value) | |
// regardless of login type (cloud or local), validate username and password | |
validateUserData(user)?.let { | |
eventsDispatcher.dispatchEvent { showError(it) } | |
return | |
} | |
// if cloud login, try login with api | |
if (cloudLogin.value) { | |
viewModelScope.launch { | |
startLoading() | |
login(user)?.let { errorString -> | |
eventsDispatcher.dispatchEvent { showError(errorString) } | |
stopLoading() | |
return@launch | |
} | |
eventsDispatcher.dispatchEvent { navigateToDeviceList(username.value)} | |
setLogged(true) | |
} | |
} else { | |
// if local login, validate ip | |
validateIpData(url.value)?.let { | |
eventsDispatcher.dispatchEvent { showError(it) } | |
return | |
} | |
eventsDispatcher.dispatchEvent { navigateToFavouritesList(url.value)} | |
setLogged(true) | |
} | |
} | |
fun onLogout(){ | |
startLoading() | |
viewModelScope.launch { | |
logout()?.let { errorString -> | |
eventsDispatcher.dispatchEvent { showError(errorString) } | |
return@launch | |
} | |
setLogged(false) | |
} | |
stopLoading() | |
} | |
private fun setLogged(logged: Boolean){ | |
_logged.value = logged | |
} | |
//TODO: move to repository | |
suspend fun login(user: User): StringDesc? { | |
val currentTimeMS = currentTimeMillis() | |
if (isExpired(currentTimeMS)) { | |
try { | |
val loginResult = ktorApi.login(user) | |
val expiresIn = loginResult.expiresIn.toLong() | |
settings.putLong(EXPIRATION_TIME_KEY, currentTimeMS + expiresIn) | |
settings.putString(ACCESS_TOKEN_KEY, loginResult.accessToken) | |
log.i { "New token granted" } | |
} catch (e: Exception) { | |
log.i { e.toString() } | |
return StringDesc.Resource(MR.strings.access_denied) | |
} | |
} else { | |
log.i { "Access token still valid" } | |
} | |
return null | |
} | |
//TODO: move to repository | |
suspend fun logout(): StringDesc? { | |
try { | |
ktorApi.logout() | |
settings.putLong(EXPIRATION_TIME_KEY, 0) | |
settings.putString(ACCESS_TOKEN_KEY, "") | |
} catch (e: Exception) { | |
log.i { e.toString() } | |
return StringDesc.Resource(MR.strings.logout_failed) | |
} | |
return null | |
} | |
private fun isExpired(currentTimeMS: Long): Boolean { | |
val expirationTime = settings.getLong(EXPIRATION_TIME_KEY, 0) | |
return (expirationTime < currentTimeMS) | |
} | |
fun getAccessToken(): String { | |
return settings.getString(ACCESS_TOKEN_KEY) | |
} | |
fun setAccessTokenCookie(url: String) { | |
// cookie string should be url encoded | |
if (cloudLogin.value) { | |
setCookie(url, getAccessToken()) | |
} | |
} | |
// StringDesc is a mutable class for Strings from moko resources | |
fun validateUserData(user: User): StringDesc?{ | |
if (!validateEmail(user.email)){ | |
return StringDesc.Resource(MR.strings.enter_valid_email) | |
} | |
if (!validatePassword(user.password)){ | |
return StringDesc.Resource(MR.strings.enter_valid_password) | |
} | |
return null | |
} | |
fun validateIpData(url: String): StringDesc?{ | |
if (!validateIp(url)){ | |
return StringDesc.Resource(MR.strings.enter_valid_ip) | |
} | |
return null | |
} | |
fun toggleCloudLogin(value: Boolean) { | |
_cloudLogin.value = value | |
} | |
fun startLoading(){ | |
_loading.value = true | |
} | |
fun stopLoading(){ | |
_loading.value = false | |
} | |
interface EventsListener { | |
fun navigateToDeviceList(username: String) | |
fun navigateToFavouritesList(url: String) | |
fun showError(error: StringDesc) | |
} | |
} | |
comp.proj |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment