protected_attributes 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/active_model/mass_assignment_security/sanitizer.rb +4 -3
- data/lib/active_record/mass_assignment_security/associations.rb +5 -1
- data/lib/protected_attributes/version.rb +1 -1
- data/test/ar_helper.rb +20 -10
- data/test/attribute_sanitization_test.rb +1 -1
- data/test/mass_assignment_security_test.rb +24 -0
- data/test/models/battle.rb +5 -0
- data/test/models/company.rb +0 -90
- data/test/models/group.rb +6 -0
- data/test/models/membership.rb +8 -0
- data/test/models/person.rb +0 -35
- data/test/models/pirate.rb +5 -0
- data/test/models/team.rb +5 -0
- data/test/models/vampire.rb +4 -0
- data/test/models/wolf.rb +4 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36faf1653ed8ee17a3e6b1ae5bccb2ba3bd0b546
|
4
|
+
data.tar.gz: 614f266410d2a0885bd6d496927cdc5c0e4c9ae3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a775497367e9893d23a26983ec37e8c2110a79e13e3a215a94785f18d43e215d5e42ce176325fd5c09ac8a65b771a35630f377536e05b0712c62cf52f73a7818
|
7
|
+
data.tar.gz: cb338465c2fa0f8d37e491f21e411cd195c7d3a875a8d700477c47ab22a17b0687f0ba527da278d1b314707188ea0ddb2197bfcad8d934d28f9fb50f9b7d7b6a
|
@@ -14,7 +14,7 @@ module ActiveModel
|
|
14
14
|
protected
|
15
15
|
|
16
16
|
def process_removed_attributes(klass, attrs)
|
17
|
-
raise NotImplementedError, "#process_removed_attributes(attrs)
|
17
|
+
raise NotImplementedError, "#process_removed_attributes(klass, attrs) is intended to be overwritten by a subclass"
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -56,8 +56,9 @@ module ActiveModel
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def process_removed_attributes(klass, attrs)
|
59
|
-
|
60
|
-
|
59
|
+
unless (attrs - insensitive_attributes).empty?
|
60
|
+
raise ActiveModel::MassAssignmentSecurity::Error.new(klass, attrs)
|
61
|
+
end
|
61
62
|
end
|
62
63
|
|
63
64
|
def insensitive_attributes
|
data/test/ar_helper.rb
CHANGED
@@ -4,14 +4,12 @@ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:'
|
|
4
4
|
|
5
5
|
ActiveRecord::Schema.verbose = false
|
6
6
|
ActiveRecord::Schema.define do
|
7
|
-
|
8
7
|
create_table :accounts, :force => true do |t|
|
9
8
|
t.integer :firm_id
|
10
9
|
t.string :firm_name
|
11
10
|
t.integer :credit_limit
|
12
11
|
end
|
13
12
|
|
14
|
-
|
15
13
|
create_table :companies, :force => true do |t|
|
16
14
|
t.string :type
|
17
15
|
t.integer :firm_id
|
@@ -26,38 +24,50 @@ ActiveRecord::Schema.define do
|
|
26
24
|
add_index :companies, [:firm_id, :type, :rating], :name => "company_index"
|
27
25
|
add_index :companies, [:firm_id, :type], :name => "company_partial_index", :where => "rating > 10"
|
28
26
|
|
29
|
-
|
30
27
|
create_table :keyboards, :force => true, :id => false do |t|
|
31
28
|
t.primary_key :key_number
|
32
29
|
t.string :name
|
33
30
|
end
|
34
31
|
|
35
|
-
|
36
32
|
create_table :people, :force => true do |t|
|
37
33
|
t.string :first_name, :null => false
|
38
|
-
t.references :primary_contact
|
39
34
|
t.string :gender, :limit => 1
|
40
|
-
t.references :number1_fan
|
41
|
-
t.integer :lock_version, :null => false, :default => 0
|
42
35
|
t.string :comments
|
43
|
-
t.integer :followers_count, :default => 0
|
44
36
|
t.references :best_friend
|
45
37
|
t.references :best_friend_of
|
46
38
|
t.timestamps
|
47
39
|
end
|
48
40
|
|
49
|
-
|
50
41
|
create_table :subscribers, :force => true, :id => false do |t|
|
51
42
|
t.string :nick, :null => false
|
52
43
|
t.string :name
|
53
44
|
end
|
54
45
|
add_index :subscribers, :nick, :unique => true
|
55
46
|
|
56
|
-
|
57
47
|
create_table :tasks, :force => true do |t|
|
58
48
|
t.datetime :starting
|
59
49
|
t.datetime :ending
|
60
50
|
end
|
51
|
+
|
52
|
+
create_table :pirates, :force => true do |t|
|
53
|
+
end
|
54
|
+
|
55
|
+
create_table :groups, :force => true do |t|
|
56
|
+
end
|
57
|
+
|
58
|
+
create_table :memberships, :force => true do |t|
|
59
|
+
t.integer "group_id"
|
60
|
+
t.integer "pirate_id"
|
61
|
+
end
|
62
|
+
|
63
|
+
create_table :teams, :force => true
|
64
|
+
create_table :wolves, :force => true
|
65
|
+
create_table :vampires, :force => true
|
66
|
+
create_table :battles, :force => true do |t|
|
67
|
+
t.integer "team_id"
|
68
|
+
t.integer "battle_id"
|
69
|
+
t.string "battle_type"
|
70
|
+
end
|
61
71
|
end
|
62
72
|
|
63
73
|
QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type')
|
@@ -246,7 +246,7 @@ class AttributeSanitizationTest < ActiveSupport::TestCase
|
|
246
246
|
def test_protection_against_class_attribute_writers
|
247
247
|
attribute_writers = [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names,
|
248
248
|
:default_timezone, :schema_format, :lock_optimistically, :timestamped_migrations, :default_scopes,
|
249
|
-
:connection_handler, :nested_attributes_options,
|
249
|
+
:connection_handler, :nested_attributes_options,
|
250
250
|
:attribute_method_matchers, :time_zone_aware_attributes, :skip_time_zone_conversion_for_attributes]
|
251
251
|
|
252
252
|
attribute_writers.push(:_attr_readonly) if active_record_40?
|
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'active_model/mass_assignment_security'
|
3
3
|
require 'models/mass_assignment_specific'
|
4
|
+
require 'models/pirate'
|
5
|
+
require 'models/group'
|
6
|
+
require 'models/membership'
|
7
|
+
require 'models/battle'
|
8
|
+
require 'models/vampire'
|
9
|
+
require 'models/wolf'
|
10
|
+
require 'models/team'
|
4
11
|
|
5
12
|
class CustomSanitizer < ActiveModel::MassAssignmentSecurity::Sanitizer
|
6
13
|
|
@@ -115,4 +122,21 @@ class MassAssignmentSecurityTest < ActiveModel::TestCase
|
|
115
122
|
ensure
|
116
123
|
User.mass_assignment_sanitizer = old_sanitizer
|
117
124
|
end
|
125
|
+
|
126
|
+
def test_concat_has_many_through_association_member
|
127
|
+
group = Group.create!
|
128
|
+
pirate = Pirate.create!
|
129
|
+
group.members << pirate
|
130
|
+
assert_equal pirate.memberships.first, group.memberships.first
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_concat_has_many_through_polymorphic_association
|
134
|
+
team = Team.create!
|
135
|
+
vampire = Vampire.create!
|
136
|
+
wolf = Wolf.create!
|
137
|
+
|
138
|
+
team.vampire_battles << vampire
|
139
|
+
wolf.teams << team
|
140
|
+
assert_equal team.wolf_battles.first, wolf
|
141
|
+
end
|
118
142
|
end
|
data/test/models/company.rb
CHANGED
@@ -4,99 +4,9 @@ end
|
|
4
4
|
|
5
5
|
class Company < AbstractCompany
|
6
6
|
attr_protected :rating
|
7
|
-
self.sequence_name = :companies_nonstd_seq
|
8
|
-
|
9
|
-
validates_presence_of :name
|
10
|
-
|
11
|
-
has_one :dummy_account, :foreign_key => "firm_id", :class_name => "Account"
|
12
|
-
has_many :contracts
|
13
|
-
has_many :developers, :through => :contracts
|
14
|
-
|
15
|
-
def arbitrary_method
|
16
|
-
"I am Jack's profound disappointment"
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def private_method
|
22
|
-
"I am Jack's innermost fears and aspirations"
|
23
|
-
end
|
24
7
|
end
|
25
8
|
|
26
9
|
class Firm < Company
|
27
|
-
has_many :unsorted_clients, :class_name => "Client"
|
28
|
-
has_many :unsorted_clients_with_symbol, :class_name => :Client
|
29
|
-
has_many :clients_sorted_desc, -> { order "id DESC" }, :class_name => "Client"
|
30
|
-
has_many :clients_of_firm, -> { order "id" }, :foreign_key => "client_of", :class_name => "Client"
|
31
|
-
has_many :clients_ordered_by_name, -> { order "name" }, :class_name => "Client"
|
32
|
-
has_many :unvalidated_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :validate => false
|
33
|
-
has_many :dependent_clients_of_firm, -> { order "id" }, :foreign_key => "client_of", :class_name => "Client", :dependent => :destroy
|
34
|
-
has_many :exclusively_dependent_clients_of_firm, -> { order "id" }, :foreign_key => "client_of", :class_name => "Client", :dependent => :delete_all
|
35
|
-
has_many :limited_clients, -> { limit 1 }, :class_name => "Client"
|
36
|
-
has_many :clients_with_interpolated_conditions, ->(firm) { where "rating > #{firm.rating}" }, :class_name => "Client"
|
37
|
-
has_many :clients_like_ms, -> { where("name = 'Microsoft'").order("id") }, :class_name => "Client"
|
38
|
-
has_many :clients_like_ms_with_hash_conditions, -> { where(:name => 'Microsoft').order("id") }, :class_name => "Client"
|
39
|
-
|
40
|
-
if active_record_40?
|
41
|
-
ActiveSupport::Deprecation.silence do
|
42
|
-
has_many :clients, -> { order "id" }, :dependent => :destroy, :counter_sql =>
|
43
|
-
"SELECT COUNT(*) FROM companies WHERE firm_id = 1 " +
|
44
|
-
"AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )",
|
45
|
-
:before_remove => :log_before_remove,
|
46
|
-
:after_remove => :log_after_remove
|
47
|
-
has_many :clients_using_sql, :class_name => "Client", :finder_sql => proc { "SELECT * FROM companies WHERE client_of = #{id}" }
|
48
|
-
has_many :clients_using_counter_sql, :class_name => "Client",
|
49
|
-
:finder_sql => proc { "SELECT * FROM companies WHERE client_of = #{id} " },
|
50
|
-
:counter_sql => proc { "SELECT COUNT(*) FROM companies WHERE client_of = #{id}" }
|
51
|
-
has_many :clients_using_zero_counter_sql, :class_name => "Client",
|
52
|
-
:finder_sql => proc { "SELECT * FROM companies WHERE client_of = #{id}" },
|
53
|
-
:counter_sql => proc { "SELECT 0 FROM companies WHERE client_of = #{id}" }
|
54
|
-
has_many :no_clients_using_counter_sql, :class_name => "Client",
|
55
|
-
:finder_sql => 'SELECT * FROM companies WHERE client_of = 1000',
|
56
|
-
:counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = 1000'
|
57
|
-
has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1'
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
has_many :plain_clients, :class_name => 'Client'
|
62
|
-
has_many :readonly_clients, -> { readonly }, :class_name => 'Client'
|
63
|
-
has_many :clients_using_primary_key, :class_name => 'Client',
|
64
|
-
:primary_key => 'name', :foreign_key => 'firm_name'
|
65
|
-
has_many :clients_using_primary_key_with_delete_all, :class_name => 'Client',
|
66
|
-
:primary_key => 'name', :foreign_key => 'firm_name', :dependent => :delete_all
|
67
|
-
has_many :clients_grouped_by_firm_id, -> { group("firm_id").select("firm_id") }, :class_name => "Client"
|
68
|
-
has_many :clients_grouped_by_name, -> { group("name").select("name") }, :class_name => "Client"
|
69
|
-
|
70
|
-
has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
|
71
|
-
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
|
72
|
-
has_one :account_with_select, -> { select("id, firm_id") }, :foreign_key => "firm_id", :class_name=>'Account'
|
73
|
-
has_one :readonly_account, -> { readonly }, :foreign_key => "firm_id", :class_name => "Account"
|
74
|
-
# added order by id as in fixtures there are two accounts for Rails Core
|
75
|
-
# Oracle tests were failing because of that as the second fixture was selected
|
76
|
-
has_one :account_using_primary_key, -> { order('id') }, :primary_key => "firm_id", :class_name => "Account"
|
77
|
-
has_one :account_using_foreign_and_primary_keys, :foreign_key => "firm_name", :primary_key => "name", :class_name => "Account"
|
78
|
-
has_one :deletable_account, :foreign_key => "firm_id", :class_name => "Account", :dependent => :delete
|
79
|
-
|
80
|
-
has_one :account_limit_500_with_hash_conditions, -> { where :credit_limit => 500 }, :foreign_key => "firm_id", :class_name => "Account"
|
81
|
-
|
82
|
-
has_one :unautosaved_account, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false
|
83
|
-
has_many :accounts
|
84
|
-
has_many :unautosaved_accounts, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false
|
85
|
-
|
86
|
-
has_many :association_with_references, -> { references(:foo) }, :class_name => 'Client'
|
87
|
-
|
88
|
-
def log
|
89
|
-
@log ||= []
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
def log_before_remove(record)
|
94
|
-
log << "before_remove#{record.id}"
|
95
|
-
end
|
96
|
-
|
97
|
-
def log_after_remove(record)
|
98
|
-
log << "after_remove#{record.id}"
|
99
|
-
end
|
100
10
|
end
|
101
11
|
|
102
12
|
class Corporation < Company
|
data/test/models/person.rb
CHANGED
@@ -1,38 +1,3 @@
|
|
1
|
-
class Person < ActiveRecord::Base
|
2
|
-
has_many :readers
|
3
|
-
has_many :secure_readers
|
4
|
-
has_one :reader
|
5
|
-
|
6
|
-
has_many :posts, :through => :readers
|
7
|
-
has_many :secure_posts, :through => :secure_readers
|
8
|
-
has_many :posts_with_no_comments, -> { includes(:comments).where('comments.id is null').references(:comments) },
|
9
|
-
:through => :readers, :source => :post
|
10
|
-
|
11
|
-
has_many :followers, foreign_key: 'friend_id', class_name: 'Friendship'
|
12
|
-
|
13
|
-
has_many :references
|
14
|
-
has_many :bad_references
|
15
|
-
has_many :fixed_bad_references, -> { where :favourite => true }, :class_name => 'BadReference'
|
16
|
-
has_one :favourite_reference, -> { where 'favourite=?', true }, :class_name => 'Reference'
|
17
|
-
has_many :posts_with_comments_sorted_by_comment_id, -> { includes(:comments).order('comments.id') }, :through => :readers, :source => :post
|
18
|
-
|
19
|
-
has_many :jobs, :through => :references
|
20
|
-
has_many :jobs_with_dependent_destroy, :source => :job, :through => :references, :dependent => :destroy
|
21
|
-
has_many :jobs_with_dependent_delete_all, :source => :job, :through => :references, :dependent => :delete_all
|
22
|
-
has_many :jobs_with_dependent_nullify, :source => :job, :through => :references, :dependent => :nullify
|
23
|
-
|
24
|
-
belongs_to :primary_contact, :class_name => 'Person'
|
25
|
-
has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id'
|
26
|
-
has_many :agents_of_agents, :through => :agents, :source => :agents
|
27
|
-
belongs_to :number1_fan, :class_name => 'Person'
|
28
|
-
|
29
|
-
has_many :agents_posts, :through => :agents, :source => :posts
|
30
|
-
has_many :agents_posts_authors, :through => :agents_posts, :source => :author
|
31
|
-
|
32
|
-
scope :males, -> { where(:gender => 'M') }
|
33
|
-
scope :females, -> { where(:gender => 'F') }
|
34
|
-
end
|
35
|
-
|
36
1
|
class LoosePerson < ActiveRecord::Base
|
37
2
|
self.table_name = 'people'
|
38
3
|
|
data/test/models/team.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
class Team < ActiveRecord::Base
|
2
|
+
has_many :battles
|
3
|
+
has_many :wolf_battles, :through => :battles, :class_name => 'Wolf', :source => :battle, :source_type => 'Wolf'
|
4
|
+
has_many :vampire_battles, :through => :battles, :class_name => 'Vampire', :source => :battle, :source_type => 'Vampire'
|
5
|
+
end
|
data/test/models/wolf.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protected_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -133,12 +133,19 @@ files:
|
|
133
133
|
- test/mass_assignment_security/sanitizer_test.rb
|
134
134
|
- test/mass_assignment_security/white_list_test.rb
|
135
135
|
- test/mass_assignment_security_test.rb
|
136
|
+
- test/models/battle.rb
|
136
137
|
- test/models/company.rb
|
138
|
+
- test/models/group.rb
|
137
139
|
- test/models/keyboard.rb
|
138
140
|
- test/models/mass_assignment_specific.rb
|
141
|
+
- test/models/membership.rb
|
139
142
|
- test/models/person.rb
|
143
|
+
- test/models/pirate.rb
|
140
144
|
- test/models/subscriber.rb
|
141
145
|
- test/models/task.rb
|
146
|
+
- test/models/team.rb
|
147
|
+
- test/models/vampire.rb
|
148
|
+
- test/models/wolf.rb
|
142
149
|
- test/test_helper.rb
|
143
150
|
homepage: https://github.com/rails/protected_attributes
|
144
151
|
licenses:
|
@@ -174,10 +181,17 @@ test_files:
|
|
174
181
|
- test/mass_assignment_security/sanitizer_test.rb
|
175
182
|
- test/mass_assignment_security/white_list_test.rb
|
176
183
|
- test/mass_assignment_security_test.rb
|
184
|
+
- test/models/battle.rb
|
177
185
|
- test/models/company.rb
|
186
|
+
- test/models/group.rb
|
178
187
|
- test/models/keyboard.rb
|
179
188
|
- test/models/mass_assignment_specific.rb
|
189
|
+
- test/models/membership.rb
|
180
190
|
- test/models/person.rb
|
191
|
+
- test/models/pirate.rb
|
181
192
|
- test/models/subscriber.rb
|
182
193
|
- test/models/task.rb
|
194
|
+
- test/models/team.rb
|
195
|
+
- test/models/vampire.rb
|
196
|
+
- test/models/wolf.rb
|
183
197
|
- test/test_helper.rb
|