IUnlockManager теперь IVault

This commit is contained in:
Пытков Роман
2025-02-11 17:55:54 +03:00
parent e1646611c2
commit 85b8517a76
8 changed files with 115 additions and 28 deletions

View File

@@ -25,9 +25,17 @@ class SingletonModule {
@Singleton
fun provideVaultsManager(
@IoDispatcher ioDispatcher: CoroutineDispatcher,
@ApplicationContext context: Context
@ApplicationContext context: Context,
keyRepo: StorageKeyMapRepository,
): IVaultsManager {
return VaultsManager(ioDispatcher, context)
return VaultsManager(ioDispatcher, context, keyRepo)
}
@Provides
fun provideUnlockManager(
vaultsManager: IVaultsManager
): IUnlockManager {
return vaultsManager.unlockManager
}
@Provides
@@ -47,18 +55,4 @@ class SingletonModule {
): StorageMetaInfoRepository {
return StorageMetaInfoRepository(dao, ioDispatcher)
}
@Provides
@Singleton
fun provideUnlockManager(
@IoDispatcher ioDispatcher: CoroutineDispatcher,
keyRepo: StorageKeyMapRepository,
vaultsManager: IVaultsManager
): IUnlockManager {
return UnlockManager(
keymapRepository = keyRepo,
ioDispatcher = ioDispatcher,
vaultsManager = vaultsManager
)
}
}

View File

@@ -5,7 +5,9 @@ import com.github.nullptroma.wallenc.data.db.app.repository.StorageMetaInfoRepos
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import com.github.nullptroma.wallenc.data.storages.encrypt.EncryptedStorage
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
import com.github.nullptroma.wallenc.domain.enums.VaultType
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
@@ -16,6 +18,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.withContext
@@ -30,6 +33,19 @@ class UnlockManager(
override val openedStorages: StateFlow<Map<UUID, IStorage>?>
get() = _openedStorages
private val mutex = Mutex()
override val type: VaultType
get() = VaultType.DECRYPTED
override val uuid: UUID
get() = TODO("Not yet implemented")
override val isAvailable: StateFlow<Boolean>
get() = MutableStateFlow(true)
override val totalSpace: StateFlow<Int?>
get() = MutableStateFlow(null)
override val availableSpace: StateFlow<Int?>
get() = MutableStateFlow(null)
override val storages: StateFlow<List<IStorage>?>
get() = TODO()
init {
CoroutineScope(ioDispatcher).launch {
@@ -103,20 +119,54 @@ class UnlockManager(
return@withContext encStorage
}
override suspend fun close(storage: IStorage) = withContext(ioDispatcher) {
/**
* Закрыть шифрование хранилища, закрывает рекурсивно, удаляя все ключи
* @param storage исходное хранилище, а не расшифрованное отображение
*/
override suspend fun close(storage: IStorage) {
close(storage.uuid)
}
/**
* Закрыть шифрование хранилища, закрывает рекурсивно, удаляя все ключи
* @param uuid uuid исходного хранилища
*/
override suspend fun close(uuid: UUID): Unit = withContext(ioDispatcher) {
mutex.lock()
val opened = _openedStorages.first { it != null }!!
val enc = opened[storage.uuid] ?: return@withContext
val enc = opened[uuid] ?: return@withContext
close(enc)
val model = StorageKeyMap(
sourceUuid = storage.uuid,
sourceUuid = uuid,
destUuid = enc.uuid,
key = EncryptKey("")
)
_openedStorages.value = opened.toMutableMap().apply {
remove(storage.uuid)
remove(uuid)
}
enc.dispose()
keymapRepository.delete(model)
mutex.unlock()
}
override suspend fun createStorage(): IStorage {
throw UnsupportedOperationException("Нельзя создать кошелёк на UnlockManager") // TODO
}
override suspend fun createStorage(enc: StorageEncryptionInfo): IStorage {
throw UnsupportedOperationException("Нельзя создать кошелёк на UnlockManager") // TODO
}
/**
* Закрыть отображение
* @param storage исходное или расшифрованное хранилище
*/
override suspend fun remove(storage: IStorage) {
val opened = _openedStorages.first { it != null }!!
val source = opened.entries.firstOrNull {
it.key == storage.uuid || it.value.uuid == storage.uuid
}
if(source != null)
close(source.key)
}
}

View File

@@ -1,19 +1,30 @@
package com.github.nullptroma.wallenc.data.vaults
import android.content.Context
import com.github.nullptroma.wallenc.data.db.app.repository.StorageKeyMapRepository
import com.github.nullptroma.wallenc.data.storages.UnlockManager
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
import com.github.nullptroma.wallenc.domain.interfaces.IVault
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class VaultsManager(ioDispatcher: CoroutineDispatcher, context: Context) : IVaultsManager {
class VaultsManager(ioDispatcher: CoroutineDispatcher, context: Context, keyRepo: StorageKeyMapRepository) : IVaultsManager {
override val localVault = LocalVault(ioDispatcher, context)
override val unlockManager: IUnlockManager = UnlockManager(
keymapRepository = keyRepo,
ioDispatcher = ioDispatcher,
vaultsManager = this
)
override val remoteVaults: StateFlow<List<IVault>>
get() = TODO("Not yet implemented")
override val allStorages: StateFlow<List<IStorage>>
get() = localVault.storages
override val allVaults: StateFlow<List<IVault>>
get() = MutableStateFlow(listOf(localVault, unlockManager))
override fun addYandexVault(email: String, token: String) {
TODO("Not yet implemented")

View File

@@ -2,5 +2,6 @@ package com.github.nullptroma.wallenc.domain.enums
enum class VaultType {
LOCAL,
DECRYPTED,
YANDEX
}

View File

@@ -4,7 +4,7 @@ import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
interface IUnlockManager {
interface IUnlockManager: IVault {
/**
* Хранилища, для которых есть ключ шифрования
*/
@@ -12,4 +12,5 @@ interface IUnlockManager {
suspend fun open(storage: IStorage, key: EncryptKey): IStorage
suspend fun close(storage: IStorage)
suspend fun close(uuid: UUID): Unit
}

View File

@@ -4,8 +4,9 @@ import kotlinx.coroutines.flow.StateFlow
interface IVaultsManager {
val localVault: IVault
val unlockManager: IUnlockManager
val remoteVaults: StateFlow<List<IVault>>
val allStorages: StateFlow<List<IStorage>>
val allVaults: StateFlow<List<IVault>>
fun addYandexVault(email: String, token: String)
}

View File

@@ -0,0 +1,12 @@
package com.github.nullptroma.wallenc.domain.usecases
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
class RemoveStorageUseCase {
suspend fun rename(storage: IStorageInfo, newName: String) {
when (storage) {
is IStorage -> storage.rename(newName)
}
}
}

View File

@@ -38,7 +38,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.style.TextAlign
@@ -65,12 +67,16 @@ fun StorageTree(
val numOfFiles by cur.numberOfFiles.collectAsStateWithLifecycle()
val size by cur.size.collectAsStateWithLifecycle()
val metaInfo by cur.metaInfo.collectAsStateWithLifecycle()
//val isAvailable by cur.isAvailable.collectAsStateWithLifecycle()
val isAvailable = metaInfo.name?.startsWith("1") != true
val borderColor =
if (cur.isVirtualStorage) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.primary
Column(modifier) {
Box(modifier = Modifier
.height(IntrinsicSize.Min)
.zIndex(100f)) {
Box(
modifier = Modifier
.height(IntrinsicSize.Min)
.zIndex(100f)
) {
val interactionSource = remember { MutableInteractionSource() }
Box(
modifier = Modifier
@@ -115,7 +121,7 @@ fun StorageTree(
modifier = Modifier,
horizontalAlignment = Alignment.End
) {
Box(modifier = Modifier.padding(0.dp, 8.dp, 8.dp, 0.dp)) {
Box(modifier = Modifier.padding(0.dp, 0.dp, 0.dp, 0.dp)) {
var expanded by remember { mutableStateOf(false) }
var showRenameDialog by remember { mutableStateOf(false) }
var showRemoveConfirmationDiaglog by remember { mutableStateOf(false) }
@@ -195,6 +201,17 @@ fun StorageTree(
}
}
}
if(!isAvailable) {
Box(
modifier = Modifier
.clip(
CardDefaults.shape
)
.fillMaxSize()
.alpha(0.5f)
.background(Color.Black)
)
}
}
for (i in tree.children ?: listOf()) {
StorageTree(