Created
July 20, 2012 11:44
-
-
Save ahawkins/3150306 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationPermitter | |
class PermittedAttribute < Struct.new(:name, :options) ; end | |
delegate :authorize!, :to => :ability | |
class_attribute :permitted_attributes | |
self.permitted_attributes = [] | |
class << self | |
def permit(*args) | |
options = args.extract_options! | |
args.each do |name| | |
self.permitted_attributes += [PermittedAttribute.new(name, options)] | |
end | |
end | |
def scope(name) | |
with_options :scope => name do |nested| | |
yield nested | |
end | |
end | |
end | |
def initialize(params, user, ability = nil) | |
@params, @user, @ablity = params, user, ability | |
end | |
def permitted_params | |
authorize_params! | |
filtered_params | |
end | |
def resource_name | |
self.class.to_s.match(/(.+)Permitter/)[1].underscore.to_sym | |
end | |
private | |
def authorize_params! | |
needing_authorization = permitted_attributes.select { |a| a.options[:authorize] } | |
needing_authorization.each do |attribute| | |
if attribute.options[:scope] | |
values = Array.wrap(filtered_params[attribute.options[:scope]]).collect do |hash| | |
hash[attribute.name] | |
end.compact | |
else | |
values = Array.wrap filtered_params[attribute.name] | |
end | |
klass = (attribute.options[:as].try(:to_s) || attribute.name.to_s.split(/(.+)_ids?/)[1]).classify.constantize | |
values.each do |record_id| | |
record = klass.find record_id | |
permission = attribute.options[:authorize].to_sym || :read | |
authorize! permission, record | |
end | |
end | |
end | |
def filtered_params | |
scopes = {} | |
unscoped_attributes = [] | |
permitted_attributes.each do |attribute| | |
if attribute.options[:scope] | |
key = attribute.options[:scope] | |
scopes[key] ||= [] | |
scopes[key] << attribute.name | |
else | |
unscoped_attributes << attribute.name | |
end | |
end | |
@filtered_params ||= params.require(resource_name).permit(*unscoped_attributes, scopes) | |
end | |
def params | |
@params | |
end | |
def user | |
@user | |
end | |
def ability | |
@ability ||= Ability.new user | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DealPermitter < ApplicationPermitter | |
# No premissions reuqired to set this | |
permit :name, :description, :close_by, :state | |
# can pass `:authorize` with a permission: | |
# This line allows user_id if the user can read the user specified | |
# by the user_id. This only happens if it's present | |
permit :user_id, :authorize => :read | |
# same thing but automatically handles arrays of ids as well. | |
# This line allows the attachment_ids if the user can manage all | |
# the specified attachments | |
permit :attachment_ids, :authorize => :manage | |
# same thing as before but scopes this it to the | |
# hash inside the line_items_attributes array | |
# | |
# line_items_attributes is permitted if every item in the array | |
# is allowed. | |
# | |
# This also only allows line items if the user can manage the parent | |
scope :line_items_attributes, :manage => true do |line_item| | |
# So you cannot manipulate line items outside the parent | |
line_item.permit :id, :authorize => :manage | |
line_item.permit :name, :quantity, :price, :currency, :notes | |
line_item.permit :product_id, :authorize => :read | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment