Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
fileId,
GrantManager,
InMemoryPartitionStore,
KeyRing,
PartitionManager,
TokenManager,
TransferManager,
userId,
wrapKey,
} from "../src/index.js";
import { getDefaultPolicy } from "../src/partitions/partition-policy/partition-policy.js";
describe("drive-sharing — end-to-end integration", () => {
it("create partition, add member, grant access, transfer file", {
timeout: 30000,
}, async () => {
// Build the full lifecycle stack with deterministic clocks / IDs.
const events = new Map<string, unknown[]>();
const bus = {
on: () => () => undefined,
emit: (k: string, p: unknown) => {
const arr = events.get(k) ?? [];
arr.push(p);
events.set(k, arr);
},
};
let counter = 0;
const idGen = () => `id-${(counter += 1)}`;
const masterKey = new Uint8Array(32).fill(0x77);
const keyRing = new KeyRing({ masterKey });
const store = new InMemoryPartitionStore();
const partitions = new PartitionManager({
store,
keyRing,
clock: () => 1_000,
idGenerator: idGen,
events: bus,
});
const grants = new GrantManager({
clock: () => 1_000,
idGenerator: idGen,
events: bus,
});
const tokens = new TokenManager({
clock: () => 1_000,
defaultTTL: 60_000,
masterKey,
idGenerator: idGen,
});
// 1. Create source and target partitions.
const src = await partitions.create({
name: "research",
type: "shared",
ownerId: userId("alice"),
});
const dst = await partitions.create({
name: "review",
type: "shared",
ownerId: userId("alice"),
});
// 2. Add bob as a member of source.
const updatedSrc = await partitions.addMember(src.id, userId("bob"), {
permissions: ["read", "share"],
});
expect(updatedSrc.members.length).toBe(1);
// 3. Mint a grant for bob to read the file.
const grant = grants.create({
grantorId: userId("alice"),
granteeId: userId("bob"),
partitionId: src.id,
permissions: ["read"],
expiresAt: 5_000_000,
});
const check = grants.check(grant.id, userId("bob"), "read");
expect(check.allowed).toBe(true);
// 4. Mint a share token for the file.
const token = tokens.create({
partitionId: src.id,
createdBy: userId("alice"),
permissions: ["read"],
});
expect(tokens.validate(token.id).valid).toBe(true);
// 5. Set up transfer with a real wrapped DEK.
const sourceKek = new Uint8Array(32).fill(0xaa);
const targetKek = new Uint8Array(32).fill(0xbb);
const dek = new Uint8Array(32).fill(0xcc);
const aadSrc = new TextEncoder().encode(
`drive-sharing/v1/transfer/${src.id}/${fileId("f-1")}`
);
const wrapped = await wrapKey(sourceKek, dek, { aad: aadSrc });
const transfer = new TransferManager({
kekResolver: async (_uid, pid) =>
pid === src.id ? sourceKek : targetKek,
policyResolver: async (pid) => {
const partition =
pid === src.id ? updatedSrc : { ...dst, members: [] };
return {
policy: getDefaultPolicy(),
partition,
};
},
wrappedKeyResolver: async () => wrapped,
clock: () => 2_000,
});
const result = await transfer.transfer({
fileId: fileId("f-1"),
sourcePartitionId: src.id,
targetPartitionId: dst.id,
userId: userId("alice"),
direction: "export",
});
expect(result.success).toBe(true);
expect(result.rewrappedKey).toBeDefined();
// 6. Verify lifecycle event emission.
expect(events.get("partition:created")?.length).toBe(2);
expect(events.get("member:added")?.length).toBe(1);
expect(events.get("grant:created")?.length).toBe(1);
// 7. Revoke the grant and confirm subsequent checks are denied.
grants.revoke(grant.id);
expect(grants.check(grant.id, userId("bob"), "read").allowed).toBe(
false
);
});
});

View File

@@ -0,0 +1,138 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import * as fc from "fast-check";
import {
GrantManager,
InMemoryPartitionStore,
KeyRing,
mergePolicies,
PartitionManager,
partitionId,
TokenManager,
userId,
} from "../src/index.js";
describe("property — grant expiry", () => {
it("grant check returns allowed false after advancing clock beyond TTL", {
timeout: 30000,
}, () => {
fc.assert(
fc.property(
fc.integer({ min: 1, max: 100_000 }),
fc.integer({ min: 1, max: 100 }),
(ttl, offset) => {
let now = 0;
const m = new GrantManager({ clock: () => now });
const grant = m.create({
grantorId: userId("a"),
granteeId: userId("b"),
partitionId: partitionId("p"),
permissions: ["read"],
expiresAt: ttl,
});
now = ttl + offset;
const r = m.check(grant.id, userId("b"), "read");
expect(r.allowed).toBe(false);
}
),
{ numRuns: 50 }
);
});
});
describe("property — token revocation finality", () => {
it("revoked token validate always returns valid false", {
timeout: 30000,
}, () => {
fc.assert(
fc.property(fc.integer({ min: 1, max: 100 }), (validateCount) => {
const m = new TokenManager({
clock: () => 0,
masterKey: new Uint8Array(32).fill(0xee),
});
const t = m.create({
partitionId: partitionId("p"),
createdBy: userId("a"),
permissions: ["read"],
});
m.revoke(t.id);
for (let i = 0; i < validateCount; i += 1) {
const r = m.validate(t.id);
expect(r.valid).toBe(false);
}
}),
{ numRuns: 30 }
);
});
});
describe("property — policy merge commutativity", () => {
it("mergePolicies on disjoint allowedActions yields union", {
timeout: 30000,
}, () => {
fc.assert(
fc.property(
fc.uniqueArray(fc.constantFrom("read", "write" as const), {
minLength: 0,
maxLength: 2,
}),
fc.uniqueArray(fc.constantFrom("delete", "share" as const), {
minLength: 0,
maxLength: 2,
}),
(a, b) => {
const aP = {
encryption: true,
reauthRequired: [],
allowedActions: a,
};
const bP = {
encryption: true,
reauthRequired: [],
allowedActions: b,
};
const ab = mergePolicies(aP, bP);
const ba = mergePolicies(bP, aP);
// Same set, order may differ.
expect(new Set(ab.allowedActions)).toEqual(
new Set(ba.allowedActions)
);
expect(new Set(ab.allowedActions)).toEqual(
new Set([...a, ...b])
);
}
),
{ numRuns: 50 }
);
});
});
describe("property — partition member invariant", () => {
it("addMember then removeMember restores member count", {
timeout: 30000,
}, async () => {
await fc.assert(
fc.asyncProperty(
fc.string({ minLength: 1, maxLength: 16 }),
async (name) => {
const manager = new PartitionManager({
store: new InMemoryPartitionStore(),
keyRing: new KeyRing(),
});
const p = await manager.create({
name,
type: "shared",
ownerId: userId("alice"),
});
const before = p.members.length;
const after1 = await manager.addMember(p.id, userId("bob"));
const after2 = await manager.removeMember(
after1.id,
userId("bob")
);
expect(after2.members.length).toBe(before);
}
),
{ numRuns: 25 }
);
});
});