mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix request namespace list permissions check if a list rule is not the first match (#7282)
* fix requestNamespaceListPermissionsForInjectable Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * more tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test descriptions Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fake -> stub Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fake-namespace -> irrelevant-namespace Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> --------- Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
33f573e405
commit
67896437f0
@ -47,9 +47,9 @@ const requestNamespaceListPermissionsForInjectable = getInjectable({
|
|||||||
const { resourceRules } = status;
|
const { resourceRules } = status;
|
||||||
|
|
||||||
return (resource) => {
|
return (resource) => {
|
||||||
const resourceRule = resourceRules.find(({
|
const rules = resourceRules.filter(({
|
||||||
apiGroups = [],
|
apiGroups = ["*"],
|
||||||
resources = [],
|
resources = ["*"],
|
||||||
}) => {
|
}) => {
|
||||||
const isAboutRelevantApiGroup = apiGroups.includes("*") || apiGroups.includes(resource.group);
|
const isAboutRelevantApiGroup = apiGroups.includes("*") || apiGroups.includes(resource.group);
|
||||||
const isAboutResource = resources.includes("*") || resources.includes(resource.apiName);
|
const isAboutResource = resources.includes("*") || resources.includes(resource.apiName);
|
||||||
@ -57,13 +57,7 @@ const requestNamespaceListPermissionsForInjectable = getInjectable({
|
|||||||
return isAboutRelevantApiGroup && isAboutResource;
|
return isAboutRelevantApiGroup && isAboutResource;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!resourceRule) {
|
return rules.some(({ verbs }) => verbs.includes("*") || verbs.includes("list"));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { verbs } = resourceRule;
|
|
||||||
|
|
||||||
return verbs.includes("*") || verbs.includes("list");
|
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review`, { namespace, error });
|
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review`, { namespace, error });
|
||||||
|
|||||||
@ -0,0 +1,336 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { V1SubjectRulesReviewStatus } from "@kubernetes/client-node";
|
||||||
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
||||||
|
import type { RequestNamespaceListPermissionsFor } from "./request-namespace-list-permissions.injectable";
|
||||||
|
import requestNamespaceListPermissionsForInjectable from "./request-namespace-list-permissions.injectable";
|
||||||
|
|
||||||
|
const createStubProxyConfig = (statusResponse: Promise<{ body: { status: V1SubjectRulesReviewStatus }}>) => ({
|
||||||
|
makeApiClient: () => ({
|
||||||
|
createSelfSubjectRulesReview: (): Promise<{ body: { status: V1SubjectRulesReviewStatus }}> => statusResponse,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("requestNamespaceListPermissions", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let requestNamespaceListPermissions: RequestNamespaceListPermissionsFor;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
requestNamespaceListPermissions = di.inject(requestNamespaceListPermissionsForInjectable);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when api returns incomplete data", () => {
|
||||||
|
it("returns truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: true,
|
||||||
|
resourceRules: [],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when api rejects", () => {
|
||||||
|
it("returns truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve, reject) => reject("unknown error")),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when first resourceRule has all permissions for everything", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["*"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when first resourceRule has list permissions for everything", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["list"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when first resourceRule has list permissions for asked resource", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: [""],
|
||||||
|
resources: ["pods"],
|
||||||
|
verbs: ["list"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when last resourceRule has all permissions for everything", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["*"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when last resourceRule has list permissions for everything", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["list"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when last resourceRule has list permissions for asked resource", () => {
|
||||||
|
it("return truthy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: ["*"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiGroups: [""],
|
||||||
|
resources: ["pods"],
|
||||||
|
verbs: ["list"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when resourceRules has matching resource without list verb", () => {
|
||||||
|
it("return falsy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: [""],
|
||||||
|
resources: ["pods"],
|
||||||
|
verbs: ["get"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when resourceRules has no matching resource with list verb", () => {
|
||||||
|
it("return falsy function", async () => {
|
||||||
|
const requestPermissions = requestNamespaceListPermissions(createStubProxyConfig(
|
||||||
|
new Promise((resolve) => resolve({
|
||||||
|
body: {
|
||||||
|
status: {
|
||||||
|
incomplete: false,
|
||||||
|
resourceRules: [
|
||||||
|
{
|
||||||
|
apiGroups: [""],
|
||||||
|
resources: ["services"],
|
||||||
|
verbs: ["list"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nonResourceRules: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) as any);
|
||||||
|
|
||||||
|
const permissionCheck = await requestPermissions("irrelevant-namespace");
|
||||||
|
|
||||||
|
expect(permissionCheck({
|
||||||
|
apiName: "pods",
|
||||||
|
group: "",
|
||||||
|
kind: "Pod",
|
||||||
|
namespaced: true,
|
||||||
|
})).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user