Skip to content

Commit

Permalink
Merge pull request #946 from radixdlt/fix/security-problems-computed-…
Browse files Browse the repository at this point in the history
…from-all-accounts

Scan all accounts when looking for security problems
  • Loading branch information
giannis-rdx authored May 29, 2024
2 parents 313182b + bf92afd commit 994094a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.radixdlt.sargon.extensions.asGeneral
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import rdx.works.core.preferences.PreferencesManager
import rdx.works.core.sargon.activeEntitiesOnCurrentNetwork
import rdx.works.core.sargon.allEntitiesOnCurrentNetwork
import rdx.works.core.sargon.factorSourceById
import rdx.works.core.sargon.factorSourceId
import rdx.works.profile.data.repository.MnemonicRepository
Expand All @@ -21,7 +21,7 @@ class GetEntitiesWithSecurityPromptUseCase @Inject constructor(
) {

operator fun invoke() = combine(
getProfileUseCase.flow.map { it.activeEntitiesOnCurrentNetwork },
getProfileUseCase.flow.map { it.allEntitiesOnCurrentNetwork },
preferencesManager.getBackedUpFactorSourceIds()
) { entities, backedUpFactorSourceIds ->
entities.mapNotNull { entity ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.annotation.StringRes
import com.babylon.wallet.android.R
import com.babylon.wallet.android.domain.model.SecurityProblem
import com.babylon.wallet.android.presentation.ui.composables.DSR
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentSetOf

sealed interface SettingsItem {

Expand Down Expand Up @@ -70,8 +72,7 @@ sealed interface SettingsItem {

data class SeedPhrases(
override val count: Int,
val needsRecovery: Boolean,
val anyEntitySeedPhraseNotWrittenDown: Boolean
val securityProblems: ImmutableSet<SecurityProblem> = persistentSetOf()
) : SecurityFactorsSettingsItem

data class LedgerHardwareWallets(override val count: Int) : SecurityFactorsSettingsItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.babylon.wallet.android.R
import com.babylon.wallet.android.designsystem.theme.RadixTheme
import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme
import com.babylon.wallet.android.domain.model.SecurityProblem
import com.babylon.wallet.android.presentation.settings.SettingsItem
import com.babylon.wallet.android.presentation.ui.composables.DefaultSettingsItem
import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar
Expand Down Expand Up @@ -123,10 +124,18 @@ private fun SecurityFactorsContent(
@Composable
fun getSecurityWarnings(securityFactorsSettingsItem: SettingsItem.SecurityFactorsSettingsItem.SeedPhrases): PersistentList<String> {
return mutableListOf<String>().apply {
if (securityFactorsSettingsItem.needsRecovery) {
add(stringResource(id = R.string.securityProblems_no9_seedPhrases))
} else if (securityFactorsSettingsItem.anyEntitySeedPhraseNotWrittenDown) {
add(stringResource(id = R.string.securityProblems_no3_securityFactors))
securityFactorsSettingsItem.securityProblems.forEach { problem ->
when (problem) {
is SecurityProblem.EntitiesNotRecoverable -> {
add(stringResource(id = R.string.securityProblems_no3_securityFactors))
}

is SecurityProblem.SeedPhraseNeedRecovery -> {
add(stringResource(id = R.string.securityProblems_no9_seedPhrases))
}

else -> {}
}
}
}.toPersistentList()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,49 @@
package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors

import androidx.lifecycle.viewModelScope
import com.babylon.wallet.android.domain.usecases.GetEntitiesWithSecurityPromptUseCase
import com.babylon.wallet.android.domain.usecases.SecurityPromptType
import com.babylon.wallet.android.domain.usecases.GetSecurityProblemsUseCase
import com.babylon.wallet.android.presentation.common.StateViewModel
import com.babylon.wallet.android.presentation.common.UiState
import com.babylon.wallet.android.presentation.settings.SettingsItem
import com.radixdlt.sargon.extensions.id
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentSet
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import rdx.works.core.sargon.factorSourceId
import rdx.works.core.sargon.deviceFactorSources
import rdx.works.core.sargon.ledgerFactorSources
import rdx.works.profile.domain.GetFactorSourcesWithAccountsUseCase
import rdx.works.profile.domain.GetProfileUseCase
import javax.inject.Inject

@Suppress("MagicNumber")
@HiltViewModel
class SecurityFactorsViewModel @Inject constructor(
private val getProfileUseCase: GetProfileUseCase,
private val getFactorSourcesWithAccountsUseCase: GetFactorSourcesWithAccountsUseCase,
private val getEntitiesWithSecurityPromptUseCase: GetEntitiesWithSecurityPromptUseCase
private val getSecurityProblemsUseCase: GetSecurityProblemsUseCase
) : StateViewModel<SecurityFactorsUiState>() {

override fun initialState(): SecurityFactorsUiState = SecurityFactorsUiState(
settings = persistentSetOf(
SettingsItem.SecurityFactorsSettingsItem.SeedPhrases(0, false, false),
SettingsItem.SecurityFactorsSettingsItem.SeedPhrases(0, persistentSetOf()),
SettingsItem.SecurityFactorsSettingsItem.LedgerHardwareWallets(0)
)
)

init {
viewModelScope.launch {
combine(
getFactorSourcesWithAccountsUseCase(),
getProfileUseCase.flow.map { it.ledgerFactorSources },
getEntitiesWithSecurityPromptUseCase(),
) { deviceFactorSources, ledgerFactorSources, entitiesWithSecurityPrompts ->
val factorSourcesIds = deviceFactorSources.map { it.deviceFactorSource.id }
val anyEntityNeedRecovery = entitiesWithSecurityPrompts.any { entityWithSecurityPrompt ->
entityWithSecurityPrompt.prompts.contains(SecurityPromptType.NEEDS_RECOVER) &&
entityWithSecurityPrompt.entity.securityState.factorSourceId in factorSourcesIds
}
val anyEntitySeedPhraseNotWrittenDown = entitiesWithSecurityPrompts.any { entityWithSecurityPrompt ->
entityWithSecurityPrompt.prompts.contains(SecurityPromptType.NEEDS_BACKUP) &&
entityWithSecurityPrompt.entity.securityState.factorSourceId in factorSourcesIds
}
getProfileUseCase.flow,
getSecurityProblemsUseCase()
) { profile, securityProblems ->
val ledgerFactorSources = profile.ledgerFactorSources
val deviceFactorSources = profile.deviceFactorSources
SecurityFactorsUiState(
settings = persistentSetOf(
SettingsItem.SecurityFactorsSettingsItem.SeedPhrases(
deviceFactorSources.size,
anyEntityNeedRecovery,
anyEntitySeedPhraseNotWrittenDown
securityProblems.toPersistentSet()
),
SettingsItem.SecurityFactorsSettingsItem.LedgerHardwareWallets(ledgerFactorSources.size)
)
Expand Down
12 changes: 9 additions & 3 deletions core/src/main/java/rdx/works/core/sargon/ProfileExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ val Profile.currentNetwork: ProfileNetwork?
val Profile.isCurrentNetworkMainnet: Boolean
get() = currentNetwork?.id == NetworkId.MAINNET

val Profile.activeEntitiesOnCurrentNetwork: List<ProfileEntity>
get() = activeAccountsOnCurrentNetwork.map { it.asProfileEntity() } +
activePersonasOnCurrentNetwork.map { it.asProfileEntity() }
val Profile.allAccountsOnCurrentNetwork: List<Account>
get() = currentNetwork?.accounts.orEmpty()

val Profile.allPersonasOnCurrentNetwork: List<Persona>
get() = currentNetwork?.personas.orEmpty()

val Profile.allEntitiesOnCurrentNetwork: List<ProfileEntity>
get() = allAccountsOnCurrentNetwork.map { it.asProfileEntity() } +
allPersonasOnCurrentNetwork.map { it.asProfileEntity() }

val Profile.activeAccountsOnCurrentNetwork: List<Account>
get() = currentNetwork?.accounts?.notHiddenAccounts().orEmpty()
Expand Down

0 comments on commit 994094a

Please sign in to comment.