protector 0.2.4 → 0.3.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68d28de469f168b9678e739b5a6193292163b33c
4
- data.tar.gz: 059591c46f57f4331ba39df89bd75ed79e10df46
3
+ metadata.gz: 2b37c2f2aabf355a3953ac75518bdb389317c460
4
+ data.tar.gz: 2a4e9e21d922f263c4518aafd19ea95f043239bb
5
5
  SHA512:
6
- metadata.gz: 20e28e28708bcf3dca908672c2783b5c8e19bb40230c85bdb041fbc0e70392e363a68438a39bcdd98c3e40634d6240318d30bbb93c3c09559e191b5f86d99cf0
7
- data.tar.gz: 6319e7cec8f0ead0ef55d4bdec193df10a59c153081cbe36c1174eb3914a7df31016369a48835610ccdc7a3c6dd6c742d6e283acc59f38423ef1daffaaacc008
6
+ metadata.gz: ce3cf9b5c16c4a1ac0c6126049eb645cc4fea48e8b264a6d833b97a9100e63d2f0dff4924073e4482e6819d695edd90a36ae864ae94b6874489c3c0bba2219e4
7
+ data.tar.gz: 9a97ac4a1ecee65b4b796ef2ca3ec9d58df8c1b9d92b9eaffb1211f3cec3c59476012361eefa2d43de996f67bc26c54f99c044ee8d51adee524b7a4022b942aa
@@ -10,7 +10,7 @@ GIT
10
10
  PATH
11
11
  remote: /Users/inossidabile/Repos/protector
12
12
  specs:
13
- protector (0.2.3)
13
+ protector (0.3.0.beta.1)
14
14
  activesupport
15
15
  i18n
16
16
 
@@ -6,7 +6,7 @@ GIT
6
6
  PATH
7
7
  remote: /Users/inossidabile/Repos/protector
8
8
  specs:
9
- protector (0.2.3)
9
+ protector (0.3.0.beta.1)
10
10
  activesupport
11
11
  i18n
12
12
 
@@ -1,19 +1,23 @@
1
1
  PATH
2
2
  remote: /Users/inossidabile/Repos/protector
3
3
  specs:
4
- protector (0.2.3)
4
+ protector (0.3.0.beta.1)
5
5
  activesupport
6
6
  i18n
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (3.2.12)
12
- i18n (~> 0.6)
13
- multi_json (~> 1.0)
11
+ activesupport (4.0.0)
12
+ i18n (~> 0.6, >= 0.6.4)
13
+ minitest (~> 4.2)
14
+ multi_json (~> 1.3)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 0.3.37)
14
17
  appraisal (0.5.2)
15
18
  bundler
16
19
  rake
20
+ atomic (1.1.10)
17
21
  coderay (1.0.9)
18
22
  colored (1.2)
19
23
  colorize (0.5.8)
@@ -45,6 +49,7 @@ GEM
45
49
  lumberjack (1.0.3)
46
50
  method_source (0.8.1)
47
51
  mime-types (1.23)
52
+ minitest (4.7.5)
48
53
  multi_json (1.7.5)
49
54
  pry (0.9.12.2)
50
55
  coderay (~> 1.0.5)
@@ -82,6 +87,9 @@ GEM
82
87
  ffi
83
88
  sqlite3 (1.3.7)
84
89
  thor (0.18.1)
90
+ thread_safe (0.1.0)
91
+ atomic
92
+ tzinfo (0.3.37)
85
93
 
86
94
  PLATFORMS
87
95
  java
@@ -17,7 +17,9 @@ module Protector
17
17
 
18
18
  # Wraps every association with current subject
19
19
  def scope_with_protector(*args)
20
- scope_without_protector(*args).restrict!(owner.protector_subject)
20
+ scope = scope_without_protector(*args)
21
+ scope = scope.restrict!(owner.protector_subject) if owner.protector_subject?
22
+ scope
21
23
  end
22
24
  end
23
25
  end
@@ -14,14 +14,14 @@ module Protector
14
14
  end
15
15
 
16
16
  validate do
17
- return unless @protector_subject
17
+ return unless protector_subject?
18
18
  if (new_record? && !creatable?) || (!new_record? && !updatable?)
19
19
  errors[:base] << I18n.t('protector.invalid')
20
20
  end
21
21
  end
22
22
 
23
23
  before_destroy do
24
- return true unless @protector_subject
24
+ return true unless protector_subject?
25
25
  destroyable?
26
26
  end
27
27
 
@@ -43,7 +43,7 @@ module Protector
43
43
 
44
44
  def [](name)
45
45
  if (
46
- !@protector_subject ||
46
+ !protector_subject? ||
47
47
  name == self.class.primary_key ||
48
48
  (self.class.primary_key.is_a?(Array) && self.class.primary_key.include?(name)) ||
49
49
  protector_meta.readable?(name)
@@ -66,7 +66,7 @@ module Protector
66
66
  alias_method #{"#{name}_unprotected".inspect}, #{name.inspect}
67
67
 
68
68
  def #{name}
69
- if !@protector_subject || protector_meta.readable?(#{name.inspect})
69
+ if !protector_subject? || protector_meta.readable?(#{name.inspect})
70
70
  #{name}_unprotected
71
71
  else
72
72
  nil
@@ -81,7 +81,7 @@ module Protector
81
81
  def protector_meta
82
82
  @protector_meta ||= self.class.protector_meta.evaluate(
83
83
  self.class,
84
- @protector_subject,
84
+ protector_subject,
85
85
  self.class.column_names,
86
86
  self
87
87
  )
@@ -23,9 +23,13 @@ module Protector
23
23
  owners.first.protector_subject
24
24
  end
25
25
 
26
+ def protector_subject?
27
+ owners.first.protector_subject?
28
+ end
29
+
26
30
  # Restricts preloading association scope with subject of the owner
27
31
  def scope_with_protector(*args)
28
- return scope_without_protector unless protector_subject
32
+ return scope_without_protector unless protector_subject?
29
33
 
30
34
  @meta ||= klass.protector_meta.evaluate(klass, protector_subject)
31
35
  scope_without_protector.merge(@meta.relation)
@@ -28,13 +28,13 @@ module Protector
28
28
  # Gets {Protector::DSL::Meta::Box} of this relation
29
29
  def protector_meta
30
30
  # We don't seem to require columns here as well
31
- # @klass.protector_meta.evaluate(@klass, @protector_subject, @klass.column_names)
32
- @klass.protector_meta.evaluate(@klass, @protector_subject)
31
+ @klass.protector_meta.evaluate(@klass, protector_subject)
33
32
  end
34
33
 
35
34
  # @note Unscoped relation drops properties and therefore should be re-restricted
36
35
  def unscoped
37
- super.restrict!(@protector_subject)
36
+ return super unless protector_subject?
37
+ super.restrict!(protector_subject)
38
38
  end
39
39
 
40
40
  # @note This is here cause `NullRelation` can return `nil` from `count`
@@ -49,13 +49,13 @@ module Protector
49
49
 
50
50
  # Merges current relation with restriction and calls real `calculate`
51
51
  def calculate(*args)
52
- return super unless @protector_subject
52
+ return super unless protector_subject?
53
53
  merge(protector_meta.relation).unrestrict!.calculate *args
54
54
  end
55
55
 
56
56
  # Merges current relation with restriction and calls real `exists?`
57
57
  def exists?(*args)
58
- return super unless @protector_subject
58
+ return super unless protector_subject?
59
59
  merge(protector_meta.relation).unrestrict!.exists? *args
60
60
  end
61
61
 
@@ -68,11 +68,11 @@ module Protector
68
68
  # * merging current relation with restriction (of self and every eager association)
69
69
  def exec_queries_with_protector(*args)
70
70
  return @records if loaded?
71
- return exec_queries_without_protector unless @protector_subject
71
+ return exec_queries_without_protector unless protector_subject?
72
72
 
73
- subject = @protector_subject
73
+ subject = protector_subject
74
74
  relation = merge(protector_meta.relation).unrestrict!
75
- relation = protector_substitute_includes(relation)
75
+ relation = protector_substitute_includes(subject, relation)
76
76
 
77
77
  # Preserve associations from internal loading. We are going to handle that
78
78
  # ourselves respecting security scopes FTW!
@@ -91,9 +91,7 @@ module Protector
91
91
 
92
92
  # Swaps `includes` with `preload` whether it's not referenced or merges
93
93
  # security scope of proper class otherwise
94
- def protector_substitute_includes(relation)
95
- subject = @protector_subject
96
-
94
+ def protector_substitute_includes(subject, relation)
97
95
  if eager_loading?
98
96
  protector_expand_inclusion(includes_values + eager_load_values).each do |klass, path|
99
97
  # AR drops default_scope for eagerly loadable associations
@@ -32,17 +32,17 @@ module Protector
32
32
 
33
33
  # Gets {Protector::DSL::Meta::Box} of this dataset
34
34
  def protector_meta
35
- model.protector_meta.evaluate(model, @protector_subject)
35
+ model.protector_meta.evaluate(model, protector_subject)
36
36
  end
37
37
 
38
38
  # Substitutes `row_proc` with {Protector} and injects protection scope
39
39
  def each_with_protector(*args, &block)
40
- return each_without_protector(*args, &block) if !@protector_subject
40
+ return each_without_protector(*args, &block) unless protector_subject?
41
41
 
42
- relation = protector_defend_graph(clone, @protector_subject)
42
+ relation = protector_defend_graph(clone, protector_subject)
43
43
  relation = relation.instance_eval(&protector_meta.scope_proc) if protector_meta.scoped?
44
44
 
45
- relation.row_proc = Restrictor.new(@protector_subject, relation.row_proc)
45
+ relation.row_proc = Restrictor.new(protector_subject, relation.row_proc)
46
46
  relation.each_without_protector(*args, &block)
47
47
  end
48
48
 
@@ -11,7 +11,7 @@ module Protector
11
11
  def initialize_with_protector(dataset)
12
12
  initialize_without_protector(dataset)
13
13
 
14
- if dataset.protector_subject
14
+ if dataset.protector_subject?
15
15
  @row_procs.each do |k,v|
16
16
  @row_procs[k] = Dataset::Restrictor.new(dataset.protector_subject, v)
17
17
  @ta_map[k][1] = @row_procs[k] if @ta_map.has_key?(k)
@@ -26,7 +26,7 @@ module Protector
26
26
  def protector_meta
27
27
  @protector_meta ||= self.class.protector_meta.evaluate(
28
28
  self.class,
29
- @protector_subject,
29
+ protector_subject,
30
30
  self.class.columns,
31
31
  self
32
32
  )
@@ -62,14 +62,14 @@ module Protector
62
62
  # Basic security validations
63
63
  def validate
64
64
  super
65
- return unless @protector_subject
65
+ return unless protector_subject?
66
66
  method = new? ? :creatable? : :updatable?
67
67
  errors.add(:base, I18n.t('protector.invalid')) unless __send__(method)
68
68
  end
69
69
 
70
70
  # Destroy availability check
71
71
  def before_destroy
72
- return false if @protector_subject && !destroyable?
72
+ return false if protector_subject? && !destroyable?
73
73
  super
74
74
  end
75
75
 
@@ -78,7 +78,7 @@ module Protector
78
78
  # @param name [Symbol] Name of attribute to read
79
79
  def [](name)
80
80
  if (
81
- !@protector_subject ||
81
+ !protector_subject? ||
82
82
  name == self.class.primary_key ||
83
83
  (self.class.primary_key.is_a?(Array) && self.class.primary_key.include?(name)) ||
84
84
  protector_meta.readable?(name.to_s)
@@ -91,12 +91,12 @@ module Protector
91
91
 
92
92
  # This is used whenever we fetch data
93
93
  def _associated_dataset(*args)
94
- super.restrict!(@protector_subject)
94
+ super.restrict!(protector_subject)
95
95
  end
96
96
 
97
97
  # This is used whenever we call counters and existance checkers
98
98
  def _dataset(*args)
99
- super.restrict!(@protector_subject)
99
+ super.restrict!(protector_subject)
100
100
  end
101
101
  end
102
102
  end
@@ -207,8 +207,6 @@ module Protector
207
207
  # @param fields [Array<String>] All the fields the model has
208
208
  # @param entry [Object] An instance of the model
209
209
  def evaluate(model, subject, fields=[], entry=nil)
210
- raise "Unprotected entity detected: use `restrict` method to protect it." unless subject
211
-
212
210
  Box.new(model, fields, subject, entry, blocks)
213
211
  end
214
212
  end
@@ -216,8 +214,14 @@ module Protector
216
214
  module Base
217
215
  extend ActiveSupport::Concern
218
216
 
219
- included do
220
- attr_reader :protector_subject
217
+ # Property accessor that makes sure you don't use
218
+ # subject on a non-protected model
219
+ def protector_subject
220
+ unless protector_subject?
221
+ raise "Unprotected entity detected: use `restrict` method to protect it."
222
+ end
223
+
224
+ @protector_subject
221
225
  end
222
226
 
223
227
  # Assigns restriction subject
@@ -225,14 +229,21 @@ module Protector
225
229
  # @param [Object] subject Subject to restrict against
226
230
  def restrict!(subject)
227
231
  @protector_subject = subject
232
+ @protector_subject_set = true
228
233
  self
229
234
  end
230
235
 
231
236
  # Clears restriction subject
232
237
  def unrestrict!
233
238
  @protector_subject = nil
239
+ @protector_subject_set = false
234
240
  self
235
241
  end
242
+
243
+ # Checks if model was restricted
244
+ def protector_subject?
245
+ @protector_subject_set == true
246
+ end
236
247
  end
237
248
 
238
249
  module Entry
@@ -1,4 +1,4 @@
1
1
  module Protector
2
2
  # Gem version
3
- VERSION = "0.2.4"
3
+ VERSION = "0.3.0.beta.2"
4
4
  end
@@ -11,6 +11,16 @@ describe Protector::DSL do
11
11
  @base.instance_methods.should include(:protector_subject)
12
12
  end
13
13
 
14
+ it "throws error for empty subect" do
15
+ base = @base.new
16
+ expect { base.protector_subject }.to raise_error
17
+ end
18
+
19
+ it "accepts nil as a subject" do
20
+ base = @base.new.restrict!(nil)
21
+ expect { base.protector_subject }.to_not raise_error
22
+ end
23
+
14
24
  it "remembers protection subject" do
15
25
  base = @base.new
16
26
  base.restrict!("universe")
@@ -22,7 +32,7 @@ describe Protector::DSL do
22
32
  base.restrict!("universe")
23
33
  base.protector_subject.should == "universe"
24
34
  base.unrestrict!
25
- base.protector_subject.should == nil
35
+ expect { base.protector_subject }.to raise_error
26
36
  end
27
37
  end
28
38
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0.beta.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Staal
@@ -104,9 +104,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
104
  version: '0'
105
105
  required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - '>='
107
+ - - '>'
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: 1.3.1
110
110
  requirements: []
111
111
  rubyforge_project:
112
112
  rubygems_version: 2.0.2