Skip to content

Commit 2623356

Browse files
authored
fix: members page with member:modify (#6561)
1 parent 2600aa1 commit 2623356

File tree

5 files changed

+118
-3
lines changed

5 files changed

+118
-3
lines changed

integration-tests/tests/api/oidc-integrations/crud.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,54 @@ describe('restrictions', () => {
933933
},
934934
);
935935
});
936+
937+
test.concurrent(
938+
'Organization.oidcIntegration resolves to null without error if user does not have oidc:modify permission',
939+
async ({ expect }) => {
940+
const seed = initSeed();
941+
const { createOrg, ownerToken } = await seed.createOwner();
942+
const { organization, inviteAndJoinMember } = await createOrg();
943+
const { createMemberRole, assignMemberRole, updateMemberRole, memberToken, member } =
944+
await inviteAndJoinMember();
945+
946+
await execute({
947+
document: CreateOIDCIntegrationMutation,
948+
variables: {
949+
input: {
950+
organizationId: organization.id,
951+
clientId: 'aaaa',
952+
clientSecret: 'aaaaaaaaaaaa',
953+
tokenEndpoint: 'http://localhost:8888/aaaa/token',
954+
userinfoEndpoint: 'http://localhost:8888/aaaa/userinfo',
955+
authorizationEndpoint: 'http://localhost:8888/aaaa/authorize',
956+
},
957+
},
958+
authToken: ownerToken,
959+
}).then(r => r.expectNoGraphQLErrors());
960+
961+
const role = await createMemberRole([]);
962+
await assignMemberRole({ roleId: role.id, userId: member.id });
963+
964+
let result = await execute({
965+
document: OrganizationWithOIDCIntegration,
966+
variables: {
967+
organizationSlug: organization.slug,
968+
},
969+
authToken: memberToken,
970+
}).then(r => r.expectNoGraphQLErrors());
971+
972+
expect(result.organization!.organization.oidcIntegration).toEqual(null);
973+
974+
await updateMemberRole(role, ['oidc:modify']);
975+
976+
result = await execute({
977+
document: OrganizationWithOIDCIntegration,
978+
variables: {
979+
organizationSlug: organization.slug,
980+
},
981+
authToken: memberToken,
982+
}).then(r => r.expectNoGraphQLErrors());
983+
984+
expect(result.organization!.organization.oidcIntegration).not.toEqual(null);
985+
},
986+
);

integration-tests/tests/api/organization/members.spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { graphql } from 'testkit/gql';
2+
import { execute } from 'testkit/graphql';
13
import { history } from '../../../testkit/emails';
24
import { initSeed } from '../../../testkit/seed';
35

@@ -141,3 +143,53 @@ test.concurrent(
141143
expect(otherJoinResult.joinOrganization.__typename).toBe('OrganizationInvitationError');
142144
},
143145
);
146+
147+
const OrganizationInvitationsQuery = graphql(`
148+
query OrganizationInvitationsQuery($organizationSlug: String!) {
149+
organization: organizationBySlug(organizationSlug: $organizationSlug) {
150+
id
151+
invitations {
152+
total
153+
nodes {
154+
id
155+
}
156+
}
157+
}
158+
}
159+
`);
160+
161+
test.concurrent(
162+
'Organization.invitations resolves to null without error if user does not have member:modify permission',
163+
async ({ expect }) => {
164+
const seed = initSeed();
165+
const { createOrg } = await seed.createOwner();
166+
const { organization, inviteAndJoinMember } = await createOrg();
167+
const { createMemberRole, assignMemberRole, updateMemberRole, memberToken, member } =
168+
await inviteAndJoinMember();
169+
170+
const role = await createMemberRole([]);
171+
await assignMemberRole({ roleId: role.id, userId: member.id });
172+
173+
let result = await execute({
174+
document: OrganizationInvitationsQuery,
175+
variables: {
176+
organizationSlug: organization.slug,
177+
},
178+
authToken: memberToken,
179+
}).then(r => r.expectNoGraphQLErrors());
180+
181+
expect(result.organization!.invitations).toEqual(null);
182+
183+
await updateMemberRole(role, ['member:modify']);
184+
185+
result = await execute({
186+
document: OrganizationInvitationsQuery,
187+
variables: {
188+
organizationSlug: organization.slug,
189+
},
190+
authToken: memberToken,
191+
}).then(r => r.expectNoGraphQLErrors());
192+
193+
expect(result.organization!.invitations).not.toEqual(null);
194+
},
195+
);

packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,18 @@ export class OIDCIntegrationsProvider {
6060
return null;
6161
}
6262

63-
await this.session.assertPerformAction({
63+
const canPerformAction = await this.session.canPerformAction({
6464
organizationId: args.organizationId,
6565
action: 'oidc:modify',
6666
params: {
6767
organizationId: args.organizationId,
6868
},
6969
});
7070

71+
if (canPerformAction === false) {
72+
return null;
73+
}
74+
7175
return await this.storage.getOIDCIntegrationForOrganization({
7276
organizationId: args.organizationId,
7377
});

packages/services/api/src/modules/organization/providers/organization-manager.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,15 +239,19 @@ export class OrganizationManager {
239239

240240
@cache((selector: OrganizationSelector) => selector.organizationId)
241241
async getInvitations(selector: OrganizationSelector) {
242-
await this.session.assertPerformAction({
242+
const canAccessInvitations = await this.session.canPerformAction({
243243
action: 'member:modify',
244244
organizationId: selector.organizationId,
245245
params: {
246246
organizationId: selector.organizationId,
247247
},
248248
});
249249

250-
return this.storage.getOrganizationInvitations(selector);
250+
if (!canAccessInvitations) {
251+
return null;
252+
}
253+
254+
return await this.storage.getOrganizationInvitations(selector);
251255
}
252256

253257
async getOrganizationOwner(selector: OrganizationSelector) {

packages/services/api/src/modules/organization/resolvers/Organization.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ export const Organization: Pick<
6666
organizationId: organization.id,
6767
});
6868

69+
if (invitations === null) {
70+
return null;
71+
}
72+
6973
return {
7074
total: invitations.length,
7175
nodes: invitations,

0 commit comments

Comments
 (0)