从自定义装饰器获取请求上下文服务实例

时间:2020-04-29 14:37:12

标签: typescript domain-driven-design clean-architecture inversifyjs typescript-decorator

我陷入了有趣的境地。我需要从自定义装饰器访问请求范围上下文。未经授权的用例:

    @injectable()
export class CreateUserUseCase implements ICreateUserUseCase {
    @inject(Types.IdentityDBContext) private _identityDBContext: IIdentityDBContext;

    public async execute(inputData: DSCreateUserInputData): Promise<void> {
        const {
            email: emailValue,
            name: nameValue,
            profileURL: profileURLValue,
            roleID: roleIDValue,
            userID: userIDValue
        } = inputData;

    // Request body to value objects here ....

        const userResult = User.createUser(
            {
                email,
                name,
                profileURL,
                auditDate,
                auditUser
            },
            userID
        );

        const user: User = userResult.getValue() as User;

        await this._identityDBContext.startTransaction();

        try {
            await this._identityDBContext.userRepository.saveUser(user, role);
        } catch (error) {
            await this._identityDBContext.rollbackTransaction();

            throw error;
        }

        await this._identityDBContext.commitTransaction();
    }
}

我无法提出在请求范围和装饰器之间找到点的方法。我需要以某种方式添加跨领域功能,以从请求上下文中检查用户权限(用户在基础结构级别(在控制器中)得到身份验证)。我不想直接避免将此上下文作为方法参数传递,因为我不想避免影响接口协定(但这是我想出的唯一方法):

  @injectable()
export class CreateUserUseCase implements ICreateUserUseCase {
    @inject(Types.IdentityDBContext) private _identityDBContext: IIdentityDBContext;

    @Permissions([PermissionType.CREATE_USER])
    public async execute(inputData: DSCreateUserInputData): Promise<void> {

有什么温柔的方法吗?

P.S。可能的装饰器解决方案:

export function Permissions(roles: PermissionType[]): any {
return function (...args: [Record<string, any>, string, PropertyDescriptor]): any {
    if (args.length === 3 && typeof args[2] !== 'number') {
        const [, , propertyDescriptor]: [Record<string, any>, string, PropertyDescriptor] = args;

        const original = propertyDescriptor.value;

        propertyDescriptor.value = function (...args1: any[]): any {

            // This one
            const systemUserService: SystemUserService = ?


            const userHasPermissions = systemUserService.currentSystemUser.systemUserRole.hasPermissions(roles);

            if (userHasPermissions) {
                const result = original.apply(this, args1);

                return result;
            }

            throw Error('Unauthorized');
        };

        return propertyDescriptor;
    }

    throw new Error('Not a valid decorator');
};
};

0 个答案:

没有答案