attribute_ext 1.0.1 → 1.1.0
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.
- data/README.md +65 -32
- data/attribute_ext.gemspec +1 -1
- data/init.rb +4 -1
- data/lib/attribute_ext.rb +1 -3
- data/lib/attribute_ext/hidden_attributes.rb +35 -22
- data/lib/attribute_ext/railtie.rb +11 -0
- data/lib/attribute_ext/safe_attributes.rb +22 -13
- data/spec/hidden_attributes_spec.rb +151 -0
- data/spec/safe_attributes_spec.rb +65 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/fake_environment.rb +29 -0
- data/spec/support/stub.rb +64 -0
- metadata +10 -4
data/README.md
CHANGED
@@ -19,27 +19,52 @@ You can also install AttributeExt as a rails plugin by cloning the repository to
|
|
19
19
|
`vendor/plugins`.
|
20
20
|
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
AttributeExt::SafeAttributes
|
23
|
+
----------------------------
|
24
24
|
|
25
|
-
|
25
|
+
Protects attributes from mass assignment using rails mass assignment authorizer.
|
26
|
+
Also support Proc blocks.
|
26
27
|
|
27
|
-
|
28
|
-
into serializable_hash now. Therefore it is possible to hide attributes when
|
29
|
-
serializing to hash via serializable_hash method too.
|
30
|
-
But by default rules will not be checked on serializable_hash, you have to
|
31
|
-
add `:on_hash => true` to hide_attributes to enabled it for this rule.
|
28
|
+
Examples:
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
Always allow mass assignment for attribute.
|
31
|
+
|
32
|
+
class User < ActiveRecord::Base
|
33
|
+
safe_attributes :attribute
|
34
|
+
end
|
35
|
+
|
36
|
+
Attributes 'login', 'admin' and 'status' can only be mass assigned if current
|
37
|
+
user is an admin.
|
38
|
+
|
39
|
+
class User < ActiveRecord::Base
|
40
|
+
safe_attributes :login, :admin, :status, :if => Proc.new { User.current.admin? }
|
41
|
+
end
|
42
|
+
|
43
|
+
Message text can not be mass assigned when post is locked.
|
44
|
+
|
45
|
+
class Message < ActiveRecord::Base
|
46
|
+
safe_attributes :text, :unless => Proc.new { |msg| msg.locked? }
|
47
|
+
end
|
48
|
+
|
49
|
+
With Rails 3 a role can be given when creating or updating an model. This
|
50
|
+
role will also be available in SafeAttributes.
|
51
|
+
|
52
|
+
class User < ActiveRecord::Base
|
53
|
+
safe_attributes :login, :as => :admin
|
54
|
+
end
|
55
|
+
|
56
|
+
or
|
57
|
+
|
58
|
+
class User < ActiveRecord::Base
|
59
|
+
safe_attributes :login, :if => Proc.new { |user,role| role == :admin }
|
60
|
+
end
|
36
61
|
|
37
62
|
|
38
63
|
AttributeExt::HiddenAttributes
|
39
64
|
------------------------------
|
40
65
|
|
41
66
|
Hides attributes when converting model to XML or JSON. Attributes can be
|
42
|
-
dynamically hidden using if or unless Procs.
|
67
|
+
dynamically hidden using if or unless Procs.
|
43
68
|
|
44
69
|
Examples:
|
45
70
|
|
@@ -66,6 +91,16 @@ Only hide email when serialzing to json.
|
|
66
91
|
hide_attributes :email, :if => Proc.new { |user, format| format == :json }
|
67
92
|
end
|
68
93
|
|
94
|
+
Simpler format conditions can be defined using :only and :except parameters:
|
95
|
+
|
96
|
+
class User < ActiveRecord::Base
|
97
|
+
hide_attributes :email, :only => :json
|
98
|
+
hide_attributes :special_attr, :except => [:xml, :json]
|
99
|
+
end
|
100
|
+
|
101
|
+
Both parameters accept single attributes and arrays. When :only or :except is
|
102
|
+
given the :on_hash option will be ignored.
|
103
|
+
|
69
104
|
Hide user_id if associated user model will be included. This rule will also
|
70
105
|
apply when calling serializable_hash.
|
71
106
|
|
@@ -74,34 +109,32 @@ apply when calling serializable_hash.
|
|
74
109
|
hide_attributes :user_id, :on_hash => true, :if => Proc.new { |event, format, opts| opts[:include].include?(:user) }
|
75
110
|
end
|
76
111
|
|
112
|
+
By default rules *do not* apply when serializing to hash.
|
77
113
|
|
78
|
-
AttributeExt::SafeAttributes
|
79
|
-
----------------------------
|
80
114
|
|
81
|
-
|
82
|
-
|
115
|
+
Changelog
|
116
|
+
---------
|
83
117
|
|
84
|
-
|
118
|
+
Sep 22, 2011
|
85
119
|
|
86
|
-
|
120
|
+
Nearly all features are successfully tested using a fake environment now.
|
121
|
+
SafeAttributes provides a new quick role validation using the :as parameters and
|
122
|
+
HiddenAttributes can apply rules only to specific formats via :only and :except
|
123
|
+
parameters.
|
87
124
|
|
88
|
-
|
89
|
-
safe_attributes :attribute
|
90
|
-
end
|
125
|
+
Sep 1, 2011
|
91
126
|
|
92
|
-
|
93
|
-
|
127
|
+
HiddenAttributes works on included model when serializing to json by hooking
|
128
|
+
into serializable_hash now. Therefore it is possible to hide attributes when
|
129
|
+
serializing to hash via serializable_hash method too.
|
130
|
+
But by default rules will not be checked on serializable_hash, you have to
|
131
|
+
add `:on_hash => true` to hide_attributes to enabled it for this rule.
|
132
|
+
|
133
|
+
Update: SafeAttributes works now with Rails 3.1 mass_assignment_authorizer that
|
134
|
+
provides a role and pass this role to if and unless blocks as second
|
135
|
+
parameter. Not tested but should also work with old mass_assignment_authorizer.
|
94
136
|
|
95
|
-
class User < ActiveRecord::Base
|
96
|
-
safe_attributes :login, :admin, :status, :if => Proc.new { User.current.admin? }
|
97
|
-
end
|
98
|
-
|
99
|
-
Message text can not be mass assigned when post is locked.
|
100
137
|
|
101
|
-
class Message < ActiveRecord::Base
|
102
|
-
safe_attributes :text, :unless => Proc.new { |msg| msg.locked? }
|
103
|
-
end
|
104
|
-
|
105
138
|
License
|
106
139
|
-------
|
107
140
|
|
data/attribute_ext.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "attribute_ext"
|
6
|
-
s.version = "1.0
|
6
|
+
s.version = "1.1.0"
|
7
7
|
s.authors = ["Jan Graichen"]
|
8
8
|
s.email = ["jan.graichen@altimos.de"]
|
9
9
|
s.homepage = "https://github.com/jgraichen/attribute_ext"
|
data/init.rb
CHANGED
data/lib/attribute_ext.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
|
2
2
|
require 'attribute_ext/hidden_attributes'
|
3
3
|
require 'attribute_ext/safe_attributes'
|
4
|
-
|
5
|
-
ActiveRecord::Base.send :include, AttributeExt::HiddenAttributes
|
6
|
-
ActiveRecord::Base.send :include, AttributeExt::SafeAttributes
|
4
|
+
require 'attribute_ext/railtie' if defined?(Rails)
|
@@ -14,55 +14,68 @@ module AttributeExt
|
|
14
14
|
@hidden_attributes
|
15
15
|
else
|
16
16
|
options = attrs.last.is_a?(Hash) ? attrs.pop : {}
|
17
|
-
@hidden_attributes << [attrs, options]
|
17
|
+
@hidden_attributes << [attrs, hide_attributes_opts(options)]
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def hide_attributes_opts(options)
|
23
|
+
opts = { :except => [], :only => [] }
|
24
|
+
opts[:except] += options[:except].is_a?(Array) ? options[:except] : [options[:except]] if options[:except]
|
25
|
+
opts[:only] += options[:only].is_a?(Array) ? options[:only] : [options[:only]] if options[:only]
|
26
|
+
opts[:if] = options[:if] if options[:if].is_a?(Proc)
|
27
|
+
opts[:unless] = options[:unless] if options[:unless].is_a?(Proc)
|
28
|
+
|
29
|
+
if opts[:except].empty? && opts[:only].empty?
|
30
|
+
opts[:except] += [:hash] unless options[:on_hash]
|
31
|
+
end
|
32
|
+
|
33
|
+
opts
|
34
|
+
end
|
20
35
|
end
|
21
36
|
|
22
37
|
def to_xml_with_hidden_attrs(options = nil, &block)
|
23
38
|
options ||= {}
|
24
|
-
options[:except] =
|
25
|
-
options[:except] += hidden_attribute_names(:xml, options)
|
39
|
+
options[:except] = hidden_attribute_names(:xml, options)
|
26
40
|
|
27
41
|
to_xml_without_hidden_attrs(options)
|
28
42
|
end
|
29
43
|
|
30
44
|
def as_json_with_hidden_attrs(options = nil, &block)
|
31
45
|
options ||= {}
|
32
|
-
options[:except] =
|
33
|
-
options[:
|
34
|
-
options[:hidden_attributes_json_export] = true
|
46
|
+
options[:except] = hidden_attribute_names(:json, options)
|
47
|
+
options[:hidden_attributes_format] = :json
|
35
48
|
|
36
49
|
as_json_without_hidden_attrs(options)
|
37
50
|
end
|
38
51
|
|
39
52
|
def serializable_hash_with_hidden_attrs(options = nil)
|
40
53
|
options ||= {}
|
41
|
-
options[:except] = []
|
42
|
-
if options[:hidden_attributes_json_export]
|
43
|
-
options[:except] += hidden_attribute_names(:json, options)
|
44
|
-
else
|
45
|
-
options[:except] += hidden_attribute_names(:hash, options)
|
46
|
-
end
|
54
|
+
options[:except] = hidden_attribute_names((options[:hidden_attributes_format] || :hash), options)
|
47
55
|
|
48
56
|
serializable_hash_without_hidden_attrs(options)
|
49
57
|
end
|
50
|
-
|
51
|
-
private
|
52
58
|
|
53
|
-
def hidden_attribute_names(format, options)
|
54
|
-
|
59
|
+
def hidden_attribute_names(format, options = {})
|
60
|
+
if options[:except].is_a?(Array)
|
61
|
+
names = options[:except]
|
62
|
+
else
|
63
|
+
names = []
|
64
|
+
names += options[:except] if options[:except]
|
65
|
+
end
|
55
66
|
|
56
67
|
self.class.hide_attributes.collect do |attrs, opts|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
68
|
+
next unless opts[:only].empty? or opts[:only].include?(format)
|
69
|
+
next unless opts[:except].empty? or !opts[:except].include?(format)
|
70
|
+
next unless opts[:if].nil? or hidden_attr_call_block(opts[:if], format, options)
|
71
|
+
next unless opts[:unless].nil? or !hidden_attr_call_block(opts[:unless], format, options)
|
72
|
+
|
73
|
+
names += attrs.collect(&:to_s)
|
62
74
|
end
|
63
75
|
names.uniq
|
64
76
|
end
|
65
|
-
|
77
|
+
|
78
|
+
private
|
66
79
|
def hidden_attr_call_block(block, format, opts)
|
67
80
|
case block.arity
|
68
81
|
when 0
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
module AttributeExt
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
initializer 'attribute_ext' do |app|
|
5
|
+
ActiveSupport.on_load :active_record do
|
6
|
+
ActiveRecord::Base.send :include, AttributeExt::HiddenAttributes
|
7
|
+
ActiveRecord::Base.send :include, AttributeExt::SafeAttributes
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -2,6 +2,7 @@ module AttributeExt
|
|
2
2
|
module SafeAttributes
|
3
3
|
def self.included(base)
|
4
4
|
base.extend(ClassMethods)
|
5
|
+
base.alias_method_chain :mass_assignment_authorizer, :safe_attrs
|
5
6
|
end
|
6
7
|
|
7
8
|
module ClassMethods
|
@@ -11,22 +12,38 @@ module AttributeExt
|
|
11
12
|
@safe_attributes
|
12
13
|
else
|
13
14
|
options = attrs.last.is_a?(Hash) ? attrs.pop : {}
|
14
|
-
@safe_attributes << [attrs, options]
|
15
|
+
@safe_attributes << [attrs, safe_attributes_opts(options)]
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def safe_attributes_opts(options)
|
21
|
+
opts = { :as => [] }
|
22
|
+
opts[:as] += options[:as].is_a?(Array) ? options[:as] : [options[:as]] if options[:as]
|
23
|
+
opts[:if] = options[:if] if options[:if].is_a?(Proc)
|
24
|
+
opts[:unless] = options[:unless] if options[:unless].is_a?(Proc)
|
25
|
+
opts
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def mass_assignment_authorizer_with_safe_attrs(role = nil)
|
30
|
+
attrs = role.nil? ? mass_assignment_authorizer_without_safe_attrs : mass_assignment_authorizer_without_safe_attrs(role)
|
31
|
+
attrs += safe_attribute_names(role ? role : :default)
|
17
32
|
end
|
18
33
|
|
19
34
|
def safe_attribute_names(role = :default)
|
20
35
|
names = []
|
21
36
|
self.class.safe_attributes.collect do |attrs, options|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
next unless options[:as].empty? or options[:as].include?(role)
|
38
|
+
next unless options[:if].nil? or safe_attrs_call_block(options[:if], role)
|
39
|
+
next unless options[:unless].nil? or !safe_attrs_call_block(options[:unless], role)
|
40
|
+
|
41
|
+
names += attrs.collect(&:to_s)
|
26
42
|
end
|
27
43
|
names.uniq
|
28
44
|
end
|
29
45
|
|
46
|
+
private
|
30
47
|
def safe_attrs_call_block(block, role)
|
31
48
|
case block.arity
|
32
49
|
when 0
|
@@ -37,13 +54,5 @@ module AttributeExt
|
|
37
54
|
return block.call(self, role)
|
38
55
|
end
|
39
56
|
end
|
40
|
-
|
41
|
-
def mass_assignment_authorizer(role = nil)
|
42
|
-
if role.nil?
|
43
|
-
super + safe_attribute_names(:default)
|
44
|
-
else
|
45
|
-
super(role) + safe_attribute_names(role)
|
46
|
-
end
|
47
|
-
end
|
48
57
|
end
|
49
58
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe AttributeExt::HiddenAttributes do
|
5
|
+
|
6
|
+
it 'can hide attributes always' do
|
7
|
+
user = User.new
|
8
|
+
|
9
|
+
user.hidden_attribute_names(:format).should include('attribute')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'can hide attributes using an if condition' do
|
13
|
+
user = User.new
|
14
|
+
user.hidden_attribute_names(:format).should_not include('attribute_if')
|
15
|
+
|
16
|
+
user = User.new :if => true
|
17
|
+
user.hidden_attribute_names(:format).should include('attribute_if')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can hide attributes using an unless condition' do
|
21
|
+
user = User.new
|
22
|
+
user.hidden_attribute_names(:format).should_not include('attribute_unless')
|
23
|
+
|
24
|
+
user = User.new :unless => false
|
25
|
+
user.hidden_attribute_names(:format).should include('attribute_unless')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can hide attributes using an if and unless condition' do
|
29
|
+
user = User.new
|
30
|
+
user.hidden_attribute_names(:format).should_not include('attribute_if_unless')
|
31
|
+
|
32
|
+
user = User.new :if => true
|
33
|
+
user.hidden_attribute_names(:format).should_not include('attribute_if_unless')
|
34
|
+
|
35
|
+
user = User.new :unless => false
|
36
|
+
user.hidden_attribute_names(:format).should_not include('attribute_if_unless')
|
37
|
+
|
38
|
+
user = User.new :unless => false, :if => true
|
39
|
+
user.hidden_attribute_names(:format).should include('attribute_if_unless')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can hide attributes using an if condition with format argument' do
|
43
|
+
user = User.new
|
44
|
+
user.hidden_attribute_names(:not_format).should_not include('attribute_if_format')
|
45
|
+
user.hidden_attribute_names(:format).should include('attribute_if_format')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'can hide attributes using an unless condition with format argument' do
|
49
|
+
user = User.new
|
50
|
+
user.hidden_attribute_names(:format).should_not include('attribute_unless_format')
|
51
|
+
user.hidden_attribute_names(:not_format).should include('attribute_unless_format')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can hide attributes using an if condition with options argument' do
|
55
|
+
user = User.new
|
56
|
+
user.hidden_attribute_names(:format, {:hide => true}).should_not include('attribute_if_opts')
|
57
|
+
user.hidden_attribute_names(:format, {:hide => false}).should include('attribute_if_opts')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'can hide attributes using an unless condition with options argument' do
|
61
|
+
user = User.new
|
62
|
+
user.hidden_attribute_names(:format, {:hide => false}).should_not include('attribute_unless_opts')
|
63
|
+
user.hidden_attribute_names(:format, {:hide => true}).should include('attribute_unless_opts')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'only applies rules to hash if wanted' do
|
67
|
+
user = User.new
|
68
|
+
user.hidden_attribute_names(:hash).should_not include('attribute')
|
69
|
+
user.hidden_attribute_names(:hash).should include('attribute_hash')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'only applies rules to hash if wanted (if condition)' do
|
73
|
+
user = User.new :if => true
|
74
|
+
user.hidden_attribute_names(:hash).should_not include('attribute_if')
|
75
|
+
user.hidden_attribute_names(:hash).should include('attribute_if_hash')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'only applies rules to hash if wanted (unless condition)' do
|
79
|
+
user = User.new :unless => false
|
80
|
+
user.hidden_attribute_names(:hash).should_not include('attribute_unless')
|
81
|
+
user.hidden_attribute_names(:hash).should include('attribute_unless_hash')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'only applies rules to given format (only option)' do
|
85
|
+
formats = [:json, :hash, :xml]
|
86
|
+
user = User.new
|
87
|
+
|
88
|
+
formats.each do |f|
|
89
|
+
formats.each do |f2|
|
90
|
+
if f == f2
|
91
|
+
user.hidden_attribute_names(f).should include("attribute_only_#{f2}")
|
92
|
+
else
|
93
|
+
user.hidden_attribute_names(f).should_not include("attribute_only_#{f2}")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'only applies rules to given format (except option)' do
|
100
|
+
formats = [:json, :xml, :hash]
|
101
|
+
user = User.new
|
102
|
+
|
103
|
+
formats.each do |f|
|
104
|
+
formats.each do |f2|
|
105
|
+
if f == f2
|
106
|
+
user.hidden_attribute_names(f).should_not include("attribute_except_#{f2}")
|
107
|
+
else
|
108
|
+
user.hidden_attribute_names(f).should include("attribute_except_#{f2}")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'only applies rules to given formats (only option)' do
|
115
|
+
user = User.new
|
116
|
+
|
117
|
+
user.hidden_attribute_names(:json).should_not include("attribute_only_xml_txt")
|
118
|
+
user.hidden_attribute_names(:hash).should_not include("attribute_only_xml_txt")
|
119
|
+
user.hidden_attribute_names(:xml).should include("attribute_only_xml_txt")
|
120
|
+
user.hidden_attribute_names(:txt).should include("attribute_only_xml_txt")
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'only applies rules to given formats (except option)' do
|
124
|
+
user = User.new
|
125
|
+
|
126
|
+
user.hidden_attribute_names(:json).should include("attribute_except_xml_txt")
|
127
|
+
user.hidden_attribute_names(:hash).should include("attribute_except_xml_txt")
|
128
|
+
user.hidden_attribute_names(:xml).should_not include("attribute_except_xml_txt")
|
129
|
+
user.hidden_attribute_names(:txt).should_not include("attribute_except_xml_txt")
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'supports json export' do
|
133
|
+
user = User.new
|
134
|
+
user.hidden_attribute_names(:json).should == user.as_json[:except]
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'supports deep json export via serializable hash (depends on rails)' do
|
138
|
+
user = User.new
|
139
|
+
user.hidden_attribute_names(:json).should == user.as_json({:include => true})[:except]
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'supports xml export' do
|
143
|
+
user = User.new
|
144
|
+
user.hidden_attribute_names(:xml).should == user.to_xml[:except]
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'supports hash export' do
|
148
|
+
user = User.new
|
149
|
+
user.hidden_attribute_names(:hash).should == user.serializable_hash[:except]
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe AttributeExt::HiddenAttributes do
|
5
|
+
|
6
|
+
it 'uses mass assignment authorizer' do
|
7
|
+
user = User.new
|
8
|
+
|
9
|
+
user.mass_assignment_authorizer.should include('always_there')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'uses mass assignment authorizer with role' do
|
13
|
+
user = User.new
|
14
|
+
|
15
|
+
user.mass_assignment_authorizer(:admin).should include('admin_role')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can whitelist attributes' do
|
19
|
+
user = User.new
|
20
|
+
|
21
|
+
user.mass_assignment_authorizer.should include('always')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can whitelist attributes using an if condition' do
|
25
|
+
user = User.new
|
26
|
+
user.mass_assignment_authorizer.should_not include('attribute_if')
|
27
|
+
|
28
|
+
user = User.new :if => true
|
29
|
+
user.mass_assignment_authorizer.should include('attribute_if')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can whitelist attributes using an unless condition' do
|
33
|
+
user = User.new
|
34
|
+
user.mass_assignment_authorizer.should_not include('attribute_unless')
|
35
|
+
|
36
|
+
user = User.new :unless => false
|
37
|
+
user.mass_assignment_authorizer.should include('attribute_unless')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'can whitelist attributes using an if and an unless condition' do
|
41
|
+
user = User.new
|
42
|
+
user.mass_assignment_authorizer.should_not include('attribute_if_unless')
|
43
|
+
user = User.new :if => true
|
44
|
+
user.mass_assignment_authorizer.should_not include('attribute_if_unless')
|
45
|
+
user = User.new :unless => false
|
46
|
+
user.mass_assignment_authorizer.should_not include('attribute_if_unless')
|
47
|
+
|
48
|
+
user = User.new :if => true, :unless => false
|
49
|
+
user.mass_assignment_authorizer.should include('attribute_if_unless')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'can whitelist attributes checking role in if condition' do
|
53
|
+
user = User.new
|
54
|
+
user.mass_assignment_authorizer(:default).should_not include('attribute_if_admin')
|
55
|
+
user = User.new
|
56
|
+
user.mass_assignment_authorizer(:admin).should include('attribute_if_admin')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'can whitelist attributes checking role in unless condition' do
|
60
|
+
user = User.new
|
61
|
+
user.mass_assignment_authorizer(:default).should include('attribute_unless_admin')
|
62
|
+
user = User.new
|
63
|
+
user.mass_assignment_authorizer(:admin).should_not include('attribute_unless_admin')
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module ActiveRecord
|
3
|
+
class Base
|
4
|
+
def as_json(options)
|
5
|
+
if options[:include]
|
6
|
+
serializable_hash(options)
|
7
|
+
else
|
8
|
+
options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_xml(options)
|
13
|
+
options
|
14
|
+
end
|
15
|
+
|
16
|
+
def serializable_hash(options)
|
17
|
+
options
|
18
|
+
end
|
19
|
+
|
20
|
+
def mass_assignment_authorizer(role = :default)
|
21
|
+
['always_there', "role=#{role}"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.alias_method_chain(target, feature)
|
25
|
+
alias_method "#{target}_without_#{feature}", target
|
26
|
+
alias_method target, "#{target}_with_#{feature}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
class User < ActiveRecord::Base
|
3
|
+
|
4
|
+
attr_accessor :opts
|
5
|
+
|
6
|
+
hide_attributes :attribute
|
7
|
+
hide_attributes :attribute_hash, :on_hash => true
|
8
|
+
|
9
|
+
hide_attributes :attribute_if,
|
10
|
+
:if => Proc.new { |user| user.opts[:if] }
|
11
|
+
hide_attributes :attribute_if_hash, :on_hash => true,
|
12
|
+
:if => Proc.new { |user| user.opts[:if] }
|
13
|
+
|
14
|
+
hide_attributes :attribute_unless,
|
15
|
+
:unless => Proc.new { |user| user.opts[:unless] }
|
16
|
+
hide_attributes :attribute_unless_hash, :on_hash => true,
|
17
|
+
:unless => Proc.new { |user| user.opts[:unless] }
|
18
|
+
|
19
|
+
hide_attributes :attribute_if_unless,
|
20
|
+
:if => Proc.new { |user| user.opts[:if] } ,
|
21
|
+
:unless => Proc.new { |user| user.opts[:unless] }
|
22
|
+
|
23
|
+
hide_attributes :attribute_if_format,
|
24
|
+
:if => Proc.new { |u,format| format == :format }
|
25
|
+
|
26
|
+
hide_attributes :attribute_unless_format,
|
27
|
+
:unless => Proc.new { |u,format| format == :format }
|
28
|
+
|
29
|
+
hide_attributes :attribute_if_opts,
|
30
|
+
:if => Proc.new { |u,format,opts| opts[:hide] == false }
|
31
|
+
|
32
|
+
hide_attributes :attribute_unless_opts,
|
33
|
+
:unless => Proc.new { |u,format,opts| opts[:hide] == false }
|
34
|
+
|
35
|
+
hide_attributes :attribute_only_xml, :only => :xml
|
36
|
+
hide_attributes :attribute_only_json, :only => :json
|
37
|
+
hide_attributes :attribute_only_hash, :only => :hash
|
38
|
+
hide_attributes :attribute_except_xml, :except => :xml
|
39
|
+
hide_attributes :attribute_except_json, :except => :json
|
40
|
+
hide_attributes :attribute_except_hash, :except => :hash
|
41
|
+
hide_attributes :attribute_only_xml_txt, :only => [:xml, :txt]
|
42
|
+
hide_attributes :attribute_except_xml_txt, :except => [:xml, :txt]
|
43
|
+
|
44
|
+
safe_attributes :always
|
45
|
+
safe_attributes :admin_role, :as => :admin
|
46
|
+
safe_attributes :attribute_if,
|
47
|
+
:if => Proc.new { |user| user.opts[:if] }
|
48
|
+
safe_attributes :attribute_unless,
|
49
|
+
:unless => Proc.new { |user| user.opts[:unless] }
|
50
|
+
safe_attributes :attribute_if_unless,
|
51
|
+
:if => Proc.new { |user| user.opts[:if] },
|
52
|
+
:unless => Proc.new { |user| user.opts[:unless] }
|
53
|
+
safe_attributes :attribute_if_admin,
|
54
|
+
:if => Proc.new { |user,role| role == :admin}
|
55
|
+
safe_attributes :attribute_unless_admin,
|
56
|
+
:unless => Proc.new { |user,role| role == :admin}
|
57
|
+
|
58
|
+
def initialize(opts = {})
|
59
|
+
@opts = {
|
60
|
+
:if => false,
|
61
|
+
:unless => true
|
62
|
+
}.merge(opts.is_a?(Hash) ? opts : {})
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribute_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jan Graichen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-22 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: AttributeExt provides additional access control for rails model attributes.
|
@@ -36,7 +36,13 @@ files:
|
|
36
36
|
- init.rb
|
37
37
|
- lib/attribute_ext.rb
|
38
38
|
- lib/attribute_ext/hidden_attributes.rb
|
39
|
+
- lib/attribute_ext/railtie.rb
|
39
40
|
- lib/attribute_ext/safe_attributes.rb
|
41
|
+
- spec/hidden_attributes_spec.rb
|
42
|
+
- spec/safe_attributes_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
- spec/support/fake_environment.rb
|
45
|
+
- spec/support/stub.rb
|
40
46
|
homepage: https://github.com/jgraichen/attribute_ext
|
41
47
|
licenses: []
|
42
48
|
|