OpenedStorages больше не nullable

This commit is contained in:
2026-04-17 22:16:28 +03:00
parent d965dd8609
commit 51436401da
4 changed files with 72 additions and 67 deletions

View File

@@ -13,9 +13,9 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import java.util.UUID
@@ -24,43 +24,41 @@ class UnlockManager(
private val ioDispatcher: CoroutineDispatcher,
vaultsManager: IVaultsManager
) : IUnlockManager {
private val _openedStorages = MutableStateFlow<Map<UUID, EncryptedStorage>?>(null)
override val openedStorages: StateFlow<Map<UUID, IStorage>?>
private val _openedStorages = MutableStateFlow<Map<UUID, EncryptedStorage>>(emptyMap())
override val openedStorages: StateFlow<Map<UUID, IStorage>>
get() = _openedStorages
private val mutex = Mutex()
init {
CoroutineScope(ioDispatcher).launch {
vaultsManager.allStorages.collectLatest {
mutex.lock()
val allKeys = keymapRepository.getAll()
val usedKeys = mutableListOf<StorageKeyMap>()
val keysToRemove = mutableListOf<StorageKeyMap>()
val allStorages = it.toMutableList()
val map = _openedStorages.value?.toMutableMap() ?: mutableMapOf()
while(allStorages.size > 0) {
val storage = allStorages[allStorages.size-1]
val key = allKeys.find { key -> key.sourceUuid == storage.uuid }
if(key == null) {
allStorages.removeAt(allStorages.size - 1)
continue
}
try {
val encStorage = createEncryptedStorage(storage, key.key, key.destUuid)
map[storage.uuid] = encStorage
usedKeys.add(key)
allStorages.removeAt(allStorages.size - 1)
allStorages.add(encStorage)
}
catch (_: Exception) {
// ключ не подошёл
keysToRemove.add(key)
allStorages.removeAt(allStorages.size - 1)
mutex.withLock {
val allKeys = keymapRepository.getAll()
val keysToRemove = mutableListOf<StorageKeyMap>()
val allStorages = it.toMutableList()
val map = _openedStorages.value.toMutableMap()
while(allStorages.isNotEmpty()) {
val storage = allStorages[allStorages.size-1]
val key = allKeys.find { key -> key.sourceUuid == storage.uuid }
if(key == null) {
allStorages.removeAt(allStorages.size - 1)
continue
}
try {
val encStorage = createEncryptedStorage(storage, key.key, key.destUuid)
map[storage.uuid] = encStorage
allStorages.removeAt(allStorages.size - 1)
allStorages.add(encStorage)
}
catch (_: Exception) {
// ключ не подошёл
keysToRemove.add(key)
allStorages.removeAt(allStorages.size - 1)
}
}
keymapRepository.delete(*keysToRemove.toTypedArray()) // удалить мёртвые ключи
_openedStorages.value = map.toMap()
}
keymapRepository.delete(*keysToRemove.toTypedArray()) // удалить мёртвые ключи
_openedStorages.value = map.toMap()
mutex.unlock()
}
}
}
@@ -78,27 +76,27 @@ class UnlockManager(
storage: IStorage,
key: EncryptKey
): EncryptedStorage = withContext(ioDispatcher) {
mutex.lock()
val encInfo = storage.metaInfo.value.encInfo ?: throw Exception("EncInfo is null") // TODO
if (!Encryptor.checkKey(key, encInfo))
throw Exception("Incorrect Key")
return@withContext mutex.withLock {
val encInfo = storage.metaInfo.value.encInfo ?: throw Exception("EncInfo is null") // TODO
if (!Encryptor.checkKey(key, encInfo))
throw Exception("Incorrect Key")
val opened = _openedStorages.first { it != null }!!.toMutableMap()
val cur = opened[storage.uuid]
if (cur != null)
throw Exception("Storage is already open")
val opened = _openedStorages.value.toMutableMap()
val cur = opened[storage.uuid]
if (cur != null)
throw Exception("Storage is already open")
val keymap = StorageKeyMap(
sourceUuid = storage.uuid,
destUuid = UUID.randomUUID(),
key = key
)
val encStorage = createEncryptedStorage(storage, keymap.key, keymap.destUuid)
opened[storage.uuid] = encStorage
_openedStorages.value = opened
keymapRepository.add(keymap)
mutex.unlock()
return@withContext encStorage
val keymap = StorageKeyMap(
sourceUuid = storage.uuid,
destUuid = UUID.randomUUID(),
key = key
)
val encStorage = createEncryptedStorage(storage, keymap.key, keymap.destUuid)
opened[storage.uuid] = encStorage
_openedStorages.value = opened
keymapRepository.add(keymap)
encStorage
}
}
/**
@@ -106,30 +104,37 @@ class UnlockManager(
* @param uuid uuid исходного хранилища
*/
override suspend fun close(uuid: UUID): Unit = withContext(ioDispatcher) {
mutex.lock()
val opened = _openedStorages.first { it != null }!!
val enc = opened[uuid] ?: return@withContext
close(enc)
val model = StorageKeyMap(
sourceUuid = uuid,
destUuid = enc.uuid,
key = EncryptKey("")
)
_openedStorages.value = opened.toMutableMap().apply {
remove(uuid)
mutex.withLock {
val opened = _openedStorages.value.toMutableMap()
closeBySourceUuid(opened, uuid)
_openedStorages.value = opened
}
enc.dispose()
keymapRepository.delete(model)
mutex.unlock()
}
// Закрытие отображения по экземпляру (source или decrypted).
override suspend fun close(storage: IStorage) {
val opened = _openedStorages.first { it != null }!!
val opened = _openedStorages.value
val source = opened.entries.firstOrNull {
it.key == storage.uuid || it.value.uuid == storage.uuid
}
if (source != null)
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("")
)
)
}
}