Skip to content

Commit

Permalink
Merge pull request #111 from YotaYota/lint.add_tests_to_permissions_c…
Browse files Browse the repository at this point in the history
…heck

Refactor permissionsCheck and test
  • Loading branch information
indy-independence committed Jun 12, 2024
2 parents 971c9bd + 8ce4967 commit 82b98f6
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 32 deletions.
67 changes: 35 additions & 32 deletions public/utils/permissions/permissionsCheck.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
import { getData } from "../getData";

const findPermission = (permissions, page, right) => {
const findPermission = (userPermissions, targetPage, requiredRight) => {
// check per permission if the page and rights request are in there
for (const permission of permissions) {

// eslint-disable-next-line no-restricted-syntax
for (const permission of userPermissions) {
const { pages } = permission;
const { rights } = permission;
if (!rights || !pages || rights.length == 0 || pages.length == 0) {
continue;
}
if (!rights.includes("*") && !rights.includes(right)) {
continue;
}
if (pages.includes("*") || pages.includes(page)) {
if (
(pages?.includes("*") || pages?.includes(targetPage)) &&
(rights?.includes("*") || rights?.includes(requiredRight))
) {
return true;
}
}

return false;
};

const permissionsCheck = (page, right) => {
if (process.env.PERMISSIONS_DISABLED === "true") {
return true;
}
// get the permissions
const permissions = JSON.parse(localStorage.getItem("permissions"));
// check if filled. Else request the permissions
if (!permissions) {
const token = localStorage.getItem("token");
if (token || token.length != 0) {
getData(`${process.env.API_URL}/api/v1.0/auth/permissions`, token)
.then((data) => {
localStorage.setItem("permissions", JSON.stringify(data));
if (!data || data.length == 0) {
return findPermission(data, page, right);
}
return false;
})
.catch((error) => {
console.log(error);
return false;
});
} else {
return false;
}
} else {
return findPermission(permissions, page, right);

// check permissions in local storage
const permissions = localStorage.getItem("permissions");
if (permissions) {
return findPermission(JSON.parse(permissions), page, right);
}

// else check and set permissions via token
const token = localStorage.getItem("token");
if (!token) {
return false;
}
getData(`${process.env.API_URL}/api/v1.0/auth/permissions`, token)
.then((data) => {
if (!data) {
return false;
}
localStorage.setItem("permissions", JSON.stringify(data));
return findPermission(data, page, right);
})
.catch((error) => {
console.log(error);
return false;
});

return false;
};

export default permissionsCheck;
116 changes: 116 additions & 0 deletions public/utils/permissions/permissionsCheck.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import permissionsCheck from "./permissionsCheck";

import { getData as mockGetData } from "../getData";

jest.mock("../../utils/getData");

mockGetData.mockResolvedValue({ data: { devices: [], inferfaces: [] } });
const mockStorageSetItem = jest.fn();
const mockPermissions = JSON.stringify([
{
methods: ["GET"],
endpoints: ["/devices", "/device/*", "/repository/**", "/groups"],
pages: ["Devices", "Dashboard", "Groups"],
rights: ["read"],
},
{
methods: ["*"],
endpoints: ["*"],
pages: ["AsterixPage"],
rights: ["*"],
},
{
methods: ["*"],
endpoints: ["*"],
pages: ["Dashboard", "Groups", "Firmware", "Config change"],
rights: ["read", "write"],
},
{
pages: ["Overlapping"],
rights: ["read"],
},
{
pages: ["Overlapping"],
rights: ["write"],
},
]);

let PERMISSIONS_DISABLED;

beforeAll(() => {
PERMISSIONS_DISABLED = process.env.PERMISSIONS_DISABLED;
process.env.PERMISSIONS_DISABLED = false;
jest.spyOn(Storage.prototype, "getItem").mockReturnValue(mockPermissions);
Storage.prototype.setItem = mockStorageSetItem;
});

afterAll(() => {
global.Storage.prototype.getItem.mockReset();
global.Storage.prototype.setItem.mockReset();
process.env.PERMISSIONS_DISABLED = PERMISSIONS_DISABLED;
});

beforeEach(() => {
mockGetData.mockClear();
mockStorageSetItem.mockClear();
});

describe("no permission in storage", () => {
test("should return false if no permissions nor token", async () => {
jest.spyOn(Storage.prototype, "getItem").mockReturnValueOnce(""); // empty permissions
jest.spyOn(Storage.prototype, "getItem").mockReturnValueOnce(""); // token

const permission = await permissionsCheck("page", "{}");

expect(permission).toBe(false);
});

test("should call auth/permissions and set permissions if not in local storage", async () => {
jest.spyOn(Storage.prototype, "getItem").mockReturnValueOnce(""); // empty permissions
jest.spyOn(Storage.prototype, "getItem").mockReturnValueOnce("mockToken"); // token

await permissionsCheck("page", "{}");

expect(mockGetData).toHaveBeenCalledWith(
`${process.env.API_URL}/api/v1.0/auth/permissions`,
"mockToken",
);
expect(localStorage.setItem).toHaveBeenCalledWith(
"permissions",
expect.anything(),
);
});
});

test("should return true", () => {
const targetPage = "Groups";
const requiredPermission = "read";
const result = permissionsCheck(targetPage, requiredPermission);

expect(result).toBe(true);
});

test("should return false", () => {
const targetPage = "Devices";
const requiredPermission = "write";
const result = permissionsCheck(targetPage, requiredPermission);

expect(result).toBe(false);
});

test("asterix should give both read and write access", () => {
const targetPage = "AsterixPage";
const resultForRead = permissionsCheck(targetPage, "read");
const resultForWrite = permissionsCheck(targetPage, "write");

expect(resultForRead).toBe(true);
expect(resultForWrite).toBe(true);
});

test("overlapping permissions picks the most allowing", () => {
const targetPage = "Overlapping";
const requiredPermission = "write";
const result = permissionsCheck(targetPage, requiredPermission);

expect(result).toBe(true);
});

0 comments on commit 82b98f6

Please sign in to comment.