amgad abdo14x
amgad abdo14x

Reputation: 5

can method always return true (@casl/ability)

i expect if the autherId = userId it allow to update the article otherwise it throw new forbiddenExcepthion but when i try it with different users it still returns true

CaslAbilityFactory

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: users) {
    const { can, cannot, build } = new AbilityBuilder(createMongoAbility);

    if (user.IsAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, articles, { userId: user.id });
    can(Action.Delete, articles, { userId: user.id });

    const ability = build();
    return ability;
  }
}

the function that triger it

  @Patch('/:id')
  @UseGuards(JwtAuthGuard)
  updateArticle(
    @currentUser() user: users,
    @Param('id') id: number,
    @Body() updateArticle: UpDateArticle,
  ) {
    const ability = this.caslAbilityFactory.createForUser(user);
    if (!ability.can(Action.Update, articles)) {
      throw new ForbiddenException('user can not update this article');
    }
    return this.articleservice.updateArticle(id, updateArticle);
  }

Upvotes: 0

Views: 570

Answers (1)

amgad abdo14x
amgad abdo14x

Reputation: 5

on the abilty can method... i am passing the etity type here in the can method for the supject

insted i tryed to get the article from the datebase and passing it

as this

 const article = this.articleservice.getById(id);
    const ability = this.caslAbilityFactory.createForUser(user);
    console.log(ability.can(Action.Update, articles));
    if (!ability.can(Action.Update, article)) {
      return new ForbiddenException('user can not update this article');
    }

its now returning false.. for this you need to set the supject type to be a string with value equal to your entity class name or your can make a static getter on your etity class that reutrn the model name modelName reedmore here https://casl.js.org/v6/en/guide/subject-type-detection#use-classes-as-subject-types

 can(Action.Update, 'articles', { userId: user.id });
 can(Action.Delete, 'articles', { userId: user.id });

this looks really un unreadable i might try to rewrite the entire thing but it works for now

Upvotes: 0

Related Questions