module Sufia
module GenericFile
module AccessibleAttributes
extend ActiveSupport::Concern
included do
class_attribute :_accessible_attributes
self._accessible_attributes = {}
end
def accessible_attributes(role = :default)
self.class._accessible_attributes[role] || []
end
# Sanitize the provided attributes using only those that are specified
# as accessible by attr_accessor
# @param [Hash] attributes the raw parameters
# @param [Hash] args a hash of options
# @option args [Symbol] :as (:default) the role to use
# @return A sanitized hash of parameters
def sanitize_attributes(attributes = {}, args = {})
role = args[:as] || :default
attributes.select { |k,v| accessible_attributes.include?(k.to_sym)}
end
module ClassMethods
# Specifies a white list of model attributes that can be set via
# mass-assignment.
#
# Like +attr_protected+, a role for the attributes is optional,
# if no role is provided then :default is used. A role can be defined by
# using the :as option.
#
# Mass-assignment will only set attributes in this list, to assign to
# the rest of # attributes you can use direct writer methods. This is
# meant to protect sensitive attributes from being overwritten by
# malicious users # tampering with URLs or forms.
#
# class Customer
# include ActiveModel::MassAssignmentSecurity
#
# attr_accessor :name, :credit_rating
#
# attr_accessible :name
# attr_accessible :name, :credit_rating, as: :admin
#
# def assign_attributes(values, options = {})
# sanitize_for_mass_assignment(values, options[:as]).each do |k, v|
# send("#{k}=", v)
# end
# end
# end
#
# When using the :default role:
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", last_login: 1.day.ago }, as: :default)
# customer.name # => "David"
# customer.credit_rating # => nil
#
# customer.credit_rating = "Average"
# customer.credit_rating # => "Average"
#
# And using the :admin role:
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", last_login: 1.day.ago }, as: :admin)
# customer.name # => "David"
# customer.credit_rating # => "Excellent"
#
# Note that using Hash#except or Hash#slice in place of
# +attr_accessible+ to sanitize attributes provides basically the same
# functionality, but it makes a bit tricky to deal with nested attributes.
def attr_accessible(*args)
options = args.extract_options!
role = options[:as] || :default
self._accessible_attributes ||= {}
Array.wrap(role).each do |name|
self._accessible_attributes[name] = args.map &:to_sym
end
end
end
end
end
end