717ae1031e
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/ binary modes, condensed snapshots, value relations) with 39 rigor test campaigns. Includes fixes for snapshot binary writer/reader format mismatch (snapshot-of-snapshot corruption), possibility write-boundary validation, empty-graph snapshot serialization, relation lookup cache direction collision, config-redefinition cache invalidation, binary threshold semantics, defeasible compiled routing, and comparator reason whitelisting.
81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
import { Arbiter } from '../../src/core/Arbiter.js';
|
|
|
|
export function createTestArbiter(options = {}) {
|
|
const defaults = {
|
|
embeddingDimensions: 256,
|
|
directCheckCacheSize: 10000,
|
|
directCheckCacheTTL: 60000,
|
|
disableCaching: false,
|
|
disableChainCaching: false,
|
|
disableDirectCaching: false
|
|
};
|
|
|
|
return new Arbiter({ ...defaults, ...options });
|
|
}
|
|
|
|
export function seedBasicGraph(arbiter) {
|
|
const nodes = [
|
|
['user:alice', 'user'],
|
|
['user:bob', 'user'],
|
|
['user:charlie', 'user'],
|
|
['doc:report', 'document'],
|
|
['doc:invoice', 'document'],
|
|
['project:web-app', 'project'],
|
|
['group:engineering', 'group'],
|
|
['group:management', 'group'],
|
|
['account:main', 'account'],
|
|
['session:sess-1', 'session']
|
|
];
|
|
|
|
for (const [key, type] of nodes) {
|
|
arbiter.addNode(key, type);
|
|
}
|
|
|
|
const relations = [
|
|
['user:alice', 'member_of', 'group:engineering', 1.0],
|
|
['user:bob', 'member_of', 'group:management', 1.0],
|
|
['group:engineering', 'can_read', 'doc:report', 0.8],
|
|
['group:engineering', 'can_read', 'project:web-app', 0.9],
|
|
['group:management', 'can_read', 'doc:invoice', 1.0],
|
|
['user:alice', 'controls', 'account:main', 1.0],
|
|
['session:sess-1', 'authenticated_as', 'user:alice', 1.0]
|
|
];
|
|
|
|
for (const [src, rel, dst, possibility, metadata] of relations) {
|
|
arbiter.addRelation(src, rel, dst, possibility, metadata);
|
|
}
|
|
|
|
const relationConfigs = [
|
|
['member_of', { type: 'direct' }],
|
|
['can_read', { type: 'direct' }],
|
|
['controls', { type: 'direct' }],
|
|
['authenticated_as', { type: 'direct' }]
|
|
];
|
|
|
|
for (const [rel, config] of relationConfigs) {
|
|
arbiter.setRelationConfig(rel, config);
|
|
}
|
|
|
|
return arbiter;
|
|
}
|
|
|
|
export function seedRelation(arbiter, src, rel, dst, possibility = 1.0, metadata = {}) {
|
|
arbiter.addRelation(src, rel, dst, possibility, metadata);
|
|
if (!arbiter.relationConfigs.has(rel)) {
|
|
arbiter.setRelationConfig(rel, { type: 'direct' });
|
|
}
|
|
return arbiter;
|
|
}
|
|
|
|
export function createPartialGraph(nodes = [], relations = []) {
|
|
return { nodes, relations };
|
|
}
|
|
|
|
export function seedPartialRelation(arbiter, src, rel, dst, possibility = 1.0, value = undefined) {
|
|
const relObj = { src, relation: rel, dst, possibility };
|
|
if (value !== undefined) {
|
|
relObj.value = value;
|
|
}
|
|
return { nodes: [], relations: [relObj] };
|
|
}
|