Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not restricting access when no hook is specified in UseAbility #612

Open
Arekian opened this issue Feb 18, 2023 · 3 comments
Open

Not restricting access when no hook is specified in UseAbility #612

Arekian opened this issue Feb 18, 2023 · 3 comments

Comments

@Arekian
Copy link

Arekian commented Feb 18, 2023

So I have this permissions:

member({ user, can }) {
    can(Actions.read, User, { id: user.id });
    can(Actions.update, User, { id: user.id });
}

In controller:

 @UseGuards(JwtAuthGuard, AccessGuard)
  @UseAbility(Actions.read, User, UserHook)
  @Get(':id')

Will work fine with UserHook getting the User given :id as param.

But when I do this for a getall:

  @UseGuards(JwtAuthGuard, AccessGuard)
  @UseAbility(Actions.read, User)
  @Get()

as no hook is specified (or if I send null), It will allow access to the @get route. Is this intended behaviour?

@okonon
Copy link

okonon commented Jun 1, 2023

@Arekian i am running into this as well. What workarounds have you considered ?

@softimiz
Copy link

softimiz commented Feb 20, 2024

I get the same (right or wrong?) behavior on my side when trying to implement an access restriction on a GetAll vs GetById.

@liquidautumn I would like your advice on this. Do you consider this a bug? If not, then I guess I should extend DefaultActions with a new action e.g. "Actions.list".

@Alaa-Ben
Copy link

Alaa-Ben commented Aug 5, 2024

This is normal behaviour.

As per CASL JS's doc:

Historically, majority of permissions management libs were built on top of roles or flags. So, a user either has permission or not. This can be expressed in pseudo code:

allow('read_article');
allow('update_article');

This is interpreted as "user can read ALL articles and user can update ALL articles". So, this is "all or nothing" mindset.

But CASL is different! It allows us to ask different questions to our permissions. So, when you check on a

subject, you ask "can I read THIS article?"
subject type, you ask "can I read SOME article?" (i.e., at least one article)
It's very useful when you don't have an instance to check but know its type (for example, during creation), so this allows your app to fail fast.

So, when you're writing
@UseAbility(Actions.read, User)
You're actually saying "can the current user read at least one user", and the answer is yes as per your condition (he can read his own user), so it allows the request to go through.

Now regarding what you want to do, I see at least 2 options for now:

  1. Implement a Roles guard, and use it instead of nest-casl (for example, if current user is admin then he can read all users)
  2. If you still want to try nest-casl, If you check the type of the subject element of the can method, it should display:
    subject: typeof User | (typeof User)[] This means that you can use [User] as a subject. It's just a lead I have from a 2mins investigation, so no idea on whether it works or not (will it be interpreted as a list of users?), to be tried.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants