protector 0.2.4 → 0.3.0.beta.2

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 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