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

Add example for possession 'own' #11

Open
JeetChaudhari opened this issue Mar 30, 2019 · 14 comments
Open

Add example for possession 'own' #11

JeetChaudhari opened this issue Mar 30, 2019 · 14 comments

Comments

@JeetChaudhari
Copy link

In Access Control docs it says

Note that own requires you to also check for the actual possession

and here it shows how to do it, but I am not sure how to check actual possession with nest-access-control.

So, please add more examples, at least for the roles and actions you have mentioned in app.roles.ts, I would really appreciate it.

@Tyler-V
Copy link

Tyler-V commented Apr 3, 2019

I also had the same thought, so I'll share what I came up with this evening:

I use the roles to define readOwn and readAny, on resource/:id routes

Inside the controller I then inject the RolesBuilder and use a custom decorator to pull the JwtPayload to get the user object for id and role.

I then check if the user can readAny and if so, return the service method that returns all of the resources and if not I call a different method to return the resource that belongs to that user.

I would prefer to provide a parameter in the route that returns the possession state but I don't think you can inject the rolesBuilder into custom decorators and access the context to retrieve the req.user object to evaluate possession so this is the best I could come up with.

  @Get(':id')
  @UseGuards(AccessControlGuard)
  @UseRoles(
    { resource: 'lease', action: 'read', possession: 'own' },
    { resource: 'lease', action: 'read', possession: 'any' },
  )
  @ApiOperation({ title: 'Get lease by id', description: 'Gets a lease with the specified id' })
  async getLease(@JwtPayload() user: User, @Param('id', new ParseIntPipe()) id: number) {
    if (this.roleBuilder.can(user.role).readAny('lease').granted) {
      return this.leasesService.findLeaseById(id);
    } else {
      return this.leasesService.findOwnLeaseById(user.id, id);
    }
  }

@JeetChaudhari
Copy link
Author

@Tyler-V Thank you for the example, I am also not sure with injecting rolesBuilder in decorator and would not prefer it because most of the time one would require to check organization access not just user id for multi tenant application. I think filter can be used in same way if attributes are also set in roles.

One more thing out of curiosity, it is not a problem but why are we using word rolesBuilder instead of accessControl as used in onury examples?

@Tyler-V
Copy link

Tyler-V commented Apr 4, 2019

I think this problem exists in all applications where you access resource/:id you need some way to determine if you are allowed to access only your own resources OR any resources and then fetch the right data, I'd rather keep my services like black boxes input/output and add any cased logic like I just described in the controller.

RolesBuilder is the Injectable class that extends AccessControl, its this author of this library's implementation of onury's accesscontrol as applied to NestJs using Angular features.

@IGassmann
Copy link

@shekohex what's the recommended way to achieve this?

@vishnu-dev
Copy link

How do we do this? Any hint would be great.

@JeetChaudhari
Copy link
Author

@vishnu-dev I do not remember exactly what I did that time, I tried to check the actual possession 'own', but it did not worked the way I wanted. It was almost 1 year ago. However I remember that in end of the day, I did not use this lib but instead I directly used https://github.com/onury/accesscontrol which is used by this lib under the hood. If you are still stuck at this let me know, I will try to find that implementation and provide you with details.

@ruslanguns
Copy link
Contributor

ruslanguns commented Jun 17, 2020

@Tyler-V nice example. But how did you inject the rolesBuilder in the controller ?

@ruslanguns
Copy link
Contributor

ruslanguns commented Jun 17, 2020

@Tyler-V nevermind I just discovered by myself the @InjectRolesBuilder() decorator...

For whom are looking for doing this kind of roles validation as @Tyler-V does above, just need to inject in the constructor something like this:

constructor(
    @InjectRolesBuilder() private readonly roleBuilder: RolesBuilder,
  ) {}

@lambrohan
Copy link

@JeetChaudhari Please share the detailed info about implementation of accesscontrol directly without using this lib.

@JeetChaudhari
Copy link
Author

@lambrohan Let me look into codes, It will take some time as it was almost couple of years before. Once I find, I will share details with you

@zanio
Copy link

zanio commented Jul 1, 2021

@lambrohan Let me look into codes, It will take some time as it was almost couple of years before. Once I find, I will share details with you

We are Still waiting for this @lambrohan

@lambrohan
Copy link

lambrohan commented Jul 1, 2021

@zanio
I actually continued my project with this lib. Injecting RoleBuilder in my controllers and having additional checks for own possession did the job for me.

// for example
if (this.roleBuilder.can(reqUser.roles).readOwn(AppResources.USER_PROFILE).granted && reqUser.id === resource.owner){
    // grant access
}

@LhonRafaat
Copy link

@zanio I actually continued my project with this lib. Injecting RoleBuilder in my controllers and having additional checks for own possession did the job for me.

// for example
if (this.roleBuilder.can(reqUser.roles).readOwn(AppResources.USER_PROFILE).granted && reqUser.id === resource.owner){
    // grant access
}

But this will not work if the user can read any resource, because req.user.id not equals to the resource owner id, which will return false and which is incorrect since the user is supposed to read any.

@mohammadrz003
Copy link

mohammadrz003 commented Jul 20, 2023

@zanio I actually continued my project with this lib. Injecting RoleBuilder in my controllers and having additional checks for own possession did the job for me.

// for example
if (this.roleBuilder.can(reqUser.roles).readOwn(AppResources.USER_PROFILE).granted && reqUser.id === resource.owner){
    // grant access
}

the right way of checking the own possession is mentioned here

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

9 participants