Remove non-deploy files from public repository
This commit is contained in:
@@ -1,128 +0,0 @@
|
||||
# План: независимые DrHider и Obfuscator
|
||||
|
||||
## Цель
|
||||
|
||||
Получить два полностью независимых production-сервиса:
|
||||
|
||||
- **DrHider** — репозиторий `Nail/drhider`, отдельный Flask-инстанс и отдельный upload-буфер.
|
||||
- **Obfuscator** — репозиторий `forcloud/obfuscator`, отдельный Flask-инстанс и отдельный upload-буфер.
|
||||
|
||||
После разделения изменения, версии, деплои, сессии и временные файлы одного сервиса не должны влиять на другой.
|
||||
|
||||
## Целевая схема
|
||||
|
||||
```text
|
||||
DrHider
|
||||
repo: https://gitea.services.ngcloud.ru/Nail/drhider.git
|
||||
app: https://drhider.pythonk8s.dev.nubes.ru/
|
||||
buffer: https://upload-drhider.sinefo.ru/buffer/
|
||||
|
||||
Obfuscator
|
||||
repo: https://gitea.services.ngcloud.ru/forcloud/obfuscator.git
|
||||
app: https://obfuscator.pythonk8s.services.ngcloud.ru/
|
||||
buffer: https://upload-obfuscator.sinefo.ru/buffer/
|
||||
```
|
||||
|
||||
Оба буфера могут находиться на VM213, но должны иметь разные hostname и разные директории:
|
||||
|
||||
```text
|
||||
/var/www/upload-drhider/
|
||||
/var/www/upload-obfuscator/
|
||||
```
|
||||
|
||||
Текущий адрес `https://upload.sinefo.ru/drhider-upload/` считать временным legacy-маршрутом. Его не использовать в новой конфигурации Obfuscator.
|
||||
|
||||
## Этап 1. Разделить production-инстансы
|
||||
|
||||
1. Создать отдельный Managed Flask-инстанс для `forcloud/obfuscator`.
|
||||
2. Оставить DrHider подключённым только к `Nail/drhider`.
|
||||
3. Проверить, что у сервисов разные:
|
||||
- instance ID;
|
||||
- hostname;
|
||||
- переменные окружения;
|
||||
- настройки Redeploy.
|
||||
4. Не добавлять `upstream`, не использовать общий Git remote и не подключать один репозиторий как submodule другого.
|
||||
|
||||
## Этап 2. Разделить upload-буферы на VM213
|
||||
|
||||
1. Создать две директории с владельцем пользователя Nginx:
|
||||
- `/var/www/upload-drhider/`;
|
||||
- `/var/www/upload-obfuscator/`.
|
||||
2. Добавить в Nginx два независимых WebDAV location:
|
||||
- `/buffer/` для `upload-drhider.sinefo.ru`;
|
||||
- `/buffer/` для `upload-obfuscator.sinefo.ru`.
|
||||
3. Для каждого location настроить отдельно:
|
||||
- `alias`;
|
||||
- `PUT`, `GET`, `DELETE`;
|
||||
- `client_max_body_size`;
|
||||
- CORS только для своего Flask-инстанса;
|
||||
- очистку старых временных файлов.
|
||||
4. Не менять и не удалять старый маршрут до завершения миграции и проверки обоих сервисов.
|
||||
|
||||
## Этап 3. DNS и TLS
|
||||
|
||||
Создать A-записи на IP VM213 `5.172.178.213`:
|
||||
|
||||
```text
|
||||
upload-drhider.sinefo.ru A 5.172.178.213
|
||||
upload-obfuscator.sinefo.ru A 5.172.178.213
|
||||
```
|
||||
|
||||
Для обоих hostname выпустить отдельные сертификаты Certbot и проверить автоматическое продление.
|
||||
|
||||
## Этап 4. Конфигурация приложений
|
||||
|
||||
В DrHider указать только его буфер. В Obfuscator указать только его буфер.
|
||||
|
||||
Проверить и при необходимости заменить во всех рабочих файлах:
|
||||
|
||||
- фронтендовый `VM_UPLOAD_URL`;
|
||||
- backend `VM_UPLOAD_PREFIX`;
|
||||
- значение `vmUploadPrefix` в health/config endpoint;
|
||||
- CORS origin;
|
||||
- пути временного хранения и очистки.
|
||||
|
||||
Переименовать общие переменные в нейтральные имена, например `UPLOAD_BUFFER_URL`, если это не ломает существующий публичный API.
|
||||
|
||||
## Этап 5. Независимые деплои
|
||||
|
||||
Для каждого сервиса отдельно:
|
||||
|
||||
1. Изменить код только в его репозитории.
|
||||
2. Выполнить локальные тесты и проверку синтаксиса.
|
||||
3. Сделать commit и push в его `master`.
|
||||
4. Выполнить Redeploy соответствующего Managed Flask-инстанса.
|
||||
5. Проверить `/health` и версию.
|
||||
|
||||
Push в `Nail/drhider` не должен запускать или изменять Obfuscator. Push в `forcloud/obfuscator` не должен запускать или изменять DrHider.
|
||||
|
||||
## Этап 6. Проверка изоляции
|
||||
|
||||
Для каждого сервиса отдельно проверить:
|
||||
|
||||
- `GET /health` возвращает правильную версию;
|
||||
- браузерный `OPTIONS` возвращает CORS только для своего origin;
|
||||
- `PUT -> GET -> DELETE` работает через собственный hostname;
|
||||
- файл одного сервиса не виден в директории другого;
|
||||
- отмена и очистка сессии не затрагивают второй сервис;
|
||||
- обновление версии одного приложения не меняет `/health` второго.
|
||||
|
||||
## Этап 7. Удаление legacy-связей
|
||||
|
||||
После успешной миграции и периода наблюдения:
|
||||
|
||||
1. Перевести оба приложения на новые buffer hostname.
|
||||
2. Проверить отсутствие `contracts.kube5s.ru` и `upload.sinefo.ru/drhider-upload/` в рабочих конфигурациях.
|
||||
3. Удалить старый WebDAV location только после подтверждения, что активных клиентов больше нет.
|
||||
4. Обновить README обоих проектов и документацию VM213.
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
Разделение считается завершённым, когда:
|
||||
|
||||
- у DrHider и Obfuscator разные production-инстансы;
|
||||
- у них разные Git-репозитории без общей синхронизации;
|
||||
- у них разные upload hostname и директории на VM213;
|
||||
- CORS и TLS настроены для каждого отдельно;
|
||||
- независимый Redeploy одного сервиса не меняет другой;
|
||||
- smoke-тесты обоих сервисов проходят одновременно.
|
||||
@@ -1,149 +0,0 @@
|
||||
# План: фильтрация файлов через `.lst`
|
||||
|
||||
## Цель
|
||||
|
||||
Добавить в file picker режим manifest-фильтра:
|
||||
|
||||
- пользователь выбирает папку целиком;
|
||||
- если в корне выбранной папки есть `obscure.lst`, он ограничивает набор файлов;
|
||||
- если `.lst` нет, сохраняется текущее поведение: выбираются все поддерживаемые файлы;
|
||||
- сам `obscure.lst` никогда не отправляется на обработку;
|
||||
- другие файлы с расширением `.lst` не являются manifest-файлами и не загружаются.
|
||||
|
||||
## Правила `obscure.lst`
|
||||
|
||||
Одна строка — одно правило.
|
||||
|
||||
- пустые строки игнорируются;
|
||||
- строки, начинающиеся с `#`, являются комментариями;
|
||||
- `!` в начале строки означает отрицательное правило;
|
||||
- пути относительны к выбранной папке;
|
||||
- абсолютные пути и сегменты `..` запрещены;
|
||||
- разделители `\` нормализуются в `/`;
|
||||
- весь путь сравнивается без учёта регистра;
|
||||
- несколько совпавших правил не создают дубли.
|
||||
|
||||
Пример:
|
||||
|
||||
```text
|
||||
*.pdf
|
||||
reports/name*.docx
|
||||
!archive/**
|
||||
!**/*draft*.*
|
||||
```
|
||||
|
||||
## Glob-маски
|
||||
|
||||
Поддержать общепринятые шаблоны:
|
||||
|
||||
- `*` — любое количество символов, кроме `/`;
|
||||
- `?` — один символ, кроме `/`;
|
||||
- `**` — любое количество каталогов;
|
||||
- `[abc]` и `[a-z]` — классы и диапазоны символов;
|
||||
- `[!a]` и `[^a]` — отрицательные классы;
|
||||
- обычный путь без glob-символов — точное совпадение.
|
||||
|
||||
Семантика:
|
||||
|
||||
- `*.pdf` — PDF только в корне выбранной папки;
|
||||
- `reports/*.pdf` — PDF внутри `reports`;
|
||||
- `**/*.pdf` — PDF на любой глубине;
|
||||
- `name*.pdf` — файлы с префиксом `name` в корне;
|
||||
- `reports/name*.pdf` — файлы с префиксом `name` непосредственно в `reports`;
|
||||
- `reports/` — то же, что `reports/**`;
|
||||
- `a**b` — две звёздочки внутри сегмента работают как обычная `*`.
|
||||
|
||||
Правило без `/` не применяется рекурсивно. Для поиска на любой глубине нужно
|
||||
явно использовать `**/`, например `**/*.pdf`.
|
||||
|
||||
Положительные правила формируют набор кандидатов. Отрицательные правила
|
||||
удаляют совпавшие файлы из результата.
|
||||
|
||||
## Алгоритм
|
||||
|
||||
1. Получить все файлы выбранной папки и подпапок через `webkitdirectory`.
|
||||
2. Нормализовать `webkitRelativePath`, убрав имя корневой выбранной папки.
|
||||
3. Найти только `obscure.lst` в корне выбранной папки, без учёта регистра.
|
||||
Остальные `.lst` игнорировать.
|
||||
4. Если `obscure.lst` нет, передать в текущую логику все поддерживаемые файлы.
|
||||
5. Если `obscure.lst` найден:
|
||||
- прочитать UTF-8 и убрать BOM;
|
||||
- разобрать строки и скомпилировать glob в RegExp;
|
||||
- отбросить некорректные правила с предупреждением и номером строки;
|
||||
- выбрать поддерживаемые файлы, совпавшие хотя бы с одним положительным правилом;
|
||||
- удалить совпадения с отрицательными правилами;
|
||||
- удалить `.lst` из результата;
|
||||
- сохранить исходный порядок файлов и убрать дубли по нормализованному пути.
|
||||
6. Передать итоговый список в существующий цикл построения таблицы без изменений.
|
||||
|
||||
Если все положительные правила отсутствуют или некорректны, результат пустой.
|
||||
Автоматический fallback на все файлы запрещён.
|
||||
|
||||
Если положительное правило не совпало ни с одним файлом, показать предупреждение,
|
||||
но продолжить обработку остальных правил. Неподдерживаемые файлы не добавлять.
|
||||
|
||||
`obscure.lst` во вложенной папке не является manifest-фильтром и обрабатывается как
|
||||
обычный неподдерживаемый файл.
|
||||
|
||||
Содержимое ZIP отдельно не фильтровать: ZIP выбирается как один файл и далее
|
||||
обрабатывается существующим механизмом раскрытия архивов.
|
||||
|
||||
## Нормализация и предупреждения
|
||||
|
||||
Перед сопоставлением:
|
||||
|
||||
- заменить `\` на `/`;
|
||||
- убрать ведущие `./`;
|
||||
- свернуть повторные `/`;
|
||||
- убрать имя корневой выбранной папки из `webkitRelativePath`;
|
||||
- отклонить абсолютные пути, сегменты `..` и пустые правила;
|
||||
- отклонить незакрытые классы `[` с указанием номера строки.
|
||||
|
||||
Ошибки и предупреждения передавать через существующий `cfg.onError` или
|
||||
`statusEl`. Ошибка одного правила не должна останавливать остальные правила.
|
||||
Ошибка чтения или декодирования `obscure.lst` даёт предупреждение и пустой результат.
|
||||
|
||||
## Где менять код
|
||||
|
||||
Алгоритм фильтра вынести в чистый модуль рядом с текущим picker, например:
|
||||
|
||||
```text
|
||||
upload/frontend/table/lst_filter.js
|
||||
```
|
||||
|
||||
Точка подключения — `on_folder_change.js`, до существующего цикла построения
|
||||
дерева. DOM и upload-транспорт в модуль фильтра не добавлять.
|
||||
|
||||
Сборочные `site/static/dist/*.js` изменять только штатной сборкой.
|
||||
|
||||
## Минимальные тесты
|
||||
|
||||
Проверить:
|
||||
|
||||
1. Папка без `.lst` сохраняет старое поведение.
|
||||
2. `obscure.lst` не попадает в результат, другие `.lst` также не загружаются.
|
||||
3. `*.pdf`, `name*.pdf`, `?`, `**` и классы символов.
|
||||
4. `*.pdf` совпадает только с файлом в корне, а `**/*.pdf` — также с `x.pdf`
|
||||
в корне и файлами в подпапках.
|
||||
5. `docs/name*.pdf`, `docs/`, `a**b` и точные пути.
|
||||
6. Положительные и отрицательные правила вместе.
|
||||
7. Комментарии, пустые строки, BOM, CRLF и пробелы.
|
||||
8. Регистр всего пути (`DOCS/A.PDF` совпадает с `docs/*.pdf`).
|
||||
9. Кириллицу, пробелы, вложенные каталоги и обратные слеши (`docs\a.pdf`).
|
||||
10. Дубли и перекрывающиеся маски.
|
||||
11. Запрет `/etc/x`, `C:/x`, `../x`, `a/../b`.
|
||||
12. Битую маску без падения всего picker.
|
||||
13. Ошибка чтения `.lst` даёт пустой результат и предупреждение.
|
||||
14. Правило без совпадений даёт предупреждение.
|
||||
15. Только отрицательные или полностью битые правила дают пустой результат.
|
||||
16. Другой `.lst` в корне не включает manifest-режим.
|
||||
17. `obscure.lst` во вложенной папке не включает manifest-режим.
|
||||
18. ZIP выбирается целиком, без фильтрации его внутреннего содержимого.
|
||||
|
||||
## Ограничения реализации
|
||||
|
||||
- Не менять backend-контракт.
|
||||
- Не добавлять базу данных, отдельный сервис или новый формат конфигурации.
|
||||
- Не переписывать существующий picker.
|
||||
- Изменить минимальное число файлов.
|
||||
- Сначала реализовать алгоритм и тесты, затем обновить dist штатной сборкой.
|
||||
@@ -1,44 +0,0 @@
|
||||
# DrHider Obfuscator
|
||||
|
||||
Чистая deploy-копия Flask-приложения DrHider без документации, истории,
|
||||
тестов и временных файлов.
|
||||
|
||||
## Репозиторий и деплой
|
||||
|
||||
- репозиторий: `https://gitea.services.ngcloud.ru/forcloud/obfuscator.git`
|
||||
- entrypoint: `site/app.py`, глобальный Flask `app`
|
||||
- зависимости: `requirements.txt`
|
||||
- публичное приложение: `https://drhider.pythonk8s.dev.nubes.ru/`
|
||||
- платформа: Managed Flask / Штурвал
|
||||
|
||||
Порядок публикации:
|
||||
|
||||
1. Push в `master`.
|
||||
2. В Штурвале выбрать приложение DrHider, подключённое к этой репе.
|
||||
3. Нажать **Redeploy**.
|
||||
4. Проверить `GET /health` и поле `version`.
|
||||
|
||||
## Структура
|
||||
|
||||
- `site/` — Flask-приложение, маршруты, шаблоны и статика.
|
||||
- `drhider/` — ядро извлечения, сканирования, замены и сборки ZIP.
|
||||
- `upload/` — runtime-часть загрузки файлов и WebDAV-транзита.
|
||||
|
||||
## Внешний upload-буфер
|
||||
|
||||
DrHider использует WebDAV-буфер на VM213 `5.172.178.213`:
|
||||
|
||||
```text
|
||||
https://upload.sinefo.ru/drhider-upload/
|
||||
```
|
||||
|
||||
Поток: браузер делает `PUT`, Flask получает ссылки через `/api/upload_refs`,
|
||||
забирает файлы с VM213 и удаляет их после обработки.
|
||||
|
||||
Nginx, DNS и TLS буфера находятся на VM213 и не управляются этим Git-репозиторием.
|
||||
Старый `contracts.kube5s.ru` не использовать.
|
||||
|
||||
## Отдельный upload-platform
|
||||
|
||||
`forcloud/upload-platform` — отдельная репа и отдельный сервис `vmfiles.service`
|
||||
на VM213. Push в этот репозиторий не обновляет данный Flask-деплой, и наоборот.
|
||||
Reference in New Issue
Block a user