Skip to content

Commit

Permalink
fix: ignore FLPs when identity type is other than admin
Browse files Browse the repository at this point in the history
  • Loading branch information
adrians5j committed Apr 11, 2024
1 parent e3882ad commit 23735d9
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
135 changes: 135 additions & 0 deletions packages/api-aco/__tests__/flp.apiTokens.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useGraphQlHandler } from "./utils/useGraphQlHandler";
import { SecurityIdentity } from "@webiny/api-security/types";

const identityA: SecurityIdentity = { id: "1", type: "admin", displayName: "A" };
const identityB: SecurityIdentity = { id: "2", type: "admin", displayName: "B" };
const identityApiToken: SecurityIdentity = { id: "3", type: "api-token", displayName: "API Token" };

describe("Folder Level Permissions - API Tokens", () => {
it("as a user with 'viewer' access to a folder, I should not be able to create, update, or delete content in it", async () => {
const gqlIdentityA = useGraphQlHandler({ identity: identityA });

const gqlIdentityApiToken = useGraphQlHandler({
identity: identityApiToken,
permissions: [{ name: "cms.*" }]
});

const modelGroup = await gqlIdentityA.cms.createTestModelGroup();
const model = await gqlIdentityA.cms.createBasicModel({ modelGroup: modelGroup.id });

const folder = await gqlIdentityA.aco
.createFolder({
data: {
title: "Folder A",
slug: "folder-a",
type: `cms:${model.modelId}`
}
})
.then(([response]) => {
return response.data.aco.createFolder.data;
});

const createdEntry = await gqlIdentityA.cms
.createEntry(model, {
data: {
title: `Test entry`,
wbyAco_location: {
folderId: folder.id
}
}
})
.then(([response]) => {
return response.data.createBasicTestModel.data;
});

// Set identity B as viewer of the folder. We need this just so FLP kicks in.
// Otherwise, anybody can access content in the folder, no FLPs are applied.
await gqlIdentityA.aco.updateFolder({
id: folder.id,
data: {
permissions: [
{
target: `admin:${identityB.id}`,
level: "viewer"
}
]
}
});

// Getting content in the folder should be allowed for API key.
await expect(
gqlIdentityApiToken.cms
.getEntry(model, { revision: createdEntry.id })
.then(([response]) => {
return response.data.getBasicTestModel;
})
).resolves.toMatchObject({
data: { id: createdEntry.id },
error: null
});

// Listing content in the folder should be now allowed for identity C.
await expect(
gqlIdentityApiToken.cms
.listEntries(model, {
where: {
wbyAco_location: {
folderId: folder.id
}
}
})
.then(([response]) => {
return response.data.listBasicTestModels;
})
).resolves.toMatchObject({
data: [{ id: createdEntry.id }],
error: null,
meta: {
cursor: null,
hasMoreItems: false,
totalCount: 1
}
});

// Creating content in the folder should be forbidden for identity C.
await expect(
gqlIdentityApiToken.cms
.createEntry(model, {
data: {
title: `Test-5`,
wbyAco_location: {
folderId: folder.id
}
}
})
.then(([response]) => {
return response.data.createBasicTestModel;
})
).resolves.toMatchObject({
data: { id: expect.any(String) }
});

// Updating content in the folder should be forbidden for identity C.
await expect(
gqlIdentityApiToken.cms
.updateEntry(model, {
revision: createdEntry.id,
data: { title: createdEntry.title + "-update" }
})
.then(([response]) => {
return response.data.updateBasicTestModel;
})
).resolves.toMatchObject({
data: { title: createdEntry.title + "-update" }
});

// Deleting a file in the folder should be now allowed for identity C.
await expect(
gqlIdentityApiToken.cms
.deleteEntry(model, { revision: createdEntry.entryId })
.then(([response]) => {
return response.data.deleteBasicTestModel;
})
).resolves.toMatchObject({ data: true, error: null });
});
});
12 changes: 11 additions & 1 deletion packages/api-aco/src/utils/FolderLevelPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,17 @@ export class FolderLevelPermissions {
this.listPermissions = params.listPermissions;
this.listAllFoldersCallback = params.listAllFolders;
this.canUseTeams = params.canUseTeams;
this.canUseFolderLevelPermissions = params.canUseFolderLevelPermissions;
this.canUseFolderLevelPermissions = () => {
// At the moment, we only want FLP to be used with identities of type "admin".
// This temporarily addresses the issue of API keys not being able to access content, because
// FLPs doesn't work tih them. Once we start adding FLPs to API keys, we can remove this check.
const identity = this.getIdentity();
if (identity.type !== "admin") {
return false;
}

return params.canUseFolderLevelPermissions();
};

this.isAuthorizationEnabled = params.isAuthorizationEnabled;
}
Expand Down

0 comments on commit 23735d9

Please sign in to comment.