OpenedStorages больше не nullable
This commit is contained in:
@@ -13,9 +13,9 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -24,21 +24,20 @@ class UnlockManager(
|
|||||||
private val ioDispatcher: CoroutineDispatcher,
|
private val ioDispatcher: CoroutineDispatcher,
|
||||||
vaultsManager: IVaultsManager
|
vaultsManager: IVaultsManager
|
||||||
) : IUnlockManager {
|
) : IUnlockManager {
|
||||||
private val _openedStorages = MutableStateFlow<Map<UUID, EncryptedStorage>?>(null)
|
private val _openedStorages = MutableStateFlow<Map<UUID, EncryptedStorage>>(emptyMap())
|
||||||
override val openedStorages: StateFlow<Map<UUID, IStorage>?>
|
override val openedStorages: StateFlow<Map<UUID, IStorage>>
|
||||||
get() = _openedStorages
|
get() = _openedStorages
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
CoroutineScope(ioDispatcher).launch {
|
CoroutineScope(ioDispatcher).launch {
|
||||||
vaultsManager.allStorages.collectLatest {
|
vaultsManager.allStorages.collectLatest {
|
||||||
mutex.lock()
|
mutex.withLock {
|
||||||
val allKeys = keymapRepository.getAll()
|
val allKeys = keymapRepository.getAll()
|
||||||
val usedKeys = mutableListOf<StorageKeyMap>()
|
|
||||||
val keysToRemove = mutableListOf<StorageKeyMap>()
|
val keysToRemove = mutableListOf<StorageKeyMap>()
|
||||||
val allStorages = it.toMutableList()
|
val allStorages = it.toMutableList()
|
||||||
val map = _openedStorages.value?.toMutableMap() ?: mutableMapOf()
|
val map = _openedStorages.value.toMutableMap()
|
||||||
while(allStorages.size > 0) {
|
while(allStorages.isNotEmpty()) {
|
||||||
val storage = allStorages[allStorages.size-1]
|
val storage = allStorages[allStorages.size-1]
|
||||||
val key = allKeys.find { key -> key.sourceUuid == storage.uuid }
|
val key = allKeys.find { key -> key.sourceUuid == storage.uuid }
|
||||||
if(key == null) {
|
if(key == null) {
|
||||||
@@ -48,7 +47,6 @@ class UnlockManager(
|
|||||||
try {
|
try {
|
||||||
val encStorage = createEncryptedStorage(storage, key.key, key.destUuid)
|
val encStorage = createEncryptedStorage(storage, key.key, key.destUuid)
|
||||||
map[storage.uuid] = encStorage
|
map[storage.uuid] = encStorage
|
||||||
usedKeys.add(key)
|
|
||||||
allStorages.removeAt(allStorages.size - 1)
|
allStorages.removeAt(allStorages.size - 1)
|
||||||
allStorages.add(encStorage)
|
allStorages.add(encStorage)
|
||||||
}
|
}
|
||||||
@@ -60,7 +58,7 @@ class UnlockManager(
|
|||||||
}
|
}
|
||||||
keymapRepository.delete(*keysToRemove.toTypedArray()) // удалить мёртвые ключи
|
keymapRepository.delete(*keysToRemove.toTypedArray()) // удалить мёртвые ключи
|
||||||
_openedStorages.value = map.toMap()
|
_openedStorages.value = map.toMap()
|
||||||
mutex.unlock()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,12 +76,12 @@ class UnlockManager(
|
|||||||
storage: IStorage,
|
storage: IStorage,
|
||||||
key: EncryptKey
|
key: EncryptKey
|
||||||
): EncryptedStorage = withContext(ioDispatcher) {
|
): EncryptedStorage = withContext(ioDispatcher) {
|
||||||
mutex.lock()
|
return@withContext mutex.withLock {
|
||||||
val encInfo = storage.metaInfo.value.encInfo ?: throw Exception("EncInfo is null") // TODO
|
val encInfo = storage.metaInfo.value.encInfo ?: throw Exception("EncInfo is null") // TODO
|
||||||
if (!Encryptor.checkKey(key, encInfo))
|
if (!Encryptor.checkKey(key, encInfo))
|
||||||
throw Exception("Incorrect Key")
|
throw Exception("Incorrect Key")
|
||||||
|
|
||||||
val opened = _openedStorages.first { it != null }!!.toMutableMap()
|
val opened = _openedStorages.value.toMutableMap()
|
||||||
val cur = opened[storage.uuid]
|
val cur = opened[storage.uuid]
|
||||||
if (cur != null)
|
if (cur != null)
|
||||||
throw Exception("Storage is already open")
|
throw Exception("Storage is already open")
|
||||||
@@ -97,8 +95,8 @@ class UnlockManager(
|
|||||||
opened[storage.uuid] = encStorage
|
opened[storage.uuid] = encStorage
|
||||||
_openedStorages.value = opened
|
_openedStorages.value = opened
|
||||||
keymapRepository.add(keymap)
|
keymapRepository.add(keymap)
|
||||||
mutex.unlock()
|
encStorage
|
||||||
return@withContext encStorage
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,30 +104,37 @@ class UnlockManager(
|
|||||||
* @param uuid uuid исходного хранилища
|
* @param uuid uuid исходного хранилища
|
||||||
*/
|
*/
|
||||||
override suspend fun close(uuid: UUID): Unit = withContext(ioDispatcher) {
|
override suspend fun close(uuid: UUID): Unit = withContext(ioDispatcher) {
|
||||||
mutex.lock()
|
mutex.withLock {
|
||||||
val opened = _openedStorages.first { it != null }!!
|
val opened = _openedStorages.value.toMutableMap()
|
||||||
val enc = opened[uuid] ?: return@withContext
|
closeBySourceUuid(opened, uuid)
|
||||||
close(enc)
|
_openedStorages.value = opened
|
||||||
val model = StorageKeyMap(
|
|
||||||
sourceUuid = uuid,
|
|
||||||
destUuid = enc.uuid,
|
|
||||||
key = EncryptKey("")
|
|
||||||
)
|
|
||||||
_openedStorages.value = opened.toMutableMap().apply {
|
|
||||||
remove(uuid)
|
|
||||||
}
|
}
|
||||||
enc.dispose()
|
|
||||||
keymapRepository.delete(model)
|
|
||||||
mutex.unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрытие отображения по экземпляру (source или decrypted).
|
// Закрытие отображения по экземпляру (source или decrypted).
|
||||||
override suspend fun close(storage: IStorage) {
|
override suspend fun close(storage: IStorage) {
|
||||||
val opened = _openedStorages.first { it != null }!!
|
val opened = _openedStorages.value
|
||||||
val source = opened.entries.firstOrNull {
|
val source = opened.entries.firstOrNull {
|
||||||
it.key == storage.uuid || it.value.uuid == storage.uuid
|
it.key == storage.uuid || it.value.uuid == storage.uuid
|
||||||
}
|
}
|
||||||
if (source != null)
|
if (source != null)
|
||||||
close(source.key)
|
close(source.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun closeBySourceUuid(opened: MutableMap<UUID, EncryptedStorage>, sourceUuid: UUID) {
|
||||||
|
val enc = opened[sourceUuid] ?: return
|
||||||
|
val childSourceUuid = opened.entries.firstOrNull { it.value.uuid == enc.uuid }?.key
|
||||||
|
if (childSourceUuid != null) {
|
||||||
|
closeBySourceUuid(opened, childSourceUuid)
|
||||||
|
}
|
||||||
|
opened.remove(sourceUuid)
|
||||||
|
enc.dispose()
|
||||||
|
keymapRepository.delete(
|
||||||
|
StorageKeyMap(
|
||||||
|
sourceUuid = sourceUuid,
|
||||||
|
destUuid = enc.uuid,
|
||||||
|
key = EncryptKey("")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ interface IUnlockManager {
|
|||||||
/**
|
/**
|
||||||
* Хранилища, для которых есть ключ шифрования
|
* Хранилища, для которых есть ключ шифрования
|
||||||
*/
|
*/
|
||||||
val openedStorages: StateFlow<Map<UUID, IStorage>?>
|
val openedStorages: StateFlow<Map<UUID, IStorage>>
|
||||||
|
|
||||||
suspend fun open(storage: IStorage, key: EncryptKey): IStorage
|
suspend fun open(storage: IStorage, key: EncryptKey): IStorage
|
||||||
suspend fun close(storage: IStorage)
|
suspend fun close(storage: IStorage)
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ import kotlinx.coroutines.flow.map
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class GetOpenedStoragesUseCase(private val unlockManager: IUnlockManager) {
|
class GetOpenedStoragesUseCase(private val unlockManager: IUnlockManager) {
|
||||||
val openedStorages: StateFlow<Map<UUID, IStorageInfo>?>
|
val openedStorages: StateFlow<Map<UUID, IStorageInfo>>
|
||||||
get() = unlockManager.openedStorages
|
get() = unlockManager.openedStorages
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ class LocalVaultViewModel @Inject constructor(
|
|||||||
private fun collectFlows() {
|
private fun collectFlows() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
manageLocalVaultUseCase.localStorages.combine(getOpenedStoragesUseCase.openedStorages) { local, opened ->
|
manageLocalVaultUseCase.localStorages.combine(getOpenedStoragesUseCase.openedStorages) { local, opened ->
|
||||||
if(local == null || opened == null)
|
if(local == null)
|
||||||
return@combine null
|
return@combine null
|
||||||
val list = mutableListOf<Tree<IStorageInfo>>()
|
val list = mutableListOf<Tree<IStorageInfo>>()
|
||||||
for (storage in local) {
|
for (storage in local) {
|
||||||
|
|||||||
Reference in New Issue
Block a user