Allow mixing of protected and accessible properties.
Any unspecified properties are now assumed to be protected by default Signed-off-by: Marcos Tapajós <tapajos@gmail.com>
This commit is contained in:
parent
bf22222fd9
commit
49c9656fe3
4 changed files with 67 additions and 55 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,3 +2,6 @@
|
|||
html/*
|
||||
pkg
|
||||
*.swp
|
||||
Gemfile*
|
||||
.rvmrc
|
||||
.bundle
|
||||
|
|
41
history.txt
41
history.txt
|
@ -4,12 +4,13 @@
|
|||
|
||||
* Minor enhancements
|
||||
* Raise error on adding objects to "collection_of" without an id
|
||||
* Allow mixing of protected and accessible properties. Any unspecified properties are now assumed to be protected by default
|
||||
|
||||
== CouchRest Model 1.0.0.beta7
|
||||
|
||||
* Major enhancements
|
||||
* Renamed ExtendedDocument to CouchRest::Model
|
||||
* Added initial support for simple belongs_to associations
|
||||
* Added initial support for simple belongs_to associations
|
||||
* Added support for basic collection_of association (unique to document databases!)
|
||||
* Moved Validation to ActiveModel
|
||||
* Moved Callbacks to ActiveModel
|
||||
|
@ -74,7 +75,7 @@
|
|||
* Adds support for continuous replication (sauy7)
|
||||
* Automatic Type Casting (Alexander Uvarov, Sam Lown, Tim Heighes, Will Leinweber)
|
||||
* Added a search method to CouchRest:Database to search the documents in a given database. (Dave Farkas, Arnaud Berthomier, John Wood)
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
* Provide a description of the timeout error (John Wood)
|
||||
|
||||
|
@ -103,9 +104,9 @@
|
|||
* Adds attribute protection to properties. (Will Leinweber)
|
||||
* Improved CouchRest::Database#save_doc, added "batch" mode to significantly speed up saves at cost of lower durability gurantees. (Igal Koshevoy)
|
||||
* Added CouchRest::Database#bulk_save_doc and #batch_save_doc as human-friendlier wrappers around #save_doc. (Igal Koshevoy)
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
* Fix content_type handling for attachments
|
||||
* Fixed a bug in the pagination code that caused it to paginate over records outside of the scope of the view parameters.(John Wood)
|
||||
* Removed amount_pages calculation for the pagination collection, since it cannot be reliably calculated without a view.(John Wood)
|
||||
|
@ -124,9 +125,9 @@
|
|||
* Major enhancements
|
||||
|
||||
* Added a new Rack logger middleware letting you log/save requests/queries (Matt Aimonetti)
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
* Added #amount_pages to a paginated result array (Matt Aimonetti)
|
||||
* Ruby 1.9.2 compatible (Matt Aimonetti)
|
||||
* Added a property? method for property cast as :boolean (John Wood)
|
||||
|
@ -135,14 +136,14 @@
|
|||
* Bug fix: made ExtendedDocument#all compatible with Couch 0.10 (tc)
|
||||
|
||||
== 0.32
|
||||
|
||||
|
||||
* Major enhancements
|
||||
|
||||
* ExtendedDocument.get doesn't raise an exception anymore. If no documents are found nil is returned.
|
||||
* ExtendedDocument.get! works the say #get used to work and will raise an exception if a document isn't found.
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
* Bug fix: Model.all(:keys => [1,2]) was not working (Matt Aimonetti)
|
||||
* Added ValidationErrors#count in order to play nicely with Rails (Peter Wagenet)
|
||||
* Bug fix: class proxy design doc refresh (Daniel Kirsh)
|
||||
|
@ -155,29 +156,29 @@
|
|||
|
||||
* Created an abstraction HTTP layer to support different http adapters (Matt Aimonetti)
|
||||
* Added ExtendedDocument.create({}) and #create!({}) so you don't have to do Model.new.create (Matt Aimonetti)
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
|
||||
* Added an init.rb file for easy usage as a Rails plugin (Aaron Quint)
|
||||
* Bug fix: pagination shouldn't die on empty results (Arnaud Berthomier)
|
||||
* Optimized ExtendedDocument.count to run about 3x faster (Matt Aimonetti)
|
||||
* Added Float casting (Ryan Felton & Matt Aimonetti)
|
||||
|
||||
== 0.30
|
||||
|
||||
|
||||
* Major enhancements
|
||||
|
||||
|
||||
* Added support for pagination (John Wood)
|
||||
* Improved performance when initializing documents with timestamps (Matt Aimonetti)
|
||||
|
||||
|
||||
* Minor enhancements
|
||||
|
||||
|
||||
* Extended the API to retrieve an attachment URI (Matt Aimonetti)
|
||||
* Bug fix: default value should be able to be set as false (Alexander Uvarov)
|
||||
* Bug fix: validates_is_numeric should be able to properly validate a Float instance (Rob Kaufman)
|
||||
* Bug fix: fixed the Timeout implementation (Seth Falcon)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Unfortunately, before 0.30 we did not keep a track of the modifications made to CouchRest.
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
module CouchRest
|
||||
module Model
|
||||
module AttributeProtection
|
||||
# Attribute protection from mass assignment to CouchRest properties
|
||||
#
|
||||
# Attribute protection from mass assignment to CouchRest::Model properties
|
||||
#
|
||||
# Protected methods will be removed from
|
||||
# * new
|
||||
# * new
|
||||
# * update_attributes
|
||||
# * upate_attributes_without_saving
|
||||
# * attributes=
|
||||
#
|
||||
# There are two modes of protection
|
||||
# 1) Declare accessible poperties, assume all the rest are protected
|
||||
# property :name, :accessible => true
|
||||
# property :admin # this will be automatically protected
|
||||
#
|
||||
# 2) Declare protected properties, assume all the rest are accessible
|
||||
# property :name # this will not be protected
|
||||
# There are two modes of protection
|
||||
# 1) Declare accessible poperties, and assume all unspecified properties are protected
|
||||
# property :name, :accessible => true
|
||||
# property :admin # this will be automatically protected
|
||||
#
|
||||
# 2) Declare protected properties, and assume all unspecified properties are accessible
|
||||
# property :name # this will not be protected
|
||||
# property :admin, :protected => true
|
||||
#
|
||||
# Note: you cannot set both flags in a single class
|
||||
|
||||
# 3) Mix and match, and assume all unspecified properties are protected.
|
||||
# property :name, :accessible => true
|
||||
# property :admin, :protected => true
|
||||
# property :phone # this will be automatically protected
|
||||
#
|
||||
# Note: the timestamps! method protectes the created_at and updated_at properties
|
||||
|
||||
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
@ -56,18 +62,13 @@ module CouchRest
|
|||
private
|
||||
|
||||
def properties_to_remove_from_mass_assignment
|
||||
has_protected = !protected_properties.empty?
|
||||
has_accessible = !accessible_properties.empty?
|
||||
to_remove = protected_properties
|
||||
|
||||
if !has_protected && !has_accessible
|
||||
[]
|
||||
elsif has_protected && !has_accessible
|
||||
protected_properties
|
||||
elsif has_accessible && !has_protected
|
||||
properties.reject { |prop| prop.options[:accessible] }
|
||||
else
|
||||
raise "Set either :accessible or :protected for #{self.class}, but not both"
|
||||
unless accessible_properties.empty?
|
||||
to_remove += properties.reject { |prop| prop.options[:accessible] }
|
||||
end
|
||||
|
||||
to_remove
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,13 +23,13 @@ describe "Model Attributes" do
|
|||
user.name.should == "will"
|
||||
user.phone.should == "555-5555"
|
||||
end
|
||||
|
||||
|
||||
it "should recreate from the database properly" do
|
||||
user = NoProtection.new
|
||||
user.name = "will"
|
||||
user.phone = "555-5555"
|
||||
user.save!
|
||||
|
||||
|
||||
user = NoProtection.get(user.id)
|
||||
user.name.should == "will"
|
||||
user.phone.should == "555-5555"
|
||||
|
@ -50,7 +50,7 @@ describe "Model Attributes" do
|
|||
end
|
||||
|
||||
it "should protect non-accessible properties set through new" do
|
||||
user = WithAccessible.new(:name => "will", :admin => true)
|
||||
user = WithAccessible.new(:name => "will", :admin => true)
|
||||
|
||||
user.name.should == "will"
|
||||
user.admin.should == false
|
||||
|
@ -79,7 +79,7 @@ describe "Model Attributes" do
|
|||
end
|
||||
|
||||
it "should protect non-accessible properties set through new" do
|
||||
user = WithProtected.new(:name => "will", :admin => true)
|
||||
user = WithProtected.new(:name => "will", :admin => true)
|
||||
|
||||
user.name.should == "will"
|
||||
user.admin.should == false
|
||||
|
@ -94,15 +94,22 @@ describe "Model Attributes" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "protected flag" do
|
||||
class WithBoth < CouchRest::Model::Base
|
||||
describe "Model Base", "mixing protected and accessible flags" do
|
||||
class WithBothAndUnspecified < CouchRest::Model::Base
|
||||
use_database TEST_SERVER.default_database
|
||||
property :name, :accessible => true
|
||||
property :admin, :default => false, :protected => true
|
||||
property :phone, :default => 'unset phone number'
|
||||
end
|
||||
|
||||
it "should raise an error when both are set" do
|
||||
lambda { WithBoth.new }.should raise_error
|
||||
it { expect { WithBothAndUnspecified.new }.to_not raise_error }
|
||||
|
||||
it 'should assume that any unspecified property is protected by default' do
|
||||
user = WithBothAndUnspecified.new(:name => 'will', :admin => true, :phone => '555-1234')
|
||||
|
||||
user.name.should == 'will'
|
||||
user.admin.should == false
|
||||
user.phone.should == 'unset phone number'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -113,7 +120,7 @@ describe "Model Attributes" do
|
|||
property :admin, :default => false, :protected => true
|
||||
view_by :name
|
||||
end
|
||||
|
||||
|
||||
before(:each) do
|
||||
@user = WithProtected.new
|
||||
@user.name = "will"
|
||||
|
@ -128,12 +135,12 @@ describe "Model Attributes" do
|
|||
|
||||
it "Base#get should not strip protected attributes" do
|
||||
reloaded = WithProtected.get( @user.id )
|
||||
verify_attrs reloaded
|
||||
verify_attrs reloaded
|
||||
end
|
||||
|
||||
it "Base#get! should not strip protected attributes" do
|
||||
reloaded = WithProtected.get!( @user.id )
|
||||
verify_attrs reloaded
|
||||
verify_attrs reloaded
|
||||
end
|
||||
|
||||
it "Base#all should not strip protected attributes" do
|
||||
|
@ -141,13 +148,13 @@ describe "Model Attributes" do
|
|||
docs = WithProtected.all(:key => @user.id)
|
||||
docs.size.should == 1
|
||||
reloaded = docs.first
|
||||
verify_attrs reloaded
|
||||
verify_attrs reloaded
|
||||
end
|
||||
|
||||
it "views should not strip protected attributes" do
|
||||
docs = WithProtected.by_name(:startkey => "will", :endkey => "will")
|
||||
reloaded = docs.first
|
||||
verify_attrs reloaded
|
||||
verify_attrs reloaded
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue