#typescript #nestjs #casl #knex
Вопрос:
Я пытаюсь использовать CASL с NestJS и Knex. Я хочу ограничить пользователей только обновлением и удалением их собственных категорий. Однако, похоже, что эта способность у меня не работает.
Я использую этот класс для создания способностей:
type Subjects = InferSubjectslt;typeof Category | typeof Usergt; | 'all'; export type AppAbility = Abilitylt;[Action, Subjects]gt;; @Injectable() export class CaslAbilityFactory { createForUser(user: User) { const { can: allow, cannot: forbid, build, } = new AbilityBuilderlt;Abilitylt;[Action, Subjects]gt;gt;(Ability as AbilityClasslt;AppAbilitygt;); allow([Action.Update, Action.Delete], Category, { id_user: user.id }); return build({ // Read https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types for details detectSubjectType: (item) =gt; item.constructor as ExtractSubjectTypelt;Subjectsgt;, }); } }
export class Category { id: string; name: string; description: string; id_user: string; // using uuids public: boolean; created_at: string; updated_at: string; }
Внутри службы я запрашиваю категорию с помощью knex, а затем пытаюсь проверить возможность с помощью этой категории , но в то время if
как первый false
оператор if
всегда соответствует второму true
, поэтому возникает исключение.
public async update(id: string, req: any, request: UpdateCategoryRequest) { const category: Category = await this.knexlt;Categorygt;('categories') .where({ id: id }) .first(); const ability = this.casl.createForUser(req.user); console.log(`Ability.Can: ${ability.can(Action.Update, category)}`); console.log(`Ability.Cannot: ${ability.cannot(Action.Update, category)}`); if (ability.can(Action.Update, category)) { console.log('I can update this.'); } if (!ability.can(Action.Update, category)) { console.log('Cannot update this resource.'); throw new HttpException('You can not update this resource.', HttpStatus.FORBIDDEN); } return this.knex('categories').where({ id: id }).update(request, ['*']); }
Я попытался проверить, какой тип возвращается из knex с помощью category instanceof Category
. Это значение равно false, поэтому, я думаю ability.can(Action.Update, category)
, не работает, потому category
что не является экземпляром класса Category
. Если я попытаюсь создать новую категорию с помощью конструктора классов, она будет работать нормально.
let cat: Category = new Category(); cat.id_user = '7dc75a42-c74c-4cae-9d46-42e590de99b0'; ability.can(Action.Update, cat); // true