Исправлено тире
This commit is contained in:
@@ -10,16 +10,16 @@
|
||||
[Обозначения и сокращения],
|
||||
2,
|
||||
table.header([Обозначение], [Расшифровка]),
|
||||
[API], [Application Programming Interface — программный интерфейс приложения],
|
||||
[DAO], [Data Access Object — объект доступа к данным],
|
||||
[E2E], [End-to-end — сквозное шифрование],
|
||||
[MVVM], [Model — View — ViewModel],
|
||||
[API], [Application Programming Interface – программный интерфейс приложения],
|
||||
[DAO], [Data Access Object – объект доступа к данным],
|
||||
[E2E], [End-to-end – сквозное шифрование],
|
||||
[MVVM], [Model – View – ViewModel],
|
||||
[OAuth], [протокол авторизации открытого типа],
|
||||
[UI], [User Interface — пользовательский интерфейс],
|
||||
[CRUD], [Create, Read, Update, Delete — создание, чтение, изменение, удаление],
|
||||
[UI], [User Interface – пользовательский интерфейс],
|
||||
[CRUD], [Create, Read, Update, Delete – создание, чтение, изменение, удаление],
|
||||
[ПЗ], [Пояснительная записка],
|
||||
[ТЗ], [Техническое задание],
|
||||
[ВКР], [Выпускная квалификационная работа],
|
||||
[JUnit], [Фреймворк модульного тестирования Java/Kotlin],
|
||||
[IT], [Instrumented Test — инструментальный тест Android],
|
||||
[IT], [Instrumented Test – инструментальный тест Android],
|
||||
) <tbl-abbr>
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
|
||||
parbreak()
|
||||
|
||||
[Реализованы иерархия VaultsManager → vault → storage → файлы (один LocalVault на устройстве, удалённые vault по OAuth), клиентское AES-шифрование, служебные метаданные в Room и проектный контур синхронизации без передачи ключей провайдеру. Исходный код размещён в приватном репозитории GitLab ЮФУ. Полный листинг исходных файлов — приложение А; программная документация — приложение Б.]
|
||||
[Реализованы иерархия VaultsManager → vault → storage → файлы (один LocalVault на устройстве, удалённые vault по OAuth), клиентское AES-шифрование, служебные метаданные в Room и проектный контур синхронизации без передачи ключей провайдеру. Исходный код размещён в приватном репозитории GitLab ЮФУ. Полный листинг исходных файлов – приложение А; программная документация – приложение Б.]
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
=== Назначение и цели создания системы
|
||||
|
||||
*Назначение* системы Wallenc — предоставление пользователю мобильного клиента для работы с иерархией *VaultsManager → vault → storage → файлы*: один `LocalVault` на устройстве, удалённые vault по OAuth; внутри vault пользователь создаёт и управляет *storage*; шифрование (`StorageEncryptionInfo`, `Encryptor`) применяется к storage, а не к vault.
|
||||
*Назначение* системы Wallenc – предоставление пользователю мобильного клиента для работы с иерархией *VaultsManager → vault → storage → файлы*: один `LocalVault` на устройстве, удалённые vault по OAuth; внутри vault пользователь создаёт и управляет *storage*; шифрование (`StorageEncryptionInfo`, `Encryptor`) применяется к storage, а не к vault.
|
||||
|
||||
*Цели создания*: обеспечить единую модель vault и storage; минимизировать доверие к провайдеру; поддержать расширение списка провайдеров через адаптеры; сохранить служебные метаданные в локальной БД без хранения пользовательского контента в открытом виде.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
[Свод функциональных требований],
|
||||
2,
|
||||
table.header([Код], [Требование]),
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault — один на устройстве)],
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault – один на устройстве)],
|
||||
[ФР-2], [Включение шифрования storage, проверка ключа, открытие и закрытие зашифрованного представления],
|
||||
[ФР-3], [Просмотр и операции с файлами внутри storage; текстовые секреты и 2FA],
|
||||
[ФР-4], [OAuth-авторизация (Яндекс), регистрация удалённых vault и листинг их storage],
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
=== Требования к программно-аппаратной платформе
|
||||
|
||||
Минимальная платформа — Android с поддержкой Jetpack Compose; для OAuth и удалённых операций требуется сетевое подключение. Объём оперативной памяти должен быть достаточен для фоновых задач шифрования и Room.
|
||||
Минимальная платформа – Android с поддержкой Jetpack Compose; для OAuth и удалённых операций требуется сетевое подключение. Объём оперативной памяти должен быть достаточен для фоновых задач шифрования и Room.
|
||||
|
||||
== Аналоги
|
||||
|
||||
@@ -92,7 +92,7 @@ Google Files Secure Folder локально прячет и защищает ф
|
||||
[Сравнительная оценка аналогов],
|
||||
6,
|
||||
table.header([Критерий], [Secure Folder], [Proton], [Bitwarden], [Cryptomator], [Wallenc]),
|
||||
[Собственный backend приложения], [—], [+], [+/−], [—], [—],
|
||||
[Собственный backend приложения], [–], [+], [+/−], [–], [–],
|
||||
[E2E / клиентское шифрование], [+/−], [+], [+], [+], [+],
|
||||
[Файловый vault], [+], [+], [−], [+], [+],
|
||||
[OAuth внешнего провайдера], [−], [+/−], [+/−], [+/−], [+],
|
||||
@@ -122,10 +122,10 @@ Google Files Secure Folder локально прячет и защищает ф
|
||||
|
||||
== Обзор рынка и обоснование выбора решения Wallenc
|
||||
|
||||
Рынок мобильных хранилищ демонстрирует поляризацию: закрытые экосистемы с удобным UX (Proton, Google) и открытые криптоклиенты с ручной настройкой (Cryptomator). Wallenc занимает промежуточную нишу — *мобильный zero-knowledge vault* с OAuth к популярному провайдеру (Яндекс) и расширяемой регистрацией типов хранилищ. Для корпоративного заказчика (Нейротех) важны: отсутствие затрат на сервер приложения, возможность аудита кода, формализованное тестирование (68 unit-тестов, см. гл. 5).
|
||||
Рынок мобильных хранилищ демонстрирует поляризацию: закрытые экосистемы с удобным UX (Proton, Google) и открытые криптоклиенты с ручной настройкой (Cryptomator). Wallenc занимает промежуточную нишу – *мобильный zero-knowledge vault* с OAuth к популярному провайдеру (Яндекс) и расширяемой регистрацией типов хранилищ. Для корпоративного заказчика (Нейротех) важны: отсутствие затрат на сервер приложения, возможность аудита кода, формализованное тестирование (68 unit-тестов, см. гл. 5).
|
||||
|
||||
Перспективы коммерциализации связаны не с продажей облака, а с лицензированием клиента или внутренним внедрением. Барьер входа — ответственность пользователя за ключ; в ПЗ это отражено в руководстве пользователя (прил. Б) и предупреждениях в UI.
|
||||
Перспективы коммерциализации связаны не с продажей облака, а с лицензированием клиента или внутренним внедрением. Барьер входа – ответственность пользователя за ключ; в ПЗ это отражено в руководстве пользователя (прил. Б) и предупреждениях в UI.
|
||||
|
||||
== Формирование технического задания
|
||||
|
||||
Структура ТЗ оформлена по ГОСТ 7.32–2017: цели, этапы, функциональные и нефункциональные требования, порядок приёмки. Приоритет отдан ядру хранения и шифрования; расширения (2FA, текстовые секреты, синхронизация) зафиксированы как дополнительные функции второго этапа практики. Полный текст ТЗ — в приложении Б.
|
||||
Структура ТЗ оформлена по ГОСТ 7.32–2017: цели, этапы, функциональные и нефункциональные требования, порядок приёмки. Приоритет отдан ядру хранения и шифрования; расширения (2FA, текстовые секреты, синхронизация) зафиксированы как дополнительные функции второго этапа практики. Полный текст ТЗ – в приложении Б.
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
=== Карта процессов
|
||||
|
||||
Основные процессы: создание storage в vault → опциональное шифрование storage → открытие storage → работа с файлами → закрытие; для удалённых vault — OAuth → привязка учётной записи → листинг storage провайдера → проектная синхронизация.
|
||||
Основные процессы: создание storage в vault → опциональное шифрование storage → открытие storage → работа с файлами → закрытие; для удалённых vault – OAuth → привязка учётной записи → листинг storage провайдера → проектная синхронизация.
|
||||
|
||||
=== Диаграмма BPMN
|
||||
|
||||
На рисунке @fig-15 представлена диаграмма BPMN основного процесса работы со storage внутри vault.
|
||||
|
||||
#pz-fig("fig_15_bpmn_vault.png", [BPMN: storage — создание, шифрование, открытие, содержимое], "fig-15")
|
||||
#pz-fig("fig_15_bpmn_vault.png", [BPMN: storage – создание, шифрование, открытие, содержимое], "fig-15")
|
||||
|
||||
=== Карта систем
|
||||
|
||||
@@ -46,9 +46,9 @@ DFD уровня 0 (рис. @fig-16) отражает потоки между UI
|
||||
|
||||
Модель данных приложения строится на трёх уровнях (см. `IVaultsManager`, `IVault`, `IStorage` на рис. @fig-04):
|
||||
|
||||
+ *VaultsManager* — единая точка доступа: реактивный список всех vault (`vaults`), агрегированный список storage (`allStorages`) и `IUnlockManager` для открытых storage;
|
||||
+ *IVault* — контейнер, объединяющий набор storage. *LocalVault* в приложении один (корень на устройстве); удалённые vault (например, `YandexVault`) добавляются по одному на привязанную учётную запись OAuth;
|
||||
+ *IStorage* — хранилище, которое пользователь создаёт, переименовывает и удаляет в интерфейсе; внутри — файлы и каталоги, доступные через `IStorageAccessor` (с опциональным клиентским шифрованием).
|
||||
- *VaultsManager* – единая точка доступа: реактивный список всех vault (`vaults`), агрегированный список storage (`allStorages`) и `IUnlockManager` для открытых storage;
|
||||
- *IVault* – контейнер, объединяющий набор storage. *LocalVault* в приложении один (корень на устройстве); удалённые vault (например, `YandexVault`) добавляются по одному на привязанную учётную запись OAuth;
|
||||
- *IStorage* – хранилище, которое пользователь создаёт, переименовывает и удаляет в интерфейсе; внутри – файлы и каталоги, доступные через `IStorageAccessor` (с опциональным клиентским шифрованием).
|
||||
|
||||
Пользовательские сценарии «создать локальный vault» в UI соответствуют созданию нового *storage* внутри единственного `LocalVault`, а не появлению второго локального vault.
|
||||
|
||||
@@ -62,13 +62,13 @@ DFD уровня 0 (рис. @fig-16) отражает потоки между UI
|
||||
|
||||
#pz-fig("fig_18_deployment.png", [Диаграмма развёртывания], "fig-18")
|
||||
|
||||
Архитектурные слои MVVM + Clean Architecture и соответствие модулям Gradle — на рисунке @fig-19.
|
||||
Архитектурные слои MVVM + Clean Architecture и соответствие модулям Gradle – на рисунке @fig-19.
|
||||
|
||||
#pz-fig("fig_19_clean_architecture.png", [Слои Clean Architecture и модули проекта], "fig-19")
|
||||
|
||||
== Проектирование локальной базы данных
|
||||
|
||||
Служебная БД Room хранит ключи шифрования для пар «исходный storage → зашифрованное представление» (`DbStorageKeyMap`), сериализованные метаданные storage (`DbStorageMetaInfo`), учётные записи Яндекс (`DbYandexAccount`) и группы синхронизации (`DbStorageSyncGroup`). Пользовательский контент в открытом виде в БД не сохраняется — только параметры, необходимые для восстановления состояния приложения при следующем запуске. Доступ инкапсулирован в DAO и репозиториях модуля `:infrastructure-android`.
|
||||
Служебная БД Room хранит ключи шифрования для пар «исходный storage → зашифрованное представление» (`DbStorageKeyMap`), сериализованные метаданные storage (`DbStorageMetaInfo`), учётные записи Яндекс (`DbYandexAccount`) и группы синхронизации (`DbStorageSyncGroup`). Пользовательский контент в открытом виде в БД не сохраняется – только параметры, необходимые для восстановления состояния приложения при следующем запуске. Доступ инкапсулирован в DAO и репозиториях модуля `:infrastructure-android`.
|
||||
|
||||
#pz-table(
|
||||
[Сущности Room и назначение],
|
||||
@@ -82,7 +82,7 @@ DFD уровня 0 (рис. @fig-16) отражает потоки между UI
|
||||
|
||||
== Проектирование подсистемы синхронизации
|
||||
|
||||
Подсистема синхронизации спроектирована как набор независимых операций над журналом изменений каждого `Storage`. Алгоритм выбирает «победителя» по ревизии, копирует или удаляет файлы на целевом хранилище, не расшифровывая данные на сервере. Блокировки предотвращают одновременную синхронизацию одной группы; при отмене задачи блокировки снимаются (покрыто unit-тестами `syncGroupCooperativeCancellationReleasesLocks` и др., гл. 5). Подробное описание реализации и выбора источника для каждого пути — в гл. 4 (§ алгоритм согласования журналов, рис. @fig-35).
|
||||
Подсистема синхронизации спроектирована как набор независимых операций над журналом изменений каждого `Storage`. Алгоритм выбирает «победителя» по ревизии, копирует или удаляет файлы на целевом хранилище, не расшифровывая данные на сервере. Блокировки предотвращают одновременную синхронизацию одной группы; при отмене задачи блокировки снимаются (покрыто unit-тестами `syncGroupCooperativeCancellationReleasesLocks` и др., гл. 5). Подробное описание реализации и выбора источника для каждого пути – в гл. 4 (§ алгоритм согласования журналов, рис. @fig-35).
|
||||
|
||||
== Нефункциональные архитектурные решения
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ CJM сценария «защитить и открыть storage» предст
|
||||
|
||||
== Проработка прототипа и особенности дизайна
|
||||
|
||||
Интерфейс реализован на Jetpack Compose @compose-docs. Экраны локальных и удалённых vault, диалоги шифрования, OAuth, а также разделы текстовых секретов и 2FA внутри storage показаны на рис. @fig-05–@fig-10 и @fig-33–@fig-34 (подробно — приложение В и руководство пользователя в приложении Б).
|
||||
Интерфейс реализован на Jetpack Compose @compose-docs. Экраны локальных и удалённых vault, диалоги шифрования, OAuth, а также разделы текстовых секретов и 2FA внутри storage показаны на рис. @fig-05–@fig-10 и @fig-33–@fig-34 (подробно – приложение В и руководство пользователя в приложении Б).
|
||||
|
||||
#pz-fig("fig_05_local_vaults.jpg", [Список storage в локальном vault (экран «локальные vault»)], "fig-05")
|
||||
#pz-fig("fig_06_encrypt_dialog.jpg", [Диалог включения шифрования], "fig-06")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
=== Модуль :vault-contracts
|
||||
|
||||
Определяет дескрипторы vault (`VaultDescriptor`, `DescribedVault`) и контракты регистрации удалённых vault (`VaultRegistrar`, `VaultRegistration`). Реализация агрегатора — `VaultsManager` в `:domain-vault`.
|
||||
Определяет дескрипторы vault (`VaultDescriptor`, `DescribedVault`) и контракты регистрации удалённых vault (`VaultRegistrar`, `VaultRegistration`). Реализация агрегатора – `VaultsManager` в `:domain-vault`.
|
||||
|
||||
=== Модуль :domain-vault
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
=== Модуль :infrastructure-android
|
||||
|
||||
Реализует Room (`AppDb` v5), DAO, репозитории, OAuth-хранилище токенов, файловые адаптеры Android. Модуль — единственная точка зависимости от Android SDK в слое данных.
|
||||
Реализует Room (`AppDb` v5), DAO, репозитории, OAuth-хранилище токенов, файловые адаптеры Android. Модуль – единственная точка зависимости от Android SDK в слое данных.
|
||||
|
||||
=== Сборка и зависимости
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
=== Модуль :domain-vault
|
||||
|
||||
Инкапсулирует сетевой доступ к Yandex Disk и преобразование исключений Retrofit/OkHttp в доменные коды. Тесты репозитория не обращаются к реальной сети — подставляется фейковый HTTP-слой, что обеспечивает детерминированность CI.
|
||||
Инкапсулирует сетевой доступ к Yandex Disk и преобразование исключений Retrofit/OkHttp в доменные коды. Тесты репозитория не обращаются к реальной сети – подставляется фейковый HTTP-слой, что обеспечивает детерминированность CI.
|
||||
|
||||
=== Модуль :ui
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
=== Модуль :infrastructure-android
|
||||
|
||||
Связывает Room, DataStore, OAuth Activity Result API, реализации репозиториев. Версия схемы БД — 5; миграции отключены (`exportSchema = false`) на этапе прототипа. Инструментальный `YandexAccountRepositoryTest` подтверждает CRUD учётной записи в in-memory БД.
|
||||
Связывает Room, DataStore, OAuth Activity Result API, реализации репозиториев. Версия схемы БД – 5; миграции отключены (`exportSchema = false`) на этапе прототипа. Инструментальный `YandexAccountRepositoryTest` подтверждает CRUD учётной записи в in-memory БД.
|
||||
|
||||
=== Модуль :task-runtime
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
=== Модуль :vault-contracts и :app
|
||||
|
||||
`:vault-contracts` задаёт точку расширения для новых провайдеров. `:app` — Hilt-модули, `Application`, навигационный граф, сборка APK. Точка входа не содержит бизнес-правил; они делегируются use case.
|
||||
`:vault-contracts` задаёт точку расширения для новых провайдеров. `:app` – Hilt-модули, `Application`, навигационный граф, сборка APK. Точка входа не содержит бизнес-правил; они делегируются use case.
|
||||
|
||||
=== Журнал разработки и контроль версий
|
||||
|
||||
|
||||
@@ -32,19 +32,19 @@ fun enableEncryption(storage: IStorageInfo, password: String, encryptPath: Boole
|
||||
}
|
||||
```
|
||||
|
||||
Блок-схема сценария — рис. @fig-21.
|
||||
Блок-схема сценария – рис. @fig-21.
|
||||
|
||||
#pz-fig("fig_21_encrypt_flow.png", [Блок-схема: enableEncryption → checkKey → openStorage], "fig-21")
|
||||
|
||||
=== Модуль адаптеров хранилищ
|
||||
|
||||
`VaultsManager` агрегирует один `LocalVault` и удалённые vault; адаптеры реализуют доступ к файлам внутри каждого `IStorage`. Регистрация удалённых vault — через модуль `:vault-contracts`.
|
||||
`VaultsManager` агрегирует один `LocalVault` и удалённые vault; адаптеры реализуют доступ к файлам внутри каждого `IStorage`. Регистрация удалённых vault – через модуль `:vault-contracts`.
|
||||
|
||||
=== Модуль синхронизации хранилищ
|
||||
|
||||
В Room хранится сущность `DbStorageSyncGroup` — набор UUID `Storage`, которые должны иметь согласованное состояние. Запуск синхронизации выполняется через `RunStorageSyncUseCase` / `WorkManager` и debounce при изменении файлов (рис. @fig-01–@fig-03). Движок `StorageSyncEngine` (модуль `:usecases`) реализует согласование журналов изменений; доработка касается в основном политики фонового расписания и UX отображения прогресса.
|
||||
В Room хранится сущность `DbStorageSyncGroup` – набор UUID `Storage`, которые должны иметь согласованное состояние. Запуск синхронизации выполняется через `RunStorageSyncUseCase` / `WorkManager` и debounce при изменении файлов (рис. @fig-01–@fig-03). Движок `StorageSyncEngine` (модуль `:usecases`) реализует согласование журналов изменений; доработка касается в основном политики фонового расписания и UX отображения прогресса.
|
||||
|
||||
Для каждого `Storage` ведётся журнал изменений по относительным путям пользовательских файлов. Запись журнала (`StorageSyncJournalEntry`) содержит операцию (`UPSERT`, `TRASH`, `DELETE`) и ревизию (`sequence`, `actorId`, `createdAt`). Ключи шифрования в обмен не включаются — провайдер видит только зашифрованные объекты. Модуль `:task-runtime` обслуживает длительные задачи шифрования и синхронизации без блокировки UI.
|
||||
Для каждого `Storage` ведётся журнал изменений по относительным путям пользовательских файлов. Запись журнала (`StorageSyncJournalEntry`) содержит операцию (`UPSERT`, `TRASH`, `DELETE`) и ревизию (`sequence`, `actorId`, `createdAt`). Ключи шифрования в обмен не включаются – провайдер видит только зашифрованные объекты. Модуль `:task-runtime` обслуживает длительные задачи шифрования и синхронизации без блокировки UI.
|
||||
|
||||
=== Алгоритм согласования журналов синхронизации
|
||||
|
||||
@@ -52,18 +52,18 @@ fun enableEncryption(storage: IStorageInfo, password: String, encryptPath: Boole
|
||||
|
||||
#pz-fig("fig_35_sync_merge_algorithm.png", [Алгоритм согласования журналов (StorageSyncEngine)], "fig-35")
|
||||
|
||||
*Подготовка.* По UUID из `DbStorageSyncGroup` загружаются объекты `IStorage`. Если в группе меньше двух хранилищ или несовместимы параметры шифрования, синхронизация пропускается. На каждом accessor запрашивается блокировка sync (lease на удалённом диске — best-effort; внутри процесса группа сериализуется `Mutex`). Параллельно для каждого storage вызываются `flushPendingSyncJournal()` и `readSyncJournal()`; служебные пути отфильтровываются (`StorageSyncPaths.isSyncableUserPath`).
|
||||
*Подготовка.* По UUID из `DbStorageSyncGroup` загружаются объекты `IStorage`. Если в группе меньше двух хранилищ или несовместимы параметры шифрования, синхронизация пропускается. На каждом accessor запрашивается блокировка sync (lease на удалённом диске – best-effort; внутри процесса группа сериализуется `Mutex`). Параллельно для каждого storage вызываются `flushPendingSyncJournal()` и `readSyncJournal()`; служебные пути отфильтровываются (`StorageSyncPaths.isSyncableUserPath`).
|
||||
|
||||
*Слияние журналов.* Объект `StorageSyncJournalMerge` объединяет журналы в отображение «путь → победитель». Для каждого пути остаётся запись с наибольшей ревизией. Сравнение реализовано функцией `compareEntries`: сначала `revision.sequence`, при равенстве — `actorId`, затем `createdAt`. Такой порядок обеспечивает детерминированный выбор одной записи при конкурентных изменениях на разных устройствах.
|
||||
*Слияние журналов.* Объект `StorageSyncJournalMerge` объединяет журналы в отображение «путь → победитель». Для каждого пути остаётся запись с наибольшей ревизией. Сравнение реализовано функцией `compareEntries`: сначала `revision.sequence`, при равенстве – `actorId`, затем `createdAt`. Такой порядок обеспечивает детерминированный выбор одной записи при конкурентных изменениях на разных устройствах.
|
||||
|
||||
*Выбор источника для пути.* После слияния для каждой пары (путь, `winnerEntry`) вызывается `findSourceStorage`:
|
||||
|
||||
+ при `UPSERT` — первый `Storage`, у которого запись по этому пути *совпадает* с победителем (`compareEntries == 0`): оттуда читаются байты для копирования;
|
||||
+ при `DELETE` или `TRASH` — первый `Storage`, где путь ещё присутствует в журнале (или любой storage группы, если записей нет): оттуда инициируется удаление на целях.
|
||||
- при `UPSERT` – первый `Storage`, у которого запись по этому пути *совпадает* с победителем (`compareEntries == 0`): оттуда читаются байты для копирования;
|
||||
- при `DELETE` или `TRASH` – первый `Storage`, где путь ещё присутствует в журнале (или любой storage группы, если записей нет): оттуда инициируется удаление на целях.
|
||||
|
||||
Если для `UPSERT` источник не найден, путь пропускается (файл уже отсутствует на всех носителях).
|
||||
|
||||
*Распространение на цели.* Для каждого `target` в группе, отличного от источника, сравнивается ревизия записи на цели с `winnerEntry`. Если цель уже не слабее победителя (`compareEntries(target, winner) >= 0`), шаг пропускается. Иначе вызывается `applyEntry`: для `UPSERT` — потоковое копирование `openRead` → `openWrite`; для `DELETE` / `TRASH` — `delete` или `moveToTrash`. Все операции выполняются с `recordSyncJournal = false`, чтобы не порождать цикл повторной синхронизации. Ошибки отдельных путей учитываются счётчиком `applyFailures`, отмена кооперативная (проверка `syncGeneration`, снятие блокировок в `finally`).
|
||||
*Распространение на цели.* Для каждого `target` в группе, отличного от источника, сравнивается ревизия записи на цели с `winnerEntry`. Если цель уже не слабее победителя (`compareEntries(target, winner) >= 0`), шаг пропускается. Иначе вызывается `applyEntry`: для `UPSERT` – потоковое копирование `openRead` → `openWrite`; для `DELETE` / `TRASH` – `delete` или `moveToTrash`. Все операции выполняются с `recordSyncJournal = false`, чтобы не порождать цикл повторной синхронизации. Ошибки отдельных путей учитываются счётчиком `applyFailures`, отмена кооперативная (проверка `syncGeneration`, снятие блокировок в `finally`).
|
||||
|
||||
Фрагмент сравнения ревизий и выбора источника:
|
||||
|
||||
@@ -154,7 +154,7 @@ remoteVaultAuthenticator.beginLink(CloudBrand.YANDEX) { outcome ->
|
||||
|
||||
#pz-fig("fig_23_module_deps.png", [Зависимости модулей Gradle], "fig-23")
|
||||
|
||||
В основном тексте приведены показательные фрагменты; полные листинги — в приложении А.
|
||||
В основном тексте приведены показательные фрагменты; полные листинги – в приложении А.
|
||||
|
||||
#include "ch04-expand.typ"
|
||||
#include "ch04-modules.typ"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
== Модульные тесты (JUnit)
|
||||
|
||||
В проекте реализовано 68 автоматических unit-тестов в пяти модулях (`:domain` — 12, `:domain-vault` — 10, `:usecases` — 25, `:ui` — 15, `:task-runtime` — 6). Тесты выполняются на JVM при сборке.
|
||||
В проекте реализовано 68 автоматических unit-тестов в пяти модулях (`:domain` – 12, `:domain-vault` – 10, `:usecases` – 25, `:ui` – 15, `:task-runtime` – 6). Тесты выполняются на JVM при сборке.
|
||||
|
||||
#include "ch05-tests-generated.typ"
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
Класс `EncryptorTest` проверяет сценарии AES: `checkKey`, шифрование строк, байтовых массивов и потоков с верным и неверным ключом (строки 5–14 табл. @tbl-unit-all). `WallencExceptionMappingTest` покрывает преобразование файловых и сетевых исключений.
|
||||
|
||||
Прогон `./gradlew :domain:test` — на рис. @fig-27.
|
||||
Прогон `./gradlew :domain:test` – на рис. @fig-27.
|
||||
|
||||
#pz-fig("fig_27_gradle_domain_test.png", [Отчёт Gradle: модуль :domain, задача test], "fig-27")
|
||||
|
||||
=== Синхронизация, 2FA и use cases
|
||||
|
||||
`StorageSyncEngineTest` моделирует группы синхронизации, копирование и удаление файлов, soft-delete, отмену и блокировки (строки 52–64 табл. @tbl-unit-all); отдельно проверяются слияние журнала (`mergeKeepsSingleEntryPerPath`) и пропуск цели с актуальной ревизией (`syncSkipsWhenTargetRevisionAlreadyWinner`) — см. алгоритм в гл. 4. `TwoFaTotpTest` сверяет TOTP с эталоном Java OTP. `StorageDomainUseCasesTest` проверяет CRUD текстовых секретов и 2FA.
|
||||
`StorageSyncEngineTest` моделирует группы синхронизации, копирование и удаление файлов, soft-delete, отмену и блокировки (строки 52–64 табл. @tbl-unit-all); отдельно проверяются слияние журнала (`mergeKeepsSingleEntryPerPath`) и пропуск цели с актуальной ревизией (`syncSkipsWhenTargetRevisionAlreadyWinner`) – см. алгоритм в гл. 4. `TwoFaTotpTest` сверяет TOTP с эталоном Java OTP. `StorageDomainUseCasesTest` проверяет CRUD текстовых секретов и 2FA.
|
||||
|
||||
#pz-fig("fig_28_gradle_usecases_test.png", [Отчёт Gradle: модуль :usecases], "fig-28")
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
[:app], [YandexDiskLiveIntegrationTest], [Живой API (при наличии токена)], [3],
|
||||
) <tbl-androidtest>
|
||||
|
||||
Запуск: `./gradlew connectedDebugAndroidTest`. Результат — рис. @fig-31. Отрисовка экранов секретов и 2FA подтверждена скриншотами @fig-33–@fig-34.
|
||||
Запуск: `./gradlew connectedDebugAndroidTest`. Результат – рис. @fig-31. Отрисовка экранов секретов и 2FA подтверждена скриншотами @fig-33–@fig-34.
|
||||
|
||||
#pz-fig("fig_31_gradle_connected_test.png", [Gradle connectedDebugAndroidTest], "fig-31")
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
== Отчёт о результатах тестирования
|
||||
|
||||
По итогам `./gradlew test` все 68 unit-тестов завершились со статусом PASSED. Инструментальные тесты `:ui` подтвердили отрисовку экранов секретов и 2FA; тесты Room — персистентность учётной записи Яндекс.
|
||||
По итогам `./gradlew test` все 68 unit-тестов завершились со статусом PASSED. Инструментальные тесты `:ui` подтвердили отрисовку экранов секретов и 2FA; тесты Room – персистентность учётной записи Яндекс.
|
||||
|
||||
#pz-fig("fig_30_gradle_test_summary.png", [Сводка Gradle test по модулям], "fig-30")
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
== Обзор рынка программного обеспечения и аналогов
|
||||
|
||||
Рынок клиентских решений для защищённого хранения данных представлен продуктами классов «локальный сейф», менеджеры секретов и zero-knowledge файловые клиенты (см. табл. @tbl-analog, гл. 1). Ниша Wallenc — мобильный универсальный vault без собственного backend приложения с возможностью подключения внешних провайдеров через OAuth.
|
||||
Рынок клиентских решений для защищённого хранения данных представлен продуктами классов «локальный сейф», менеджеры секретов и zero-knowledge файловые клиенты (см. табл. @tbl-analog, гл. 1). Ниша Wallenc – мобильный универсальный vault без собственного backend приложения с возможностью подключения внешних провайдеров через OAuth.
|
||||
|
||||
== Оценка экономических затрат на разработку проекта
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
[06.05.2026], [Защита практики, итоговая сборка ПЗ],
|
||||
) <tbl-calendar>
|
||||
|
||||
Календарный график работ совпадает с дневником практики: этап 1 — аналитика и проектирование (февраль–март 2026); этап 2 — реализация (29.03–19.04.2026); оформление документации — апрель–май 2026.
|
||||
Календарный график работ совпадает с дневником практики: этап 1 – аналитика и проектирование (февраль–март 2026); этап 2 – реализация (29.03–19.04.2026); оформление документации – апрель–май 2026.
|
||||
|
||||
== Модель применения и окупаемости
|
||||
|
||||
*Сценарий применения* — внедрение в ООО НМФ «Нейротех» как внутренний инструмент защищённого хранения файлов сотрудников на корпоративных или личных облачных аккаунтах при сохранении zero-knowledge модели.
|
||||
*Сценарий применения* – внедрение в ООО НМФ «Нейротех» как внутренний инструмент защищённого хранения файлов сотрудников на корпоративных или личных облачных аккаунтах при сохранении zero-knowledge модели.
|
||||
|
||||
*Эффект*: снижение риска утечки при компрометации провайдера; отсутствие затрат на собственный сервер приложения. Окупаемость для учебно-промышленного прототипа выражается не в прямой прибыли, а в сокращении рисков и возможности доработки продукта без смены архитектуры.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
== Связь компетенции с предметом ВКР
|
||||
|
||||
Wallenc уже оперирует структурированными данными, пригодными для анализа: журнал синхронизации (пути, операции, ревизии, метки времени), метаданные файлов (имя, размер, тип по расширению), события фоновых задач. Это не «сырой» пользовательский контент, а агрегаты, которые можно обрабатывать локально. Компетенция ВПК-2 в контексте ВКР раскрывается постановкой задач, выбором данных и моделей, метриками качества и правилами принятия решений — даже если в MVP остаётся только проектный анализ.
|
||||
Wallenc уже оперирует структурированными данными, пригодными для анализа: журнал синхронизации (пути, операции, ревизии, метки времени), метаданные файлов (имя, размер, тип по расширению), события фоновых задач. Это не «сырой» пользовательский контент, а агрегаты, которые можно обрабатывать локально. Компетенция ВПК-2 в контексте ВКР раскрывается постановкой задач, выбором данных и моделей, метриками качества и правилами принятия решений – даже если в MVP остаётся только проектный анализ.
|
||||
|
||||
== Прикладные задачи анализа данных и принимаемые решения
|
||||
|
||||
@@ -34,12 +34,12 @@ Wallenc уже оперирует структурированными данн
|
||||
|
||||
*OCR.* Google ML Kit Text Recognition @mlkit-text позволяет извлечь текст без собственного обучения; дообучение нужно только для специфичных шрифтов. Решение: предзаполнить поле секрета с возможностью редактирования.
|
||||
|
||||
Общая схема on-device inference приведена на рис. @fig-36: метаданные и признаки не покидают устройство в открытом виде; обучение на расшифрованном содержимом всех пользователей в облаке для Wallenc неприемлемо. Альтернатива — *федеративное обучение* только на агрегированных градиентах по opt-in, без централизованного хранения файлов.
|
||||
Общая схема on-device inference приведена на рис. @fig-36: метаданные и признаки не покидают устройство в открытом виде; обучение на расшифрованном содержимом всех пользователей в облаке для Wallenc неприемлемо. Альтернатива – *федеративное обучение* только на агрегированных градиентах по opt-in, без централизованного хранения файлов.
|
||||
|
||||
#pz-fig("fig_36_ml_on_device.png", [Гипотетический контур on-device ML], "fig-36")
|
||||
|
||||
== Этика, ограничения и вывод по ВПК-2
|
||||
|
||||
Любой модуль ИИ должен быть отключаемым (opt-in), объяснять пользователю основание рекомендации (например, «похожее имя файла») и не подменять явное действие при удалении или синхронизации. Конфликт с E2E возникает, если отправлять ciphertext или ключи на внешний API inference — в проекте такой путь не рассматривается.
|
||||
Любой модуль ИИ должен быть отключаемым (opt-in), объяснять пользователю основание рекомендации (например, «похожее имя файла») и не подменять явное действие при удалении или синхронизации. Конфликт с E2E возникает, если отправлять ciphertext или ключи на внешний API inference – в проекте такой путь не рассматривается.
|
||||
|
||||
*Вывод.* Компетенция «решать прикладные задачи анализа данных и принятия решений с использованием искусственного интеллекта» в пояснительной записке раскрыта анализом применимости ML к Wallenc: сформулированы задачи, источники данных, типы моделей, метрики обучения и границы развёртывания on-device. Внедрение в текущий MVP не выполнялось осознанно — в соответствии с целями ВКР по защищённому хранению без доверенного backend.
|
||||
*Вывод.* Компетенция «решать прикладные задачи анализа данных и принятия решений с использованием искусственного интеллекта» в пояснительной записке раскрыта анализом применимости ML к Wallenc: сформулированы задачи, источники данных, типы моделей, метрики обучения и границы развёртывания on-device. Внедрение в текущий MVP не выполнялось осознанно – в соответствии с целями ВКР по защищённому хранению без доверенного backend.
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Таблицы — как в «Пример работы с Typst.typ» и gost: figure + table + table.header.
|
||||
// Таблицы – как в «Пример работы с Typst.typ» и gost: figure + table + table.header.
|
||||
// ГОСТ 7.32 / чек-лист: в тексте и подписях – среднее тире «–» (U+2013), не длинное «—».
|
||||
#let pz-figure-caption-separator = [#sym.space.nobreak#sym.dash.en#sym.space.nobreak]
|
||||
// Разрыв длинных таблиц и подпись сверху задаёт шаблон modern-g7-32 (style.typ).
|
||||
|
||||
#show table: set text(hyphenate: true, lang: "ru")
|
||||
#show table.cell: set block(inset: (x: 5pt, y: 3pt))
|
||||
|
||||
// Таблица внутри figure — по умолчанию один неразрывный block (обрезка длинных реестров).
|
||||
// Таблица внутри figure – по умолчанию один неразрывный block (обрезка длинных реестров).
|
||||
#show figure.where(kind: table): set block(breakable: true)
|
||||
|
||||
#let pz-appendix-title(body) = heading(level: 1)[#body]
|
||||
@@ -31,7 +33,7 @@
|
||||
#let pz-thesis-topic-en = "Mobile application for secure storage of user data"
|
||||
#let pz-thesis-subject = "мобильном приложении для защищённого хранения пользовательских данных"
|
||||
|
||||
// Бланк аннотации: 2×2 без рамок; левый столбец — отступ, текст во 2-м (2 ячейки).
|
||||
// Бланк аннотации: 2×2 без рамок; левый столбец – отступ, текст во 2-м (2 ячейки).
|
||||
#let pz-dept-mop = "кафедра МОП ЭВМ"
|
||||
#let pz-dept-sait = "кафедра системного анализа и телекоммуникаций"
|
||||
|
||||
@@ -73,7 +75,7 @@
|
||||
#linebreak()
|
||||
#institute,
|
||||
#linebreak()
|
||||
#faculty, #department — #year#sym.space.nobreak г.,
|
||||
#faculty, #department – #year#sym.space.nobreak г.,
|
||||
#linebreak()
|
||||
#pages#sym.space.nobreak с.
|
||||
],
|
||||
@@ -106,7 +108,7 @@
|
||||
#linebreak()
|
||||
#institute,
|
||||
#linebreak()
|
||||
#faculty, #department — #year,
|
||||
#faculty, #department – #year,
|
||||
#linebreak()
|
||||
#pages#sym.space.nobreak p.
|
||||
],
|
||||
@@ -121,7 +123,7 @@
|
||||
1
|
||||
}
|
||||
|
||||
// Строка из ..range().map(i => ([a], [b])) в body.pos() — один аргумент-массив.
|
||||
// Строка из ..range().map(i => ([a], [b])) в body.pos() – один аргумент-массив.
|
||||
#let pz-flatten-cells(cells) = cells.fold((), (acc, cell) => {
|
||||
if type(cell) == array { acc + cell } else { acc + (cell,) }
|
||||
})
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
*Перспективы развития*: расширение фонового расписания sync; поддержка дополнительных провайдеров; опциональные on-device модели по сценариям гл. 6; расширение автоматизированных UI-тестов.
|
||||
|
||||
Программная документация приведена в приложении Б; иллюстрации интерфейса — в приложении В.
|
||||
Программная документация приведена в приложении Б; иллюстрации интерфейса – в приложении В.
|
||||
|
||||
По тестированию подтверждено: 68 модульных unit-тестов, инструментальные тесты Compose и Room, ручной протокол из двенадцати сценариев (гл. 5).
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
|
||||
*Актуальность* темы обусловлена распространением мобильных приложений для хранения файлов и секретов, а также ограниченностью готовых решений: многие продукты привязаны к собственному backend, закрытой экосистеме или узкой предметной области @google-secure-folder @bitwarden-help @cryptomator-docs.
|
||||
|
||||
*Цель работы* — повысить конфиденциальность пользовательских данных при работе с недоверенными хранилищами за счёт разработки мобильного приложения для защищённого хранения пользовательских данных (Wallenc) без собственного сервера приложения, с иерархией vault → storage → файлы и клиентским шифрованием.
|
||||
*Цель работы* – повысить конфиденциальность пользовательских данных при работе с недоверенными хранилищами за счёт разработки мобильного приложения для защищённого хранения пользовательских данных (Wallenc) без собственного сервера приложения, с иерархией vault → storage → файлы и клиентским шифрованием.
|
||||
|
||||
Для достижения цели были поставлены следующие *задачи*:
|
||||
+ выполнить анализ предметной области и сравнительный обзор аналогов, сформировать требования к программному продукту;
|
||||
+ спроектировать архитектуру системы, модель данных и пользовательские сценарии;
|
||||
+ реализовать программные модули приложения Wallenc на платформе Android (Kotlin);
|
||||
+ провести тестирование программного обеспечения и оформить программную документацию.
|
||||
- выполнить анализ предметной области и сравнительный обзор аналогов, сформировать требования к программному продукту;
|
||||
- спроектировать архитектуру системы, модель данных и пользовательские сценарии;
|
||||
- реализовать программные модули приложения Wallenc на платформе Android (Kotlin);
|
||||
- провести тестирование программного обеспечения и оформить программную документацию.
|
||||
|
||||
*Объект исследования* — методы и средства клиентской защиты данных в мобильных приложениях. *Предмет исследования* — проектные и программные решения приложения Wallenc.
|
||||
*Объект исследования* – методы и средства клиентской защиты данных в мобильных приложениях. *Предмет исследования* – проектные и программные решения приложения Wallenc.
|
||||
|
||||
*Методы исследования*: анализ нормативной и технической документации, сравнительный анализ программных аналогов, объектно-ориентированное проектирование (UML, BPMN, DFD), прототипирование пользовательского интерфейса, программная реализация и тестирование @gost7322017 @kotlin-docs.
|
||||
|
||||
*Практическая база.* Работа выполнена в рамках производственной практики в ООО НМФ «Нейротех» (09.02.2026–06.05.2026) по направлению 09.03.04 «Программная инженерия» на кафедре математического обеспечения и применения ЭВМ (МОП ЭВМ). Научный руководитель — Беликов А. Н. (кафедра системного анализа и телекоммуникаций, САИТ); руководитель от организации — Алексеев Д. М.
|
||||
*Практическая база.* Работа выполнена в рамках производственной практики в ООО НМФ «Нейротех» (09.02.2026–06.05.2026) по направлению 09.03.04 «Программная инженерия» на кафедре математического обеспечения и применения ЭВМ (МОП ЭВМ). Научный руководитель – Беликов А. Н. (кафедра системного анализа и телекоммуникаций, САИТ); руководитель от организации – Алексеев Д. М.
|
||||
|
||||
*Научная новизна* заключается в сочетании единого `VaultsManager`, модели vault/storage, клиентского шифрования и адаптерного доступа к провайдерам без собственного сервера приложения, с проектным контуром синхронизации зашифрованных данных без передачи ключей провайдеру.
|
||||
|
||||
*Практическая значимость* — использование результатов при дальнейшей разработке продукта и в учебных проектах по мобильной разработке и информационной безопасности.
|
||||
*Практическая значимость* – использование результатов при дальнейшей разработке продукта и в учебных проектах по мобильной разработке и информационной безопасности.
|
||||
|
||||
Пояснительная записка состоит из введения, шести глав, заключения, списка использованных источников и трёх приложений (листинги исходного кода, программная документация, скриншоты интерфейса). В главе 1 обоснована актуальность и приведено сравнение аналогов; глава 2 описывает архитектуру и модель Room; глава 3 — UX и пользовательские сценарии; глава 4 — реализацию по модулям, алгоритм синхронизации журналов и применение ИИ-ассистента при разработке; глава 5 — тестирование; глава 6 — вариативную профессиональную компетенцию по анализу данных и решениям с использованием ИИ.
|
||||
Пояснительная записка состоит из введения, шести глав, заключения, списка использованных источников и трёх приложений (листинги исходного кода, программная документация, скриншоты интерфейса). В главе 1 обоснована актуальность и приведено сравнение аналогов; глава 2 описывает архитектуру и модель Room; глава 3 – UX и пользовательские сценарии; глава 4 – реализацию по модулям, алгоритм синхронизации журналов и применение ИИ-ассистента при разработке; глава 5 – тестирование; глава 6 – вариативную профессиональную компетенцию по анализу данных и решениям с использованием ИИ.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "common.typ": pz-sig-line, pz-thesis-topic
|
||||
|
||||
// Строка ТЗ с линией на всю ширину (как бланк ВКР).
|
||||
// Не входит в Пояснительная_записка_ПытковРЕ.typ — черновик: front-matter-export/tz-vkr-assignment.typ
|
||||
// Не входит в Пояснительная_записка_ПытковРЕ.typ – черновик: front-matter-export/tz-vkr-assignment.typ
|
||||
#let tz-row(body) = {
|
||||
v(0.35em)
|
||||
table(
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
#tz-row[2.2 ОС разработки: GNU/Linux / Windows 11.]
|
||||
|
||||
#tz-row[2.3 Язык программирования: Kotlin; целевая платформа — Android (API 26+).]
|
||||
#tz-row[2.3 Язык программирования: Kotlin; целевая платформа – Android (API 26+).]
|
||||
|
||||
#tz-row[2.4 Стек и инструменты: Jetpack Compose, Kotlin Coroutines/Flow, Hilt, Room, JUnit, PlantUML.]
|
||||
|
||||
@@ -76,53 +76,53 @@
|
||||
|
||||
#tz-row[3.9 Список использованных источников]
|
||||
|
||||
#tz-row[3.10 Приложение А — листинги исходного кода проекта Wallenc]
|
||||
#tz-row[3.10 Приложение А – листинги исходного кода проекта Wallenc]
|
||||
|
||||
#tz-row[3.11 Приложение Б — программная документация (ТЗ, руководство пользователя)]
|
||||
#tz-row[3.11 Приложение Б – программная документация (ТЗ, руководство пользователя)]
|
||||
|
||||
#tz-row[3.12 Приложение В — скриншоты пользовательского интерфейса]
|
||||
#tz-row[3.12 Приложение В – скриншоты пользовательского интерфейса]
|
||||
|
||||
#tz-row[4. Перечень графического материала:]
|
||||
|
||||
#tz-row-split(
|
||||
[4.1 Цель, задачи и актуальность работы],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.2 Контекстная диаграмма и анализ предметной области],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.3 Обзор аналогов],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.4 Требования к системе (функциональные и нефункциональные)],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.5 Архитектура системы (BPMN, DFD, прецеденты, Clean Architecture, развёртывание, Room)],
|
||||
[— 6 пл.],
|
||||
[– 6 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.6 Алгоритмы и диаграммы реализации (OAuth, шифрование, синхронизация журналов, зависимости модулей)],
|
||||
[— 4 пл.],
|
||||
[– 4 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.7 Пользовательские сценарии и экраны UI],
|
||||
[— 12 пл.],
|
||||
[– 12 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.8 Тестирование ПО],
|
||||
[— 6 пл.],
|
||||
[– 6 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.9 Апробация результатов (производственная практика)],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
#tz-row-split(
|
||||
[4.10 Выводы по работе],
|
||||
[— 1 пл.],
|
||||
[– 1 пл.],
|
||||
)
|
||||
|
||||
#tz-row[
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
=== Назначение и цели создания системы
|
||||
|
||||
*Назначение* системы Wallenc — предоставление пользователю мобильного клиента для работы с иерархией *VaultsManager → vault → storage → файлы*: один `LocalVault` на устройстве, удалённые vault по OAuth; внутри vault пользователь создаёт и управляет *storage*; шифрование (`StorageEncryptionInfo`, `Encryptor`) применяется к storage, а не к vault.
|
||||
*Назначение* системы Wallenc – предоставление пользователю мобильного клиента для работы с иерархией *VaultsManager → vault → storage → файлы*: один `LocalVault` на устройстве, удалённые vault по OAuth; внутри vault пользователь создаёт и управляет *storage*; шифрование (`StorageEncryptionInfo`, `Encryptor`) применяется к storage, а не к vault.
|
||||
|
||||
*Цели создания*: обеспечить единую модель vault и storage; минимизировать доверие к провайдеру; поддержать расширение списка провайдеров через адаптеры; сохранить служебные метаданные в локальной БД без хранения пользовательского контента в открытом виде.
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
[Свод функциональных требований],
|
||||
2,
|
||||
table.header([Код], [Требование]),
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault — один на устройстве)],
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault – один на устройстве)],
|
||||
[ФР-2], [Включение шифрования storage, проверка ключа, открытие и закрытие зашифрованного представления],
|
||||
[ФР-3], [Просмотр и операции с файлами внутри storage; текстовые секреты и 2FA],
|
||||
[ФР-4], [OAuth-авторизация (Яндекс), регистрация удалённых vault и листинг их storage],
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
=== Требования к программно-аппаратной платформе
|
||||
|
||||
Минимальная платформа — Android с поддержкой Jetpack Compose; для OAuth и удалённых операций требуется сетевое подключение. Объём оперативной памяти должен быть достаточен для фоновых задач шифрования и Room.
|
||||
Минимальная платформа – Android с поддержкой Jetpack Compose; для OAuth и удалённых операций требуется сетевое подключение. Объём оперативной памяти должен быть достаточен для фоновых задач шифрования и Room.
|
||||
|
||||
== Сравнение аналогов (обоснование требований)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
[Сравнительная оценка аналогов],
|
||||
6,
|
||||
table.header([Критерий], [Secure Folder], [Proton], [Bitwarden], [Cryptomator], [Wallenc]),
|
||||
[Собственный backend приложения], [—], [+], [+/−], [—], [—],
|
||||
[Собственный backend приложения], [–], [+], [+/−], [–], [–],
|
||||
[E2E / клиентское шифрование], [+/−], [+], [+], [+], [+],
|
||||
[Файловый vault], [+], [+], [−], [+], [+],
|
||||
[OAuth внешнего провайдера], [−], [+/−], [+/−], [+/−], [+],
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
=== Цели и задачи испытаний
|
||||
|
||||
Основная цель — подтвердить корректность криптографического ядра, доменной логики синхронизации и сценариев UI. Были поставлены следующие задачи:
|
||||
Основная цель – подтвердить корректность криптографического ядра, доменной логики синхронизации и сценариев UI. Были поставлены следующие задачи:
|
||||
|
||||
+ проверить `Encryptor` и проверку ключа для строк, байтов и потоков;
|
||||
+ убедиться в корректном маппинге исключений в коды ошибок;
|
||||
+ протестировать движок синхронизации (`StorageSyncEngine`, журнал, блокировки);
|
||||
+ проверить оркестратор фоновых задач;
|
||||
+ выполнить smoke-тесты навигации, deep link и 2FA/TOTP;
|
||||
+ зафиксировать результаты ручных сценариев vault, OAuth и экрана задач.
|
||||
- проверить `Encryptor` и проверку ключа для строк, байтов и потоков;
|
||||
- убедиться в корректном маппинге исключений в коды ошибок;
|
||||
- протестировать движок синхронизации (`StorageSyncEngine`, журнал, блокировки);
|
||||
- проверить оркестратор фоновых задач;
|
||||
- выполнить smoke-тесты навигации, deep link и 2FA/TOTP;
|
||||
- зафиксировать результаты ручных сценариев vault, OAuth и экрана задач.
|
||||
|
||||
=== Объект и уровни тестирования
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
== Автоматизированное тестирование (код модулей)
|
||||
|
||||
В проекте реализовано 68 автоматических unit-тестов в пяти модулях (`:domain` — 12, `:domain-vault` — 10, `:usecases` — 25, `:ui` — 15, `:task-runtime` — 6). Тесты выполняются на JVM при сборке (`./gradlew test`). Инструментальные тесты размещены в `src/androidTest` соответствующих модулей.
|
||||
В проекте реализовано 68 автоматических unit-тестов в пяти модулях (`:domain` – 12, `:domain-vault` – 10, `:usecases` – 25, `:ui` – 15, `:task-runtime` – 6). Тесты выполняются на JVM при сборке (`./gradlew test`). Инструментальные тесты размещены в `src/androidTest` соответствующих модулей.
|
||||
|
||||
=== Листинги исходного кода автотестов
|
||||
|
||||
Ниже — листинги файлов `src/test` и `src/androidTest` (при сборке PDF читаются из дерева проекта Wallenc, по тому же принципу, что приложение А пояснительной записки).
|
||||
Ниже – листинги файлов `src/test` и `src/androidTest` (при сборке PDF читаются из дерева проекта Wallenc, по тому же принципу, что приложение А пояснительной записки).
|
||||
|
||||
#include "../../listings/generated-tests/appendix-tests.typ"
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
|
||||
== Инструментальные тесты (androidTest)
|
||||
|
||||
Запуск: `./gradlew connectedDebugAndroidTest`. Результат — на рис. @fig-31-export.
|
||||
Запуск: `./gradlew connectedDebugAndroidTest`. Результат – на рис. @fig-31-export.
|
||||
|
||||
#pz-fig("fig_31_gradle_connected_test.png", [Gradle connectedDebugAndroidTest], "fig-31-export")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
== Отчёт о проведении тестирования
|
||||
|
||||
По итогам `./gradlew test` все 68 unit-тестов завершились со статусом PASSED. Инструментальные тесты `:ui` подтвердили отрисовку экранов секретов и 2FA; тесты Room — персистентность учётной записи Яндекс.
|
||||
По итогам `./gradlew test` все 68 unit-тестов завершились со статусом PASSED. Инструментальные тесты `:ui` подтвердили отрисовку экранов секретов и 2FA; тесты Room – персистентность учётной записи Яндекс.
|
||||
|
||||
#import "../common.typ": pz-fig, pz-table
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[Свод функциональных требований (фрагмент ПЗ, гл. 1)],
|
||||
2,
|
||||
table.header([Код], [Требование]),
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault — один на устройстве)],
|
||||
[ФР-1], [Создание, просмотр, переименование и удаление storage в локальном vault (LocalVault – один на устройстве)],
|
||||
[ФР-2], [Включение шифрования storage, проверка ключа, открытие и закрытие зашифрованного представления],
|
||||
[ФР-3], [Просмотр и операции с файлами внутри storage; текстовые секреты и 2FA],
|
||||
[ФР-4], [OAuth-авторизация (Яндекс), регистрация удалённых vault и листинг их storage],
|
||||
|
||||
Reference in New Issue
Block a user