From 50b43e1379e7b5d7120e7064bd5940f46f9f0b9f Mon Sep 17 00:00:00 2001 From: Arnei Date: Mon, 10 Aug 2026 17:08:01 +0200 Subject: [PATCH] Type acl default config keys We know which keys we can receive from the backend, so we might as well properly type them. Should make our code simpler to read. --- .../modals/ResourceDetailsAccessPolicyTab.tsx | 32 +++++----------- src/selectors/aclSelectors.ts | 2 +- src/slices/aclSlice.ts | 38 +++++++++++++++++-- src/utils/aclUtils.ts | 9 ++--- 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx index b45978c763..4d2ba8cfab 100644 --- a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx +++ b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx @@ -454,19 +454,9 @@ export const AccessPolicyTable = ({ // If config exists, set defaults according to config if (aclDefaults) { - if (aclDefaults["read_enabled"] && aclDefaults["read_enabled"] === "true") { - newRole.read = true; - } else if (aclDefaults["read_enabled"] && aclDefaults["read_enabled"] === "false") { - newRole.read = false; - } - if (aclDefaults["write_enabled"] && aclDefaults["write_enabled"] === "true") { - newRole.write = true; - } else if (aclDefaults["write_enabled"] && aclDefaults["write_enabled"] === "false") { - newRole.write = false; - } - if (aclDefaults["default_actions"]) { - newRole.actions = newRole.actions.concat(aclDefaults["default_actions"].split(",")); - } + newRole.read = aclDefaults["read_enabled"]; + newRole.write = aclDefaults["write_enabled"]; + newRole.actions = newRole.actions.concat(aclDefaults["default_actions"]); } return newRole; @@ -474,12 +464,10 @@ export const AccessPolicyTable = ({ // Filter available options by custom prefixes from the config if (aclDefaults) { - if (aclDefaults["display_role_filter_blacklist_prefixes"]) { - const prefixes = aclDefaults["display_role_filter_blacklist_prefixes"].split(","); - rolesFilteredbyPolicies = rolesFilteredbyPolicies.filter(role => - !prefixes.some(prefix => role.name.startsWith(prefix)), - ); - } + const prefixes = aclDefaults["display_role_filter_blacklist_prefixes"]; + rolesFilteredbyPolicies = rolesFilteredbyPolicies.filter(role => + !prefixes.some(prefix => role.name.startsWith(prefix)), + ); } return ( @@ -596,7 +584,7 @@ export const AccessPolicyTable = ({ editAccessRole, user, ) || - (aclDefaults && aclDefaults["read_readonly"] !== "false") + (aclDefaults && aclDefaults["read_readonly"] !== false) } className={`${ transactions.readOnly @@ -621,9 +609,7 @@ export const AccessPolicyTable = ({ editAccessRole, user, ) || - (aclDefaults - && aclDefaults["write_readonly"] - && aclDefaults["write_readonly"] === "true") + (aclDefaults && aclDefaults["write_readonly"] === true) } className={`${ transactions.readOnly diff --git a/src/selectors/aclSelectors.ts b/src/selectors/aclSelectors.ts index a459acf412..4407655b9c 100644 --- a/src/selectors/aclSelectors.ts +++ b/src/selectors/aclSelectors.ts @@ -9,6 +9,6 @@ export const getTotalAcls = (state: RootState) => state.acls.total; export const getAclDefaults = (state: RootState) => state.acls.aclDefaults; export const getAclDefaultActions = createSelector( [getAclDefaults], - aclDefaults => aclDefaults["default_actions"] ? aclDefaults["default_actions"].split(",") : [], // derived value + aclDefaults => aclDefaults ? aclDefaults["default_actions"] : [], ); export const getAclDefaultTemplate = (state: RootState) => state.acls.aclDefaultTemplate; diff --git a/src/slices/aclSlice.ts b/src/slices/aclSlice.ts index 01f6e13052..f3844a7ee2 100644 --- a/src/slices/aclSlice.ts +++ b/src/slices/aclSlice.ts @@ -60,6 +60,17 @@ export type AclTemplate = { organizationId: string, } +export type AclDefaults = { + "read_enabled": boolean, + "write_enabled": boolean, + "read_readonly": boolean, + "write_readonly": boolean, + "default_actions": string[], + "keep_on_template_switch_role_prefixes": string[], + "display_role_filter_blacklist_prefixes": string[], + // [key: string]: string +} + type AclsState = { status: "uninitialized" | "loading" | "succeeded" | "failed", error: SerializedError | null, @@ -69,7 +80,7 @@ type AclsState = { count: number, offset: number, limit: number, - aclDefaults: { [key: string]: string }, + aclDefaults?: AclDefaults, aclDefaultTemplate?: AclTemplate, }; @@ -89,7 +100,7 @@ const initialState: AclsState = { count: 0, offset: 0, limit: 0, - aclDefaults: {}, + aclDefaults: undefined, }; export const fetchAcls = createAppAsyncThunk("acls/fetchAcls", async (_, { getState }) => { @@ -126,10 +137,29 @@ export const fetchAclActions = async () => { // fetch defaults for the access policy tab in the details views export const fetchAclDefaults = createAppAsyncThunk("acls/fetchAclDefaults", async (_, { getState }) => { const state = getState(); - const data = await axios.get<{ [key: string]: string }>("/admin-ng/resources/ACL.DEFAULTS.json"); + const data = await axios.get<{ + "read_enabled": string, + "write_enabled": string, + "read_readonly": string, + "write_readonly": string, + "default_actions": string, + "default_template": string, + "keep_on_template_switch_role_prefixes": string, + "display_role_filter_blacklist_prefixes": string + }>("/admin-ng/resources/ACL.DEFAULTS.json"); const response = data.data; + const aclDefaults: AclDefaults = { + "read_enabled": response.read_enabled === "true" ? true : false, + "write_enabled": response.write_enabled === "true" ? true : false, + "read_readonly": response.read_readonly === "true" ? true : false, + "write_readonly": response.write_readonly === "true" ? true : false, + "default_actions": response.default_actions ? response.default_actions.split(",") : [], + "keep_on_template_switch_role_prefixes": response.keep_on_template_switch_role_prefixes ? response.keep_on_template_switch_role_prefixes.split(",") : [], + "display_role_filter_blacklist_prefixes": response.display_role_filter_blacklist_prefixes ? response.display_role_filter_blacklist_prefixes.split(",") : [], + }; + let defaultTemplate = undefined; // If the a default template id is configured and we haven't fetched the default template // yet, do that now. @@ -156,7 +186,7 @@ export const fetchAclDefaults = createAppAsyncThunk("acls/fetchAclDefaults", asy defaultTemplate = template; } - return { aclDefaults: response, aclDefaultTemplate: defaultTemplate }; + return { aclDefaults: aclDefaults, aclDefaultTemplate: defaultTemplate }; }); // fetch all policies of an certain acl template diff --git a/src/utils/aclUtils.ts b/src/utils/aclUtils.ts index 9aab0406fe..5d8aefdb59 100644 --- a/src/utils/aclUtils.ts +++ b/src/utils/aclUtils.ts @@ -2,7 +2,7 @@ import { FormikProps } from "formik"; import { TransformedAcl } from "../slices/aclDetailsSlice"; -import { checkAcls, fetchAclTemplateById, Role } from "../slices/aclSlice"; +import { AclDefaults, checkAcls, fetchAclTemplateById, Role } from "../slices/aclSlice"; import { UserInfoState } from "../slices/userInfoSlice"; import { fetchUsersForTemplate } from "../slices/userSlice"; import { AppDispatch } from "../store"; @@ -53,7 +53,7 @@ export const handleTemplateChange = async , dispatch: AppDispatch, - aclDefaults: { [key: string]: string } | undefined, + aclDefaults?: AclDefaults, defaultUser?: UserInfoState, ) => { // fetch information about chosen template from backend @@ -80,7 +80,7 @@ export const handleTemplateChange = async policy.role.startsWith(prefix)) && !template.acl.find(acl => acl.role === policy.role)) { template.acl.push(policy);