Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new permission system #5674

Merged
merged 42 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
92aab41
feat: introduce session and authentication strategies
n1ru4l Oct 15, 2024
19e16c7
feat: supertokens auth strategy
n1ru4l Oct 15, 2024
b3eeb49
feat: target access token strategy and session
n1ru4l Oct 15, 2024
e409810
feat: permission granularity
n1ru4l Oct 21, 2024
7ec3cf2
provide session via dependency injection
n1ru4l Oct 21, 2024
7530244
type-safety for action strings in policy statements
n1ru4l Oct 22, 2024
2804cc1
feat: use new permission system within oidc provider
n1ru4l Oct 22, 2024
98e365b
feat: drop generic envelop auth plugin
n1ru4l Oct 22, 2024
42c9e0d
fix: unhandled rejection
n1ru4l Oct 22, 2024
4b27eda
feat: use session in support manager
n1ru4l Oct 22, 2024
30a3aac
fix: update permission name
n1ru4l Oct 22, 2024
ffc5da3
feat: use new session class within alerts manager
n1ru4l Oct 22, 2024
2621e1d
feat: use session class in app deployments manager
n1ru4l Oct 23, 2024
bd281ae
feat: use session class within contracts manager
n1ru4l Oct 23, 2024
43cc4b0
feat: use session class within cdn access token manager
n1ru4l Oct 23, 2024
a32c98a
feat: use session class within github-integration-manager
n1ru4l Oct 23, 2024
4db4825
feat: use session within slack-integration-manager
n1ru4l Oct 23, 2024
ce7fda3
feat: use session within schema-publisher
n1ru4l Oct 23, 2024
412d953
feat: update token manager class
n1ru4l Oct 23, 2024
23c5328
fix: permission scoping
n1ru4l Oct 24, 2024
c313a8e
feat: use session in operation manager, schema manager and schema pub…
n1ru4l Oct 25, 2024
19c2b33
chore: remove annotations fixed by dependency upgrade
n1ru4l Oct 28, 2024
1c04793
use correct access
n1ru4l Oct 28, 2024
df433e9
admin
n1ru4l Oct 30, 2024
c4f5262
me
n1ru4l Oct 30, 2024
f54397c
memory rate limit
n1ru4l Oct 30, 2024
e622a4b
collection
n1ru4l Oct 30, 2024
74eb597
project manager
n1ru4l Oct 30, 2024
1478383
contracts manager
n1ru4l Oct 30, 2024
a1c9536
activity manager
n1ru4l Oct 30, 2024
fb456de
missing permissions
n1ru4l Oct 30, 2024
5583425
schema publish and checks
n1ru4l Oct 30, 2024
cc5a8bf
lint
n1ru4l Oct 30, 2024
59a570c
delete feedback module
n1ru4l Oct 30, 2024
4959256
schema policy
n1ru4l Oct 30, 2024
109ec53
usage estimation
n1ru4l Oct 30, 2024
fadbe9e
remove unused file
n1ru4l Oct 30, 2024
c9f0cda
more permissions
n1ru4l Oct 31, 2024
4b86af5
small fixes
n1ru4l Oct 31, 2024
84550fa
some logging
n1ru4l Oct 31, 2024
bec8391
admin things
n1ru4l Oct 31, 2024
63dc998
lockfile thingz
n1ru4l Oct 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions integration-tests/testkit/schema-policy.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,6 @@
import { RuleInstanceSeverityLevel, SchemaPolicyInput } from 'testkit/gql/graphql';
import { graphql } from './gql';

export const TargetCalculatedPolicy = graphql(`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am deleting all this stuff since it is not used by the app anyways and I wanted to avoid having to update the permission checks for these.

query TargetCalculatedPolicy($selector: TargetSelectorInput!) {
target(selector: $selector) {
id
schemaPolicy {
mergedRules {
...SchemaPolicyRuleInstanceFields
}
projectPolicy {
id
rules {
...SchemaPolicyRuleInstanceFields
}
}
organizationPolicy {
id
allowOverrides
rules {
...SchemaPolicyRuleInstanceFields
}
}
}
}
}

fragment SchemaPolicyRuleInstanceFields on SchemaPolicyRuleInstance {
rule {
id
}
severity
configuration
}
`);

export const OrganizationAndProjectsWithSchemaPolicy = graphql(`
query OrganizationAndProjectsWithSchemaPolicy($organization: String!) {
organization(selector: { organizationSlug: $organization }) {
Expand Down
29 changes: 16 additions & 13 deletions integration-tests/testkit/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,19 +495,6 @@ export function initSeed() {
secret,
);
},

async updateSchemaVersionStatus(versionId: string, valid: boolean) {
return await updateSchemaVersionStatus(
{
organizationSlug: organization.slug,
projectSlug: project.slug,
targetSlug: target.slug,
valid,
versionId,
},
secret,
).then(r => r.expectNoGraphQLErrors());
},
async publishSchema(options: {
sdl: string;
headerName?: 'x-api-token' | 'authorization';
Expand Down Expand Up @@ -708,6 +695,22 @@ export function initSeed() {

return result.target?.schemaVersions.edges.map(edge => edge.node);
},
async updateSchemaVersionStatus(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was never intended to run this via a registry access token, so I moved it to the project level and execute it with the organization owner token instead.

versionId: string,
valid: boolean,
ttarget: TargetOverwrite = target,
) {
return await updateSchemaVersionStatus(
{
organizationSlug: organization.slug,
projectSlug: project.slug,
targetSlug: ttarget.slug,
valid,
versionId,
},
ownerToken,
).then(r => r.expectNoGraphQLErrors());
},
};
},
async inviteAndJoinMember(inviteToken: string = ownerToken) {
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/api/artifacts-cdn.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ describe('CDN token', () => {
expect(deleteResult).toEqual(
expect.arrayContaining([
expect.objectContaining({
message: `No access (reason: "Missing target:settings permission")`,
message: `No access (reason: "Missing permission for performing 'cdnAccessToken:delete' on resource")`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we now have granular permissions the messages changed slightly. We do not have any logic that depends on the message contents, except integration test fixtures.

}),
]),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ describe('Document Collections', () => {
).rejects.toEqual(
expect.objectContaining({
message: expect.stringContaining(
`No access (reason: "Missing target:registry:write permission")`,
`No access (reason: "Missing permission for performing 'laboratory:createCollection' on resource")`,
),
}),
);
Expand Down Expand Up @@ -172,7 +172,7 @@ describe('Document Collections', () => {
).rejects.toEqual(
expect.objectContaining({
message: expect.stringContaining(
'No access (reason: "Missing target:registry:write permission")',
`No access (reason: "Missing permission for performing 'laboratory:modifyCollection' on resource")`,
),
}),
);
Expand Down Expand Up @@ -202,7 +202,7 @@ describe('Document Collections', () => {
).rejects.toEqual(
expect.objectContaining({
message: expect.stringContaining(
`No access (reason: "Missing target:registry:write permission")`,
`No access (reason: "Missing permission for performing 'laboratory:deleteCollection' on resource")`,
),
}),
);
Expand Down
6 changes: 3 additions & 3 deletions integration-tests/tests/api/oidc-integrations/crud.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ describe('create', () => {
expect(errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
message: `No access (reason: "Missing organization:integrations permission")`,
message: `No access (reason: "Missing permission for performing 'oidc:modify' on resource")`,
}),
]),
);
Expand Down Expand Up @@ -545,7 +545,7 @@ describe('delete', () => {
expect(errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
message: `No access (reason: "Missing organization:integrations permission")`,
message: `No access (reason: "Missing permission for performing 'oidc:modify' on resource")`,
}),
]),
);
Expand Down Expand Up @@ -742,7 +742,7 @@ describe('update', () => {
expect(errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
message: `No access (reason: "Missing organization:integrations permission")`,
message: `No access (reason: "Missing permission for performing 'oidc:modify' on resource")`,
}),
]),
);
Expand Down
70 changes: 0 additions & 70 deletions integration-tests/tests/api/policy/policy-access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,6 @@ import { execute } from '../../../testkit/graphql';
import { initSeed } from '../../../testkit/seed';

describe('Policy Access', () => {
describe('Target', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted as unused.

const query = graphql(`
query TargetSchemaPolicyAccess($selector: TargetSelectorInput!) {
target(selector: $selector) {
schemaPolicy {
mergedRules {
severity
}
}
}
}
`);

test.concurrent(
'should successfully fetch Target.schemaPolicy if the user has access to SETTINGS',
async ({ expect }) => {
const { createOrg } = await initSeed().createOwner();
const { organization, createProject, inviteAndJoinMember } = await createOrg();
const { project, target } = await createProject(ProjectType.Single);
const adminRole = organization.memberRoles.find(r => r.name === 'Admin');

if (!adminRole) {
throw new Error('Admin role not found');
}

const { member, memberToken, assignMemberRole } = await inviteAndJoinMember();
await assignMemberRole({
roleId: adminRole.id,
userId: member.user.id,
});

const result = await execute({
document: query,
variables: {
selector: {
organizationSlug: organization.slug,
projectSlug: project.slug,
targetSlug: target.slug,
},
},
authToken: memberToken,
}).then(r => r.expectNoGraphQLErrors());

expect(result.target?.schemaPolicy?.mergedRules).not.toBeNull();
},
);

test.concurrent(
'should fail to fetch Target.schemaPolicy if the user lacks access to SETTINGS',
async ({ expect }) => {
const { createOrg } = await initSeed().createOwner();
const { organization, createProject, inviteAndJoinMember } = await createOrg();
const { project, target } = await createProject(ProjectType.Single);
const { memberToken } = await inviteAndJoinMember();

await execute({
document: query,
variables: {
selector: {
organizationSlug: organization.slug,
projectSlug: project.slug,
targetSlug: target.slug,
},
},
authToken: memberToken,
}).then(r => r.expectGraphQLErrors());
},
);
});

describe('Project', () => {
const query = graphql(`
query ProjectSchemaPolicyAccess($selector: ProjectSelectorInput!) {
Expand Down
Loading
Loading