Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

Commit

Web: work scopes in the token tests

G1T-Session:
ses_01m560bz6eeqc8v1hrrha03pap
syntaqxcommitted Parent17fe2dfBrowse files
6 files+26−260/6 viewed
+8−8
4949 repository_selection: "selected",
5050 repo: ["web", "acme/api", "web"],
5151 "perm.code": "write",
52− "perm.issues": "none",
52+ "perm.work": "none",
5353 "perm.workflow_files": "write",
5454 "perm.packages": "delete",
5555 }),
8888 });
8989
9090 test("editing reads neither the expiry nor needs a name", () => {
91− const parsed = tokenFromForm(form({ expires: "9999", "perm.issues": "read" }), { editing: true });
91+ const parsed = tokenFromForm(form({ expires: "9999", "perm.work": "read" }), { editing: true });
9292 assert.ok(parsed.ok);
9393 assert.equal(parsed.value.name, "");
9494 });
9999 assert.match(error({ name: "x", expires: "400", "perm.repo": "read" }), /366/);
100100 assert.match(error({ name: "x", workspace: "acme", repository_selection: "selected", "perm.repo": "read" }), /repository/);
101101 assert.match(error({ name: "x", "perm.workflow_files": "read" }), /Workflow files/);
102− assert.match(error({ name: "x", "perm.issues": "admin" }), /Issues/);
102+ assert.match(error({ name: "x", "perm.work": "admin" }), /Work/);
103103 assert.match(error({ name: "x" }), /at least one permission/);
104104 });
105105
106106 test("permissions are scopes read per resource", () => {
107− assert.deepEqual(permissionsOf(["repo:read", "repo:admin", "issues:write", "bogus"]), { repo: "admin", issues: "write" });
108− assert.deepEqual(scopesOfPermissions({ issues: "write", repo: "read" }), ["repo:read", "issues:write"]);
107+ assert.deepEqual(permissionsOf(["repo:read", "repo:admin", "work:write", "bogus"]), { repo: "admin", work: "write" });
108+ assert.deepEqual(scopesOfPermissions({ work: "write", repo: "read" }), ["repo:read", "work:write"]);
109109 assert.equal(Object.keys(permissionsOf(null)).length, SCOPE_RESOURCES.length, "full access is every resource");
110110 assert.equal(levelLabel("workflow_files", "write"), "Write");
111− assert.equal(levelLabel("issues", "write"), "Read and write");
111+ assert.equal(levelLabel("work", "write"), "Read and write");
112112 assert.equal(levelLabel("packages", "delete"), "Read, write and delete");
113113 });
114114
124124
125125 test("lists read a token in a line", () => {
126126 const token = {
127− scopes: ["repo:read", "code:write", "issues:read"],
127+ scopes: ["repo:read", "code:write", "work:read"],
128128 workspace: "acme",
129129 repositorySelection: "selected" as const,
130130 repositories: ["acme/web", "acme/api"],
135135 assert.equal(reachSummary({ workspaceOwned: true, repositorySelection: "all" }), "All repositories");
136136 assert.deepEqual(
137137 permissionChips(token).map((chip) => chip.label),
138− ["Repositories: read", "Code: write", "Issues: read"],
138+ ["Repositories: read", "Code: write", "Work: read"],
139139 );
140140 assert.ok(permissionChips({ scopes: ["repo:admin"] })[0]!.dangerous);
141141 assert.deepEqual(statusBadge("pending"), { label: "Pending approval", tone: "warn" });
+1−1
4848 assert.deepEqual(found.soon.map((view) => view.id), ["pagerduty"], "what is coming sorts after what works");
4949 assert.ok(matchesQuery(personal.find((view) => view.id === "google-calendar")!, "in a meeting"));
5050 assert.ok(matchesQuery(workspace.find((view) => view.id === "incident-io")!, "incidentio"));
51− assert.ok(matchesQuery(workspace.find((view) => view.id === "pagerduty")!, "opens ISSUES"));
51+ assert.ok(matchesQuery(workspace.find((view) => view.id === "pagerduty")!, "opens WORK ITEMS"));
5252 assert.ok(!matchesQuery(workspace.find((view) => view.id === "miro")!, "kubernetes"));
5353 });
5454
+3−3
6464
6565 test("changing one filter keeps the others", () => {
6666 const current = new URLSearchParams("state=closed&label=bug");
67− assert.equal(withFilter("/a/b/issues", current, "milestone", "3"), "/a/b/issues?state=closed&label=bug&milestone=3");
68− assert.equal(withFilter("/a/b/issues", current, "label", null), "/a/b/issues?state=closed");
69− assert.equal(withFilter("/a/b/issues", new URLSearchParams("label=bug"), "label", ""), "/a/b/issues");
67+ assert.equal(withFilter("/a/-/work", current, "milestone", "3"), "/a/-/work?state=closed&label=bug&milestone=3");
68+ assert.equal(withFilter("/a/-/work", current, "label", null), "/a/-/work?state=closed");
69+ assert.equal(withFilter("/a/-/work", new URLSearchParams("label=bug"), "label", ""), "/a/-/work");
7070 });
+12−12
3838
3939 test("ticked boxes store the highest level of each resource", () => {
4040 const parsed = scopesFromForm(
41− form({ scope: ["issues:read", "issues:write", "code:read", "agents:run", "memory:write", "bogus:read"] }),
41+ form({ scope: ["work:read", "work:write", "code:read", "agents:run", "memory:write", "bogus:read"] }),
4242 );
43− assert.deepEqual(parsed, { ok: true, value: ["code:read", "issues:write"] });
43+ assert.deepEqual(parsed, { ok: true, value: ["code:read", "work:write"] });
4444 assert.deepEqual(normalizeScopes(["repo:read", "repo:admin", "repo:write"]), ["repo:admin"]);
4545 });
4646
4747 test("full access is null, and nothing ticked is refused", () => {
48− assert.deepEqual(scopesFromForm(form({ preset: "full", scope: "issues:read" })), { ok: true, value: null });
48+ assert.deepEqual(scopesFromForm(form({ preset: "full", scope: "work:read" })), { ok: true, value: null });
4949 assert.equal(scopesFromForm(form({ preset: "full" }), { allowFull: false }).ok, false);
5050 assert.equal(scopesFromForm(form({ preset: "custom" })).ok, false);
5151 assert.deepEqual(grantFromForm(form({ scope: "observability:read" })), { ok: true, value: { scopes: ["observability:read"] } });
5252 });
5353
5454 test("a higher level ticks the lower ones of its resource only", () => {
55− assert.equal(impliedBy(["issues:write"], "issues:read"), "issues:write");
55+ assert.equal(impliedBy(["work:write"], "work:read"), "work:write");
5656 assert.equal(impliedBy(["repo:admin"], "repo:write"), "repo:admin");
57− assert.equal(impliedBy(["issues:write"], "issues:write"), null);
58− assert.equal(impliedBy(["issues:write"], "pull_requests:read"), null);
57+ assert.equal(impliedBy(["work:write"], "work:write"), null);
58+ assert.equal(impliedBy(["work:write"], "pull_requests:read"), null);
5959 assert.equal(impliedBy(["code:read"], "code:write"), null);
6060 });
6161
7272 assert.equal(matchingPreset(null), "full");
7373 assert.equal(matchingPreset(["repo:read", "code:write", "packages:write", "workflows:write", "checks:write", "deployments:write"]), "ci");
7474 assert.equal(matchingPreset([...OAUTH_DEFAULT_SCOPES]), "agent");
75− assert.equal(matchingPreset(["issues:read"]), null);
75+ assert.equal(matchingPreset(["work:read"]), null);
7676 });
7777
7878 test("a token's access reads plainly", () => {
7979 assert.equal(accessSummary({ scopes: null, legacy: true }), "Legacy · full access");
8080 assert.equal(accessSummary({ scopes: null, legacy: false }), "Full access");
8181 assert.equal(accessSummary({ scopes: ["code:read", "code:write", "packages:write", "workflows:write", "checks:write", "deployments:write", "repo:read"], legacy: false }), "CI");
82− assert.equal(accessSummary({ scopes: ["issues:read", "issues:write", "pull_requests:read"], legacy: false }), "2 scopes");
82+ assert.equal(accessSummary({ scopes: ["work:read", "work:write", "pull_requests:read"], legacy: false }), "2 scopes");
8383 assert.equal(accessSummary({ scopes: [], legacy: false }), "No scopes");
8484 });
8585
8787 assert.deepEqual(requestedScopes(null), OAUTH_DEFAULT_SCOPES);
8888 assert.deepEqual(requestedScopes("openid profile *"), OAUTH_DEFAULT_SCOPES);
8989 assert.ok(!requestedScopes("").some((scope) => scope.endsWith(":admin")));
90− assert.deepEqual(requestedScopes("issues:write nonsense repo:read"), ["repo:read", "issues:write"]);
90+ assert.deepEqual(requestedScopes("work:write nonsense repo:read"), ["repo:read", "work:write"]);
9191 });
9292
9393 test("consent keeps only what was asked for", () => {
94− const requested = requestedScopes("repo:read issues:read issues:write");
95− assert.deepEqual(consentedScopes(form({ scope: ["issues:write", "repo:admin", "secrets:admin"] }), requested), ["issues:write"]);
96− assert.deepEqual(consentedScopes(form({ scope: ["issues:read", "repo:read"] }), requested), ["repo:read", "issues:read"]);
94+ const requested = requestedScopes("repo:read work:read work:write");
95+ assert.deepEqual(consentedScopes(form({ scope: ["work:write", "repo:admin", "secrets:admin"] }), requested), ["work:write"]);
96+ assert.deepEqual(consentedScopes(form({ scope: ["work:read", "repo:read"] }), requested), ["repo:read", "work:read"]);
9797 assert.deepEqual(consentedScopes(form({}), requested), []);
9898 });
9999
+1−1
66 * read per resource.
77 *
88 * The checklist posts one `scope` field per ticked box. A higher level of
9− * a resource includes the lower ones (`issues:write` gives `issues:read`),
9+ * a resource includes the lower ones (`work:write` gives `work:read`),
1010 * so only the highest ticked level of each resource is stored.
1111 */
1212
+1−1
182182 const scopedTokens = lookup({
183183 g1t_chat_read: scoped(["chat:read", "notifications:read"]),
184184 g1t_chat_write: scoped(["chat:write", "notifications:write"]),
185− g1t_no_chat: scoped(["repo:read", "issues:write", "notifications:read"]),
185+ g1t_no_chat: scoped(["repo:read", "work:write", "notifications:read"]),
186186 g1t_full: scoped(null),
187187 g1t_legacy: scoped(null, { legacy: true }),
188188 g1t_web: ada,

Comments

Sign in to comment.