Preserve minimal app permissions/validations when merging (#20347)

* preserve app minimal permissions when merging

* update test

* add changeset
This commit is contained in:
Azri Kahar
2023-11-09 01:06:19 +08:00
committed by GitHub
parent 0a8e7b7d2e
commit 1b01f2c4b4
3 changed files with 32 additions and 21 deletions

View File

@@ -0,0 +1,5 @@
---
'@directus/api': patch
---
Preserved minimal app permissions/validations when merging

View File

@@ -76,24 +76,34 @@ describe('merging permissions', () => {
});
});
test('{} supersedes conditional permissions in _or', () => {
test('{} is removed from conditional permissions in _or', () => {
const mergedPermission = mergePermission(
'or',
{ ...permissionTemplate, permissions: fullFilter },
{ ...permissionTemplate, permissions: conditionalFilter }
);
expect(mergedPermission).toStrictEqual({ ...permissionTemplate, permissions: fullFilter });
expect(mergedPermission).toStrictEqual({
...permissionTemplate,
permissions: {
_or: [conditionalFilter],
},
});
});
test('{} supersedes conditional validations in _or', () => {
test('{} is removed from conditional validations in _or', () => {
const mergedPermission = mergePermission(
'or',
{ ...permissionTemplate, validation: fullFilter },
{ ...permissionTemplate, validation: conditionalFilter }
);
expect(mergedPermission).toStrictEqual({ ...permissionTemplate, validation: fullFilter });
expect(mergedPermission).toStrictEqual({
...permissionTemplate,
validation: {
_or: [conditionalFilter],
},
});
});
test('{} does not supersede conditional permissions in _and', () => {

View File

@@ -1,5 +1,5 @@
import type { LogicalFilterAND, LogicalFilterOR, Permission } from '@directus/types';
import { flatten, intersection, isEqual, merge, omit } from 'lodash-es';
import { flatten, intersection, isEmpty, merge, omit } from 'lodash-es';
export function mergePermissions(strategy: 'and' | 'or', ...permissions: Permission[][]): Permission[] {
const allPermissions = flatten(permissions);
@@ -37,14 +37,12 @@ export function mergePermission(
],
} as LogicalFilterAND | LogicalFilterOR;
} else if (currentPerm.permissions) {
// Empty {} supersedes other permissions in _OR merge
if (strategy === 'or' && (isEqual(currentPerm.permissions, {}) || isEqual(newPerm.permissions, {}))) {
permissions = {};
} else {
permissions = {
[logicalKey]: [currentPerm.permissions, newPerm.permissions],
} as LogicalFilterAND | LogicalFilterOR;
}
permissions = {
[logicalKey]:
strategy === 'or'
? [currentPerm.permissions, newPerm.permissions].filter((p) => !isEmpty(p))
: [currentPerm.permissions, newPerm.permissions],
} as LogicalFilterAND | LogicalFilterOR;
} else {
permissions = {
[logicalKey]: [newPerm.permissions],
@@ -61,14 +59,12 @@ export function mergePermission(
],
} as LogicalFilterAND | LogicalFilterOR;
} else if (currentPerm.validation) {
// Empty {} supersedes other validations in _OR merge
if (strategy === 'or' && (isEqual(currentPerm.validation, {}) || isEqual(newPerm.validation, {}))) {
validation = {};
} else {
validation = {
[logicalKey]: [currentPerm.validation, newPerm.validation],
} as LogicalFilterAND | LogicalFilterOR;
}
validation = {
[logicalKey]:
strategy === 'or'
? [currentPerm.validation, newPerm.validation].filter((p) => !isEmpty(p))
: [currentPerm.validation, newPerm.validation],
} as LogicalFilterAND | LogicalFilterOR;
} else {
validation = {
[logicalKey]: [newPerm.validation],