Require at least one item in allOf/anyOf criteria

Signed-off-by: Joe Porpeglia <josephp@spotify.com>
This commit is contained in:
Joe Porpeglia
2022-02-03 18:58:24 -05:00
committed by Joe Porpeglia
parent de103e5fc1
commit e66bb84798
8 changed files with 66 additions and 18 deletions
@@ -25,17 +25,31 @@ import {
isOrCriteria,
} from './util';
const nonEmpty = <T>(list: T[]): [T, ...T[]] => {
if (list.length === 0) {
throw new Error(
'Invalid conditions provided. Expected at least one item for `allOf`/`anyOf` criteria but received none.',
);
}
return list as [T, ...T[]];
};
const mapConditions = <TQuery>(
criteria: PermissionCriteria<PermissionCondition>,
getRule: (name: string) => PermissionRule<unknown, TQuery>,
): PermissionCriteria<TQuery> => {
if (isAndCriteria(criteria)) {
return {
allOf: criteria.allOf.map(child => mapConditions(child, getRule)),
allOf: nonEmpty(
criteria.allOf.map(child => mapConditions(child, getRule)),
),
};
} else if (isOrCriteria(criteria)) {
return {
anyOf: criteria.anyOf.map(child => mapConditions(child, getRule)),
anyOf: nonEmpty(
criteria.anyOf.map(child => mapConditions(child, getRule)),
),
};
} else if (isNotCriteria(criteria)) {
return {
@@ -247,7 +247,8 @@ describe('createPermissionIntegrationRouter', () => {
resourceRef: 'default:test/resource-1',
resourceType: 'test-incorrect-resource-1',
conditions: {
anyOf: [],
rule: 'test-rule-1',
params: [{}],
},
},
{
@@ -255,7 +256,8 @@ describe('createPermissionIntegrationRouter', () => {
resourceRef: 'default:test/resource-2',
resourceType: 'test-resource',
conditions: {
anyOf: [],
rule: 'test-rule-1',
params: [{}],
},
},
{
@@ -263,7 +265,8 @@ describe('createPermissionIntegrationRouter', () => {
resourceRef: 'default:test/resource-3',
resourceType: 'test-incorrect-resource-2',
conditions: {
anyOf: [],
rule: 'test-rule-1',
params: [{}],
},
},
],
@@ -38,8 +38,8 @@ const permissionCriteriaSchema: z.ZodSchema<
PermissionCriteria<PermissionCondition>
> = z.lazy(() =>
z.union([
z.object({ anyOf: z.array(permissionCriteriaSchema) }),
z.object({ allOf: z.array(permissionCriteriaSchema) }),
z.object({ anyOf: z.array(permissionCriteriaSchema).nonempty() }),
z.object({ allOf: z.array(permissionCriteriaSchema).nonempty() }),
z.object({ not: permissionCriteriaSchema }),
z.object({
rule: z.string(),
@@ -14,22 +14,27 @@
* limitations under the License.
*/
import { PermissionCriteria } from '@backstage/plugin-permission-common';
import {
AllOfCriteria,
AnyOfCriteria,
NotCriteria,
PermissionCriteria,
} from '@backstage/plugin-permission-common';
import { PermissionRule } from '../types';
export const isAndCriteria = (
filter: PermissionCriteria<unknown>,
): filter is { allOf: PermissionCriteria<unknown>[] } =>
): filter is AllOfCriteria<unknown> =>
Object.prototype.hasOwnProperty.call(filter, 'allOf');
export const isOrCriteria = (
filter: PermissionCriteria<unknown>,
): filter is { anyOf: PermissionCriteria<unknown>[] } =>
): filter is AnyOfCriteria<unknown> =>
Object.prototype.hasOwnProperty.call(filter, 'anyOf');
export const isNotCriteria = (
filter: PermissionCriteria<unknown>,
): filter is { not: PermissionCriteria<unknown> } =>
): filter is NotCriteria<unknown> =>
Object.prototype.hasOwnProperty.call(filter, 'not');
export const createGetRule = <TResource, TQuery>(