我陷入了有趣的境地。我需要从自定义装饰器访问请求范围上下文。未经授权的用例:
@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');
};
};