From e5815279a14845153c0e31b28f570860379e7f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sat, 13 Jun 2026 07:52:01 +0400 Subject: [PATCH] =?UTF-8?q?v2:=20+admin=20=D0=BC=D0=BE=D0=BA-=D1=8E=D0=B7?= =?UTF-8?q?=D0=B5=D1=80=20(3=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8,=20=D0=B1=D0=B5=D0=B7=20=D0=B8=D0=BC=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=81=D0=BE=D0=BD=D0=B0=D1=86=D0=B8=D0=B8)=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- v2/history/2026-06-12.md | 125 +++++++++++++++++++++++++++++++++++++++ v2/src/config/index.js | 2 +- v2/src/test/index.js | 3 + 4 files changed, 130 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9eb1f80..a2583cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.5.94", + "version": "0.5.95", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/v2/history/2026-06-12.md b/v2/history/2026-06-12.md index a29dfb5..f23987c 100644 --- a/v2/history/2026-06-12.md +++ b/v2/history/2026-06-12.md @@ -552,3 +552,128 @@ VM (italo.kube5s.ru) — НЕ используется для деплоя v2. | 105/150 ошибок | 3 задачи × 15 > лимит 15 | 1 задача × 10 | 0.5.89 | | /chaos → 302 /login | Роутер на /test/api | Сменили на /test | 0.5.88 | | validate() в db/queries | Смешаны слои | Вынесен в crud/ | 0.5.91 | + + +--- + +## Результаты тестирования (0.5.94, 2026-06-13) + +### Среда + +- **URL**: `https://whitelist.nodejsk8s.services.ngcloud.ru/v2/test` +- **БД**: production PostgreSQL (k8s) +- **Метод**: Python-скрипт через `urllib.request` (эмуляция curl) +- **Слои под тестом**: HTTP → test → crud → validate → db → PostgreSQL + +### Результаты: 41/41 ✅ + +#### 1. Запрещённые диапазоны (14/14 ✅) + +Все 14 диапазонов из Приложения А ТЗ корректно отклоняются: + +| Диапазон | Описание | Результат | +|----------|---------|-----------| +| 10.0.0.0/8 | Private RFC1918 | ✅ blocked | +| 172.16.0.0/12 | Private RFC1918 | ✅ blocked | +| 192.168.0.0/16 | Private RFC1918 | ✅ blocked | +| 100.64.0.0/10 | CGNAT RFC6598 | ✅ blocked | +| 127.0.0.0/8 | Loopback | ✅ blocked | +| 169.254.0.0/16 | Link-local | ✅ blocked | +| 192.0.0.0/24 | IANA special | ✅ blocked | +| 192.0.2.0/24 | TEST-NET-1 | ✅ blocked | +| 198.51.100.0/24 | TEST-NET-2 | ✅ blocked | +| 203.0.113.0/24 | TEST-NET-3 | ✅ blocked | +| 198.18.0.0/15 | Benchmarking | ✅ blocked | +| 224.0.0.0/4 | Multicast | ✅ blocked | +| 240.0.0.0/4 | Reserved Class E | ✅ blocked | +| 255.255.255.255/32 | Broadcast | ✅ blocked | + +Тестируется через: `?action=add&user=u1&cidr=X.X.X.X/XX` + +#### 2. Нормализация и маски (6/6 ✅) + +| Тест | Вход | Ожидание | Результат | +|------|------|---------|-----------| +| Маска /22 | 11.0.0.0/22 | ok (минимальная) | ✅ | +| Маска /21 | 12.0.0.0/21 | fail (< /22) | ✅ | +| Маска /33 | 1.1.1.1/33 | fail (> /32) | ✅ | +| IPv6 | 2001:db8::1 | fail | ✅ | +| Домен | example.com | fail | ✅ | +| Нормализация | 13.0.0.5/24 | wasNormalized=true | ✅ | + +#### 3. Лимиты (1/1 ✅) + +| Тест | Результат | +|------|-----------| +| 16-я запись отклонена (лимит 15) | ✅ | + +#### 4. CRUD полный цикл (7/7 ✅) + +| Операция | Результат | +|----------|-----------| +| add (30.30.30.0/24) | ✅ | +| add2 (31.31.31.0/24) | ✅ | +| add /32 (32.32.32.32) | ✅ | +| list → 3 записи | ✅ | +| edit (33.33.33.0/24) | ✅ | +| delete (soft) | ✅ | +| after delete → 2 записи | ✅ | + +#### 5. Изоляция компаний (3/3 ✅) + +| Тест | Результат | +|------|-----------| +| add в компанию A (WZ20002) | ✅ | +| add в компанию B (WZ20001, через switch) | ✅ | +| Пересечение между компаниями разрешено | ✅ | + +#### 6. Switch + имперсонация (4/4 ✅) + +| Тест | Результат | +|------|-----------| +| switch на WZ20001 | ✅ | +| switch обратно на WZ20002 | ✅ | +| imp add (impersonation) | ✅ | +| audit: impersonated_by=admin@t.ru, user_email=real@t.ru | ✅ | + +#### 7. UserFlow — полная эмуляция юзера (4/4 ✅) + +| Тест | Слой | Результат | +|------|------|-----------| +| uf add (77.77.77.0/24) | user→crud→db | ✅ | +| uf list | user→crud→db | ✅ | +| uf blocked (10.0.0.0/24) | user→crud→db | ✅ (ошибка валидации) | +| uf imp add (78.78.78.0/24) | user→crud→db | ✅ | + +Ключевое: `layer: "user→crud→db"` в ответе подтверждает прохождение через все слои. + +#### 8. Chaos — параллельные операции (1/1 ✅) + +``` +ok: True, ok: 40, errors: 0, entries: 40, audit: 40 +WZ10001: entries=10 audit=10 dupes=False overLimit=False +WZ20002: entries=10 audit=10 dupes=False overLimit=False +WZ30001: entries=10 audit=10 dupes=False overLimit=False +WZ01112: entries=10 audit=10 dupes=False overLimit=False +``` + +4 компании × 10 записей = 40 параллельных Promise.all. +Проверки: без дубликатов, в лимите, аудит записан. + +### Итого + +| Группа | Тестов | Статус | +|--------|--------|--------| +| Запрещённые диапазоны | 14 | ✅ | +| Нормализация | 6 | ✅ | +| Лимиты | 1 | ✅ | +| CRUD | 7 | ✅ | +| Изоляция | 3 | ✅ | +| Switch + имперсонация | 4 | ✅ | +| UserFlow | 4 | ✅ | +| Chaos | 1 | ✅ | +| Cleanup | 1 | ✅ | +| **Всего** | **41** | **✅** | + +Предыдущие тесты (test.sh, router): 64 теста. +Общий итог: **105 тестов, все пройдены** ✅ diff --git a/v2/src/config/index.js b/v2/src/config/index.js index b253b1e..3ebb8bf 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -9,7 +9,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.5.94', + version: '0.5.95', // ── IAM ────────────────────────────────────────────────────────────────── iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user', diff --git a/v2/src/test/index.js b/v2/src/test/index.js index 5335e45..870c36c 100644 --- a/v2/src/test/index.js +++ b/v2/src/test/index.js @@ -14,6 +14,7 @@ // u1 — обычный юзер, одна компания (WZ10001) // u2 — юзер с двумя компаниями (WZ20001, WZ20002) // imp — админ под имперсонацией (WZ01112 → WZ03709) +// adm — админ без имперсонации, 3 компании (WZ01112, WZ03709, WZ09999) // // ACTIONS (GET ?action=...): // add/edit/delete/list — CRUD через crud/ @@ -38,6 +39,8 @@ const USERS = { u1: { email:'u1@t.ru', clientId:'WZ10001', activeClientId:'WZ10001', allClientIds:['WZ10001'], companyName:'Одна', isAdmin:false, profiles:[{client_id:'WZ10001',company_name:'Одна'}] }, u2: { email:'u2@t.ru', clientId:'WZ20001', activeClientId:'WZ20002', allClientIds:['WZ20001','WZ20002'], companyName:'Вторая', isAdmin:false, profiles:[{client_id:'WZ20001',company_name:'Первая'},{client_id:'WZ20002',company_name:'Вторая'}] }, imp:{ email:'admin@t.ru', clientId:'WZ01112', activeClientId:'WZ01112', allClientIds:['WZ01112','WZ03709'], companyName:'Nubes', isAdmin:true, isImpersonated:true, originalUserEmail:'real@t.ru', impersonatedCompanyId:'WZ03709', profiles:[] }, + // admin — админ с 3 компаниями, БЕЗ имперсонации + adm:{ email:'admin@t.ru', clientId:'WZ01112', activeClientId:'WZ01112', allClientIds:['WZ01112','WZ03709','WZ09999'], companyName:'Nubes', isAdmin:true, profiles:[{client_id:'WZ01112',company_name:'Nubes'},{client_id:'WZ03709',company_name:'Дочка'},{client_id:'WZ09999',company_name:'Третья'}] }, }; function createTestRouter() {