Улучшение соответсвия
This commit is contained in:
@@ -21,9 +21,8 @@ start
|
||||
:Инициализация Room,
|
||||
загрузка метаданных vault;
|
||||
|
||||
if (Есть сохранённые vault?) then (нет)
|
||||
:Экран «первый запуск» /
|
||||
создание локального vault;
|
||||
if (Есть LocalVault / storage?) then (нет)
|
||||
:Первый запуск;
|
||||
else (да)
|
||||
endif
|
||||
|
||||
@@ -35,10 +34,10 @@ else (нет)
|
||||
endif
|
||||
|
||||
partition "**Основной поток (UI)**" {
|
||||
:(A) Главный экран:
|
||||
список локальных и удалённых vault;
|
||||
:Действия пользователя
|
||||
(открыть, зашифровать, содержимое…);
|
||||
:(A) Main: LocalVault — список storage,
|
||||
вкладка удалённых — список IVault;
|
||||
:Действия с **storage**
|
||||
(шифрование, открытие, файлы…);
|
||||
}
|
||||
|
||||
fork
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@startuml fig_02_vault_lifecycle
|
||||
scale 3
|
||||
title
|
||||
Wallenc — пользовательский поток: жизненный цикл vault
|
||||
и точки постановки в очередь синхронизации (проект)
|
||||
Wallenc — жизненный цикл storage (IStorage)
|
||||
внутри IVault; журнал синхронизации
|
||||
end title
|
||||
|
||||
skinparam defaultFontName "DejaVu Sans"
|
||||
@@ -13,45 +13,41 @@ skinparam state {
|
||||
skinparam noteBackgroundColor #E3F2FD
|
||||
skinparam noteBorderColor #1565C0
|
||||
|
||||
state "(Б) Список vault" as List
|
||||
state "(Б) Список storage\n(LocalVault или VaultBrowser)" as List
|
||||
|
||||
List --> Create : Создать vault
|
||||
Create --> List : Vault создан
|
||||
List --> Create : Создать storage\n(FAB)
|
||||
Create --> List : Storage создан
|
||||
|
||||
List --> EncryptDlg : Включить шифрование
|
||||
EncryptDlg --> Encrypting : Подтверждение, мастер-ключ
|
||||
List --> EncryptDlg : Включить шифрование storage
|
||||
EncryptDlg --> Encrypting : Подтверждение, ключ
|
||||
state Encrypting {
|
||||
state "Шифрование данных + запись метаданных" as EncWork
|
||||
state "Шифрование + метаданные Room" as EncWork
|
||||
}
|
||||
Encrypting --> List : Готово
|
||||
|
||||
note right of Encrypting
|
||||
После успешной записи **коммита**
|
||||
в историю Storage (проект):
|
||||
UUID storage → **очередь синхронизации**
|
||||
в Room (для таймера)
|
||||
Запись в журнал sync (проект):
|
||||
UUID **storage** → очередь
|
||||
группы DbStorageSyncGroup
|
||||
end note
|
||||
|
||||
List --> OpenDlg : Открыть зашифрованный
|
||||
List --> OpenDlg : Открыть зашифрованный storage
|
||||
OpenDlg --> Opened : Ключ верный
|
||||
OpenDlg --> List : Отмена / неверный ключ
|
||||
|
||||
state Opened {
|
||||
state "Просмотр / работа с содержимым" as Browse
|
||||
state "Файлы, секреты, 2FA\n(StorageHome)" as Browse
|
||||
}
|
||||
Opened --> List : Закрыть vault / блокировка
|
||||
Opened --> List : Закрыть / заблокировать storage
|
||||
|
||||
List --> RenameDel : Переименовать / удалить
|
||||
List --> RenameDel : Переименовать / удалить storage
|
||||
RenameDel --> List : Подтверждение
|
||||
|
||||
note bottom of List
|
||||
**Синхронизация (проект):** любое изменение,
|
||||
порождающее новый **коммит** в Storage,
|
||||
добавляет storage UUID в таблицу очереди;
|
||||
**SyncService** по таймеру обрабатывает очередь,
|
||||
сравнивает истории коммитов с удалённой копией
|
||||
и приводит зашифрованное содержимое
|
||||
к одному состоянию (без передачи ключей).
|
||||
**Синхронизация:** изменения в **storage**
|
||||
пишутся в журнал; StorageSyncEngine
|
||||
согласует группы storage по ревизиям
|
||||
(зашифрованное содержимое, без ключей).
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@startuml fig_03_navigation_hub
|
||||
scale 2
|
||||
title
|
||||
Wallenc — навигация от главного экрана
|
||||
и связь с фоновой синхронизацией (проект)
|
||||
Wallenc — навигация (Main) и доменная иерархия
|
||||
VaultsManager → IVault → IStorage → файлы
|
||||
end title
|
||||
|
||||
skinparam defaultFontName "DejaVu Sans"
|
||||
@@ -13,39 +13,42 @@ skinparam noteBorderColor #C2185B
|
||||
|
||||
start
|
||||
|
||||
:(A) Главный экран:
|
||||
список локальных vault;
|
||||
partition "**Main: нижняя навигация**" {
|
||||
:(A) Вкладка LocalVault\n(один LocalVault на устройстве);
|
||||
note right
|
||||
На экране — список **IStorage**,
|
||||
не список vault
|
||||
end note
|
||||
|
||||
repeat
|
||||
:Ожидание действия пользователя;
|
||||
backward:Назад с подэкрана;
|
||||
switch (Действие?)
|
||||
case (FAB / новый vault)
|
||||
:Создание локального vault;
|
||||
case (Выбор vault)
|
||||
:Карточка / детали vault;
|
||||
case (Удалённые vault)
|
||||
:Экран удалённых vault;
|
||||
if (Нужен OAuth Яндекс?) then (да)
|
||||
:Авторизация Яндекс;
|
||||
endif
|
||||
case (Настройки)
|
||||
:Экран настроек;
|
||||
endswitch
|
||||
repeat while (Пользователь в приложении?) is (да)
|
||||
-> нет;
|
||||
repeat
|
||||
:Ожидание действия;
|
||||
backward:Назад с вложенного экрана;
|
||||
switch (Действие?)
|
||||
case (FAB)
|
||||
:createStorage()\nновый **storage** в LocalVault;
|
||||
case (Выбор storage)
|
||||
:StorageHome:\nфайлы, 2FA, текстовые секреты;
|
||||
case (Вкладка «Удалённые vault»)
|
||||
:Список **IVault** (Yandex по OAuth);
|
||||
if (Нужен OAuth?) then (да)
|
||||
:Авторизация Яндекс;
|
||||
endif
|
||||
:Выбор vault → VaultBrowser;
|
||||
:Список **storage** в выбранном vault;
|
||||
:StorageHome;
|
||||
endswitch
|
||||
repeat while (Пользователь в Main?) is (да)
|
||||
-> нет;
|
||||
}
|
||||
|
||||
stop
|
||||
|
||||
floating note right
|
||||
**Фон: SyncWorker (по таймеру Android) — проект**
|
||||
• Room: таблица очереди с **UUID storage**
|
||||
• Периодический запуск метода синхронизации
|
||||
• Для каждого Storage — история **коммитов** (как git)
|
||||
• Сравнение локальной и удалённой истории,
|
||||
приведение зашифрованного содержимого
|
||||
к одному состоянию (ключи на сервер не уходят)
|
||||
• Работает **независимо** от текущего экрана UI
|
||||
**Фон: StorageSyncEngine**
|
||||
• DbStorageSyncGroup: UUID **storage** в группе
|
||||
• Журнал изменений по путям, merge ревизий
|
||||
• Независимо от текущего экрана UI
|
||||
• Ключи шифрования провайдеру не передаются
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@startuml fig_04_domain_class
|
||||
title Модуль :domain — IVaultsManager / IVault / IStorage
|
||||
scale 1.15
|
||||
skinparam shadowing false
|
||||
skinparam classFontSize 10
|
||||
@@ -23,9 +24,13 @@ package usecases {
|
||||
class GetOpenedStoragesUseCase {
|
||||
+ getOpenedStorages(): StateFlow<Map<UUID, IStorageInfo>>
|
||||
}
|
||||
class ManageLocalVaultUseCase {
|
||||
+ getLocalStorages(): StateFlow<List<IStorageInfo>>
|
||||
+ createStorage(): Unit
|
||||
class ManageVaultUseCase {
|
||||
+ find(UUID): IVault?
|
||||
+ storagesOf(UUID): Flow<List<IStorage>>
|
||||
+ createStorage(UUID): IStorage
|
||||
}
|
||||
class FindStorageUseCase {
|
||||
+ find(UUID): IStorage?
|
||||
}
|
||||
class StorageFileManagementUseCase {
|
||||
+ getAllDirs(): Unit
|
||||
@@ -101,9 +106,6 @@ package interfaces {
|
||||
class ILogger {
|
||||
+ debug(String, String): void
|
||||
}
|
||||
class IYandexVault {
|
||||
+ getAccountEmail(): String
|
||||
}
|
||||
class IMetaInfo {
|
||||
+ getSize(): long
|
||||
+ isDeleted(): boolean
|
||||
@@ -125,13 +127,9 @@ package interfaces {
|
||||
+ isVirtualStorage(): boolean
|
||||
}
|
||||
class IVaultsManager {
|
||||
+ getLocalVault(): IVault
|
||||
+ removeRemoteVault(UUID): Unit
|
||||
+ addYandexVault(String): Unit
|
||||
+ getRemoteVaults(): StateFlow<List<IVault>>
|
||||
+ getAllStorages(): StateFlow<List<IStorage>>
|
||||
+ getAllVaults(): StateFlow<List<IVault>>
|
||||
+ getUnlockManager(): IUnlockManager
|
||||
+ vaults: StateFlow<List<IVault>>
|
||||
+ allStorages: StateFlow<List<IStorage>>
|
||||
+ unlockManager: IUnlockManager
|
||||
}
|
||||
class IStorageMetaInfo {
|
||||
+ getEncInfo(): StorageEncryptionInfo
|
||||
@@ -150,22 +148,16 @@ package interfaces {
|
||||
+ getMetaInfo(): StateFlow<IStorageMetaInfo>
|
||||
+ isVirtualStorage(): boolean
|
||||
}
|
||||
class IStorageExplorer {
|
||||
+ getCurrentPath(): StateFlow<String>
|
||||
}
|
||||
class IVaultInfo {
|
||||
+ getAvailableSpace(): StateFlow<Integer>
|
||||
+ getType(): VaultType
|
||||
+ getTotalSpace(): StateFlow<Integer>
|
||||
+ getUuid(): UUID
|
||||
+ isAvailable(): StateFlow<Boolean>
|
||||
+ getStorages(): StateFlow<List<IStorageInfo>>
|
||||
+ uuid: UUID
|
||||
}
|
||||
class IUnlockManager {
|
||||
+ openedStorages: StateFlow<Map<UUID, IStorage>>
|
||||
+ getOpenedStorageKey(UUID): EncryptKey
|
||||
+ open(IStorage, EncryptKey, boolean): IStorage
|
||||
+ rememberKey(IStorage, EncryptKey): Unit
|
||||
+ close(IStorage): Unit
|
||||
+ close(UUID): Unit
|
||||
+ open(IStorage, EncryptKey, boolean): Unit
|
||||
+ getOpenedStorages(): StateFlow<Map<UUID, IStorage>>
|
||||
}
|
||||
class IDirectory {
|
||||
+ getMetaInfo(): IMetaInfo
|
||||
@@ -194,15 +186,16 @@ package interfaces {
|
||||
+ getFileInfo(String): Unit
|
||||
}
|
||||
class IVault {
|
||||
+ getAvailableSpace(): StateFlow<Integer>
|
||||
+ getType(): VaultType
|
||||
+ getTotalSpace(): StateFlow<Integer>
|
||||
+ uuid: UUID
|
||||
+ storages: StateFlow<List<IStorage>>
|
||||
+ storagesScanInProgress: StateFlow<Boolean>
|
||||
+ isAvailable: StateFlow<Boolean>
|
||||
+ totalSpace: StateFlow<Long>
|
||||
+ availableSpace: StateFlow<Long>
|
||||
+ createStorage(): IStorage
|
||||
+ createStorage(StorageEncryptionInfo): IStorage
|
||||
+ remove(IStorage): Unit
|
||||
+ createStorage(StorageEncryptionInfo): Unit
|
||||
+ getUuid(): UUID
|
||||
+ isAvailable(): StateFlow<Boolean>
|
||||
+ getStorages(): StateFlow<List<IStorage>>
|
||||
+ createStorage(): Unit
|
||||
+ rescanStorages(): Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,25 +270,6 @@ package common.impl {
|
||||
}
|
||||
}
|
||||
|
||||
package auth {
|
||||
class RemoteYandexAuthResult {
|
||||
}
|
||||
class RemoteYandexSignInLauncher {
|
||||
+ launch(): void
|
||||
}
|
||||
}
|
||||
|
||||
package enums {
|
||||
class VaultType {
|
||||
+ DECRYPTED: VaultType
|
||||
+ LOCAL: VaultType
|
||||
+ YANDEX: VaultType
|
||||
+ valueOf(String): VaultType
|
||||
+ values(): VaultType[]
|
||||
+ getEntries(): EnumEntries<VaultType>
|
||||
}
|
||||
}
|
||||
|
||||
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageMetaInfo
|
||||
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageInfo
|
||||
usecases.ManageStoragesEncryptionUseCase ..> tasks.TaskProgress
|
||||
@@ -312,20 +286,16 @@ usecases.RemoveStorageUseCase ..> interfaces.IUnlockManager
|
||||
usecases.RemoveStorageUseCase ..> interfaces.IVault
|
||||
tasks.TaskLogLine ..> tasks.TaskLogLevel
|
||||
tasks.PipelineWork ..> tasks.TaskContext
|
||||
interfaces.IVault <|.. interfaces.IYandexVault
|
||||
interfaces.IVaultInfo <|.. interfaces.IYandexVault
|
||||
interfaces.IYandexVault ..> interfaces.IStorage
|
||||
interfaces.IYandexVault ..> interfaces.IVault
|
||||
interfaces.IYandexVault ..> enums.VaultType
|
||||
interfaces.IYandexVault ..> datatypes.StorageEncryptionInfo
|
||||
usecases.GetOpenedStoragesUseCase ..> interfaces.IStorageInfo
|
||||
usecases.GetOpenedStoragesUseCase ..> interfaces.IUnlockManager
|
||||
tasks.TaskContext ..> tasks.TaskLogLevel
|
||||
tasks.TaskContext ..> tasks.TaskProgress
|
||||
tasks.TaskContext ..> tasks.TaskId
|
||||
usecases.ManageLocalVaultUseCase ..> interfaces.IStorageInfo
|
||||
usecases.ManageLocalVaultUseCase ..> interfaces.IVaultsManager
|
||||
usecases.ManageLocalVaultUseCase ..> interfaces.IVault
|
||||
usecases.ManageVaultUseCase ..> interfaces.IStorage
|
||||
usecases.ManageVaultUseCase ..> interfaces.IVaultsManager
|
||||
usecases.ManageVaultUseCase ..> interfaces.IVault
|
||||
usecases.FindStorageUseCase ..> interfaces.IStorage
|
||||
usecases.FindStorageUseCase ..> interfaces.IVaultsManager
|
||||
usecases.StorageFileManagementUseCase ..> interfaces.IFile
|
||||
usecases.StorageFileManagementUseCase ..> interfaces.IStorage
|
||||
usecases.StorageFileManagementUseCase ..> interfaces.IStorageInfo
|
||||
@@ -362,9 +332,7 @@ interfaces.IStorageInfo ..> interfaces.IStorageMetaInfo
|
||||
interfaces.IStorageInfo ..> interfaces.IStorage
|
||||
usecases.RenameStorageUseCase ..> interfaces.IStorage
|
||||
usecases.RenameStorageUseCase ..> interfaces.IStorageInfo
|
||||
interfaces.IVaultInfo ..> interfaces.IStorageInfo
|
||||
interfaces.IVaultInfo ..> interfaces.IVault
|
||||
interfaces.IVaultInfo ..> enums.VaultType
|
||||
tasks.TaskForegroundItem ..> tasks.TaskProgress
|
||||
tasks.TaskForegroundItem ..> tasks.TaskId
|
||||
interfaces.IUnlockManager ..> interfaces.IStorage
|
||||
@@ -376,9 +344,7 @@ interfaces.IStorageAccessor ..> datatypes.DataPackage
|
||||
interfaces.IVaultInfo <|.. interfaces.IVault
|
||||
interfaces.IVault ..> interfaces.IStorage
|
||||
interfaces.IVault ..> interfaces.IVaultInfo
|
||||
interfaces.IVault ..> enums.VaultType
|
||||
interfaces.IVault ..> datatypes.StorageEncryptionInfo
|
||||
auth.RemoteYandexSignInLauncher ..> auth.RemoteYandexAuthResult
|
||||
datatypes.DataPackage <|-- datatypes.DataPage
|
||||
datatypes.DataPage ..> datatypes.DataPackage
|
||||
interfaces.IFile <|.. common.impl.CommonFile
|
||||
|
||||
@@ -12,7 +12,7 @@ rectangle "Wallenc\n(Android)" as App {
|
||||
|
||||
cloud "Внешний провайдер\n(Яндекс Диск API)" as Cloud
|
||||
|
||||
User --> UI : управление vault,\nфайлы, OAuth
|
||||
User --> UI : storage, vault,\nOAuth, файлы
|
||||
UI --> Domain
|
||||
Domain --> Room
|
||||
Domain --> Cloud : ciphertext,\nOAuth, метаданные API
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@startuml fig_15_bpmn_vault
|
||||
scale 2
|
||||
title BPMN: жизненный цикл vault
|
||||
title BPMN: жизненный цикл storage (IStorage)
|
||||
skinparam defaultFontName "DejaVu Sans"
|
||||
skinparam activity {
|
||||
BackgroundColor #F8F8F8
|
||||
@@ -8,20 +8,23 @@ skinparam activity {
|
||||
}
|
||||
|
||||
start
|
||||
:Создать vault;
|
||||
if (Нужно шифрование?) then (да)
|
||||
:Создать **storage** в vault\n(createStorage);
|
||||
note right
|
||||
Vault (IVault) не шифруется.
|
||||
Шифрование только у **storage**
|
||||
end note
|
||||
if (Включить шифрование storage?) then (да)
|
||||
:Ввести пароль;
|
||||
:Шифрование данных;
|
||||
:enableEncryption(storage);
|
||||
else (нет)
|
||||
endif
|
||||
:Открыть vault;
|
||||
:Работа с содержимым;
|
||||
if (Удалённое хранилище?) then (да)
|
||||
:OAuth / привязка;
|
||||
:Синхронизация;
|
||||
:openStorage(storage)\nпри необходимости;
|
||||
:Работа с содержимым storage:\nфайлы, 2FA, секреты;
|
||||
if (Storage в группе синхронизации?) then (да)
|
||||
:StorageSyncEngine\n(журнал ревизий);
|
||||
else (нет)
|
||||
endif
|
||||
:Закрыть vault;
|
||||
:closeStorage / блокировка;
|
||||
stop
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -10,14 +10,14 @@ skinparam activity {
|
||||
start
|
||||
:Пользователь включает шифрование;
|
||||
:Сформировать EncryptKey;
|
||||
:Encryptor.encrypt данные vault;
|
||||
:Записать StorageEncryptionInfo\nв Room;
|
||||
:Encryptor: шифрование файлов\n**storage** (IStorageAccessor);
|
||||
:storage.setEncInfo → Room\n(DbStorageMetaInfo);
|
||||
:checkKey(ключ);
|
||||
if (Ключ верный?) then (да)
|
||||
:openStorage(зашифрованное представление);
|
||||
:Доступ к содержимому;
|
||||
:IUnlockManager.open(storage)\nвиртуальное представление;
|
||||
:Доступ к файлам storage;
|
||||
else (нет)
|
||||
:Ошибка, vault закрыт;
|
||||
:Ошибка, storage не открыт;
|
||||
endif
|
||||
stop
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@startuml fig_22_cjm_vault
|
||||
scale 3
|
||||
title Customer Journey Map: защита vault
|
||||
title Customer Journey Map: защита storage
|
||||
skinparam defaultFontName "DejaVu Sans"
|
||||
|
||||
|Этап|
|
||||
@@ -11,9 +11,9 @@ skinparam defaultFontName "DejaVu Sans"
|
||||
|
||||
|Действия|
|
||||
|Понимает риск\nоблака|
|
||||
|Создаёт vault,\nвключает шифрование|
|
||||
|Открывает vault,\nработает с файлами|
|
||||
|Синхронизирует\nбез передачи ключей|
|
||||
|Создаёт storage,\nвключает шифрование storage|
|
||||
|Открывает storage,\nработает с файлами|
|
||||
|Синхронизирует storage\nбез передачи ключей|
|
||||
|
||||
|Ожидания|
|
||||
|Данные не читаются\nпровайдером|
|
||||
|
||||
@@ -24,7 +24,7 @@ Enc ..> ML : опционально\nлокальные эмбеддинги\nп
|
||||
|
||||
note bottom of ML
|
||||
Обучение: офлайн на размеченных\nсинтетических/агрегированных данных;
|
||||
выгрузка содержимого vault\nна облако для train — не используется
|
||||
выгрузка содержимого storage\nна облако для train — не используется
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
||||
Reference in New Issue
Block a user