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

Support for anonymous users #2

Open
ragaskar opened this issue Jan 8, 2011 · 1 comment
Open

Support for anonymous users #2

ragaskar opened this issue Jan 8, 2011 · 1 comment

Comments

@ragaskar
Copy link

ragaskar commented Jan 8, 2011

I notice you only support anonymous (ie nil current_user, which is what devise provides when there is no user logged in) users through overriding can_xx behaviors on the controller. Although it ruins some of the elegance of the code, if you essentially duplicate the user's can_xx in the enforcer's can_xx, it would be possible to describe anonymous user permissions in the model, which would be really nice (ie, I could deal with nil values on a case by case basis in the model). For most of my use cases, I'm thinking I'm going to want permissions for anon, 'regular', and admin users -- in order to do that right now, I'll need to essentially dupe the model permissions in the controller to avoid nil errors. More than willing to submit code with tests if this is something you would consider merging, but if this isn't the direction you want to go in, I'll probably just go with a monkey patch. My implementation would probably just dupe the user can_xx into the enforcer can_xx, which again, isn't pretty, but should have the desired effect of passing the current user down into the resource even if they're nil. I guess this could be surprising if people have overridden the can_xx on the user model, but right now I can think of very few reasons to do that, unless you wanted to create a user that's forbidden entirely from some kind of action.

Eager to hear if you have encountered this problem and solved it in a different way (null user pattern as opposed to a nil value?).

Thanks for the library, btw -- nice and succinct. I like it.

EDIT: I think we can workaround the problem of providing expected behavior when overriding user can_xx by checking to see if the current user exists and if it responds to the method. Implemented below in the monkey patch. Yes, this further sullies the code, but again, gets me the behavior I want. If you wanted to pretty it up, I guess you could create a class method that both the enforcer can_xx and the user can_xx share.

@ragaskar
Copy link
Author

ragaskar commented Jan 8, 2011

FWIW, here's what the monkey patch looks like. Gross? Yes, but seems to do the trick:

module Canable
  def self.add(can, able)
    @actions[can] = able
    add_can_method(can, able)
    add_able_method(able)
    add_enforcer_method(can, able)
  end

  def self.add_enforcer_method(can, able)
      Enforcers.module_eval <<-EOM
        def can_#{can}?(resource)
          return current_user.can_#{can}?(resource) if current_user
          return false if resource.blank?
          resource.#{able}_by?(current_user)
        end
      EOM
    end
end

Canable.add(:view,    :viewable)
Canable.add(:create,  :creatable)
Canable.add(:update,  :updatable)
Canable.add(:destroy, :destroyable)

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

1 participant