IUnlockManager теперь IVault
This commit is contained in:
@@ -25,9 +25,17 @@ class SingletonModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
fun provideVaultsManager(
|
fun provideVaultsManager(
|
||||||
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
||||||
@ApplicationContext context: Context
|
@ApplicationContext context: Context,
|
||||||
|
keyRepo: StorageKeyMapRepository,
|
||||||
): IVaultsManager {
|
): IVaultsManager {
|
||||||
return VaultsManager(ioDispatcher, context)
|
return VaultsManager(ioDispatcher, context, keyRepo)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideUnlockManager(
|
||||||
|
vaultsManager: IVaultsManager
|
||||||
|
): IUnlockManager {
|
||||||
|
return vaultsManager.unlockManager
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -47,18 +55,4 @@ class SingletonModule {
|
|||||||
): StorageMetaInfoRepository {
|
): StorageMetaInfoRepository {
|
||||||
return StorageMetaInfoRepository(dao, ioDispatcher)
|
return StorageMetaInfoRepository(dao, ioDispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
fun provideUnlockManager(
|
|
||||||
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
|
||||||
keyRepo: StorageKeyMapRepository,
|
|
||||||
vaultsManager: IVaultsManager
|
|
||||||
): IUnlockManager {
|
|
||||||
return UnlockManager(
|
|
||||||
keymapRepository = keyRepo,
|
|
||||||
ioDispatcher = ioDispatcher,
|
|
||||||
vaultsManager = vaultsManager
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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.data.model.StorageKeyMap
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import com.github.nullptroma.wallenc.data.storages.encrypt.EncryptedStorage
|
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.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.IStorage
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
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.StateFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -30,6 +33,19 @@ class UnlockManager(
|
|||||||
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()
|
||||||
|
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 {
|
init {
|
||||||
CoroutineScope(ioDispatcher).launch {
|
CoroutineScope(ioDispatcher).launch {
|
||||||
@@ -103,20 +119,54 @@ class UnlockManager(
|
|||||||
return@withContext encStorage
|
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()
|
mutex.lock()
|
||||||
val opened = _openedStorages.first { it != null }!!
|
val opened = _openedStorages.first { it != null }!!
|
||||||
val enc = opened[storage.uuid] ?: return@withContext
|
val enc = opened[uuid] ?: return@withContext
|
||||||
|
close(enc)
|
||||||
val model = StorageKeyMap(
|
val model = StorageKeyMap(
|
||||||
sourceUuid = storage.uuid,
|
sourceUuid = uuid,
|
||||||
destUuid = enc.uuid,
|
destUuid = enc.uuid,
|
||||||
key = EncryptKey("")
|
key = EncryptKey("")
|
||||||
)
|
)
|
||||||
_openedStorages.value = opened.toMutableMap().apply {
|
_openedStorages.value = opened.toMutableMap().apply {
|
||||||
remove(storage.uuid)
|
remove(uuid)
|
||||||
}
|
}
|
||||||
enc.dispose()
|
enc.dispose()
|
||||||
keymapRepository.delete(model)
|
keymapRepository.delete(model)
|
||||||
mutex.unlock()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,30 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults
|
package com.github.nullptroma.wallenc.data.vaults
|
||||||
|
|
||||||
import android.content.Context
|
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.IStorage
|
||||||
|
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVault
|
import com.github.nullptroma.wallenc.domain.interfaces.IVault
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
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 localVault = LocalVault(ioDispatcher, context)
|
||||||
|
override val unlockManager: IUnlockManager = UnlockManager(
|
||||||
|
keymapRepository = keyRepo,
|
||||||
|
ioDispatcher = ioDispatcher,
|
||||||
|
vaultsManager = this
|
||||||
|
)
|
||||||
override val remoteVaults: StateFlow<List<IVault>>
|
override val remoteVaults: StateFlow<List<IVault>>
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val allStorages: StateFlow<List<IStorage>>
|
override val allStorages: StateFlow<List<IStorage>>
|
||||||
get() = localVault.storages
|
get() = localVault.storages
|
||||||
|
override val allVaults: StateFlow<List<IVault>>
|
||||||
|
get() = MutableStateFlow(listOf(localVault, unlockManager))
|
||||||
|
|
||||||
|
|
||||||
override fun addYandexVault(email: String, token: String) {
|
override fun addYandexVault(email: String, token: String) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ package com.github.nullptroma.wallenc.domain.enums
|
|||||||
|
|
||||||
enum class VaultType {
|
enum class VaultType {
|
||||||
LOCAL,
|
LOCAL,
|
||||||
|
DECRYPTED,
|
||||||
YANDEX
|
YANDEX
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import java.util.UUID
|
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 open(storage: IStorage, key: EncryptKey): IStorage
|
||||||
suspend fun close(storage: IStorage)
|
suspend fun close(storage: IStorage)
|
||||||
|
suspend fun close(uuid: UUID): Unit
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,9 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
|
|
||||||
interface IVaultsManager {
|
interface IVaultsManager {
|
||||||
val localVault: IVault
|
val localVault: IVault
|
||||||
|
val unlockManager: IUnlockManager
|
||||||
val remoteVaults: StateFlow<List<IVault>>
|
val remoteVaults: StateFlow<List<IVault>>
|
||||||
|
|
||||||
val allStorages: StateFlow<List<IStorage>>
|
val allStorages: StateFlow<List<IStorage>>
|
||||||
|
val allVaults: StateFlow<List<IVault>>
|
||||||
fun addYandexVault(email: String, token: String)
|
fun addYandexVault(email: String, token: String)
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,9 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.PlatformTextStyle
|
import androidx.compose.ui.text.PlatformTextStyle
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -65,12 +67,16 @@ fun StorageTree(
|
|||||||
val numOfFiles by cur.numberOfFiles.collectAsStateWithLifecycle()
|
val numOfFiles by cur.numberOfFiles.collectAsStateWithLifecycle()
|
||||||
val size by cur.size.collectAsStateWithLifecycle()
|
val size by cur.size.collectAsStateWithLifecycle()
|
||||||
val metaInfo by cur.metaInfo.collectAsStateWithLifecycle()
|
val metaInfo by cur.metaInfo.collectAsStateWithLifecycle()
|
||||||
|
//val isAvailable by cur.isAvailable.collectAsStateWithLifecycle()
|
||||||
|
val isAvailable = metaInfo.name?.startsWith("1") != true
|
||||||
val borderColor =
|
val borderColor =
|
||||||
if (cur.isVirtualStorage) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.primary
|
if (cur.isVirtualStorage) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.primary
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
Box(modifier = Modifier
|
Box(
|
||||||
.height(IntrinsicSize.Min)
|
modifier = Modifier
|
||||||
.zIndex(100f)) {
|
.height(IntrinsicSize.Min)
|
||||||
|
.zIndex(100f)
|
||||||
|
) {
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -115,7 +121,7 @@ fun StorageTree(
|
|||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
horizontalAlignment = Alignment.End
|
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 expanded by remember { mutableStateOf(false) }
|
||||||
var showRenameDialog by remember { mutableStateOf(false) }
|
var showRenameDialog by remember { mutableStateOf(false) }
|
||||||
var showRemoveConfirmationDiaglog 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()) {
|
for (i in tree.children ?: listOf()) {
|
||||||
StorageTree(
|
StorageTree(
|
||||||
|
|||||||
Reference in New Issue
Block a user