diff --git a/dashboard/src/stores/__tests__/auth.test.ts b/dashboard/src/stores/__tests__/auth.test.ts index 1ca4674e..27a03b7b 100644 --- a/dashboard/src/stores/__tests__/auth.test.ts +++ b/dashboard/src/stores/__tests__/auth.test.ts @@ -262,15 +262,45 @@ describe("useAuthStore", () => { }, }, }, + { + title: "invalid roles mapping", + stubEnv: { + VITE_OIDC_ABAC_ROLES_MAPPING: '{"admin": ["*"}', + }, + error: + "Error parsing OIDC ABAC roles mapping: SyntaxError: Expected ',' or ']' after array element in JSON at position 14 (line 1 column 15)", + }, + { + title: "not array roles mapping", + stubEnv: { + VITE_OIDC_ABAC_ROLES_MAPPING: '{"admin": ["*"], "other": "not array"}', + }, + error: + "Error parsing OIDC ABAC roles mapping: unexpected JSON format, each role key must be an array of string attributes", + }, + { + title: "not strings roles mapping", + stubEnv: { + VITE_OIDC_ABAC_ROLES_MAPPING: '{"admin": ["string", 1]}', + }, + error: + "Error parsing OIDC ABAC roles mapping: unexpected JSON format, each role key must be an array of string attributes", + }, ])("loads the configuration from the environment ($title)", (test) => { if (test.stubEnv) { Object.entries(test.stubEnv).forEach(([key, value]) => vi.stubEnv(key, value), ); } + const authStore = useAuthStore(); - authStore.loadConfig(); - expect(authStore.config).toEqual(test.expected); + if (test.error) { + assert.throws(authStore.loadConfig, test.error); + } else { + authStore.loadConfig(); + expect(authStore.config).toEqual(test.expected); + } + vi.unstubAllEnvs(); }); diff --git a/dashboard/src/stores/auth.ts b/dashboard/src/stores/auth.ts index cd469c6e..d2fc6152 100644 --- a/dashboard/src/stores/auth.ts +++ b/dashboard/src/stores/auth.ts @@ -22,6 +22,17 @@ type ABACConfig = { rolesMapping: Record; }; +function isRolesMapping(obj: any): obj is Record { + for (const key in obj) { + if ( + !Array.isArray(obj[key]) || + !obj[key].every((item) => typeof item === "string") + ) + return false; + } + return true; +} + export const useAuthStore = defineStore("auth", { state: () => ({ config: {} as OIDCConfig, @@ -142,11 +153,15 @@ export const useAuthStore = defineStore("auth", { } if (this.config.abac.useRoles && env.VITE_OIDC_ABAC_ROLES_MAPPING) { try { - this.config.abac.rolesMapping = JSON.parse( - env.VITE_OIDC_ABAC_ROLES_MAPPING.trim(), - ); + const map = JSON.parse(env.VITE_OIDC_ABAC_ROLES_MAPPING.trim()); + if (!isRolesMapping(map)) { + throw new Error( + "Error parsing OIDC ABAC roles mapping: unexpected JSON format, each role key must be an array of string attributes", + ); + } + this.config.abac.rolesMapping = map; } catch (err) { - throw new Error(`Error parsing roles mapping: ${err}`); + throw new Error(`Error parsing OIDC ABAC roles mapping: ${err}`); } } },