2009-09-27 01:24:26 +02:00
|
|
|
module CouchRest
|
2010-06-20 22:01:11 +02:00
|
|
|
module Model
|
2010-10-22 15:39:12 +02:00
|
|
|
module PropertyProtection
|
2010-09-18 15:19:15 +02:00
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
2010-10-22 15:39:12 +02:00
|
|
|
# Property protection from mass assignment to CouchRest::Model properties
|
2010-08-12 00:41:32 +02:00
|
|
|
#
|
2009-09-27 01:24:26 +02:00
|
|
|
# Protected methods will be removed from
|
2010-08-12 00:41:32 +02:00
|
|
|
# * new
|
2009-09-27 01:24:26 +02:00
|
|
|
# * update_attributes
|
|
|
|
# * upate_attributes_without_saving
|
|
|
|
# * attributes=
|
2010-08-12 00:41:32 +02:00
|
|
|
#
|
2009-09-27 01:24:26 +02:00
|
|
|
# There are two modes of protection
|
2010-08-12 00:41:32 +02:00
|
|
|
# 1) Declare accessible poperties, and assume all unspecified properties are protected
|
|
|
|
# property :name, :accessible => true
|
|
|
|
# property :admin # this will be automatically protected
|
2009-09-27 01:24:26 +02:00
|
|
|
#
|
2010-08-12 00:41:32 +02:00
|
|
|
# 2) Declare protected properties, and assume all unspecified properties are accessible
|
|
|
|
# property :name # this will not be protected
|
2009-09-27 01:24:26 +02:00
|
|
|
# property :admin, :protected => true
|
|
|
|
#
|
2010-08-12 00:41:32 +02:00
|
|
|
# 3) Mix and match, and assume all unspecified properties are protected.
|
|
|
|
# property :name, :accessible => true
|
2010-10-22 15:39:12 +02:00
|
|
|
# property :admin, :protected => true # ignored
|
2010-08-12 00:41:32 +02:00
|
|
|
# property :phone # this will be automatically protected
|
|
|
|
#
|
|
|
|
# Note: the timestamps! method protectes the created_at and updated_at properties
|
|
|
|
|
|
|
|
|
2009-09-27 01:24:26 +02:00
|
|
|
def self.included(base)
|
|
|
|
base.extend(ClassMethods)
|
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
|
|
|
def accessible_properties
|
2010-10-22 15:39:12 +02:00
|
|
|
props = properties.select { |prop| prop.options[:accessible] }
|
|
|
|
if props.empty?
|
|
|
|
props = properties.select { |prop| !prop.options[:protected] }
|
|
|
|
end
|
|
|
|
props
|
2009-09-27 01:24:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def protected_properties
|
2010-10-22 15:39:12 +02:00
|
|
|
accessibles = accessible_properties
|
|
|
|
properties.reject { |prop| accessibles.include?(prop) }
|
2009-09-27 01:24:26 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def accessible_properties
|
|
|
|
self.class.accessible_properties
|
|
|
|
end
|
|
|
|
|
|
|
|
def protected_properties
|
|
|
|
self.class.protected_properties
|
|
|
|
end
|
|
|
|
|
2010-10-22 15:39:12 +02:00
|
|
|
# Return a new copy of the attributes hash with protected attributes
|
|
|
|
# removed.
|
2009-09-27 01:24:26 +02:00
|
|
|
def remove_protected_attributes(attributes)
|
2010-10-22 15:39:12 +02:00
|
|
|
protected_names = protected_properties.map { |prop| prop.name }
|
|
|
|
return attributes if protected_names.empty? or attributes.nil?
|
2009-09-27 01:24:26 +02:00
|
|
|
|
2010-10-22 15:39:12 +02:00
|
|
|
attributes.reject do |property_name, property_value|
|
2009-10-31 13:49:26 +01:00
|
|
|
protected_names.include?(property_name.to_s)
|
2009-09-27 01:24:26 +02:00
|
|
|
end
|
|
|
|
end
|
2010-10-22 15:39:12 +02:00
|
|
|
|
2009-09-27 01:24:26 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|