Skip to content

Commit

Permalink
feat: enable programmatic creation of roles and teams (webiny#4303)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrians5j authored Oct 4, 2024
1 parent 0ea4dcd commit 80f00cb
Show file tree
Hide file tree
Showing 38 changed files with 1,054 additions and 249 deletions.
2 changes: 1 addition & 1 deletion packages/api-aco/__tests__/utils/useGraphQlHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import { FileManagerStorageOperations } from "@webiny/api-file-manager/types";
import { DecryptedWcpProjectLicense } from "@webiny/wcp/types";
import createAdminUsersApp from "@webiny/api-admin-users";
import { createWcpContext } from "@webiny/api-wcp";
import { createTestWcpLicense } from "~tests/utils/createTestWcpLicense";
import { createTestWcpLicense } from "@webiny/wcp/testing/createTestWcpLicense";
import { AdminUsersStorageOperations } from "@webiny/api-admin-users/types";

export interface UseGQLHandlerParams {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getIntrospectionQuery } from "graphql";
import { APIGatewayEvent, LambdaContext } from "@webiny/handler-aws/types";
import { DecryptedWcpProjectLicense } from "@webiny/wcp/types";
import createAdminUsersApp from "@webiny/api-admin-users";
import { createTestWcpLicense } from "~tests/utils/createTestWcpLicense";
import { createTestWcpLicense } from "@webiny/wcp/testing/createTestWcpLicense";
import { createWcpContext } from "@webiny/api-wcp";
import { AdminUsersStorageOperations } from "@webiny/api-admin-users/types";
import { until } from "@webiny/project-utils/testing/helpers/until";
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { getIntrospectionQuery } from "graphql";
import { APIGatewayEvent, LambdaContext } from "@webiny/handler-aws/types";
import { DecryptedWcpProjectLicense } from "@webiny/wcp/types";
import createAdminUsersApp from "@webiny/api-admin-users";
import { createTestWcpLicense } from "~tests/utils/createTestWcpLicense";
import { createTestWcpLicense } from "@webiny/wcp/testing/createTestWcpLicense";
import { createWcpContext } from "@webiny/api-wcp";
import { AdminUsersStorageOperations } from "@webiny/api-admin-users/types";

Expand Down
75 changes: 75 additions & 0 deletions packages/api-security/__tests__/graphql/teams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const DATA_FIELD = (extra = "") => /* GraphQL */ `
{
name
description
slug
groups {
id
name
}
${extra}
}
`;

const ERROR_FIELD = /* GraphQL */ `
{
code
data
message
}
`;

export const CREATE_SECURITY_TEAM = /* GraphQL */ `
mutation CreateTeam($data: SecurityTeamCreateInput!) {
security {
createTeam(data: $data) {
data ${DATA_FIELD("id")}
error ${ERROR_FIELD}
}
}
}
`;

export const UPDATE_SECURITY_TEAM = /* GraphQL */ `
mutation UpdateTeam($id: ID!, $data: SecurityTeamUpdateInput!) {
security {
updateTeam(id: $id, data: $data) {
data ${DATA_FIELD()}
error ${ERROR_FIELD}
}
}
}
`;

export const DELETE_SECURITY_TEAM = /* GraphQL */ `
mutation DeleteTeam($id: ID!) {
security {
deleteTeam(id: $id) {
data
error ${ERROR_FIELD}
}
}
}
`;

export const LIST_SECURITY_TEAMS = /* GraphQL */ `
query ListTeams {
security {
listTeams {
data ${DATA_FIELD()}
error ${ERROR_FIELD}
}
}
}
`;

export const GET_SECURITY_TEAM = /* GraphQL */ `
query GetTeam($id: ID!) {
security {
getTeam(where: { id: $id }) {
data ${DATA_FIELD()}
error ${ERROR_FIELD}
}
}
}
`;
137 changes: 123 additions & 14 deletions packages/api-security/__tests__/groups.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import useGqlHandler from "./useGqlHandler";
import mocks from "./mocks/securityGroup";
import { createSecurityRolePlugin } from "~/plugins/SecurityRolePlugin";

describe("Security Group CRUD Test", () => {
const { install, securityGroup } = useGqlHandler();
const { install, securityGroup } = useGqlHandler({
plugins: [
createSecurityRolePlugin({
id: "test-role-1",
name: "Test Role 1",
description: "1st test role defined via an extension.",
permissions: [{ name: "cms.*" }]
}),
createSecurityRolePlugin({
id: "test-role-2",
name: "Test Role 2",
description: "2nd test role defined via an extension.",
permissions: [{ name: "pb.*" }]
})
]
});

beforeEach(async () => {
await install.install();
Expand All @@ -23,19 +39,67 @@ describe("Security Group CRUD Test", () => {
// Let's check whether both of the group exists
const [listResponse] = await securityGroup.list();

expect(listResponse.data.security.listGroups).toEqual(
expect.objectContaining({
data: expect.arrayContaining([
{
name: expect.any(String),
description: expect.any(String),
slug: expect.stringMatching(/anonymous|full-access|group-a|group-b/),
permissions: expect.any(Array)
}
]),
error: null
})
);
expect(listResponse.data.security.listGroups).toEqual({
error: null,
data: [
{
name: "Test Role 1",
description: "1st test role defined via an extension.",
slug: "test-role-1",
permissions: [
{
name: "cms.*"
}
]
},
{
name: "Test Role 2",
description: "2nd test role defined via an extension.",
slug: "test-role-2",
permissions: [
{
name: "pb.*"
}
]
},
{
name: "Full Access",
description: "Grants full access to all apps.",
slug: "full-access",
permissions: [
{
name: "*"
}
]
},
{
name: "Anonymous",
description: "Permissions for anonymous users (public access).",
slug: "anonymous",
permissions: []
},
{
name: "Group-A",
description: "A: Dolor odit et quia animi ipsum nostrum nesciunt.",
slug: "group-a",
permissions: [
{
name: "security.*"
}
]
},
{
name: "Group-B",
description: "B: Dolor odit et quia animi ipsum nostrum nesciunt.",
slug: "group-b",
permissions: [
{
name: "security.*"
}
]
}
]
});

// Let's update the "groupB" name
const updatedName = "Group B - updated";
Expand Down Expand Up @@ -131,4 +195,49 @@ describe("Security Group CRUD Test", () => {
}
});
});

test("should not allow update of a group created via a plugin", async () => {
// Creating a group with same "slug" should not be allowed
const [response] = await securityGroup.update({
id: "test-role-1",
data: {
name: "Test Role 1 - updated"
}
});

expect(response).toEqual({
data: {
security: {
updateGroup: {
data: null,
error: {
code: "CANNOT_UPDATE_PLUGIN_GROUPS",
data: null,
message: "Cannot update groups created via plugins."
}
}
}
}
});
});

test("should not allow deletion of a group created via a plugin", async () => {
// Creating a group with same "slug" should not be allowed
const [response] = await securityGroup.delete({ id: "" });

expect(response).toEqual({
data: {
security: {
deleteGroup: {
data: null,
error: {
code: "CANNOT_DELETE_PLUGIN_GROUPS",
data: null,
message: "Cannot delete groups created via plugins."
}
}
}
}
});
});
});
16 changes: 16 additions & 0 deletions packages/api-security/__tests__/mocks/securityTeam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const mocks = {
teamA: {
name: "Team-A",
slug: "team-a",
description: "A: Dolor odit et quia animi ipsum nostrum nesciunt.",
groups: []
},
teamB: {
name: "Team-B",
slug: "team-b",
description: "B: Dolor odit et quia animi ipsum nostrum nesciunt.",
groups: []
}
};

export default mocks;
Loading

0 comments on commit 80f00cb

Please sign in to comment.