Улучшение соответсвия

This commit is contained in:
2026-05-28 17:23:54 +03:00
parent 5c40687011
commit 0c15c7b786
39 changed files with 161 additions and 204 deletions

View File

@@ -7,7 +7,7 @@
В настоящем документе применяются следующие обозначения и сокращения:
#pz-table(
[],
[Обозначения и сокращения],
2,
table.header([Обозначение], [Расшифровка]),
[API], [Application Programming Interface программный интерфейс приложения],

View File

@@ -12,15 +12,11 @@
#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()
[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.]
parbreak()
[Keywords: mobile application, client-side encryption, Android, vault, OAuth, Room.]
[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.]
}

View File

@@ -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; минимизировать доверие к провайдеру; поддержать расширение списка провайдеров через адаптеры; сохранить служебные метаданные в локальной БД без хранения пользовательского контента в открытом виде.

View File

@@ -10,13 +10,13 @@
=== Карта процессов
Основные процессы: создание storage в vault опциональное шифрование открытие работа с файлами закрытие; для удалённых vault OAuth привязка учётной записи листинг storage провайдера проектная синхронизация.
Основные процессы: создание storage в vault опциональное шифрование storage открытие storage работа с файлами закрытие; для удалённых vault OAuth привязка учётной записи листинг storage провайдера проектная синхронизация.
=== Диаграмма 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")

View File

@@ -6,7 +6,7 @@
=== Анализ конкурентов и определение сильных и слабых сторон
По результатам сравнения аналогов (табл. @tbl-analog) для Wallenc выделены сильные стороны: единый UI для локальных и удалённых vault, явное отображение состояния шифрования, диалоги подтверждения деструктивных операций. Слабые стороны конкурентов (привязка к экосистеме, узкая предметная область) учтены при проектировании навигации.
По результатам сравнения аналогов (табл. @tbl-analog) для Wallenc выделены сильные стороны: единый UI для списков storage LocalVault и удалённых vault), явное отображение состояния шифрования storage, диалоги подтверждения деструктивных операций. Слабые стороны конкурентов (привязка к экосистеме, узкая предметная область) учтены при проектировании навигации.
=== Ограничения и допущения проектирования UI
@@ -16,7 +16,7 @@
=== Потребности и барьеры пользователя
Потребности: хранить файлы в «сейфе» без доверия к облаку; синхронизировать между устройствами. Барьеры: сложность OAuth, страх потери пароля, неочевидность состояния «vault открыт».
Потребности: хранить файлы в «сейфе» без доверия к облаку; синхронизировать между устройствами. Барьеры: сложность OAuth, страх потери пароля, неочевидность состояния «storage открыт» (разблокирован).
=== Полезные сценарии из аналогов
@@ -31,26 +31,26 @@
3,
table.header([ID], [Формулировка], [Критерий приёмки]),
[US-1], [Создаю storage для файлов в локальном vault на устройстве], [Storage в списке (рис. 5)],
[US-2], [Включаю шифрование vault паролем], [Статус encrypted, тест T-8],
[US-3], [Открываю зашифрованный vault ключом], [Доступ к контенту, тест T-9],
[US-2], [Включаю шифрование storage паролем], [Статус encrypted, тест T-8],
[US-3], [Открываю зашифрованный storage ключом], [Доступ к контенту, тест T-9],
[US-4], [Подключаю Яндекс и удалённый vault], [OAuth OK, тест T-10],
[US-5], [Вижу прогресс фоновых задач], [Экран задач, тест T-11],
[US-6], [Храню TOTP и текстовые секреты в vault], [`TwoFaTotpTest`, UI IT],
[US-6], [Храню TOTP и текстовые секреты в storage], [`TwoFaTotpTest`, UI IT],
) <tbl-userstory>
=== 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_02_vault_lifecycle.png", [Жизненный цикл vault и очередь синхронизации], "fig-02")
#pz-fig("fig_03_navigation_hub.png", [Навигация с главного экрана и SyncWorker], "fig-03")
#pz-fig("fig_01_start_sync.png", [Старт приложения и фоновая синхронизация], "fig-01")
#pz-fig("fig_02_vault_lifecycle.png", [Жизненный цикл storage и журнал синхронизации], "fig-02")
#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_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_09_remote_vaults.jpg", [Экран удалённых vault], "fig-09")
#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 и неверном ключе формулируются нейтрально, без раскрытия внутренних путей и имён файлов.
== Вывод

View File

@@ -10,7 +10,7 @@
Класс `Encryptor` формирует `StorageEncryptionInfo`, проверяет ключ и выполняет шифрование/дешифрование на клиенте. Unit-тесты подтверждают корректность для верного и неверного ключа (гл. 5).
=== Модуль управления vault и шифрованием
=== Модуль управления storage и шифрованием
Use case `ManageStoragesEncryptionUseCase` инкапсулирует проверку `canEncrypt`, включение шифрования и открытие хранилища. ViewModel предотвращает повторный запуск шифрования для занятого storage.
@@ -136,12 +136,12 @@ abstract class AppDb : IAppDb, RoomDatabase()
Модуль `:ui` и `:app` содержат Compose-экраны, ViewModel и навигацию. OAuth Яндекс запускается из UI удалённых vault:
```kotlin
viewModel.yandexSignIn.launch { outcome ->
remoteVaultAuthenticator.beginLink(CloudBrand.YANDEX) { outcome ->
when (outcome) {
is RemoteYandexAuthResult.Success ->
viewModel.onYandexAuthSuccess(outcome.accessToken)
is RemoteYandexAuthResult.Failure -> { /* ошибка */ }
RemoteYandexAuthResult.Cancelled -> { }
is VaultLinkOutcome.Success ->
viewModel.onVaultLinked(outcome.registration)
is VaultLinkOutcome.Failed -> { /* ошибка */ }
VaultLinkOutcome.Cancelled -> { }
}
}
```

View File

@@ -42,8 +42,8 @@
[T-5], [2FA TOTP генерация], [Unit], [Да], [Совпадение с эталоном Java OTP],
[T-6], [Маппинг ошибок сети/диска], [Unit], [Да], [Типизированные `WallencException`],
[T-7], [CRUD storage в LocalVault], [Ручной], [Нет], [Список обновлён (рис. @fig-05)],
[T-8], [Включение шифрования vault], [Ручной], [Нет], [Статус «зашифровано» (рис. @fig-06)],
[T-9], [Открытие/закрытие vault], [Ручной], [Нет], [Доступ только с ключом (рис. @fig-07)],
[T-8], [Включение шифрования storage], [Ручной], [Нет], [Статус «зашифровано» (рис. @fig-06)],
[T-9], [Открытие/закрытие storage], [Ручной], [Нет], [Доступ только с ключом (рис. @fig-07)],
[T-10], [OAuth Яндекс], [Ручной / IT], [Частично], [Токен в Room (рис. @fig-10)],
[T-11], [Экран задач и уведомления], [Ручной], [Частично], [Прогресс и завершение (рис. 1213)],
[T-12], [Compose: секреты и 2FA], [IT], [Да], [Отображение без падений (рис. @fig-33@fig-34)],
@@ -127,7 +127,7 @@
table.header([ID], [Шаг], [Статус], [Фактический результат], [Иллюстрация]),
[T-7], [Создать storage в LocalVault], [OK], [Storage в списке], [@fig-05],
[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-11], [Фоновая задача шифрования], [OK], [Прогресс на экране задач], [рис. 12],
[T-12], [Уведомление о завершении], [OK], [Notification отображён], [рис. 13],

View File

@@ -6,7 +6,7 @@
#emph[Способен решать прикладные задачи анализа данных и принятия решений с использованием искусственного интеллекта.]
В текущей версии Wallenc модели машинного обучения в runtime не внедрены: продукт строится на zero-knowledge модели, отсутствует доверенный сервер приложения, а выгрузка расшифрованного содержимого vault на облако для обучения противоречила бы заявленным требованиям безопасности. Ниже рассмотрено, какие прикладные задачи анализа данных и автоматизированных решений *могли бы* быть добавлены в перспективе без нарушения клиентской модели угроз.
В текущей версии Wallenc модели машинного обучения в runtime не внедрены: продукт строится на zero-knowledge модели, отсутствует доверенный сервер приложения, а выгрузка расшифрованного содержимого storage на облако для обучения противоречила бы заявленным требованиям безопасности. Ниже рассмотрено, какие прикладные задачи анализа данных и автоматизированных решений *могли бы* быть добавлены в перспективе без нарушения клиентской модели угроз.
== Связь компетенции с предметом ВКР

View File

@@ -1,7 +1,7 @@
// Таблицы — как в «Пример работы с Typst.typ» и gost: figure + table + table.header.
// Разрыв длинных таблиц и подпись сверху задаёт шаблон 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]
@@ -160,19 +160,11 @@
let start-page = state("pz-table-start-page", none)
figure(
kind: table,
{
show table: set text(hyphenate: true, lang: "ru")
show table.cell: it => {
set align(left + top)
set par(justify: false)
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))
}
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,
)