Улучшение соответсвия
@@ -50,17 +50,17 @@ Wallenc — мобильное приложение для Android: `VaultsManag
|
|||||||
|
|
||||||
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог включения шифрования], "fig-06-rp")
|
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог включения шифрования], "fig-06-rp")
|
||||||
|
|
||||||
=== Открытие и закрытие зашифрованного vault
|
=== Открытие и закрытие зашифрованного storage
|
||||||
|
|
||||||
1. Для зашифрованного vault выберите «Открыть».
|
1. Для зашифрованного storage выберите «Открыть».
|
||||||
2. Введите пароль. При успехе содержимое доступно для просмотра.
|
2. Введите пароль. При успехе содержимое storage доступно для просмотра (`IUnlockManager`).
|
||||||
3. Используйте «Закрыть» для блокировки.
|
3. Используйте «Закрыть» для блокировки storage.
|
||||||
|
|
||||||
#pz-fig("fig_07_open_close_dialog.jpg", [Диалог открытия и закрытия], "fig-07-rp")
|
#pz-fig("fig_07_open_close_dialog.jpg", [Диалог открытия и закрытия], "fig-07-rp")
|
||||||
|
|
||||||
=== Переименование и удаление
|
=== Переименование и удаление
|
||||||
|
|
||||||
Долгое нажатие или меню vault → «Переименовать» / «Удалить». Подтвердите действие в диалоге.
|
Долгое нажатие или меню storage → «Переименовать» / «Удалить». Подтвердите действие в диалоге.
|
||||||
|
|
||||||
#pz-fig("fig_08_rename_delete_dialog.jpg", [Диалог переименования и удаления], "fig-08-rp")
|
#pz-fig("fig_08_rename_delete_dialog.jpg", [Диалог переименования и удаления], "fig-08-rp")
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
| № | Имя файла | Тип | Статус | Где в ПЗ | Примечание (содержание) | label |
|
| № | Имя файла | Тип | Статус | Где в ПЗ | Примечание (содержание) | label |
|
||||||
|---|-----------|-----|--------|----------|-------------------------|-------|
|
|---|-----------|-----|--------|----------|-------------------------|-------|
|
||||||
| 01 | `fig_01_start_sync.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Старт → Room → SyncWorker. **PUML** | fig-01 |
|
| 01 | `fig_01_start_sync.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Старт → Room → SyncWorker. **PUML** | fig-01 |
|
||||||
| 02 | `fig_02_vault_lifecycle.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Жизненный цикл storage. **PUML** | fig-02 |
|
| 02 | `fig_02_vault_lifecycle.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Жизненный цикл **IStorage** (не vault). **PUML** | fig-02 |
|
||||||
| 03 | `fig_03_navigation_hub.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Навигация + SyncWorker. **PUML** | fig-03 |
|
| 03 | `fig_03_navigation_hub.png` | PlantUML | ready | гл. 3.3.3, 4.1.4 | Main: LocalVault → storage; удалённые vault → VaultBrowser → storage. **PUML** | fig-03 |
|
||||||
| 04 | `fig_04_domain_class.png` | PlantUML | ready | гл. 2.3.2, 4.2.1 | Классы `:domain`. **PUML** | fig-04 |
|
| 04 | `fig_04_domain_class.png` | PlantUML | ready | гл. 2.3.2, 4.2.1 | Классы `:domain`. **PUML** | fig-04 |
|
||||||
| 05 | `fig_05_local_vaults.jpg` | Скриншот UI | ready | гл. 3.4, 5, прил. Б, В | Список storage (локальный vault) | fig-05 |
|
| 05 | `fig_05_local_vaults.jpg` | Скриншот UI | ready | гл. 3.4, 5, прил. Б, В | Список storage (локальный vault) | fig-05 |
|
||||||
| 06 | `fig_06_encrypt_dialog.jpg` | Скриншот UI | ready | гл. 3.4, 4.1.1, 5, прил. Б, В | Диалог включения шифрования | fig-06 |
|
| 06 | `fig_06_encrypt_dialog.jpg` | Скриншот UI | ready | гл. 3.4, 4.1.1, 5, прил. Б, В | Диалог включения шифрования | fig-06 |
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
| 12 | `fig_12_tasks_screen.jpg` | Скриншот UI | ready | гл. 5.2.3, прил. В | Экран задач | fig-12 |
|
| 12 | `fig_12_tasks_screen.jpg` | Скриншот UI | ready | гл. 5.2.3, прил. В | Экран задач | fig-12 |
|
||||||
| 13 | `fig_13_tasks_notification.jpg` | Скриншот UI | ready | гл. 5.2.3, прил. В | Уведомление о задаче | fig-13 |
|
| 13 | `fig_13_tasks_notification.jpg` | Скриншот UI | ready | гл. 5.2.3, прил. В | Уведомление о задаче | fig-13 |
|
||||||
| 14 | `fig_14_context_system.png` | PlantUML | ready | гл. 1.2.1, 2.1.4 | Контекстная диаграмма. **PUML** | fig-14 |
|
| 14 | `fig_14_context_system.png` | PlantUML | ready | гл. 1.2.1, 2.1.4 | Контекстная диаграмма. **PUML** | fig-14 |
|
||||||
| 15 | `fig_15_bpmn_vault.png` | PlantUML | ready | гл. 2.1.3 | BPMN. **PUML** | fig-15 |
|
| 15 | `fig_15_bpmn_vault.png` | PlantUML | ready | гл. 2.1.3 | BPMN жизненный цикл **storage** (шифрование storage, не vault). **PUML** | fig-15 |
|
||||||
| 16 | `fig_16_dfd_level0.png` | PlantUML | ready | гл. 2.2 | DFD-0. **PUML** | fig-16 |
|
| 16 | `fig_16_dfd_level0.png` | PlantUML | ready | гл. 2.2 | DFD-0. **PUML** | fig-16 |
|
||||||
| 17 | `fig_17_use_case.png` | PlantUML | ready | гл. 2.3.1 | Прецеденты. **PUML** | fig-17 |
|
| 17 | `fig_17_use_case.png` | PlantUML | ready | гл. 2.3.1 | Прецеденты. **PUML** | fig-17 |
|
||||||
| 18 | `fig_18_deployment.png` | PlantUML | ready | гл. 2.3.3 | Развёртывание. **PUML** | fig-18 |
|
| 18 | `fig_18_deployment.png` | PlantUML | ready | гл. 2.3.3 | Развёртывание. **PUML** | fig-18 |
|
||||||
@@ -60,6 +60,8 @@
|
|||||||
|
|
||||||
Номер «Рисунок N» — по порядку появления в тексте, не по номеру в имени файла.
|
Номер «Рисунок N» — по порядку появления в тексте, не по номеру в имени файла.
|
||||||
|
|
||||||
|
Пример: **Рисунок 3** в ПЗ — это `fig_15_bpmn_vault.png` (гл. 2), а не `fig_03_navigation_hub.png` (гл. 3, обычно ~рис. 6).
|
||||||
|
|
||||||
## fig_31
|
## fig_31
|
||||||
|
|
||||||
Один скрин `./gradlew connectedDebugAndroidTest` из корня репозитория, `BUILD SUCCESSFUL` (см. прежнее описание в истории реестра).
|
Один скрин `./gradlew connectedDebugAndroidTest` из корня репозитория, `BUILD SUCCESSFUL` (см. прежнее описание в истории реестра).
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 560 KiB After Width: | Height: | Size: 501 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 108 KiB |
@@ -7,7 +7,7 @@
|
|||||||
В настоящем документе применяются следующие обозначения и сокращения:
|
В настоящем документе применяются следующие обозначения и сокращения:
|
||||||
|
|
||||||
#pz-table(
|
#pz-table(
|
||||||
[],
|
[Обозначения и сокращения],
|
||||||
2,
|
2,
|
||||||
table.header([Обозначение], [Расшифровка]),
|
table.header([Обозначение], [Расшифровка]),
|
||||||
[API], [Application Programming Interface — программный интерфейс приложения],
|
[API], [Application Programming Interface — программный интерфейс приложения],
|
||||||
|
|||||||
@@ -12,15 +12,11 @@
|
|||||||
#pz-front-heading(page-break: false)[Annotation]
|
#pz-front-heading(page-break: false)[Annotation]
|
||||||
|
|
||||||
#{
|
#{
|
||||||
set par(first-line-indent: 0pt, justify: true)
|
set par(first-line-indent: 1.25cm, justify: true)
|
||||||
|
|
||||||
[The thesis is devoted to a mobile application for secure storage of user data (the Wallenc software product). Data is encrypted on the device before upload; decryption is performed only when the user enters a valid key. The work includes analysis of analogues, requirements, architecture and UI design, Kotlin implementation for Android, testing, and a brief economic assessment.]
|
[This explanatory note is devoted to the development of a mobile application for secure storage of user data (the Wallenc software product). It describes analysis of the subject area and analogues, requirements formulation, architecture and user interface design, software implementation in Kotlin (Android, Jetpack Compose, Room, Hilt), testing, and a brief economic assessment.]
|
||||||
|
|
||||||
parbreak()
|
parbreak()
|
||||||
|
|
||||||
[The application uses MVVM and Clean Architecture. Main features are local and remote vault management, client-side AES encryption, Room metadata storage, and Yandex OAuth integration.]
|
[Implemented: the VaultsManager → vault → storage → files hierarchy (one LocalVault on the device, remote vaults via OAuth), client-side AES encryption, service metadata in Room, and a project-level synchronization contour without passing encryption keys to the provider. The source code is hosted in a private GitLab repository at Southern Federal University. Full source listings are in Appendix A; software documentation is in Appendix B.]
|
||||||
|
|
||||||
parbreak()
|
|
||||||
|
|
||||||
[Keywords: mobile application, client-side encryption, Android, vault, OAuth, Room.]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
=== Назначение и цели создания системы
|
=== Назначение и цели создания системы
|
||||||
|
|
||||||
*Назначение* системы Wallenc — предоставление пользователю мобильного клиента для работы с иерархией *vault → storage → файлы*: один локальный vault на устройстве, удалённые vault по учётным записям провайдера; внутри каждого vault пользователь управляет отдельными storage с обязательным клиентским шифрованием до выгрузки во внешнее хранилище.
|
*Назначение* системы Wallenc — предоставление пользователю мобильного клиента для работы с иерархией *VaultsManager → vault → storage → файлы*: один `LocalVault` на устройстве, удалённые vault по OAuth; внутри vault пользователь создаёт и управляет *storage*; шифрование (`StorageEncryptionInfo`, `Encryptor`) применяется к storage, а не к vault.
|
||||||
|
|
||||||
*Цели создания*: обеспечить единую модель vault и storage; минимизировать доверие к провайдеру; поддержать расширение списка провайдеров через адаптеры; сохранить служебные метаданные в локальной БД без хранения пользовательского контента в открытом виде.
|
*Цели создания*: обеспечить единую модель vault и storage; минимизировать доверие к провайдеру; поддержать расширение списка провайдеров через адаптеры; сохранить служебные метаданные в локальной БД без хранения пользовательского контента в открытом виде.
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
|
|
||||||
=== Карта процессов
|
=== Карта процессов
|
||||||
|
|
||||||
Основные процессы: создание storage в vault → опциональное шифрование → открытие → работа с файлами → закрытие; для удалённых vault — OAuth → привязка учётной записи → листинг storage провайдера → проектная синхронизация.
|
Основные процессы: создание storage в vault → опциональное шифрование storage → открытие storage → работа с файлами → закрытие; для удалённых vault — OAuth → привязка учётной записи → листинг storage провайдера → проектная синхронизация.
|
||||||
|
|
||||||
=== Диаграмма BPMN
|
=== Диаграмма BPMN
|
||||||
|
|
||||||
На рисунке @fig-15 представлена диаграмма BPMN основного процесса работы с vault.
|
На рисунке @fig-15 представлена диаграмма BPMN основного процесса работы со storage внутри vault.
|
||||||
|
|
||||||
#pz-fig("fig_15_bpmn_vault.png", [BPMN: создание vault, шифрование, открытие, работа с содержимым], "fig-15")
|
#pz-fig("fig_15_bpmn_vault.png", [BPMN: storage — создание, шифрование, открытие, содержимое], "fig-15")
|
||||||
|
|
||||||
=== Карта систем
|
=== Карта систем
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ DFD уровня 0 (рис. @fig-16) отражает потоки между UI
|
|||||||
|
|
||||||
=== Диаграмма прецедентов
|
=== Диаграмма прецедентов
|
||||||
|
|
||||||
Прецеденты включают управление vault, шифрование, работу с содержимым, OAuth и проектную синхронизацию (рис. @fig-17).
|
Прецеденты включают управление storage, подключение удалённых vault (OAuth), шифрование и открытие storage, работу с файлами и синхронизацию групп storage (рис. @fig-17).
|
||||||
|
|
||||||
#pz-fig("fig_17_use_case.png", [Диаграмма прецедентов Wallenc], "fig-17")
|
#pz-fig("fig_17_use_case.png", [Диаграмма прецедентов Wallenc], "fig-17")
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
=== Анализ конкурентов и определение сильных и слабых сторон
|
=== Анализ конкурентов и определение сильных и слабых сторон
|
||||||
|
|
||||||
По результатам сравнения аналогов (табл. @tbl-analog) для Wallenc выделены сильные стороны: единый UI для локальных и удалённых vault, явное отображение состояния шифрования, диалоги подтверждения деструктивных операций. Слабые стороны конкурентов (привязка к экосистеме, узкая предметная область) учтены при проектировании навигации.
|
По результатам сравнения аналогов (табл. @tbl-analog) для Wallenc выделены сильные стороны: единый UI для списков storage (в LocalVault и удалённых vault), явное отображение состояния шифрования storage, диалоги подтверждения деструктивных операций. Слабые стороны конкурентов (привязка к экосистеме, узкая предметная область) учтены при проектировании навигации.
|
||||||
|
|
||||||
=== Ограничения и допущения проектирования UI
|
=== Ограничения и допущения проектирования UI
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
=== Потребности и барьеры пользователя
|
=== Потребности и барьеры пользователя
|
||||||
|
|
||||||
Потребности: хранить файлы в «сейфе» без доверия к облаку; синхронизировать между устройствами. Барьеры: сложность OAuth, страх потери пароля, неочевидность состояния «vault открыт».
|
Потребности: хранить файлы в «сейфе» без доверия к облаку; синхронизировать между устройствами. Барьеры: сложность OAuth, страх потери пароля, неочевидность состояния «storage открыт» (разблокирован).
|
||||||
|
|
||||||
=== Полезные сценарии из аналогов
|
=== Полезные сценарии из аналогов
|
||||||
|
|
||||||
@@ -31,26 +31,26 @@
|
|||||||
3,
|
3,
|
||||||
table.header([ID], [Формулировка], [Критерий приёмки]),
|
table.header([ID], [Формулировка], [Критерий приёмки]),
|
||||||
[US-1], [Создаю storage для файлов в локальном vault на устройстве], [Storage в списке (рис. 5)],
|
[US-1], [Создаю storage для файлов в локальном vault на устройстве], [Storage в списке (рис. 5)],
|
||||||
[US-2], [Включаю шифрование vault паролем], [Статус encrypted, тест T-8],
|
[US-2], [Включаю шифрование storage паролем], [Статус encrypted, тест T-8],
|
||||||
[US-3], [Открываю зашифрованный vault ключом], [Доступ к контенту, тест T-9],
|
[US-3], [Открываю зашифрованный storage ключом], [Доступ к контенту, тест T-9],
|
||||||
[US-4], [Подключаю Яндекс и удалённый vault], [OAuth OK, тест T-10],
|
[US-4], [Подключаю Яндекс и удалённый vault], [OAuth OK, тест T-10],
|
||||||
[US-5], [Вижу прогресс фоновых задач], [Экран задач, тест T-11],
|
[US-5], [Вижу прогресс фоновых задач], [Экран задач, тест T-11],
|
||||||
[US-6], [Храню TOTP и текстовые секреты в vault], [`TwoFaTotpTest`, UI IT],
|
[US-6], [Храню TOTP и текстовые секреты в storage], [`TwoFaTotpTest`, UI IT],
|
||||||
) <tbl-userstory>
|
) <tbl-userstory>
|
||||||
|
|
||||||
=== Customer Journey Map
|
=== Customer Journey Map
|
||||||
|
|
||||||
CJM сценария «защитить и открыть vault» представлен на рисунке @fig-22.
|
CJM сценария «защитить и открыть storage» представлен на рисунке @fig-22.
|
||||||
|
|
||||||
#pz-fig("fig_22_cjm_vault.png", [Customer Journey Map: защита и открытие vault], "fig-22")
|
#pz-fig("fig_22_cjm_vault.png", [Customer Journey Map: защита и открытие storage], "fig-22")
|
||||||
|
|
||||||
=== Пользовательский сценарий
|
=== Пользовательский сценарий
|
||||||
|
|
||||||
Диаграммы потоков: старт приложения и фоновая синхронизация (@fig-01), жизненный цикл vault (@fig-02), навигация с главного экрана (@fig-03).
|
Диаграммы потоков: старт приложения и фоновая синхронизация (@fig-01), жизненный цикл storage (@fig-02), навигация Main: LocalVault / удалённые vault → storage (@fig-03).
|
||||||
|
|
||||||
#pz-fig("fig_01_start_sync.png", [Старт приложения и фоновая синхронизация (проект)], "fig-01")
|
#pz-fig("fig_01_start_sync.png", [Старт приложения и фоновая синхронизация], "fig-01")
|
||||||
#pz-fig("fig_02_vault_lifecycle.png", [Жизненный цикл vault и очередь синхронизации], "fig-02")
|
#pz-fig("fig_02_vault_lifecycle.png", [Жизненный цикл storage и журнал синхронизации], "fig-02")
|
||||||
#pz-fig("fig_03_navigation_hub.png", [Навигация с главного экрана и SyncWorker], "fig-03")
|
#pz-fig("fig_03_navigation_hub.png", [Навигация Main: список storage, VaultBrowser, StorageHome], "fig-03")
|
||||||
|
|
||||||
== Проработка прототипа и особенности дизайна
|
== Проработка прототипа и особенности дизайна
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ CJM сценария «защитить и открыть vault» предста
|
|||||||
|
|
||||||
#pz-fig("fig_05_local_vaults.jpg", [Список storage в локальном vault (экран «локальные vault»)], "fig-05")
|
#pz-fig("fig_05_local_vaults.jpg", [Список storage в локальном vault (экран «локальные vault»)], "fig-05")
|
||||||
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог включения шифрования], "fig-06")
|
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог включения шифрования], "fig-06")
|
||||||
#pz-fig("fig_07_open_close_dialog.jpg", [Диалог открытия и закрытия vault], "fig-07")
|
#pz-fig("fig_07_open_close_dialog.jpg", [Диалог открытия и закрытия storage], "fig-07")
|
||||||
#pz-fig("fig_08_rename_delete_dialog.jpg", [Диалог переименования и удаления], "fig-08")
|
#pz-fig("fig_08_rename_delete_dialog.jpg", [Диалог переименования и удаления], "fig-08")
|
||||||
#pz-fig("fig_09_remote_vaults.jpg", [Экран удалённых vault], "fig-09")
|
#pz-fig("fig_09_remote_vaults.jpg", [Экран удалённых vault], "fig-09")
|
||||||
#pz-fig("fig_10_yandex_oauth.jpg", [Добавление удалённого vault, OAuth Яндекс], "fig-10")
|
#pz-fig("fig_10_yandex_oauth.jpg", [Добавление удалённого vault, OAuth Яндекс], "fig-10")
|
||||||
@@ -67,7 +67,7 @@ CJM сценария «защитить и открыть vault» предста
|
|||||||
|
|
||||||
== Требования к эргономике и доступности
|
== Требования к эргономике и доступности
|
||||||
|
|
||||||
Интерфейс должен отображать состояние vault без перехода в технические экраны: признаки «зашифровано», «открыто», «выполняется операция» (`isBusy`). Диалоги деструктивных действий (удаление, отключение шифрования) требуют явного подтверждения. Тексты сообщений об ошибках OAuth и неверном ключе формулируются нейтрально, без раскрытия внутренних путей и имён файлов.
|
Интерфейс должен отображать состояние каждого storage без перехода в технические экраны: признаки «зашифровано», «открыто» (`IUnlockManager.openedStorages`), «выполняется операция» (`isBusy`). Диалоги деструктивных действий (удаление storage, отключение шифрования) требуют явного подтверждения. Тексты сообщений об ошибках OAuth и неверном ключе формулируются нейтрально, без раскрытия внутренних путей и имён файлов.
|
||||||
|
|
||||||
== Вывод
|
== Вывод
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
Класс `Encryptor` формирует `StorageEncryptionInfo`, проверяет ключ и выполняет шифрование/дешифрование на клиенте. Unit-тесты подтверждают корректность для верного и неверного ключа (гл. 5).
|
Класс `Encryptor` формирует `StorageEncryptionInfo`, проверяет ключ и выполняет шифрование/дешифрование на клиенте. Unit-тесты подтверждают корректность для верного и неверного ключа (гл. 5).
|
||||||
|
|
||||||
=== Модуль управления vault и шифрованием
|
=== Модуль управления storage и шифрованием
|
||||||
|
|
||||||
Use case `ManageStoragesEncryptionUseCase` инкапсулирует проверку `canEncrypt`, включение шифрования и открытие хранилища. ViewModel предотвращает повторный запуск шифрования для занятого storage.
|
Use case `ManageStoragesEncryptionUseCase` инкапсулирует проверку `canEncrypt`, включение шифрования и открытие хранилища. ViewModel предотвращает повторный запуск шифрования для занятого storage.
|
||||||
|
|
||||||
@@ -136,12 +136,12 @@ abstract class AppDb : IAppDb, RoomDatabase()
|
|||||||
Модуль `:ui` и `:app` содержат Compose-экраны, ViewModel и навигацию. OAuth Яндекс запускается из UI удалённых vault:
|
Модуль `:ui` и `:app` содержат Compose-экраны, ViewModel и навигацию. OAuth Яндекс запускается из UI удалённых vault:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
viewModel.yandexSignIn.launch { outcome ->
|
remoteVaultAuthenticator.beginLink(CloudBrand.YANDEX) { outcome ->
|
||||||
when (outcome) {
|
when (outcome) {
|
||||||
is RemoteYandexAuthResult.Success ->
|
is VaultLinkOutcome.Success ->
|
||||||
viewModel.onYandexAuthSuccess(outcome.accessToken)
|
viewModel.onVaultLinked(outcome.registration)
|
||||||
is RemoteYandexAuthResult.Failure -> { /* ошибка */ }
|
is VaultLinkOutcome.Failed -> { /* ошибка */ }
|
||||||
RemoteYandexAuthResult.Cancelled -> { }
|
VaultLinkOutcome.Cancelled -> { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
[T-5], [2FA TOTP генерация], [Unit], [Да], [Совпадение с эталоном Java OTP],
|
[T-5], [2FA TOTP генерация], [Unit], [Да], [Совпадение с эталоном Java OTP],
|
||||||
[T-6], [Маппинг ошибок сети/диска], [Unit], [Да], [Типизированные `WallencException`],
|
[T-6], [Маппинг ошибок сети/диска], [Unit], [Да], [Типизированные `WallencException`],
|
||||||
[T-7], [CRUD storage в LocalVault], [Ручной], [Нет], [Список обновлён (рис. @fig-05)],
|
[T-7], [CRUD storage в LocalVault], [Ручной], [Нет], [Список обновлён (рис. @fig-05)],
|
||||||
[T-8], [Включение шифрования vault], [Ручной], [Нет], [Статус «зашифровано» (рис. @fig-06)],
|
[T-8], [Включение шифрования storage], [Ручной], [Нет], [Статус «зашифровано» (рис. @fig-06)],
|
||||||
[T-9], [Открытие/закрытие vault], [Ручной], [Нет], [Доступ только с ключом (рис. @fig-07)],
|
[T-9], [Открытие/закрытие storage], [Ручной], [Нет], [Доступ только с ключом (рис. @fig-07)],
|
||||||
[T-10], [OAuth Яндекс], [Ручной / IT], [Частично], [Токен в Room (рис. @fig-10)],
|
[T-10], [OAuth Яндекс], [Ручной / IT], [Частично], [Токен в Room (рис. @fig-10)],
|
||||||
[T-11], [Экран задач и уведомления], [Ручной], [Частично], [Прогресс и завершение (рис. 12–13)],
|
[T-11], [Экран задач и уведомления], [Ручной], [Частично], [Прогресс и завершение (рис. 12–13)],
|
||||||
[T-12], [Compose: секреты и 2FA], [IT], [Да], [Отображение без падений (рис. @fig-33–@fig-34)],
|
[T-12], [Compose: секреты и 2FA], [IT], [Да], [Отображение без падений (рис. @fig-33–@fig-34)],
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
table.header([ID], [Шаг], [Статус], [Фактический результат], [Иллюстрация]),
|
table.header([ID], [Шаг], [Статус], [Фактический результат], [Иллюстрация]),
|
||||||
[T-7], [Создать storage в LocalVault], [OK], [Storage в списке], [@fig-05],
|
[T-7], [Создать storage в LocalVault], [OK], [Storage в списке], [@fig-05],
|
||||||
[T-8], [Включить шифрование], [OK], [Статус encrypted], [@fig-06],
|
[T-8], [Включить шифрование], [OK], [Статус encrypted], [@fig-06],
|
||||||
[T-9], [Открыть/закрыть vault], [OK], [Контент только при открытом vault], [@fig-07],
|
[T-9], [Открыть/закрыть storage], [OK], [Контент только при открытом storage], [@fig-07],
|
||||||
[T-10], [OAuth Яндекс], [OK], [Запись в `DbYandexAccount`], [@fig-10],
|
[T-10], [OAuth Яндекс], [OK], [Запись в `DbYandexAccount`], [@fig-10],
|
||||||
[T-11], [Фоновая задача шифрования], [OK], [Прогресс на экране задач], [рис. 12],
|
[T-11], [Фоновая задача шифрования], [OK], [Прогресс на экране задач], [рис. 12],
|
||||||
[T-12], [Уведомление о завершении], [OK], [Notification отображён], [рис. 13],
|
[T-12], [Уведомление о завершении], [OK], [Notification отображён], [рис. 13],
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#emph[Способен решать прикладные задачи анализа данных и принятия решений с использованием искусственного интеллекта.]
|
#emph[Способен решать прикладные задачи анализа данных и принятия решений с использованием искусственного интеллекта.]
|
||||||
|
|
||||||
В текущей версии Wallenc модели машинного обучения в runtime не внедрены: продукт строится на zero-knowledge модели, отсутствует доверенный сервер приложения, а выгрузка расшифрованного содержимого vault на облако для обучения противоречила бы заявленным требованиям безопасности. Ниже рассмотрено, какие прикладные задачи анализа данных и автоматизированных решений *могли бы* быть добавлены в перспективе без нарушения клиентской модели угроз.
|
В текущей версии Wallenc модели машинного обучения в runtime не внедрены: продукт строится на zero-knowledge модели, отсутствует доверенный сервер приложения, а выгрузка расшифрованного содержимого storage на облако для обучения противоречила бы заявленным требованиям безопасности. Ниже рассмотрено, какие прикладные задачи анализа данных и автоматизированных решений *могли бы* быть добавлены в перспективе без нарушения клиентской модели угроз.
|
||||||
|
|
||||||
== Связь компетенции с предметом ВКР
|
== Связь компетенции с предметом ВКР
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Таблицы — как в «Пример работы с Typst.typ» и gost: figure + table + table.header.
|
// Таблицы — как в «Пример работы с Typst.typ» и gost: figure + table + table.header.
|
||||||
// Разрыв длинных таблиц и подпись сверху задаёт шаблон modern-g7-32 (style.typ).
|
// Разрыв длинных таблиц и подпись сверху задаёт шаблон modern-g7-32 (style.typ).
|
||||||
|
|
||||||
#show table: set text(hyphenate: true)
|
#show table: set text(hyphenate: true, lang: "ru")
|
||||||
|
|
||||||
#let pz-appendix-title(body) = heading(level: 1)[#body]
|
#let pz-appendix-title(body) = heading(level: 1)[#body]
|
||||||
|
|
||||||
@@ -160,19 +160,11 @@
|
|||||||
let start-page = state("pz-table-start-page", none)
|
let start-page = state("pz-table-start-page", none)
|
||||||
figure(
|
figure(
|
||||||
kind: table,
|
kind: table,
|
||||||
{
|
context {
|
||||||
show table: set text(hyphenate: true, lang: "ru")
|
let fig-loc = here()
|
||||||
show table.cell: it => {
|
let tab-num = counter(figure.where(kind: table)).at(fig-loc).first()
|
||||||
set align(left + top)
|
start-page.update(none)
|
||||||
set par(justify: false)
|
pz-table-inner(columns, header-cells, tab-num, start-page, ..arguments(..tail))
|
||||||
it
|
|
||||||
}
|
|
||||||
context {
|
|
||||||
let fig-loc = here()
|
|
||||||
let tab-num = counter(figure.where(kind: table)).at(fig-loc).first()
|
|
||||||
start-page.update(none)
|
|
||||||
pz-table-inner(columns, header-cells, tab-num, start-page, ..arguments(..tail))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
caption: caption,
|
caption: caption,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ start
|
|||||||
:Инициализация Room,
|
:Инициализация Room,
|
||||||
загрузка метаданных vault;
|
загрузка метаданных vault;
|
||||||
|
|
||||||
if (Есть сохранённые vault?) then (нет)
|
if (Есть LocalVault / storage?) then (нет)
|
||||||
:Экран «первый запуск» /
|
:Первый запуск;
|
||||||
создание локального vault;
|
|
||||||
else (да)
|
else (да)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -35,10 +34,10 @@ else (нет)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
partition "**Основной поток (UI)**" {
|
partition "**Основной поток (UI)**" {
|
||||||
:(A) Главный экран:
|
:(A) Main: LocalVault — список storage,
|
||||||
список локальных и удалённых vault;
|
вкладка удалённых — список IVault;
|
||||||
:Действия пользователя
|
:Действия с **storage**
|
||||||
(открыть, зашифровать, содержимое…);
|
(шифрование, открытие, файлы…);
|
||||||
}
|
}
|
||||||
|
|
||||||
fork
|
fork
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
@startuml fig_02_vault_lifecycle
|
@startuml fig_02_vault_lifecycle
|
||||||
scale 3
|
scale 3
|
||||||
title
|
title
|
||||||
Wallenc — пользовательский поток: жизненный цикл vault
|
Wallenc — жизненный цикл storage (IStorage)
|
||||||
и точки постановки в очередь синхронизации (проект)
|
внутри IVault; журнал синхронизации
|
||||||
end title
|
end title
|
||||||
|
|
||||||
skinparam defaultFontName "DejaVu Sans"
|
skinparam defaultFontName "DejaVu Sans"
|
||||||
@@ -13,45 +13,41 @@ skinparam state {
|
|||||||
skinparam noteBackgroundColor #E3F2FD
|
skinparam noteBackgroundColor #E3F2FD
|
||||||
skinparam noteBorderColor #1565C0
|
skinparam noteBorderColor #1565C0
|
||||||
|
|
||||||
state "(Б) Список vault" as List
|
state "(Б) Список storage\n(LocalVault или VaultBrowser)" as List
|
||||||
|
|
||||||
List --> Create : Создать vault
|
List --> Create : Создать storage\n(FAB)
|
||||||
Create --> List : Vault создан
|
Create --> List : Storage создан
|
||||||
|
|
||||||
List --> EncryptDlg : Включить шифрование
|
List --> EncryptDlg : Включить шифрование storage
|
||||||
EncryptDlg --> Encrypting : Подтверждение, мастер-ключ
|
EncryptDlg --> Encrypting : Подтверждение, ключ
|
||||||
state Encrypting {
|
state Encrypting {
|
||||||
state "Шифрование данных + запись метаданных" as EncWork
|
state "Шифрование + метаданные Room" as EncWork
|
||||||
}
|
}
|
||||||
Encrypting --> List : Готово
|
Encrypting --> List : Готово
|
||||||
|
|
||||||
note right of Encrypting
|
note right of Encrypting
|
||||||
После успешной записи **коммита**
|
Запись в журнал sync (проект):
|
||||||
в историю Storage (проект):
|
UUID **storage** → очередь
|
||||||
UUID storage → **очередь синхронизации**
|
группы DbStorageSyncGroup
|
||||||
в Room (для таймера)
|
|
||||||
end note
|
end note
|
||||||
|
|
||||||
List --> OpenDlg : Открыть зашифрованный
|
List --> OpenDlg : Открыть зашифрованный storage
|
||||||
OpenDlg --> Opened : Ключ верный
|
OpenDlg --> Opened : Ключ верный
|
||||||
OpenDlg --> List : Отмена / неверный ключ
|
OpenDlg --> List : Отмена / неверный ключ
|
||||||
|
|
||||||
state Opened {
|
state Opened {
|
||||||
state "Просмотр / работа с содержимым" as Browse
|
state "Файлы, секреты, 2FA\n(StorageHome)" as Browse
|
||||||
}
|
}
|
||||||
Opened --> List : Закрыть vault / блокировка
|
Opened --> List : Закрыть / заблокировать storage
|
||||||
|
|
||||||
List --> RenameDel : Переименовать / удалить
|
List --> RenameDel : Переименовать / удалить storage
|
||||||
RenameDel --> List : Подтверждение
|
RenameDel --> List : Подтверждение
|
||||||
|
|
||||||
note bottom of List
|
note bottom of List
|
||||||
**Синхронизация (проект):** любое изменение,
|
**Синхронизация:** изменения в **storage**
|
||||||
порождающее новый **коммит** в Storage,
|
пишутся в журнал; StorageSyncEngine
|
||||||
добавляет storage UUID в таблицу очереди;
|
согласует группы storage по ревизиям
|
||||||
**SyncService** по таймеру обрабатывает очередь,
|
(зашифрованное содержимое, без ключей).
|
||||||
сравнивает истории коммитов с удалённой копией
|
|
||||||
и приводит зашифрованное содержимое
|
|
||||||
к одному состоянию (без передачи ключей).
|
|
||||||
end note
|
end note
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
@startuml fig_03_navigation_hub
|
@startuml fig_03_navigation_hub
|
||||||
scale 2
|
scale 2
|
||||||
title
|
title
|
||||||
Wallenc — навигация от главного экрана
|
Wallenc — навигация (Main) и доменная иерархия
|
||||||
и связь с фоновой синхронизацией (проект)
|
VaultsManager → IVault → IStorage → файлы
|
||||||
end title
|
end title
|
||||||
|
|
||||||
skinparam defaultFontName "DejaVu Sans"
|
skinparam defaultFontName "DejaVu Sans"
|
||||||
@@ -13,39 +13,42 @@ skinparam noteBorderColor #C2185B
|
|||||||
|
|
||||||
start
|
start
|
||||||
|
|
||||||
:(A) Главный экран:
|
partition "**Main: нижняя навигация**" {
|
||||||
список локальных vault;
|
:(A) Вкладка LocalVault\n(один LocalVault на устройстве);
|
||||||
|
note right
|
||||||
|
На экране — список **IStorage**,
|
||||||
|
не список vault
|
||||||
|
end note
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
:Ожидание действия пользователя;
|
:Ожидание действия;
|
||||||
backward:Назад с подэкрана;
|
backward:Назад с вложенного экрана;
|
||||||
switch (Действие?)
|
switch (Действие?)
|
||||||
case (FAB / новый vault)
|
case (FAB)
|
||||||
:Создание локального vault;
|
:createStorage()\nновый **storage** в LocalVault;
|
||||||
case (Выбор vault)
|
case (Выбор storage)
|
||||||
:Карточка / детали vault;
|
:StorageHome:\nфайлы, 2FA, текстовые секреты;
|
||||||
case (Удалённые vault)
|
case (Вкладка «Удалённые vault»)
|
||||||
:Экран удалённых vault;
|
:Список **IVault** (Yandex по OAuth);
|
||||||
if (Нужен OAuth Яндекс?) then (да)
|
if (Нужен OAuth?) then (да)
|
||||||
:Авторизация Яндекс;
|
:Авторизация Яндекс;
|
||||||
endif
|
endif
|
||||||
case (Настройки)
|
:Выбор vault → VaultBrowser;
|
||||||
:Экран настроек;
|
:Список **storage** в выбранном vault;
|
||||||
endswitch
|
:StorageHome;
|
||||||
repeat while (Пользователь в приложении?) is (да)
|
endswitch
|
||||||
-> нет;
|
repeat while (Пользователь в Main?) is (да)
|
||||||
|
-> нет;
|
||||||
|
}
|
||||||
|
|
||||||
stop
|
stop
|
||||||
|
|
||||||
floating note right
|
floating note right
|
||||||
**Фон: SyncWorker (по таймеру Android) — проект**
|
**Фон: StorageSyncEngine**
|
||||||
• Room: таблица очереди с **UUID storage**
|
• DbStorageSyncGroup: UUID **storage** в группе
|
||||||
• Периодический запуск метода синхронизации
|
• Журнал изменений по путям, merge ревизий
|
||||||
• Для каждого Storage — история **коммитов** (как git)
|
• Независимо от текущего экрана UI
|
||||||
• Сравнение локальной и удалённой истории,
|
• Ключи шифрования провайдеру не передаются
|
||||||
приведение зашифрованного содержимого
|
|
||||||
к одному состоянию (ключи на сервер не уходят)
|
|
||||||
• Работает **независимо** от текущего экрана UI
|
|
||||||
end note
|
end note
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@startuml fig_04_domain_class
|
@startuml fig_04_domain_class
|
||||||
|
title Модуль :domain — IVaultsManager / IVault / IStorage
|
||||||
scale 1.15
|
scale 1.15
|
||||||
skinparam shadowing false
|
skinparam shadowing false
|
||||||
skinparam classFontSize 10
|
skinparam classFontSize 10
|
||||||
@@ -23,9 +24,13 @@ package usecases {
|
|||||||
class GetOpenedStoragesUseCase {
|
class GetOpenedStoragesUseCase {
|
||||||
+ getOpenedStorages(): StateFlow<Map<UUID, IStorageInfo>>
|
+ getOpenedStorages(): StateFlow<Map<UUID, IStorageInfo>>
|
||||||
}
|
}
|
||||||
class ManageLocalVaultUseCase {
|
class ManageVaultUseCase {
|
||||||
+ getLocalStorages(): StateFlow<List<IStorageInfo>>
|
+ find(UUID): IVault?
|
||||||
+ createStorage(): Unit
|
+ storagesOf(UUID): Flow<List<IStorage>>
|
||||||
|
+ createStorage(UUID): IStorage
|
||||||
|
}
|
||||||
|
class FindStorageUseCase {
|
||||||
|
+ find(UUID): IStorage?
|
||||||
}
|
}
|
||||||
class StorageFileManagementUseCase {
|
class StorageFileManagementUseCase {
|
||||||
+ getAllDirs(): Unit
|
+ getAllDirs(): Unit
|
||||||
@@ -101,9 +106,6 @@ package interfaces {
|
|||||||
class ILogger {
|
class ILogger {
|
||||||
+ debug(String, String): void
|
+ debug(String, String): void
|
||||||
}
|
}
|
||||||
class IYandexVault {
|
|
||||||
+ getAccountEmail(): String
|
|
||||||
}
|
|
||||||
class IMetaInfo {
|
class IMetaInfo {
|
||||||
+ getSize(): long
|
+ getSize(): long
|
||||||
+ isDeleted(): boolean
|
+ isDeleted(): boolean
|
||||||
@@ -125,13 +127,9 @@ package interfaces {
|
|||||||
+ isVirtualStorage(): boolean
|
+ isVirtualStorage(): boolean
|
||||||
}
|
}
|
||||||
class IVaultsManager {
|
class IVaultsManager {
|
||||||
+ getLocalVault(): IVault
|
+ vaults: StateFlow<List<IVault>>
|
||||||
+ removeRemoteVault(UUID): Unit
|
+ allStorages: StateFlow<List<IStorage>>
|
||||||
+ addYandexVault(String): Unit
|
+ unlockManager: IUnlockManager
|
||||||
+ getRemoteVaults(): StateFlow<List<IVault>>
|
|
||||||
+ getAllStorages(): StateFlow<List<IStorage>>
|
|
||||||
+ getAllVaults(): StateFlow<List<IVault>>
|
|
||||||
+ getUnlockManager(): IUnlockManager
|
|
||||||
}
|
}
|
||||||
class IStorageMetaInfo {
|
class IStorageMetaInfo {
|
||||||
+ getEncInfo(): StorageEncryptionInfo
|
+ getEncInfo(): StorageEncryptionInfo
|
||||||
@@ -150,22 +148,16 @@ package interfaces {
|
|||||||
+ getMetaInfo(): StateFlow<IStorageMetaInfo>
|
+ getMetaInfo(): StateFlow<IStorageMetaInfo>
|
||||||
+ isVirtualStorage(): boolean
|
+ isVirtualStorage(): boolean
|
||||||
}
|
}
|
||||||
class IStorageExplorer {
|
|
||||||
+ getCurrentPath(): StateFlow<String>
|
|
||||||
}
|
|
||||||
class IVaultInfo {
|
class IVaultInfo {
|
||||||
+ getAvailableSpace(): StateFlow<Integer>
|
+ uuid: UUID
|
||||||
+ getType(): VaultType
|
|
||||||
+ getTotalSpace(): StateFlow<Integer>
|
|
||||||
+ getUuid(): UUID
|
|
||||||
+ isAvailable(): StateFlow<Boolean>
|
|
||||||
+ getStorages(): StateFlow<List<IStorageInfo>>
|
|
||||||
}
|
}
|
||||||
class IUnlockManager {
|
class IUnlockManager {
|
||||||
|
+ openedStorages: StateFlow<Map<UUID, IStorage>>
|
||||||
|
+ getOpenedStorageKey(UUID): EncryptKey
|
||||||
|
+ open(IStorage, EncryptKey, boolean): IStorage
|
||||||
|
+ rememberKey(IStorage, EncryptKey): Unit
|
||||||
+ close(IStorage): Unit
|
+ close(IStorage): Unit
|
||||||
+ close(UUID): Unit
|
+ close(UUID): Unit
|
||||||
+ open(IStorage, EncryptKey, boolean): Unit
|
|
||||||
+ getOpenedStorages(): StateFlow<Map<UUID, IStorage>>
|
|
||||||
}
|
}
|
||||||
class IDirectory {
|
class IDirectory {
|
||||||
+ getMetaInfo(): IMetaInfo
|
+ getMetaInfo(): IMetaInfo
|
||||||
@@ -194,15 +186,16 @@ package interfaces {
|
|||||||
+ getFileInfo(String): Unit
|
+ getFileInfo(String): Unit
|
||||||
}
|
}
|
||||||
class IVault {
|
class IVault {
|
||||||
+ getAvailableSpace(): StateFlow<Integer>
|
+ uuid: UUID
|
||||||
+ getType(): VaultType
|
+ storages: StateFlow<List<IStorage>>
|
||||||
+ getTotalSpace(): StateFlow<Integer>
|
+ storagesScanInProgress: StateFlow<Boolean>
|
||||||
|
+ isAvailable: StateFlow<Boolean>
|
||||||
|
+ totalSpace: StateFlow<Long>
|
||||||
|
+ availableSpace: StateFlow<Long>
|
||||||
|
+ createStorage(): IStorage
|
||||||
|
+ createStorage(StorageEncryptionInfo): IStorage
|
||||||
+ remove(IStorage): Unit
|
+ remove(IStorage): Unit
|
||||||
+ createStorage(StorageEncryptionInfo): Unit
|
+ rescanStorages(): Unit
|
||||||
+ getUuid(): UUID
|
|
||||||
+ isAvailable(): StateFlow<Boolean>
|
|
||||||
+ getStorages(): StateFlow<List<IStorage>>
|
|
||||||
+ createStorage(): 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.IStorageMetaInfo
|
||||||
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageInfo
|
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageInfo
|
||||||
usecases.ManageStoragesEncryptionUseCase ..> tasks.TaskProgress
|
usecases.ManageStoragesEncryptionUseCase ..> tasks.TaskProgress
|
||||||
@@ -312,20 +286,16 @@ usecases.RemoveStorageUseCase ..> interfaces.IUnlockManager
|
|||||||
usecases.RemoveStorageUseCase ..> interfaces.IVault
|
usecases.RemoveStorageUseCase ..> interfaces.IVault
|
||||||
tasks.TaskLogLine ..> tasks.TaskLogLevel
|
tasks.TaskLogLine ..> tasks.TaskLogLevel
|
||||||
tasks.PipelineWork ..> tasks.TaskContext
|
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.IStorageInfo
|
||||||
usecases.GetOpenedStoragesUseCase ..> interfaces.IUnlockManager
|
usecases.GetOpenedStoragesUseCase ..> interfaces.IUnlockManager
|
||||||
tasks.TaskContext ..> tasks.TaskLogLevel
|
tasks.TaskContext ..> tasks.TaskLogLevel
|
||||||
tasks.TaskContext ..> tasks.TaskProgress
|
tasks.TaskContext ..> tasks.TaskProgress
|
||||||
tasks.TaskContext ..> tasks.TaskId
|
tasks.TaskContext ..> tasks.TaskId
|
||||||
usecases.ManageLocalVaultUseCase ..> interfaces.IStorageInfo
|
usecases.ManageVaultUseCase ..> interfaces.IStorage
|
||||||
usecases.ManageLocalVaultUseCase ..> interfaces.IVaultsManager
|
usecases.ManageVaultUseCase ..> interfaces.IVaultsManager
|
||||||
usecases.ManageLocalVaultUseCase ..> interfaces.IVault
|
usecases.ManageVaultUseCase ..> interfaces.IVault
|
||||||
|
usecases.FindStorageUseCase ..> interfaces.IStorage
|
||||||
|
usecases.FindStorageUseCase ..> interfaces.IVaultsManager
|
||||||
usecases.StorageFileManagementUseCase ..> interfaces.IFile
|
usecases.StorageFileManagementUseCase ..> interfaces.IFile
|
||||||
usecases.StorageFileManagementUseCase ..> interfaces.IStorage
|
usecases.StorageFileManagementUseCase ..> interfaces.IStorage
|
||||||
usecases.StorageFileManagementUseCase ..> interfaces.IStorageInfo
|
usecases.StorageFileManagementUseCase ..> interfaces.IStorageInfo
|
||||||
@@ -362,9 +332,7 @@ interfaces.IStorageInfo ..> interfaces.IStorageMetaInfo
|
|||||||
interfaces.IStorageInfo ..> interfaces.IStorage
|
interfaces.IStorageInfo ..> interfaces.IStorage
|
||||||
usecases.RenameStorageUseCase ..> interfaces.IStorage
|
usecases.RenameStorageUseCase ..> interfaces.IStorage
|
||||||
usecases.RenameStorageUseCase ..> interfaces.IStorageInfo
|
usecases.RenameStorageUseCase ..> interfaces.IStorageInfo
|
||||||
interfaces.IVaultInfo ..> interfaces.IStorageInfo
|
|
||||||
interfaces.IVaultInfo ..> interfaces.IVault
|
interfaces.IVaultInfo ..> interfaces.IVault
|
||||||
interfaces.IVaultInfo ..> enums.VaultType
|
|
||||||
tasks.TaskForegroundItem ..> tasks.TaskProgress
|
tasks.TaskForegroundItem ..> tasks.TaskProgress
|
||||||
tasks.TaskForegroundItem ..> tasks.TaskId
|
tasks.TaskForegroundItem ..> tasks.TaskId
|
||||||
interfaces.IUnlockManager ..> interfaces.IStorage
|
interfaces.IUnlockManager ..> interfaces.IStorage
|
||||||
@@ -376,9 +344,7 @@ interfaces.IStorageAccessor ..> datatypes.DataPackage
|
|||||||
interfaces.IVaultInfo <|.. interfaces.IVault
|
interfaces.IVaultInfo <|.. interfaces.IVault
|
||||||
interfaces.IVault ..> interfaces.IStorage
|
interfaces.IVault ..> interfaces.IStorage
|
||||||
interfaces.IVault ..> interfaces.IVaultInfo
|
interfaces.IVault ..> interfaces.IVaultInfo
|
||||||
interfaces.IVault ..> enums.VaultType
|
|
||||||
interfaces.IVault ..> datatypes.StorageEncryptionInfo
|
interfaces.IVault ..> datatypes.StorageEncryptionInfo
|
||||||
auth.RemoteYandexSignInLauncher ..> auth.RemoteYandexAuthResult
|
|
||||||
datatypes.DataPackage <|-- datatypes.DataPage
|
datatypes.DataPackage <|-- datatypes.DataPage
|
||||||
datatypes.DataPage ..> datatypes.DataPackage
|
datatypes.DataPage ..> datatypes.DataPackage
|
||||||
interfaces.IFile <|.. common.impl.CommonFile
|
interfaces.IFile <|.. common.impl.CommonFile
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ rectangle "Wallenc\n(Android)" as App {
|
|||||||
|
|
||||||
cloud "Внешний провайдер\n(Яндекс Диск API)" as Cloud
|
cloud "Внешний провайдер\n(Яндекс Диск API)" as Cloud
|
||||||
|
|
||||||
User --> UI : управление vault,\nфайлы, OAuth
|
User --> UI : storage, vault,\nOAuth, файлы
|
||||||
UI --> Domain
|
UI --> Domain
|
||||||
Domain --> Room
|
Domain --> Room
|
||||||
Domain --> Cloud : ciphertext,\nOAuth, метаданные API
|
Domain --> Cloud : ciphertext,\nOAuth, метаданные API
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@startuml fig_15_bpmn_vault
|
@startuml fig_15_bpmn_vault
|
||||||
scale 2
|
scale 2
|
||||||
title BPMN: жизненный цикл vault
|
title BPMN: жизненный цикл storage (IStorage)
|
||||||
skinparam defaultFontName "DejaVu Sans"
|
skinparam defaultFontName "DejaVu Sans"
|
||||||
skinparam activity {
|
skinparam activity {
|
||||||
BackgroundColor #F8F8F8
|
BackgroundColor #F8F8F8
|
||||||
@@ -8,20 +8,23 @@ skinparam activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
start
|
start
|
||||||
:Создать vault;
|
:Создать **storage** в vault\n(createStorage);
|
||||||
if (Нужно шифрование?) then (да)
|
note right
|
||||||
|
Vault (IVault) не шифруется.
|
||||||
|
Шифрование только у **storage**
|
||||||
|
end note
|
||||||
|
if (Включить шифрование storage?) then (да)
|
||||||
:Ввести пароль;
|
:Ввести пароль;
|
||||||
:Шифрование данных;
|
:enableEncryption(storage);
|
||||||
else (нет)
|
else (нет)
|
||||||
endif
|
endif
|
||||||
:Открыть vault;
|
:openStorage(storage)\nпри необходимости;
|
||||||
:Работа с содержимым;
|
:Работа с содержимым storage:\nфайлы, 2FA, секреты;
|
||||||
if (Удалённое хранилище?) then (да)
|
if (Storage в группе синхронизации?) then (да)
|
||||||
:OAuth / привязка;
|
:StorageSyncEngine\n(журнал ревизий);
|
||||||
:Синхронизация;
|
|
||||||
else (нет)
|
else (нет)
|
||||||
endif
|
endif
|
||||||
:Закрыть vault;
|
:closeStorage / блокировка;
|
||||||
stop
|
stop
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ skinparam activity {
|
|||||||
start
|
start
|
||||||
:Пользователь включает шифрование;
|
:Пользователь включает шифрование;
|
||||||
:Сформировать EncryptKey;
|
:Сформировать EncryptKey;
|
||||||
:Encryptor.encrypt данные vault;
|
:Encryptor: шифрование файлов\n**storage** (IStorageAccessor);
|
||||||
:Записать StorageEncryptionInfo\nв Room;
|
:storage.setEncInfo → Room\n(DbStorageMetaInfo);
|
||||||
:checkKey(ключ);
|
:checkKey(ключ);
|
||||||
if (Ключ верный?) then (да)
|
if (Ключ верный?) then (да)
|
||||||
:openStorage(зашифрованное представление);
|
:IUnlockManager.open(storage)\nвиртуальное представление;
|
||||||
:Доступ к содержимому;
|
:Доступ к файлам storage;
|
||||||
else (нет)
|
else (нет)
|
||||||
:Ошибка, vault закрыт;
|
:Ошибка, storage не открыт;
|
||||||
endif
|
endif
|
||||||
stop
|
stop
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@startuml fig_22_cjm_vault
|
@startuml fig_22_cjm_vault
|
||||||
scale 3
|
scale 3
|
||||||
title Customer Journey Map: защита vault
|
title Customer Journey Map: защита storage
|
||||||
skinparam defaultFontName "DejaVu Sans"
|
skinparam defaultFontName "DejaVu Sans"
|
||||||
|
|
||||||
|Этап|
|
|Этап|
|
||||||
@@ -11,9 +11,9 @@ skinparam defaultFontName "DejaVu Sans"
|
|||||||
|
|
||||||
|Действия|
|
|Действия|
|
||||||
|Понимает риск\nоблака|
|
|Понимает риск\nоблака|
|
||||||
|Создаёт vault,\nвключает шифрование|
|
|Создаёт storage,\nвключает шифрование storage|
|
||||||
|Открывает vault,\nработает с файлами|
|
|Открывает storage,\nработает с файлами|
|
||||||
|Синхронизирует\nбез передачи ключей|
|
|Синхронизирует storage\nбез передачи ключей|
|
||||||
|
|
||||||
|Ожидания|
|
|Ожидания|
|
||||||
|Данные не читаются\nпровайдером|
|
|Данные не читаются\nпровайдером|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Enc ..> ML : опционально\nлокальные эмбеддинги\nп
|
|||||||
|
|
||||||
note bottom of ML
|
note bottom of ML
|
||||||
Обучение: офлайн на размеченных\nсинтетических/агрегированных данных;
|
Обучение: офлайн на размеченных\nсинтетических/агрегированных данных;
|
||||||
выгрузка содержимого vault\nна облако для train — не используется
|
выгрузка содержимого storage\nна облако для train — не используется
|
||||||
end note
|
end note
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
#pz-fig("fig_05_local_vaults.jpg", [Локальные vault], "fig-05-app")
|
#pz-fig("fig_05_local_vaults.jpg", [Локальные vault], "fig-05-app")
|
||||||
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог шифрования], "fig-06-app")
|
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог шифрования], "fig-06-app")
|
||||||
#pz-fig("fig_07_open_close_dialog.jpg", [Открытие и закрытие vault], "fig-07-app")
|
#pz-fig("fig_07_open_close_dialog.jpg", [Открытие и закрытие storage], "fig-07-app")
|
||||||
#pz-fig("fig_08_rename_delete_dialog.jpg", [Переименование и удаление], "fig-08-app")
|
#pz-fig("fig_08_rename_delete_dialog.jpg", [Переименование и удаление], "fig-08-app")
|
||||||
#pz-fig("fig_09_remote_vaults.jpg", [Удалённые vault], "fig-09-app")
|
#pz-fig("fig_09_remote_vaults.jpg", [Удалённые vault], "fig-09-app")
|
||||||
#pz-fig("fig_10_yandex_oauth.jpg", [OAuth Яндекс], "fig-10-app")
|
#pz-fig("fig_10_yandex_oauth.jpg", [OAuth Яндекс], "fig-10-app")
|
||||||
|
|||||||