Code Monkey home page Code Monkey logo

Comments (7)

tommyalvarez avatar tommyalvarez commented on May 14, 2024 9

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.

thomasklemm avatar thomasklemm commented on May 14, 2024

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.

lserman avatar lserman commented on May 14, 2024

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.

jnicklas avatar jnicklas commented on May 14, 2024

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.

lserman avatar lserman commented on May 14, 2024

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.

jnicklas avatar jnicklas commented on May 14, 2024

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.

iangreenleaf avatar iangreenleaf commented on May 14, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.