Using declarative_authorization to limit results in the model
I am using the declarative authorization gem for permissions in a rails project and I am trying to limit output from the model based on user permissions.
My abbreviated authorization file looks like this:
roles do
开发者_开发问答 role :supervisor
has_permission_on :people, :to => :manage_all
end
role :basic_user
has_permission_on :people, :to => :manage_subordinates
end
end
privileges do
privilege :manage_subordinates do
includes :subordinate_records
end
privilege :manage_all do
includes :all_records
end
end
In my people model, I have a static method that I want to look like this
def self.supervised_by(user)
if user.permitted_to? :all_records
#return all of the records
elsif user.permitted_to? :subordinate_records
#return some of the records
else
#return none of the records
end
end
It looks like there is support for this using the AuthorizationInModel object in the documentation using with_permissions_to or permitted_to. I haven't been able to figure out how to use those functions based on the documentation or how to return a list of the current user's privileges on the current model.
Any ideas?
I found an alternative solution using the built in if-attribute method. I originally moved away from it because I was using non-namespaced models and namespaced controllers and views. This structure is an artifact form the original version of the project I am working on. Most of my work has been getting declarative authorization to deal with this structure.
The major piece of information that was not clear to me was how to name the permissions in a partially namespaced environment. The model expected the model name (:people), the controller expected the namespace and the model (:staff_people), and the views didn't care as long as you picked one. The solution I picked was to use the model name and explicitly set the context in every controller. If the context is not set in the controller, using filter_access_to does not work because it would be looking for the staff_people permission rather than the correct permission, people.
In the declarative authorization config file, I am giving full permissions to administration and partial permissions to supervisor. person.supervised returns an array of itself and all other supervised people.
roles do
role :administrator
has_permission_on :people, :to => [:create, :read, :update, :delete]
end
role :supervisor
has_permission_on :people do
to => [:create, :read, :update, :delete]
if_attribute :id => is_in { Person.find_by_user_id(user.id).supervised }
end
end
end
To access this information in a Namespaced controller, I am using filer_resource_access.
module Staff
class PeopleController < ApplicationController
filter_resource_access :context => :people
def index
@people = People.with_permissions_to(:read)
end
I found that using
filter_access_to :all, :with_attribute => true
did not work for methods that need to use with_permissions_to and an if_attribute permission. I am not sure why this was a problem
It is still necessary to use filter_access_to for nonstandard controller actions that do not include an id fetching a single record as part of the arguments. For example, if an action called part_timers returns a list of people, this solution seems like it should work:
filter_resource_access :context => :people, :additional_member => { :part_timers => :read }
The correct solution is to keep the filter_resource_access as is and add a filter_access_to for that action
filter_resource_access :context => :people
fitler_access_to :part_timers, :required => :read, :context => people
There may be a better way to do this but this should work for your supervised_by
method if everything else is setup right.
def self.supervised_by(user)
if Person.new.permitted_to? :all_records, :user=>user
#return all of the records
elsif Person.new.permitted_to? :subordinate_records, :user=>user
#return some of the records
else
#return none of the records
end
end
精彩评论