Comments (7)
I also need a convetion for handling this type of scenario, for example on batch destroy actions, it may happen that the user is trying to delete a bunch of records, without having permission to destroy some of those records. @jnicklas do you have any advice on this scenario?
from pundit.
Hi Dimitry, this sounds like an interesting idea. Could you be so kind and explain your use case with an example for better understanding of how we should check that the items relate to one another?
from pundit.
I am the author of this SO post: http://stackoverflow.com/questions/18338731/authorizing-an-array-of-ids-with-the-pundit-gem and was told to post here.
In my use case, a multiselect dropdown box is populated with an association of records. For simplicity lets say I want to be adding users (User
) to my groups (Group
).
In this case, I would be updating a group and the params would include params[:groups][:user_ids]
, which would come into the Rails controller as an array of record IDs.
def update
@group.users = authorized_users
@group.save
end
private
def authorized_users
users = User.find(params[:group][:user_ids]) # array of Users
users.each { |u| authorize u, :manage? }
end
This is something like what I'm currently doing. In my case the :manage
permission is very specific to my application, but it can be anything that determines whether or not a user can add another user to his/her group. For example, if my application had friends lists maybe I would only want users to be able to add their friends to a group.
It would be useful to be able to authorize an entire collection so that doing the each
is not necessary in every controller.
from pundit.
One nice thing about Pundit is that it's really just a set of conventions, so when you have something which slightly deviates from the convention, like you guys have in this case, it's easy to just drop down to implementing this by hand. Authorize basically boils down to this:
raise Pundit::NotAuthorized unless SomePolicy.new(object).allowed?
Knowing that, you can just do this yourselves:
raise Pundit::NotAuthorized unless CollectionPolicy.new(collection).allowed?
raise Pundit::NotAuthorized unless policy(user).allowed?(collection)
Or anything similar, really. Does that make sense?
from pundit.
That is nice and I can make my own version of authorize
that accepts a collection and would leave my controllers looking much better.
I guess the question is if this method should be included in the Pundit gem. I don't believe authorizing a collection is that rare of a use case (I could be wrong). Do you just feel that authorizing a single record is so much more common that it warrants the included authorize
method, while authorizing a collection should be done manually by those using the gem?
I respect the simplicity of Pundit so I would understand if that was the case. The application I'm working on has an unusually high number of has_many relationships and forms so it could just be that my situation is rare.
from pundit.
I would say that, in most cases, if you're running into situations where you're trying to authorize collections, you probably have something backwards. There's probably a more sensible place where you can put your authorization logic. At least that would be the idomatic Pundit way of doing things. I've built authorization systems using Pundit for applications with very complex authorization needs, and many associations between objects, and I've never run into this problem. I still think there could be edge cases where you might want to do something like this, but I think it's rare, and probably not something which should be encouraged or codified by the gem.
from pundit.
I realize this is a super old issue, but I have a similar use case and wanted to submit one additional quirk in for consideration.
Like the other commenters, I'm receiving a list of IDs and the current user may or may not have permission to "assign" each of these objects. In my case the array is a list of permissions, and we're actually talking about who has permission to assign permissions, which is very meta. But let's stick with the previous example: assigning users to groups.
When you perform an update like this:
@group.users = authorized_users
you need to check that the current user has permission to manage the users being added to that group. However, you may also want to check that the current user has permission to remove any other users who were previously in the group. Consider this:
@group.ids # => [1, 3, 5]
params[:group][:user_ids] # => [1, 2, 3, 4]
@group.users = authorized_users
- I must have permission to manage users 2 and 4 as I am adding them to the group
- I don't actually need permission to manage users 1 and 3 as I am not changing their group membership
- Oops! I also should have had permission to manage user 5 because I just removed them from the group by not including them in the array, but we didn't check!
I'll probably write some sort of helper to manage this process, but it seems like an easy thing to screw up and would be nice if there was some sort of convention for dealing with these sorts of scenarios.
from pundit.
Related Issues (20)
- [Request] Generate policy file when using scaffolding HOT 3
- Readme: update_attributes is deprecated
- policy_class and policy usage HOT 2
- Add `policy_class` parameter to `permitted_attributes` function HOT 3
- Manually specifying policy class via an instance method does not always work HOT 1
- Singular model class name vs. Plural module name HOT 3
- Split this into two methods?
- [Request] policy_scope should not alter joined table structure HOT 2
- Policy Finder `find` does not strip namespace. HOT 2
- Support authorization error flash messages when using turbo frames and streams? HOT 6
- Git tag for v2.3.0? HOT 1
- generator fails with ruby 3.2.0 HOT 6
- "include Pundit::Authorization" undefined ? HOT 3
- Enable custom description for permit matcher
- Do not use NotImplementedError HOT 1
- Rubygems version fully support Ruby 3.2
- Hook into Rails generators (scaffold, model) to generate policy classes HOT 3
- Helper policy_scope does not accept policy_scope_class HOT 1
- README for headless section is incorrect? HOT 1
- uninitialized constant Pundit::Authorization HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pundit.