Skip to content

Commit

Permalink
Simplify GitHub patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Dec 15, 2024
1 parent 8ca084b commit 1507d53
Show file tree
Hide file tree
Showing 8 changed files with 6 additions and 180 deletions.
41 changes: 1 addition & 40 deletions src/github-pattern.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
import { createNamePattern } from "./name-pattern.js";
import type { Pattern } from "./pattern.js";

export type GitHubPattern = Pattern & {
readonly account: Pattern;
readonly repo: Pattern | undefined;
isAllForAccount: (forAccount: string) => boolean;
};

export function createGitHubPattern(pattern: string): GitHubPattern {
export function createGitHubPattern(pattern: string): Pattern {
const [accountPart, repoPart] = splitGitHubPattern(pattern);
const account = createNamePattern(accountPart);
const repo = repoPart ? createNamePattern(repoPart) : undefined;

return {
get isAll() {
return repo ? account.isAll && repo.isAll : false;
},

get account() {
return account;
},

get repo() {
return repo;
},

test: (string) => {
const parts = string.split("/");

Expand All @@ -35,10 +17,6 @@ export function createGitHubPattern(pattern: string): GitHubPattern {
},

toString: () => pattern,

isAllForAccount: (forAccount: string) => {
return repo ? account.test(forAccount) && repo.isAll : false;
},
};
}

Expand All @@ -52,23 +30,6 @@ export function normalizeGitHubPattern(
return repoPart == null ? definingAccount : `${definingAccount}/${repoPart}`;
}

export function gitHubPatternsForAccount(
account: string,
patterns: GitHubPattern[],
): GitHubPattern[] {
const result: GitHubPattern[] = [];
for (const pattern of patterns) {
if (pattern.account.test(account)) result.push(pattern);
}

return result;
}

export function anyGitHubPatternIsAllRepos(patterns: GitHubPattern[]): boolean {
for (const pattern of patterns) if (pattern.repo?.isAll) return true;
return false;
}

function splitGitHubPattern(pattern: string): [string, string | undefined] {
const parts = pattern.split("/");

Expand Down
7 changes: 0 additions & 7 deletions src/name-pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@ export function createNamePattern(pattern: string): Pattern {
const literals = pattern.split("*");
const expression = patternRegExp(literals);

let isAll = true;
for (const l of literals) if (l) isAll = false;

return {
get isAll() {
return isAll;
},

test: (string) => expression.test(string),
toString: () => pattern,
};
Expand Down
1 change: 0 additions & 1 deletion src/pattern.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type Pattern = {
readonly isAll: boolean;
test: (string: string) => boolean;
toString: () => string;
};
Expand Down
13 changes: 5 additions & 8 deletions src/token-authorizer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createGitHubPattern, type GitHubPattern } from "./github-pattern.js";
import { createGitHubPattern } from "./github-pattern.js";
import { createNamePattern } from "./name-pattern.js";
import { anyPatternMatches, type Pattern } from "./pattern.js";
import { isSufficientPermissions } from "./permissions.js";
Expand Down Expand Up @@ -225,12 +225,9 @@ export function createTokenAuthorizer(

function patternsForRules(
rules: PermissionsRule[],
): [
Record<number, ResourceCriteriaPatterns[]>,
Record<number, GitHubPattern[]>,
] {
): [Record<number, ResourceCriteriaPatterns[]>, Record<number, Pattern[]>] {
const resourcePatterns: Record<number, ResourceCriteriaPatterns[]> = {};
const consumerPatterns: Record<number, GitHubPattern[]> = {};
const consumerPatterns: Record<number, Pattern[]> = {};

for (let i = 0; i < rules.length; ++i) {
[resourcePatterns[i], consumerPatterns[i]] = patternsForRule(rules[i]);
Expand All @@ -241,9 +238,9 @@ export function createTokenAuthorizer(

function patternsForRule(
rule: PermissionsRule,
): [ResourceCriteriaPatterns[], GitHubPattern[]] {
): [ResourceCriteriaPatterns[], Pattern[]] {
const resourcePatterns: ResourceCriteriaPatterns[] = [];
const consumerPatterns: GitHubPattern[] = [];
const consumerPatterns: Pattern[] = [];

for (const criteria of rule.resources) {
resourcePatterns.push(patternsForResourceCriteria(criteria));
Expand Down
27 changes: 0 additions & 27 deletions test/suite/unit/pattern/any-github-pattern-is-all-repos.spec.ts

This file was deleted.

64 changes: 0 additions & 64 deletions test/suite/unit/pattern/github-pattern.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,70 +29,6 @@ it("can be converted to a string", () => {
expect(String(createGitHubPattern("a*b/c*d"))).toBe("a*b/c*d");
});

it.each([["*/*"], ["**/**"], ["**********/**********"]])(
"knows that %s matches all repos",
(pattern) => {
expect(createGitHubPattern(pattern).isAll).toBe(true);
},
);

it.each([
["a"],
["a/*"],
["a*/*"],
["*a/*"],
["*a*/*"],
["*/a"],
["*/a*"],
["*/*a"],
["*/*a*"],
["a/a"],
["a*/a*"],
["*a/*a"],
["*a*/*a*"],
])("knows that %s doesn't match all repos", (pattern) => {
expect(createGitHubPattern(pattern).isAll).toBe(false);
});

it.each`
pattern | account
${"*/*"} | ${"account-a"}
${"**/**"} | ${"account-a"}
${"account-*/*"} | ${"account-a"}
${"account-**/**"} | ${"account-a"}
${"*-a/*"} | ${"account-a"}
${"**-a/**"} | ${"account-a"}
${"account-a/*"} | ${"account-a"}
${"account-a/**"} | ${"account-a"}
${"account-a/**********"} | ${"account-a"}
`(
"knows that $pattern matches all repos with account $account",
({ pattern, account }) => {
const actual = createGitHubPattern(pattern);

expect(actual.isAllForAccount(account)).toBe(true);
},
);

it.each`
pattern | account
${"account-b/*"} | ${"account-a"}
${"account-b/**"} | ${"account-a"}
${"account-b/**********"} | ${"account-a"}
${"account-a"} | ${"account-a"}
${"account-a/a"} | ${"account-a"}
${"account-a/a*"} | ${"account-a"}
${"account-a/*a"} | ${"account-a"}
${"account-a/*a*"} | ${"account-a"}
`(
"knows that $pattern doesn't match all repos with account $account",
({ pattern, account }) => {
const actual = createGitHubPattern(pattern);

expect(actual.isAllForAccount(account)).toBe(false);
},
);

const patterns: [pattern: string, matches: string[], nonMatches: string[]][] = [
["name-a", ["name-a"], ["name-b"]],
["name.a", ["name.a"], ["name-b"]],
Expand Down
19 changes: 0 additions & 19 deletions test/suite/unit/pattern/github-patterns-for-account.spec.ts

This file was deleted.

14 changes: 0 additions & 14 deletions test/suite/unit/pattern/name-pattern.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,6 @@ it("can be converted to a string", () => {
expect(String(createNamePattern("a*b"))).toBe("a*b");
});

it.each([["*"], ["**"], ["**********"]])(
"knows that %s matches all",
(pattern) => {
expect(createNamePattern(pattern).isAll).toBe(true);
},
);

it.each([["a"], ["a*"], ["*a"], ["*a*"]])(
"knows that %s doesn't match all",
(pattern) => {
expect(createNamePattern(pattern).isAll).toBe(false);
},
);

const patterns: [pattern: string, matches: string[], nonMatches: string[]][] = [
["name-a", ["name-a"], ["name-b"]],
["name.a", ["name.a"], ["name-b"]],
Expand Down

0 comments on commit 1507d53

Please sign in to comment.