feat(rbac): implemented granular blocking of actions based on permissions on org level ui

This commit is contained in:
Akhil Mohan
2023-09-08 21:21:43 +05:30
parent 34fb7be1c4
commit aac3168c80
41 changed files with 1992 additions and 1652 deletions
@@ -38,10 +38,9 @@ export const BillingPermission = ({ isNonEditable, setValue, control }: Props) =
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -52,11 +51,14 @@ export const BillingPermission = ({ isNonEditable, setValue, control }: Props) =
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
val === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setValue(
@@ -38,10 +38,9 @@ export const IncidentContactPermission = ({ isNonEditable, setValue, control }:
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -52,14 +51,16 @@ export const IncidentContactPermission = ({ isNonEditable, setValue, control }:
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
val === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setIsCustom.off();
setValue(
"permissions.incident-contact",
{ read: false, edit: false, create: false, delete: false },
@@ -67,7 +68,6 @@ export const IncidentContactPermission = ({ isNonEditable, setValue, control }:
);
break;
case Permission.FullAccess:
setIsCustom.off();
setValue(
"permissions.incident-contact",
{ read: true, edit: true, create: true, delete: true },
@@ -75,7 +75,6 @@ export const IncidentContactPermission = ({ isNonEditable, setValue, control }:
);
break;
case Permission.ReadOnly:
setIsCustom.off();
setValue(
"permissions.incident-contact",
{ read: true, edit: false, create: false, delete: false },
@@ -83,7 +82,6 @@ export const IncidentContactPermission = ({ isNonEditable, setValue, control }:
);
break;
default:
setIsCustom.on();
setValue(
"permissions.incident-contact",
{ read: false, edit: false, create: false, delete: false },
@@ -31,31 +31,34 @@ const PERMISSIONS = [
] as const;
export const MemberPermission = ({ isNonEditable, setValue, control }: Props) => {
const memberRule = useWatch({
const rule = useWatch({
control,
name: "permissions.member"
});
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(memberRule || {}) as Array<keyof typeof memberRule>;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += memberRule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
if (score === totalActions) return Permission.FullAccess;
if (score === 1 && memberRule.read) return Permission.ReadOnly;
if (score === 1 && rule.read) return Permission.ReadOnly;
return Permission.Custom;
}, [memberRule, isCustom]);
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setValue(
@@ -31,34 +31,36 @@ const PERMISSIONS = [
] as const;
export const RolePermission = ({ isNonEditable, setValue, control }: Props) => {
const roleRule = useWatch({
const rule = useWatch({
control,
name: "permissions.role"
});
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(roleRule || {}) as Array<keyof typeof roleRule>;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += roleRule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
if (score === totalActions) return Permission.FullAccess;
if (score === 1 && roleRule.read) return Permission.ReadOnly;
if (score === 1 && rule.read) return Permission.ReadOnly;
return Permission.Custom;
}, [roleRule, isCustom]);
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setIsCustom.off();
setValue(
"permissions.role",
{ read: false, edit: false, create: false, delete: false },
@@ -66,7 +68,6 @@ export const RolePermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
case Permission.FullAccess:
setIsCustom.off();
setValue(
"permissions.role",
{ read: true, edit: true, create: true, delete: true },
@@ -74,7 +75,6 @@ export const RolePermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
case Permission.ReadOnly:
setIsCustom.off();
setValue(
"permissions.role",
{ read: true, edit: false, create: false, delete: false },
@@ -82,7 +82,6 @@ export const RolePermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
default:
setIsCustom.on();
setValue(
"permissions.role",
{ read: false, edit: false, create: false, delete: false },
@@ -38,10 +38,9 @@ export const SecretScannigPermission = ({ isNonEditable, setValue, control }: Pr
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -52,13 +51,16 @@ export const SecretScannigPermission = ({ isNonEditable, setValue, control }: Pr
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setIsCustom.off();
setValue(
"permissions.secret-scanning",
{ read: false, edit: false, create: false, delete: false },
@@ -66,7 +68,6 @@ export const SecretScannigPermission = ({ isNonEditable, setValue, control }: Pr
);
break;
case Permission.FullAccess:
setIsCustom.off();
setValue(
"permissions.secret-scanning",
{ read: true, edit: true, create: true, delete: true },
@@ -74,7 +75,6 @@ export const SecretScannigPermission = ({ isNonEditable, setValue, control }: Pr
);
break;
case Permission.ReadOnly:
setIsCustom.off();
setValue(
"permissions.secret-scanning",
{ read: true, edit: false, create: false, delete: false },
@@ -82,7 +82,6 @@ export const SecretScannigPermission = ({ isNonEditable, setValue, control }: Pr
);
break;
default:
setIsCustom.on();
setValue(
"permissions.secret-scanning",
{ read: false, edit: false, create: false, delete: false },
@@ -38,10 +38,9 @@ export const SettingsPermission = ({ isNonEditable, setValue, control }: Props)
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -52,13 +51,16 @@ export const SettingsPermission = ({ isNonEditable, setValue, control }: Props)
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setIsCustom.off();
setValue(
"permissions.settings",
{ read: false, edit: false, create: false, delete: false },
@@ -66,7 +68,6 @@ export const SettingsPermission = ({ isNonEditable, setValue, control }: Props)
);
break;
case Permission.FullAccess:
setIsCustom.off();
setValue(
"permissions.settings",
{ read: true, edit: true, create: true, delete: true },
@@ -74,7 +75,6 @@ export const SettingsPermission = ({ isNonEditable, setValue, control }: Props)
);
break;
case Permission.ReadOnly:
setIsCustom.off();
setValue(
"permissions.settings",
{ read: true, edit: false, create: false, delete: false },
@@ -82,7 +82,6 @@ export const SettingsPermission = ({ isNonEditable, setValue, control }: Props)
);
break;
default:
setIsCustom.on();
setValue(
"permissions.settings",
{ read: false, edit: false, create: false, delete: false },
@@ -38,10 +38,9 @@ export const SsoPermission = ({ isNonEditable, setValue, control }: Props) => {
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -52,13 +51,16 @@ export const SsoPermission = ({ isNonEditable, setValue, control }: Props) => {
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setIsCustom.off();
setValue(
"permissions.sso",
{ read: false, edit: false, create: false, delete: false },
@@ -66,7 +68,6 @@ export const SsoPermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
case Permission.FullAccess:
setIsCustom.off();
setValue(
"permissions.sso",
{ read: true, edit: true, create: true, delete: true },
@@ -74,7 +75,6 @@ export const SsoPermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
case Permission.ReadOnly:
setIsCustom.off();
setValue(
"permissions.sso",
{ read: true, edit: false, create: false, delete: false },
@@ -82,7 +82,6 @@ export const SsoPermission = ({ isNonEditable, setValue, control }: Props) => {
);
break;
default:
setIsCustom.on();
setValue(
"permissions.sso",
{ read: false, edit: false, create: false, delete: false },
@@ -36,10 +36,9 @@ export const WorkspacePermission = ({ isNonEditable, setValue, control }: Props)
const [isCustom, setIsCustom] = useToggle();
const selectedPermissionCategory = useMemo(() => {
let score = 0;
const actions = Object.keys(rule || {}) as Array<keyof typeof rule>;
const totalActions = PERMISSIONS.length;
actions.forEach((key) => (score += rule[key] ? 1 : 0));
const score = actions.map((key) => (rule[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number);
if (isCustom) return Permission.Custom;
if (score === 0) return Permission.NoAccess;
@@ -50,11 +49,14 @@ export const WorkspacePermission = ({ isNonEditable, setValue, control }: Props)
}, [rule, isCustom]);
useEffect(() => {
selectedPermissionCategory === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (selectedPermissionCategory === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
}, [selectedPermissionCategory]);
const handlePermissionChange = (val: Permission) => {
val === Permission.Custom ? setIsCustom.on() : setIsCustom.off();
if (val === Permission.Custom) setIsCustom.on();
else setIsCustom.off();
switch (val) {
case Permission.NoAccess:
setValue("permissions.workspace", { read: false, create: false }, { shouldDirty: true });