Skip to content

Commit

Permalink
Add a token declaration registry
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Oct 13, 2024
1 parent 2479f28 commit eadfc59
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 11 deletions.
39 changes: 39 additions & 0 deletions src/token-declaration-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { TokenDeclaration } from "./type/token-declaration.js";

export type TokenDeclarationRegistry = {
registerDeclaration: (
definingOwner: string,
definingRepo: string,
name: string,
declaration: TokenDeclaration,
) => void;

findDeclarationForRequester: (
requestingOwner: string,
requestingRepo: string,
reference: string,
) => [declaration: TokenDeclaration | undefined, isRegistered: boolean];
};

export function createTokenDeclarationRegistry(): TokenDeclarationRegistry {
const declarations = new Map<string, TokenDeclaration>();

return {
registerDeclaration(definingOwner, definingRepo, name, declaration) {
declarations.set(`${definingOwner}/${definingRepo}.${name}`, declaration);
},

findDeclarationForRequester(requestingOwner, requestingRepo, reference) {
const declaration = declarations.get(reference);

if (!declaration) return [undefined, false];
if (declaration.shared) return [declaration, true];

const requiredPrefix = `${requestingOwner}/${requestingRepo}.`;

return reference.startsWith(requiredPrefix)
? [declaration, true]
: [undefined, true];
},
};
}
13 changes: 2 additions & 11 deletions src/type/consumer-config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import type { InstallationPermissions } from "./github-api.js";
import type {
GitHubOrganizationSecretTypes,
GitHubRepositorySecretTypes,
} from "./github-secret-type.js";
import type { TokenDeclaration } from "./token-declaration.js";

export type PartialConsumerConfig = {
$schema: string;
tokens: Record<
string,
{
shared: boolean;
as?: string;
owner?: string;
repositories: string[];
permissions: InstallationPermissions;
}
>;
tokens: Record<string, TokenDeclaration>;
provision: {
secrets: Record<
string,
Expand Down
9 changes: 9 additions & 0 deletions src/type/token-declaration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { InstallationPermissions } from "./github-api.js";

export type TokenDeclaration = {
shared: boolean;
as?: string;
owner?: string;
repositories: string[];
permissions: InstallationPermissions;
};
111 changes: 111 additions & 0 deletions test/suite/unit/token-declaration-registry.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { expect, it } from "vitest";
import { createTokenDeclarationRegistry } from "../../../src/token-declaration-registry.js";
import type { TokenDeclaration } from "../../../src/type/token-declaration.js";

it("finds local token declarations", () => {
const declarationA: TokenDeclaration = {
shared: false,
repositories: ["owner-x/repo-x"],
permissions: { metadata: "read" },
};
const declarationB: TokenDeclaration = {
shared: false,
repositories: ["owner-y/repo-y"],
permissions: { contents: "write" },
};

const registry = createTokenDeclarationRegistry();
registry.registerDeclaration("owner-a", "repo-a", "token-a", declarationA);
registry.registerDeclaration("owner-b", "repo-b", "token-b", declarationB);

expect(
registry.findDeclarationForRequester(
"owner-a",
"repo-a",
"owner-a/repo-a.token-a",
),
).toEqual([declarationA, true]);
expect(
registry.findDeclarationForRequester(
"owner-b",
"repo-b",
"owner-b/repo-b.token-b",
),
).toEqual([declarationB, true]);
});

it("finds shared token declarations", () => {
const declarationA: TokenDeclaration = {
shared: true,
repositories: ["owner-x/repo-x"],
permissions: { metadata: "read" },
};
const declarationB: TokenDeclaration = {
shared: true,
repositories: ["owner-y/repo-y"],
permissions: { contents: "write" },
};

const registry = createTokenDeclarationRegistry();
registry.registerDeclaration("owner-a", "repo-a", "token-a", declarationA);
registry.registerDeclaration("owner-b", "repo-b", "token-b", declarationB);

expect(
registry.findDeclarationForRequester(
"owner-b",
"repo-b",
"owner-a/repo-a.token-a",
),
).toEqual([declarationA, true]);
expect(
registry.findDeclarationForRequester(
"owner-a",
"repo-a",
"owner-b/repo-b.token-b",
),
).toEqual([declarationB, true]);
});

it("doesn't find unshared tokens in other repositories", () => {
const declarationA: TokenDeclaration = {
shared: false,
repositories: ["owner-x/repo-x"],
permissions: { metadata: "read" },
};
const declarationB: TokenDeclaration = {
shared: false,
repositories: ["owner-y/repo-y"],
permissions: { contents: "write" },
};

const registry = createTokenDeclarationRegistry();
registry.registerDeclaration("owner-a", "repo-a", "token-a", declarationA);
registry.registerDeclaration("owner-b", "repo-b", "token-b", declarationB);

expect(
registry.findDeclarationForRequester(
"owner-b",
"repo-b",
"owner-a/repo-a.token-a",
),
).toEqual([undefined, true]);
expect(
registry.findDeclarationForRequester(
"owner-a",
"repo-a",
"owner-b/repo-b.token-b",
),
).toEqual([undefined, true]);
});

it("doesn't find unregistered tokens", () => {
const registry = createTokenDeclarationRegistry();

expect(
registry.findDeclarationForRequester(
"owner-a",
"repo-a",
"owner-a/repo-a.token-a",
),
).toEqual([undefined, false]);
});

0 comments on commit eadfc59

Please sign in to comment.