test: helpers.js — безопасные тестовые CIDR, проверка коллизий, удаление аудита + fix compliance
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* tests/helpers.js — генерация безопасных тестовых CIDR.
|
||||
*
|
||||
* Правила:
|
||||
* 1. Используем «кривые» публичные диапазоны — маловероятно в реальной жизни.
|
||||
* 2. Перед тестом проверяем что в БД нет реальных записей с таким CIDR.
|
||||
* Если есть — генерируем замену.
|
||||
* 3. После теста — удаляем аудит-записи (только для dev).
|
||||
*/
|
||||
|
||||
const { pool } = require('../src/db');
|
||||
|
||||
// «Кривые» публичные диапазоны (никто в здравом уме не использует)
|
||||
const WEIRD_RANGES = [
|
||||
'37.9.0.0/16', // чей-то мелкий хостинг
|
||||
'46.8.0.0/16', // ещё более мелкий
|
||||
'79.133.0.0/16', // какой-то ISP
|
||||
'91.210.0.0/16', // random
|
||||
'176.120.0.0/16', // random
|
||||
'185.50.0.0/16', // random
|
||||
'212.8.0.0/16', // random
|
||||
];
|
||||
|
||||
/**
|
||||
* Сгенерировать N уникальных тестовых CIDR /32 из WEIRD_RANGES.
|
||||
* Проверяет что в БД нет активных записей с таким CIDR.
|
||||
* Если есть коллизия — берёт следующий IP.
|
||||
*/
|
||||
async function generateTestCIDRs(count = 15, poolRef = pool) {
|
||||
const result = [];
|
||||
let rangeIdx = 0;
|
||||
let host = 1;
|
||||
|
||||
while (result.length < count) {
|
||||
const range = WEIRD_RANGES[rangeIdx % WEIRD_RANGES.length];
|
||||
const network = range.split('/')[0];
|
||||
const octets = network.split('.').map(Number);
|
||||
octets[3] = host;
|
||||
const ip = octets.join('.');
|
||||
const cidr = ip + '/32';
|
||||
|
||||
// Проверить коллизию с реальными записями
|
||||
const existing = await poolRef.query(
|
||||
'SELECT id FROM whitelist_entries WHERE value_cidr = $1 AND deleted_at IS NULL',
|
||||
[cidr]
|
||||
);
|
||||
|
||||
if (existing.rows.length === 0) {
|
||||
// Также проверить что этот CIDR не уже в нашем списке
|
||||
if (!result.includes(cidr)) {
|
||||
result.push(cidr);
|
||||
}
|
||||
}
|
||||
|
||||
host++;
|
||||
if (host > 254) { host = 1; rangeIdx++; }
|
||||
if (rangeIdx >= WEIRD_RANGES.length * 2) {
|
||||
throw new Error('Не могу сгенерировать достаточно уникальных CIDR');
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить тестовые аудит-записи.
|
||||
* Только для dev — в проде аудит должен быть неизменяемым (ТЗ 4.6).
|
||||
*/
|
||||
async function deleteTestAudit(marker = 'tz-cleanup') {
|
||||
try {
|
||||
const res = await pool.query(
|
||||
"DELETE FROM audit_log WHERE user_email = $1 OR user_email LIKE $2",
|
||||
[marker, '%test%']
|
||||
);
|
||||
if (res.rowCount > 0) console.log(` Audit cleanup: ${res.rowCount} записей удалено`);
|
||||
} catch (e) {
|
||||
console.warn(' Audit cleanup failed:', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Мягкое удаление тестовых записей по CIDR.
|
||||
*/
|
||||
async function softDeleteByCIDR(cidrList, marker = 'test-cleanup') {
|
||||
for (const c of cidrList) {
|
||||
await pool.query(
|
||||
"UPDATE whitelist_entries SET deleted_at=NOW(), deleted_by=$1 WHERE value_cidr=$2 AND deleted_at IS NULL",
|
||||
[marker, c]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { generateTestCIDRs, deleteTestAudit, softDeleteByCIDR, WEIRD_RANGES };
|
||||
Reference in New Issue
Block a user