POST /v1/identity/verify: an AERE Identity presentation judged by the published command line -> VALID / PARTIAL / INVALID with every row, the claims shown and the subject when no row failed, and the command that reproduces the verdict. POST /v1/compliance/check: your policy judged on a presentation -> COMPLIANT / NOT_COMPLIANT with the reasons and, with record, the decision as an AIP-23 envelope without personal data. In Go the presentation, keys, lists and policy travel as json.RawMessage: a map or float64 would change numbers above 2^53 and the canonical text the signatures cover. The .NET negative control now builds clean for each planted defect (an incremental build could run the tests against the previous planted library). A negative control for the JavaScript and Python routes is added. Tests: JavaScript 13, Python 14, Go ok, Java 10/10 (and the Java 8 API gate); negative controls Go 9/9, Java 10/10, .NET 12/12, JavaScript and Python 4/4.
54 lines
4.4 KiB
JavaScript
54 lines
4.4 KiB
JavaScript
// Controlul negativ al probelor offline ale clientilor JavaScript si Python pentru rutele 1.7.0 (identityVerify / identity_verify,
|
|
// complianceCheck / compliance_check): fiecare paznic se strica intr-o COPIE a SDK-ului (depozitul nu se atinge), proba ruleaza pe copie
|
|
// si proba numita TREBUIE sa pice. Trei stari: ROSU cum trebuia, CONTROL CAZUT (proba a ramas verde), STRICAT (ancora nu apare exact o
|
|
// data, sau probele nu au ajuns la rezumat). La urma, copia neatinsa trebuie sa fie verde (martorul).
|
|
// node sdk/test/control-negativ-js-python.mjs -> 0 toate rosii si martorul verde, 1 altfel
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const SDK = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const PLANTARI = [
|
|
// [nume, fisier, vechi, nou, limbaj, proba (fragment din numele ei)]
|
|
['JS: complianceCheck pe ruta identitatii', 'index.mjs', "complianceCheck(request) { return this._req('POST', '/compliance/check', { body: request }); }", "complianceCheck(request) { return this._req('POST', '/identity/verify', { body: request }); }", 'js', '1.7.0: identityVerify si complianceCheck'],
|
|
['JS: identityVerify trimite o cerere schimbata', 'index.mjs', "identityVerify(request) { return this._req('POST', '/identity/verify', { body: request }); }", "identityVerify(request) { return this._req('POST', '/identity/verify', { body: { ...request, maxAgeSeconds: 3600 } }); }", 'js', '1.7.0: identityVerify si complianceCheck'],
|
|
['Python: compliance_check pe ruta identitatii', 'python/aere_cloud/__init__.py', 'return self._req("POST", "/compliance/check", request)', 'return self._req("POST", "/identity/verify", request)', 'py', 'identity_verify si compliance_check'],
|
|
['Python: identity_verify trimite o cerere schimbata', 'python/aere_cloud/__init__.py', 'return self._req("POST", "/identity/verify", request)', 'return self._req("POST", "/identity/verify", {**request, "maxAgeSeconds": 3600})', 'py', 'identity_verify si compliance_check'],
|
|
];
|
|
function copie() {
|
|
const d = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-sdk-cn-'));
|
|
for (const f of ['index.mjs', 'package.json', 'test/sdk.test.mjs', 'python/aere_cloud/__init__.py', 'python/test_aere_cloud.py', 'python/pyproject.toml']) {
|
|
fs.mkdirSync(path.dirname(path.join(d, f)), { recursive: true }); fs.copyFileSync(path.join(SDK, f), path.join(d, f));
|
|
}
|
|
return d;
|
|
}
|
|
function ruleaza(d, limbaj) {
|
|
const r = limbaj === 'js'
|
|
? spawnSync(process.execPath, ['test/sdk.test.mjs'], { cwd: d, encoding: 'utf8', env: { ...process.env, AERE_CHEIE: '' } })
|
|
: spawnSync(process.platform === 'win32' ? 'python' : 'python3', ['test_aere_cloud.py'], { cwd: path.join(d, 'python'), encoding: 'utf8', env: { ...process.env, AERE_KEY: '' } });
|
|
const out = (r.stdout || '') + (r.stderr || '');
|
|
// JS: '<n> teste trecute' si randuri ' ESEC <nume>'; Python: '<n> treceri, <m> esecuri' si randuri ' PICA <nume>'
|
|
return { out, rulat: /\d+ (teste trecute|treceri)/.test(out), rosii: out.split('\n').filter((l) => /^\s*(ESEC|PICA)\b/.test(l)) };
|
|
}
|
|
let rele = 0;
|
|
for (const limbaj of ['js', 'py']) {
|
|
const d = copie(); const m = ruleaza(d, limbaj); fs.rmSync(d, { recursive: true, force: true });
|
|
if (m.rulat && !m.rosii.length) console.log(` martor ${limbaj}: copia neatinsa verde`); else { rele++; console.log(` STRICAT martorul ${limbaj} nu e verde (${m.rosii.length} rosii, rulat ${m.rulat})`); }
|
|
}
|
|
for (const [nume, fisier, vechi, nou, limbaj, tinta] of PLANTARI) {
|
|
const d = copie();
|
|
try {
|
|
const f = path.join(d, fisier); const t = fs.readFileSync(f, 'utf8');
|
|
if (t.split(vechi).length !== 2) { rele++; console.log(` STRICAT ${nume}: ancora apare de ${t.split(vechi).length - 1} ori`); continue; }
|
|
fs.writeFileSync(f, t.replace(vechi, nou));
|
|
const r = ruleaza(d, limbaj);
|
|
if (!r.rulat) { rele++; console.log(` STRICAT ${nume}: probele nu au ajuns la rezumat`); continue; }
|
|
if (r.rosii.some((l) => l.includes(tinta))) console.log(` ROSU cum trebuia ${nume}`);
|
|
else { rele++; console.log(` CONTROL CAZUT ${nume}: '${tinta}' a ramas verde`); }
|
|
} finally { fs.rmSync(d, { recursive: true, force: true }); }
|
|
}
|
|
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `CONTROL NEGATIV TRECUT (${PLANTARI.length} din ${PLANTARI.length} rosii, martorii verzi)`);
|
|
process.exitCode = rele ? 1 : 0;
|