mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 18:33:55 +00:00
fix(permissions): circular dependency (#18986)
* fix(permissions): circular dependency * Apply suggestions from code review Co-authored-by: Ben Irvin <ben@innerdvations.com> * Apply suggestions from code review Co-authored-by: Jean-Sébastien Herbaux <jean-sebastien.herbaux@epitech.eu> --------- Co-authored-by: Ben Irvin <ben@innerdvations.com> Co-authored-by: Jean-Sébastien Herbaux <jean-sebastien.herbaux@epitech.eu>
This commit is contained in:
parent
295178369f
commit
e85a23d937
@ -2,12 +2,11 @@ import * as sift from 'sift';
|
||||
import qs from 'qs';
|
||||
import { AbilityBuilder, Ability } from '@casl/ability';
|
||||
import { pick, isNil, isObject } from 'lodash/fp';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-extraneous-import
|
||||
import { Permissions as PermissionsTypes } from '@strapi/types';
|
||||
import type { ParametrizedAction, PermissionRule } from '../../types';
|
||||
|
||||
export interface CustomAbilityBuilder {
|
||||
can(permission: PermissionsTypes.PermissionRule): ReturnType<AbilityBuilder<Ability>['can']>;
|
||||
buildParametrizedAction: (parametrizedAction: PermissionsTypes.ParametrizedAction) => string;
|
||||
can(permission: PermissionRule): ReturnType<AbilityBuilder<Ability>['can']>;
|
||||
buildParametrizedAction: (parametrizedAction: ParametrizedAction) => string;
|
||||
build(): Ability;
|
||||
}
|
||||
|
||||
@ -32,7 +31,7 @@ const conditionsMatcher = (conditions: unknown) => {
|
||||
return sift.createQueryTester(conditions, { operations });
|
||||
};
|
||||
|
||||
const buildParametrizedAction = ({ name, params }: PermissionsTypes.ParametrizedAction) => {
|
||||
const buildParametrizedAction = ({ name, params }: ParametrizedAction) => {
|
||||
return `${name}?${qs.stringify(params)}`;
|
||||
};
|
||||
|
||||
@ -43,7 +42,7 @@ export const caslAbilityBuilder = (): CustomAbilityBuilder => {
|
||||
const { can, build, ...rest } = new AbilityBuilder(Ability);
|
||||
|
||||
return {
|
||||
can(permission: PermissionsTypes.PermissionRule) {
|
||||
can(permission: PermissionRule) {
|
||||
const { action, subject, properties = {}, condition } = permission;
|
||||
const { fields } = properties;
|
||||
|
||||
@ -57,7 +56,7 @@ export const caslAbilityBuilder = (): CustomAbilityBuilder => {
|
||||
);
|
||||
},
|
||||
|
||||
buildParametrizedAction({ name, params }: PermissionsTypes.ParametrizedAction) {
|
||||
buildParametrizedAction({ name, params }: ParametrizedAction) {
|
||||
return `${name}?${qs.stringify(params)}`;
|
||||
},
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { cloneDeep, has, isArray } from 'lodash/fp';
|
||||
import { hooks } from '@strapi/utils';
|
||||
// eslint-disable-next-line node/no-extraneous-import
|
||||
import type { Permissions as PermissionsTypes } from '@strapi/types';
|
||||
|
||||
import * as domain from '../domain';
|
||||
import type { Permission } from '../domain/permission';
|
||||
import type { PermissionRule } from '../types';
|
||||
|
||||
export interface PermissionEngineHooks {
|
||||
'before-format::validate.permission': ReturnType<typeof hooks.createAsyncBailHook>;
|
||||
@ -52,7 +51,7 @@ const createBeforeEvaluateContext = (permission: Permission) => ({
|
||||
});
|
||||
|
||||
interface WillRegisterContextParams {
|
||||
permission: PermissionsTypes.PermissionRule;
|
||||
permission: PermissionRule;
|
||||
options: Record<string, unknown>;
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@ import _ from 'lodash/fp';
|
||||
import qs from 'qs';
|
||||
import { Ability } from '@casl/ability';
|
||||
import { providerFactory } from '@strapi/utils';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-extraneous-import
|
||||
import { Permissions as PermissionsTypes } from '@strapi/types';
|
||||
|
||||
import {
|
||||
createEngineHooks,
|
||||
@ -15,6 +13,7 @@ import type { PermissionEngineHooks, HookName } from './hooks';
|
||||
|
||||
import * as abilities from './abilities';
|
||||
import { Permission } from '../domain/permission';
|
||||
import type { PermissionRule } from '../types';
|
||||
|
||||
export { abilities };
|
||||
|
||||
@ -30,9 +29,9 @@ export interface Engine {
|
||||
on(hook: HookName, handler: (...args: any[]) => any): Engine;
|
||||
generateAbility(permissions: Permission[], options?: object): Promise<Ability>;
|
||||
createRegisterFunction(
|
||||
can: (permission: PermissionsTypes.PermissionRule) => unknown,
|
||||
can: (permission: PermissionRule) => unknown,
|
||||
options: Record<string, unknown>
|
||||
): (permission: PermissionsTypes.PermissionRule) => Promise<unknown>;
|
||||
): (permission: PermissionRule) => Promise<unknown>;
|
||||
}
|
||||
|
||||
export interface EngineParams {
|
||||
@ -42,7 +41,7 @@ export interface EngineParams {
|
||||
|
||||
interface EvaluateParams {
|
||||
options: Record<string, unknown>;
|
||||
register: (permission: PermissionsTypes.PermissionRule) => Promise<unknown>;
|
||||
register: (permission: PermissionRule) => Promise<unknown>;
|
||||
permission: Permission;
|
||||
}
|
||||
|
||||
@ -179,7 +178,7 @@ const newEngine = (params: EngineParams): Engine => {
|
||||
* used to register a permission in the ability builder
|
||||
*/
|
||||
createRegisterFunction(can, options: Record<string, unknown>) {
|
||||
return async (permission: PermissionsTypes.PermissionRule) => {
|
||||
return async (permission: PermissionRule) => {
|
||||
const hookContext = createWillRegisterContext({ options, permission });
|
||||
|
||||
await state.hooks['before-register.permission'].call(hookContext);
|
||||
|
||||
19
packages/core/permissions/src/types.ts
Normal file
19
packages/core/permissions/src/types.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* These were imported from `@strapi/types` but if we do that
|
||||
* it becomes a circular dependency. This is the source of truth,
|
||||
* they're re-exported from `@strapi/types` for convenience.
|
||||
*/
|
||||
import type { Subject } from '@casl/ability';
|
||||
|
||||
export interface ParametrizedAction {
|
||||
name: string;
|
||||
params: Record<string, unknown>;
|
||||
}
|
||||
export interface PermissionRule {
|
||||
action: string | ParametrizedAction;
|
||||
subject?: Subject | null;
|
||||
properties?: {
|
||||
fields?: string[];
|
||||
};
|
||||
condition?: Record<string, unknown>;
|
||||
}
|
||||
@ -50,11 +50,9 @@ export {
|
||||
};
|
||||
|
||||
declare global {
|
||||
// @ts-expect-error - global strapi variable is also defined in the index.d.ts file
|
||||
var strapi: LoadedStrapi;
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
// @ts-expect-error - global strapi variable is also defined in the index.d.ts file
|
||||
strapi: LoadedStrapi;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,8 @@
|
||||
import { Subject } from '@casl/ability';
|
||||
import type { engine } from '@strapi/permissions';
|
||||
|
||||
export interface ParametrizedAction {
|
||||
name: string;
|
||||
params: Record<string, unknown>;
|
||||
}
|
||||
export interface PermissionRule {
|
||||
action: string | ParametrizedAction;
|
||||
subject?: Subject | null;
|
||||
properties?: {
|
||||
fields?: string[];
|
||||
};
|
||||
condition?: Record<string, unknown>;
|
||||
}
|
||||
type PermissionRule = Parameters<engine.abilities.CustomAbilityBuilder['can']>[0];
|
||||
type ParametrizedAction = Parameters<
|
||||
engine.abilities.CustomAbilityBuilder['buildParametrizedAction']
|
||||
>[0];
|
||||
|
||||
export type { PermissionRule, ParametrizedAction };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user