Assessor_2.0/tests/server/advanced-audit-parser.test.ts

111 lines
4.5 KiB
TypeScript

import { createHash } from 'node:crypto';
import { describe, expect, it } from 'vitest';
import {
parseAdvancedAuditCsv,
reduceAdvancedAuditPolicy
} from '../../server/gpo/advanced-audit-parser';
import type { VerifiedZipFile } from '../../server/gpo/zip-inventory';
const firstGuid = '0cce9210-69ae-11d9-bed3-505054503030';
const secondGuid = '0cce9211-69ae-11d9-bed3-505054503030';
function verifiedFile(content: string | Uint8Array): VerifiedZipFile {
const bytes = typeof content === 'string' ? new TextEncoder().encode(content) : content;
return {
entry: {
index: 1,
relativePath: 'synthetic/DomainSysvol/GPO/Machine/Microsoft/Windows NT/Audit/audit.csv',
kind: 'file',
compressionMethod: 8,
compressedBytes: bytes.byteLength,
uncompressedBytes: bytes.byteLength,
crc32: '00000000',
sha256: createHash('sha256').update(bytes).digest('hex')
},
bytes
};
}
function context() {
return { backupInstanceId: 'backup-synthetic', sourceArtifactId: 'source-synthetic', artifactId: 'entry-synthetic' };
}
function csv(rows: string[]): string {
return [
'Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting,Setting Value',
...rows
].join('\r\n');
}
describe('Advanced Audit Policy parser and reducer', () => {
it('uses technical subcategory GUIDs and numeric audit flags instead of display names', () => {
const document = parseAdvancedAuditCsv(verifiedFile(csv([
`,System,"Localized, ignored name",{${firstGuid}},Success and Failure,,3`,
`,System,Another ignored name,{${secondGuid}},Failure,,2`
])), 'computer');
expect(document).toMatchObject({ status: 'complete', scope: 'computer' });
expect(reduceAdvancedAuditPolicy(document, context())).toEqual(expect.arrayContaining([
expect.objectContaining({
identity: expect.objectContaining({ key: firstGuid }),
values: [{ kind: 'audit-flags', code: 3, success: true, failure: true }],
sourceLines: [2],
effectiveState: 'unknown'
}),
expect.objectContaining({
identity: expect.objectContaining({ key: secondGuid }),
values: [{ kind: 'audit-flags', code: 2, success: false, failure: true }]
})
]));
});
it('models differing duplicate GUID settings as a conflict', () => {
const document = parseAdvancedAuditCsv(verifiedFile(csv([
`,System,ignored,{${firstGuid}},Success,,1`,
`,System,ignored,{${firstGuid}},Failure,,2`
])), 'computer');
expect(reduceAdvancedAuditPolicy(document, context())).toEqual([
expect.objectContaining({
state: 'conflicted',
values: [
{ kind: 'audit-flags', code: 1, success: true, failure: false },
{ kind: 'audit-flags', code: 2, success: false, failure: true }
],
diagnosticCodes: ['gpo-advanced-audit-value-conflict']
})
]);
});
it('keeps non-system targets partial without interpreting per-user semantics', () => {
const document = parseAdvancedAuditCsv(verifiedFile(csv([
`,SyntheticUser,ignored,{${firstGuid}},Success,,1`,
`,System,ignored,{${secondGuid}},Success,,1`
])), 'computer');
expect(document).toMatchObject({
status: 'partial',
diagnosticCodes: ['gpo-advanced-audit-target-unsupported']
});
expect(reduceAdvancedAuditPolicy(document, context())).toHaveLength(1);
});
it('fails closed for malformed technical GUIDs, setting codes, rows and headers', () => {
const invalidValue = parseAdvancedAuditCsv(verifiedFile(csv([
',System,ignored,not-a-guid,Success,,7'
])), 'computer');
expect(invalidValue).toMatchObject({ status: 'invalid', instructions: [] });
expect(reduceAdvancedAuditPolicy(invalidValue, context())).toEqual([]);
const missingHeader = parseAdvancedAuditCsv(verifiedFile('Policy Target,Subcategory GUID\r\nSystem,{0cce9210-69ae-11d9-bed3-505054503030}'), 'computer');
expect(missingHeader).toMatchObject({
status: 'invalid',
diagnosticCodes: ['gpo-advanced-audit-required-column-missing']
});
});
it('rejects user-scope interpretation and accepts BOM-marked UTF-16LE', () => {
const encoded = Buffer.from(`\ufeff${csv([`,System,ignored,{${firstGuid}},Success,,1`])}`, 'utf16le');
const document = parseAdvancedAuditCsv(verifiedFile(encoded), 'user');
expect(document).toMatchObject({ status: 'partial', diagnosticCodes: ['gpo-advanced-audit-scope-unsupported'] });
expect(reduceAdvancedAuditPolicy(document, context())).toEqual([]);
});
});