Starting process of retrieving login credentials from credential manager
This commit is contained in:
parent
2a69fbcef7
commit
26c26ed054
8 changed files with 100 additions and 22 deletions
|
@ -1,7 +1,7 @@
|
|||
CREATE TABLE IF NOT EXISTS
|
||||
public.status (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE NULL
|
||||
);
|
||||
|
@ -21,9 +21,9 @@ VALUES
|
|||
CREATE TABLE IF NOT EXISTS
|
||||
public.user (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(97) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
status_id INT NOT NULL REFERENCES status(id) DEFAULT 2,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE NULL
|
||||
|
@ -34,7 +34,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS user_email_uniq_idx ON public.user(email);
|
|||
CREATE TABLE IF NOT EXISTS
|
||||
public.permission (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
status_id INT NOT NULL REFERENCES status(id) DEFAULT 1,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE NULL
|
||||
|
|
|
@ -27,9 +27,11 @@ import androidx.compose.material3.OutlinedTextField
|
|||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
@ -41,7 +43,9 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ing.bikeshedengineer.debtpirate.domain.model.AccountManagerResult
|
||||
import ing.bikeshedengineer.debtpirate.domain.repository.AccountManager
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
|
@ -53,6 +57,20 @@ fun LoginScreen(
|
|||
AccountManager(context)
|
||||
}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LaunchedEffect(true) {
|
||||
coroutineScope.launch {
|
||||
val result = accountManager.getCredentials()
|
||||
when (result) {
|
||||
is AccountManagerResult.FoundCredentials -> {
|
||||
val (emailAddress, password) = result
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
|
@ -74,7 +92,7 @@ fun LoginScreen(
|
|||
LoginComponent(
|
||||
emailAddress = emailAddress,
|
||||
onUpdateEmailAddress = {
|
||||
viewModel.updateState(
|
||||
viewModel.onAction(
|
||||
LoginScreenStateAction.UpdateEmailAddress(
|
||||
it
|
||||
)
|
||||
|
@ -82,13 +100,20 @@ fun LoginScreen(
|
|||
},
|
||||
password = password,
|
||||
onUpdatePassword = {
|
||||
viewModel.updateState(
|
||||
viewModel.onAction(
|
||||
LoginScreenStateAction.UpdatePassword(
|
||||
it
|
||||
)
|
||||
)
|
||||
},
|
||||
submitLoginRequest = viewModel::submitLoginRequest
|
||||
submitLoginRequest = {
|
||||
viewModel.onAction(
|
||||
LoginScreenStateAction.ValidateCredentials(
|
||||
emailAddress.value,
|
||||
password.value
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
Separator(
|
||||
|
|
|
@ -3,4 +3,6 @@ package ing.bikeshedengineer.debtpirate.app.screen.auth.presentation.login
|
|||
sealed interface LoginScreenStateAction {
|
||||
data class UpdateEmailAddress(val emailAddress: String) : LoginScreenStateAction
|
||||
data class UpdatePassword(val password: String) : LoginScreenStateAction
|
||||
data class ValidateCredentials(val emailAddress: String, val password: String) : LoginScreenStateAction
|
||||
data class SubmitLoginRequest(val emailAddress: String, val password: String) : LoginScreenStateAction
|
||||
}
|
|
@ -41,15 +41,13 @@ class LoginScreenViewModel @Inject constructor(
|
|||
private val submitLoginCredentials: SubmitLoginCredentialsUseCase,
|
||||
private val validateLoginCredentials: ValidateLoginCredentialsUseCase,
|
||||
) : ViewModel() {
|
||||
// private val storeLoginData = StoreLoginDataUseCase(dataStore)
|
||||
|
||||
private val _emailAddress = MutableStateFlow("")
|
||||
val emailAddress = _emailAddress.asStateFlow()
|
||||
|
||||
private val _password = MutableStateFlow("")
|
||||
val password = _password.asStateFlow()
|
||||
|
||||
fun updateState(action: LoginScreenStateAction) {
|
||||
fun onAction(action: LoginScreenStateAction) {
|
||||
when (action) {
|
||||
is LoginScreenStateAction.UpdateEmailAddress -> {
|
||||
_emailAddress.value = action.emailAddress
|
||||
|
@ -58,19 +56,25 @@ class LoginScreenViewModel @Inject constructor(
|
|||
is LoginScreenStateAction.UpdatePassword -> {
|
||||
_password.value = action.password
|
||||
}
|
||||
|
||||
is LoginScreenStateAction.ValidateCredentials -> {
|
||||
val (emailAddress, password) = action
|
||||
onValidateLoginCredentials(emailAddress, password)
|
||||
}
|
||||
|
||||
is LoginScreenStateAction.SubmitLoginRequest -> {
|
||||
viewModelScope.launch {
|
||||
val (emailAddress, password) = action
|
||||
onSubmitLoginRequest(emailAddress, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun submitLoginRequest() {
|
||||
when (validateLoginCredentials(emailAddress.value, password.value)) {
|
||||
private fun onValidateLoginCredentials(emailAddress: String, password: String) {
|
||||
when (validateLoginCredentials(emailAddress, password)) {
|
||||
is LoginCredentialsValidationResult.ValidCredentials -> {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val result = submitLoginCredentials(emailAddress.value, password.value)
|
||||
} catch (err: Throwable) {
|
||||
// TODO...
|
||||
}
|
||||
}
|
||||
onAction(LoginScreenStateAction.SubmitLoginRequest(emailAddress, password))
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -80,6 +84,14 @@ class LoginScreenViewModel @Inject constructor(
|
|||
|
||||
}
|
||||
|
||||
private suspend fun onSubmitLoginRequest(emailAddress: String, password: String) {
|
||||
try {
|
||||
val result = submitLoginCredentials(emailAddress, password)
|
||||
} catch (err: Throwable) {
|
||||
// TODO...
|
||||
}
|
||||
}
|
||||
|
||||
fun storeAuthData(userId: Int, sessionToken: Token, authToken: Token) {
|
||||
viewModelScope.launch {
|
||||
prefsStore.updateData { currentPrefs ->
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ing.bikeshedengineer.debtpirate.app.screen.auth.presentation.register
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
|
@ -6,5 +6,10 @@ sealed interface RegistrationScreenAction {
|
|||
data class UpdatePassword(val password: String) : RegistrationScreenAction
|
||||
data class UpdateConfirmPassword(val confirmPassword: String) : RegistrationScreenAction
|
||||
data object ResetFields : RegistrationScreenAction
|
||||
data class RegisterNewUser(val emailAddress: String, val name: String, val password: String, val confirmPassword: String) : RegistrationScreenAction
|
||||
data class RegisterNewUser(
|
||||
val emailAddress: String,
|
||||
val name: String,
|
||||
val password: String,
|
||||
val confirmPassword: String
|
||||
) : RegistrationScreenAction
|
||||
}
|
|
@ -2,7 +2,9 @@ package ing.bikeshedengineer.debtpirate.domain.model
|
|||
|
||||
sealed interface AccountManagerResult {
|
||||
data object Success : AccountManagerResult
|
||||
data class FoundCredentials(val emailAddress: String, val password: String) : AccountManagerResult
|
||||
data object Unavailable : AccountManagerResult
|
||||
data object Canceled : AccountManagerResult
|
||||
data object Failure : AccountManagerResult
|
||||
data object Invalid : AccountManagerResult
|
||||
}
|
|
@ -4,6 +4,9 @@ import android.app.Activity
|
|||
import android.util.Log
|
||||
import androidx.credentials.CreatePasswordRequest
|
||||
import androidx.credentials.CredentialManager
|
||||
import androidx.credentials.GetCredentialRequest
|
||||
import androidx.credentials.GetPasswordOption
|
||||
import androidx.credentials.PasswordCredential
|
||||
import androidx.credentials.exceptions.CreateCredentialCancellationException
|
||||
import androidx.credentials.exceptions.CreateCredentialException
|
||||
import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException
|
||||
|
@ -30,11 +33,41 @@ class AccountManager(private val context: Activity) {
|
|||
"DebtPirate::AccountManager",
|
||||
"Cannot store credentials; a Google account isn't associated with this device"
|
||||
)
|
||||
|
||||
AccountManagerResult.Unavailable
|
||||
} catch (_: CreateCredentialCancellationException) {
|
||||
AccountManagerResult.Canceled
|
||||
} catch (err: CreateCredentialException) {
|
||||
err.printStackTrace()
|
||||
Log.i(
|
||||
"DebtPirate::AccountManager",
|
||||
"Unable to store credentials: ${err.message}"
|
||||
)
|
||||
|
||||
AccountManagerResult.Failure
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getCredentials(): AccountManagerResult {
|
||||
return try {
|
||||
val result = credentialManager.getCredential(
|
||||
context, request = GetCredentialRequest(
|
||||
credentialOptions = listOf(GetPasswordOption(isAutoSelectAllowed = true))
|
||||
)
|
||||
)
|
||||
|
||||
val credentials = result.credential
|
||||
when (credentials) {
|
||||
is PasswordCredential -> {
|
||||
val emailAddress = credentials.id
|
||||
val password = credentials.password
|
||||
|
||||
AccountManagerResult.FoundCredentials(emailAddress, password)
|
||||
}
|
||||
|
||||
else -> AccountManagerResult.Invalid
|
||||
}
|
||||
} catch (err: Exception) {
|
||||
AccountManagerResult.Failure
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue