Skip to content

Commit 916e579

Browse files
authored
feat(server): expose fields for managing access tokens via the public API (#6710)
1 parent a3f1ea9 commit 916e579

File tree

21 files changed

+267
-226
lines changed

21 files changed

+267
-226
lines changed

integration-tests/testkit/seed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ export function initSeed() {
843843
userId: input.userId,
844844
roleId: input.roleId,
845845
resources: input.resources ?? {
846-
mode: GraphQLSchema.ResourceAssignmentMode.All,
846+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
847847
projects: [],
848848
},
849849
},

integration-tests/tests/api/organization-access-tokens.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ test.concurrent('create: success', async () => {
8686
},
8787
title: 'a access token',
8888
description: 'Some description',
89-
resources: { mode: GraphQLSchema.ResourceAssignmentMode.All },
89+
resources: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
9090
permissions: [],
9191
},
9292
},
@@ -118,7 +118,7 @@ test.concurrent('create: failure invalid title', async ({ expect }) => {
118118
},
119119
title: ' ',
120120
description: 'Some description',
121-
resources: { mode: GraphQLSchema.ResourceAssignmentMode.All },
121+
resources: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
122122
permissions: [],
123123
},
124124
},
@@ -149,7 +149,7 @@ test.concurrent('create: failure invalid description', async ({ expect }) => {
149149
},
150150
title: 'a access token',
151151
description: new Array(300).fill('A').join(''),
152-
resources: { mode: GraphQLSchema.ResourceAssignmentMode.All },
152+
resources: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
153153
permissions: [],
154154
},
155155
},
@@ -181,7 +181,7 @@ test.concurrent('create: failure because no access to organization', async ({ ex
181181
},
182182
title: 'a access token',
183183
description: 'Some description',
184-
resources: { mode: GraphQLSchema.ResourceAssignmentMode.All },
184+
resources: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
185185
permissions: [],
186186
},
187187
},
@@ -213,7 +213,7 @@ test.concurrent('query GraphQL API on resources with access', async ({ expect })
213213
},
214214
title: 'a access token',
215215
description: 'a description',
216-
resources: { mode: GraphQLSchema.ResourceAssignmentMode.All },
216+
resources: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
217217
permissions: ['organization:describe', 'project:describe'],
218218
},
219219
},
@@ -263,11 +263,11 @@ test.concurrent('query GraphQL API on resources without access', async ({ expect
263263
title: 'a access token',
264264
description: 'a description',
265265
resources: {
266-
mode: GraphQLSchema.ResourceAssignmentMode.Granular,
266+
mode: GraphQLSchema.ResourceAssignmentModeType.Granular,
267267
projects: [
268268
{
269269
projectId: project1.project.id,
270-
targets: { mode: GraphQLSchema.ResourceAssignmentMode.All },
270+
targets: { mode: GraphQLSchema.ResourceAssignmentModeType.All },
271271
},
272272
],
273273
},
@@ -327,7 +327,7 @@ test.concurrent('pagination', async ({ expect }) => {
327327
title: 'first access token',
328328
description: 'a description',
329329
resources: {
330-
mode: GraphQLSchema.ResourceAssignmentMode.All,
330+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
331331
},
332332
permissions: ['organization:describe'],
333333
},
@@ -345,7 +345,7 @@ test.concurrent('pagination', async ({ expect }) => {
345345
title: 'second access token',
346346
description: 'a description',
347347
resources: {
348-
mode: GraphQLSchema.ResourceAssignmentMode.All,
348+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
349349
},
350350
permissions: ['organization:describe'],
351351
},

integration-tests/tests/api/project/crud.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ProjectType, ResourceAssignmentMode } from 'testkit/gql/graphql';
1+
import { ProjectType, ResourceAssignmentModeType } from 'testkit/gql/graphql';
22
import { updateProjectSlug } from '../../../testkit/flow';
33
import { initSeed } from '../../../testkit/seed';
44

@@ -217,7 +217,7 @@ test.concurrent('prevent access to projects with assigned resources on member',
217217
roleId: member.role.id,
218218
userId: member.user.id,
219219
resources: {
220-
mode: ResourceAssignmentMode.Granular,
220+
mode: ResourceAssignmentModeType.Granular,
221221
projects: [],
222222
},
223223
});
@@ -246,11 +246,11 @@ test.concurrent('restrict access to single project with assigned resources on me
246246
roleId: member.role.id,
247247
userId: member.user.id,
248248
resources: {
249-
mode: ResourceAssignmentMode.Granular,
249+
mode: ResourceAssignmentModeType.Granular,
250250
projects: [
251251
{
252252
projectId: firstProject.id,
253-
targets: { mode: ResourceAssignmentMode.All },
253+
targets: { mode: ResourceAssignmentModeType.All },
254254
},
255255
],
256256
},

integration-tests/tests/api/schema/check.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
ProjectType,
3-
ResourceAssignmentMode,
3+
ResourceAssignmentModeType,
44
RuleInstanceSeverityLevel,
55
} from 'testkit/gql/graphql';
66
// eslint-disable-next-line import/no-extraneous-dependencies
@@ -1370,7 +1370,7 @@ test.concurrent(
13701370
await assignMemberRole({
13711371
roleId: member.role.id,
13721372
userId: member.user.id,
1373-
resources: { mode: ResourceAssignmentMode.Granular, projects: [] },
1373+
resources: { mode: ResourceAssignmentModeType.Granular, projects: [] },
13741374
});
13751375

13761376
// Attempt approving the failed schema check
@@ -1448,7 +1448,7 @@ test.concurrent(
14481448
await assignMemberRole({
14491449
roleId: memberRole.id,
14501450
userId: member.user.id,
1451-
resources: { mode: ResourceAssignmentMode.Granular, projects: [] },
1451+
resources: { mode: ResourceAssignmentModeType.Granular, projects: [] },
14521452
});
14531453

14541454
// Attempt approving the failed schema check
@@ -1529,12 +1529,12 @@ test.concurrent(
15291529
roleId: memberRole.id,
15301530
userId: member.user.id,
15311531
resources: {
1532-
mode: ResourceAssignmentMode.Granular,
1532+
mode: ResourceAssignmentModeType.Granular,
15331533
projects: [
15341534
{
15351535
projectId: project.id,
15361536
targets: {
1537-
mode: ResourceAssignmentMode.Granular,
1537+
mode: ResourceAssignmentModeType.Granular,
15381538
targets: [],
15391539
},
15401540
},
@@ -1618,17 +1618,17 @@ test.concurrent(
16181618
roleId: memberRole.id,
16191619
userId: member.user.id,
16201620
resources: {
1621-
mode: ResourceAssignmentMode.Granular,
1621+
mode: ResourceAssignmentModeType.Granular,
16221622
projects: [
16231623
{
16241624
projectId: project.id,
16251625
targets: {
1626-
mode: ResourceAssignmentMode.Granular,
1626+
mode: ResourceAssignmentModeType.Granular,
16271627
targets: [
16281628
{
16291629
targetId: target.id,
1630-
appDeployments: { mode: ResourceAssignmentMode.All },
1631-
services: { mode: ResourceAssignmentMode.All },
1630+
appDeployments: { mode: ResourceAssignmentModeType.All },
1631+
services: { mode: ResourceAssignmentModeType.All },
16321632
},
16331633
],
16341634
},

integration-tests/tests/cli/schema.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ test('schema:check without `--target` flag fails for organization access token',
770770
const privateKey = await createOrganizationAccessToken({
771771
permissions: ['schemaCheck:create', 'project:describe'],
772772
resources: {
773-
mode: GraphQLSchema.ResourceAssignmentMode.All,
773+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
774774
},
775775
});
776776

@@ -809,7 +809,7 @@ test('schema:check with `--target` flag succeeds for organization access token',
809809
const privateKey = await createOrganizationAccessToken({
810810
permissions: ['schemaCheck:create', 'project:describe'],
811811
resources: {
812-
mode: GraphQLSchema.ResourceAssignmentMode.All,
812+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
813813
},
814814
});
815815

@@ -841,7 +841,7 @@ test('schema:publish without `--target` flag fails for organization access token
841841
const privateKey = await createOrganizationAccessToken({
842842
permissions: ['project:describe', 'schemaVersion:publish'],
843843
resources: {
844-
mode: GraphQLSchema.ResourceAssignmentMode.All,
844+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
845845
},
846846
});
847847

@@ -881,7 +881,7 @@ test('schema:publish with `--target` flag succeeds for organization access token
881881
const privateKey = await createOrganizationAccessToken({
882882
permissions: ['project:describe', 'schemaVersion:publish'],
883883
resources: {
884-
mode: GraphQLSchema.ResourceAssignmentMode.All,
884+
mode: GraphQLSchema.ResourceAssignmentModeType.All,
885885
},
886886
});
887887

integration-tests/tests/usage-reporting/organization-access-token.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { initSeed } from 'testkit/seed';
2-
import { ResourceAssignmentMode } from '../../testkit/gql/graphql';
2+
import { ResourceAssignmentModeType } from '../../testkit/gql/graphql';
33
import { getServiceHost } from '../../testkit/utils';
44

55
test('/:targetId > operation is accepted with wildcard access token', async () => {
@@ -12,7 +12,7 @@ test('/:targetId > operation is accepted with wildcard access token', async () =
1212
const accessToken = await createOrganizationAccessToken({
1313
permissions: ['usage:report'],
1414
resources: {
15-
mode: ResourceAssignmentMode.All,
15+
mode: ResourceAssignmentModeType.All,
1616
},
1717
});
1818

@@ -71,12 +71,12 @@ test('/:targetId > operation is denied without access to target', async () => {
7171
const accessToken = await createOrganizationAccessToken({
7272
permissions: ['usage:report'],
7373
resources: {
74-
mode: ResourceAssignmentMode.Granular,
74+
mode: ResourceAssignmentModeType.Granular,
7575
projects: [
7676
{
7777
projectId: project.id,
7878
targets: {
79-
mode: ResourceAssignmentMode.Granular,
79+
mode: ResourceAssignmentModeType.Granular,
8080
targets: [],
8181
},
8282
},
@@ -133,22 +133,22 @@ test('/:targetId > operation is accepted with specific access to target', async
133133
const accessToken = await createOrganizationAccessToken({
134134
permissions: ['usage:report'],
135135
resources: {
136-
mode: ResourceAssignmentMode.Granular,
136+
mode: ResourceAssignmentModeType.Granular,
137137
projects: [
138138
{
139139
projectId: project.id,
140140
targets: {
141-
mode: ResourceAssignmentMode.Granular,
141+
mode: ResourceAssignmentModeType.Granular,
142142
targets: [
143143
{
144144
targetId: target.id,
145145
services: {
146146
services: [],
147-
mode: ResourceAssignmentMode.Granular,
147+
mode: ResourceAssignmentModeType.Granular,
148148
},
149149
appDeployments: {
150150
appDeployments: [],
151-
mode: ResourceAssignmentMode.Granular,
151+
mode: ResourceAssignmentModeType.Granular,
152152
},
153153
},
154154
],
@@ -213,7 +213,7 @@ test('/:orgSlug/:projectSlug/:targetSlug > operation is accepted with wildcard a
213213
const accessToken = await createOrganizationAccessToken({
214214
permissions: ['usage:report'],
215215
resources: {
216-
mode: ResourceAssignmentMode.All,
216+
mode: ResourceAssignmentModeType.All,
217217
},
218218
});
219219

@@ -275,12 +275,12 @@ test('/:orgSlug/:projectSlug/:targetSlug > operation is denied without access to
275275
const accessToken = await createOrganizationAccessToken({
276276
permissions: ['usage:report'],
277277
resources: {
278-
mode: ResourceAssignmentMode.Granular,
278+
mode: ResourceAssignmentModeType.Granular,
279279
projects: [
280280
{
281281
projectId: project.id,
282282
targets: {
283-
mode: ResourceAssignmentMode.Granular,
283+
mode: ResourceAssignmentModeType.Granular,
284284
targets: [],
285285
},
286286
},
@@ -340,22 +340,22 @@ test('/:orgSlug/:projectSlug/:targetSlug > operation is accepted with specific a
340340
const accessToken = await createOrganizationAccessToken({
341341
permissions: ['usage:report'],
342342
resources: {
343-
mode: ResourceAssignmentMode.Granular,
343+
mode: ResourceAssignmentModeType.Granular,
344344
projects: [
345345
{
346346
projectId: project.id,
347347
targets: {
348-
mode: ResourceAssignmentMode.Granular,
348+
mode: ResourceAssignmentModeType.Granular,
349349
targets: [
350350
{
351351
targetId: target.id,
352352
services: {
353353
services: [],
354-
mode: ResourceAssignmentMode.Granular,
354+
mode: ResourceAssignmentModeType.Granular,
355355
},
356356
appDeployments: {
357357
appDeployments: [],
358-
mode: ResourceAssignmentMode.Granular,
358+
mode: ResourceAssignmentModeType.Granular,
359359
},
360360
},
361361
],

packages/services/api/src/modules/auth/module.graphql.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ export default gql`
55
me: User!
66
}
77
8-
interface Error {
9-
message: String!
10-
}
11-
128
extend type Mutation {
139
updateMe(input: UpdateMeInput!): UpdateMeResult!
1410
}
@@ -97,19 +93,19 @@ export default gql`
9793
TOKENS_WRITE
9894
}
9995
100-
enum PermissionLevel {
101-
organization
102-
project
103-
target
104-
service
105-
appDeployment
96+
enum PermissionLevelType {
97+
ORGANIZATION
98+
PROJECT
99+
TARGET
100+
SERVICE
101+
APP_DEPLOYMENT
106102
}
107103
108104
type Permission {
109105
id: ID!
110106
title: String!
111107
description: String!
112-
level: PermissionLevel!
108+
level: PermissionLevelType!
113109
dependsOnId: ID
114110
isReadOnly: Boolean!
115111
warning: String

packages/services/api/src/modules/auth/resolvers/Permission.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getPermissionGroup } from '../lib/authz';
1+
import { getPermissionGroup, type ResourceLevel } from '../lib/authz';
22
import type { PermissionResolvers } from './../../../__generated__/types';
33

44
/*
@@ -18,9 +18,24 @@ export const Permission: PermissionResolvers = {
1818
return permission.isReadOnly ?? false;
1919
},
2020
level: async (permission, _arg, _ctx) => {
21-
return getPermissionGroup(permission.id);
21+
return resourceLevelToResourceLevelType(getPermissionGroup(permission.id));
2222
},
2323
warning: async (permission, _arg, _ctx) => {
2424
return permission.warning ?? null;
2525
},
2626
};
27+
28+
function resourceLevelToResourceLevelType(resourceLevel: ResourceLevel) {
29+
switch (resourceLevel) {
30+
case 'target':
31+
return 'TARGET' as const;
32+
case 'service':
33+
return 'SERVICE' as const;
34+
case 'project':
35+
return 'PROJECT' as const;
36+
case 'organization':
37+
return 'ORGANIZATION' as const;
38+
case 'appDeployment':
39+
return 'APP_DEPLOYMENT' as const;
40+
}
41+
}

0 commit comments

Comments
 (0)