protector 0.1.1 → 0.2.1
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/Appraisals +8 -0
- data/Gemfile +5 -1
- data/README.md +16 -7
- data/gemfiles/AR_3.2.gemfile +3 -1
- data/gemfiles/AR_3.2.gemfile.lock +33 -2
- data/gemfiles/AR_4.gemfile +3 -1
- data/gemfiles/AR_4.gemfile.lock +18 -1
- data/gemfiles/Mongoid.gemfile +17 -0
- data/gemfiles/Mongoid.gemfile.lock +112 -0
- data/gemfiles/Sequel.gemfile +18 -0
- data/gemfiles/Sequel.gemfile.lock +103 -0
- data/lib/protector/adapters/active_record/base.rb +15 -17
- data/lib/protector/adapters/active_record/relation.rb +20 -61
- data/lib/protector/adapters/sequel/dataset.rb +66 -0
- data/lib/protector/adapters/sequel/eager_graph_loader.rb +24 -0
- data/lib/protector/adapters/sequel/model.rb +99 -0
- data/lib/protector/adapters/sequel.rb +17 -0
- data/lib/protector/dsl.rb +5 -2
- data/lib/protector/version.rb +1 -1
- data/lib/protector.rb +3 -1
- data/migrations/active_record.rb +0 -1
- data/migrations/sequel.rb +49 -0
- data/perf/{active_record.rb → active_record_perf.rb} +2 -0
- data/perf/perf_helpers/boot.rb +20 -2
- data/perf/sequel_perf.rb +84 -0
- data/spec/lib/adapters/active_record_spec.rb +17 -4
- data/spec/lib/adapters/sequel_spec.rb +156 -0
- data/spec/spec_helpers/adapters/active_record.rb +34 -0
- data/spec/spec_helpers/adapters/sequel.rb +64 -0
- data/spec/spec_helpers/boot.rb +3 -13
- data/spec/spec_helpers/examples/model.rb +20 -20
- metadata +17 -3
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helpers/boot'
|
2
|
+
|
3
|
+
if defined?(Sequel)
|
4
|
+
load 'spec_helpers/adapters/sequel.rb'
|
5
|
+
|
6
|
+
describe Protector::Adapters::Sequel do
|
7
|
+
before(:all) do
|
8
|
+
load 'migrations/sequel.rb'
|
9
|
+
|
10
|
+
module ProtectionCase
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do |klass|
|
14
|
+
protect do |x|
|
15
|
+
scope{ where('1=0') } if x == '-'
|
16
|
+
scope{ where("#{klass.table_name}__number".to_sym => 999) } if x == '+'
|
17
|
+
|
18
|
+
can :view, :dummy_id unless x == '-'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
[Dummy, Fluffy].each{|c| c.send :include, ProtectionCase}
|
24
|
+
|
25
|
+
Dummy.create string: 'zomgstring', number: 999, text: 'zomgtext'
|
26
|
+
Dummy.create string: 'zomgstring', number: 999, text: 'zomgtext'
|
27
|
+
Dummy.create string: 'zomgstring', number: 777, text: 'zomgtext'
|
28
|
+
Dummy.create string: 'zomgstring', number: 777, text: 'zomgtext'
|
29
|
+
|
30
|
+
[Fluffy, Bobby].each do |m|
|
31
|
+
m.create string: 'zomgstring', number: 999, text: 'zomgtext', dummy_id: 1
|
32
|
+
m.create string: 'zomgstring', number: 777, text: 'zomgtext', dummy_id: 1
|
33
|
+
m.create string: 'zomgstring', number: 999, text: 'zomgtext', dummy_id: 2
|
34
|
+
m.create string: 'zomgstring', number: 777, text: 'zomgtext', dummy_id: 2
|
35
|
+
end
|
36
|
+
|
37
|
+
Fluffy.all.each{|f| Loony.create fluffy_id: f.id, string: 'zomgstring' }
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Model instance
|
42
|
+
#
|
43
|
+
describe Protector::Adapters::Sequel::Model do
|
44
|
+
let(:dummy) do
|
45
|
+
Class.new Sequel::Model(:dummies)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "includes" do
|
49
|
+
Dummy.ancestors.should include(Protector::Adapters::Sequel::Model)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "scopes" do
|
53
|
+
scope = Dummy.restrict!('!')
|
54
|
+
scope.should be_a_kind_of Sequel::Dataset
|
55
|
+
scope.protector_subject.should == '!'
|
56
|
+
end
|
57
|
+
|
58
|
+
it_behaves_like "a model"
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Model scope
|
63
|
+
#
|
64
|
+
describe Protector::Adapters::Sequel::Dataset do
|
65
|
+
it "includes" do
|
66
|
+
Dummy.none.class.ancestors.should include(Protector::DSL::Base)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "saves subject" do
|
70
|
+
Dummy.restrict!('!').where(number: 999).protector_subject.should == '!'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "forwards subject" do
|
74
|
+
Dummy.restrict!('!').where(number: 999).first.protector_subject.should == '!'
|
75
|
+
Dummy.restrict!('!').where(number: 999).to_a.first.protector_subject.should == '!'
|
76
|
+
Dummy.restrict!('!').eager_graph(fluffies: :loony).all.first.fluffies.first.loony.protector_subject.should == '!'
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with null relation" do
|
80
|
+
it "checks existence" do
|
81
|
+
Dummy.any?.should == true
|
82
|
+
Dummy.restrict!('-').any?.should == false
|
83
|
+
end
|
84
|
+
|
85
|
+
it "counts" do
|
86
|
+
Dummy.count.should == 4
|
87
|
+
Dummy.restrict!('-').count.should == 0
|
88
|
+
end
|
89
|
+
|
90
|
+
context do
|
91
|
+
it "fetches first" do
|
92
|
+
Dummy.restrict!('-').first.should == nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "fetches all" do
|
97
|
+
fetched = Dummy.restrict!('-').to_a
|
98
|
+
|
99
|
+
Dummy.count.should == 4
|
100
|
+
fetched.length.should == 0
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with active relation" do
|
105
|
+
it "checks existence" do
|
106
|
+
Dummy.any?.should == true
|
107
|
+
Dummy.restrict!('+').any?.should == true
|
108
|
+
end
|
109
|
+
|
110
|
+
it "counts" do
|
111
|
+
Dummy.count.should == 4
|
112
|
+
Dummy.restrict!('+').count.should == 2
|
113
|
+
end
|
114
|
+
|
115
|
+
it "fetches first" do
|
116
|
+
Dummy.restrict!('+').first.should be_a_kind_of Dummy
|
117
|
+
end
|
118
|
+
|
119
|
+
it "fetches all" do
|
120
|
+
fetched = Dummy.restrict!('+').to_a
|
121
|
+
|
122
|
+
Dummy.count.should == 4
|
123
|
+
fetched.length.should == 2
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Eager loading
|
130
|
+
#
|
131
|
+
describe Protector::Adapters::Sequel::Dataset do
|
132
|
+
describe "eager loading" do
|
133
|
+
|
134
|
+
context "straight" do
|
135
|
+
it "scopes" do
|
136
|
+
d = Dummy.restrict!('+').eager(:fluffies)
|
137
|
+
d.count.should == 2
|
138
|
+
d.first.fluffies.length.should == 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "graph" do
|
143
|
+
it "scopes" do
|
144
|
+
d = Dummy.restrict!('+').eager_graph(fluffies: :loony)
|
145
|
+
d.count.should == 4
|
146
|
+
d = d.all
|
147
|
+
d.length.should == 2 # which is terribly sick :doh:
|
148
|
+
d.first.fluffies.length.should == 1
|
149
|
+
d.first.fluffies.first.loony.should be_a_kind_of Loony
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
@@ -16,10 +16,44 @@ RSpec::Matchers.define :validate do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
RSpec::Matchers.define :destroy do
|
20
|
+
match do |actual|
|
21
|
+
actual.class.transaction do
|
22
|
+
actual.destroy.should == actual
|
23
|
+
raise ActiveRecord::Rollback
|
24
|
+
end
|
25
|
+
|
26
|
+
actual.class.where(id: actual.id).delete_all
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec::Matchers.define :survive do
|
33
|
+
match do |actual|
|
34
|
+
actual.class.transaction do
|
35
|
+
actual.destroy.should == false
|
36
|
+
raise ActiveRecord::Rollback
|
37
|
+
end
|
38
|
+
|
39
|
+
actual.class.where(id: actual.id).delete_all
|
40
|
+
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
19
45
|
def log!
|
20
46
|
around(:each) do |e|
|
21
47
|
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
22
48
|
e.run
|
23
49
|
ActiveRecord::Base.logger = nil
|
24
50
|
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign!(model, fields)
|
54
|
+
model.assign_attributes(fields)
|
55
|
+
end
|
56
|
+
|
57
|
+
def read_attribute(model, field)
|
58
|
+
model.read_attribute(field)
|
25
59
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
RSpec::Matchers.define :invalidate do
|
2
|
+
match do |actual|
|
3
|
+
DB.transaction do
|
4
|
+
expect{ actual.save }.to raise_error
|
5
|
+
actual.errors.on(:base).should == ["Access denied"]
|
6
|
+
raise Sequel::Rollback
|
7
|
+
end
|
8
|
+
|
9
|
+
true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Matchers.define :validate do
|
14
|
+
match do |actual|
|
15
|
+
DB.transaction do
|
16
|
+
expect{ actual.save }.to_not raise_error
|
17
|
+
raise Sequel::Rollback
|
18
|
+
end
|
19
|
+
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec::Matchers.define :destroy do
|
25
|
+
match do |actual|
|
26
|
+
DB.transaction do
|
27
|
+
expect{ actual.destroy.should }.to_not raise_error
|
28
|
+
raise Sequel::Rollback
|
29
|
+
end
|
30
|
+
|
31
|
+
actual.class.where(id: actual.id).delete
|
32
|
+
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
RSpec::Matchers.define :survive do
|
38
|
+
match do |actual|
|
39
|
+
DB.transaction do
|
40
|
+
expect{ actual.destroy.should }.to raise_error
|
41
|
+
raise Sequel::Rollback
|
42
|
+
end
|
43
|
+
|
44
|
+
actual.class.where(id: actual.id).delete
|
45
|
+
|
46
|
+
true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def log!
|
51
|
+
around(:each) do |e|
|
52
|
+
DB.loggers << Logger.new(STDOUT)
|
53
|
+
e.run
|
54
|
+
DB.loggers = []
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def assign!(model, fields)
|
59
|
+
model.set_all(fields)
|
60
|
+
end
|
61
|
+
|
62
|
+
def read_attribute(model, field)
|
63
|
+
model.instance_variable_get("@values")[field]
|
64
|
+
end
|
data/spec/spec_helpers/boot.rb
CHANGED
@@ -1,21 +1,11 @@
|
|
1
1
|
Bundler.require
|
2
2
|
|
3
|
+
require 'coveralls'
|
4
|
+
Coveralls.wear! if Coveralls.should_run?
|
5
|
+
|
3
6
|
require 'protector'
|
4
7
|
require_relative 'examples/model'
|
5
8
|
|
6
|
-
module ProtectionCase
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
protect do |x|
|
11
|
-
scope{ where('1=0') } if x == '-'
|
12
|
-
scope{ where(number: 999) } if x == '+'
|
13
|
-
|
14
|
-
can :view, :dummy_id unless x == '-'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
9
|
RSpec.configure do |config|
|
20
10
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
21
11
|
config.run_all_when_everything_filtered = true
|
@@ -12,7 +12,7 @@ shared_examples_for "a model" do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
fields = Hash[*%w(id string number text dummy_id
|
15
|
+
fields = Hash[*%w(id string number text dummy_id).map{|x| [x, nil]}.flatten]
|
16
16
|
meta = dummy.new.restrict!('!').protector_meta
|
17
17
|
|
18
18
|
meta.access[:view].should == fields
|
@@ -53,7 +53,7 @@ shared_examples_for "a model" do
|
|
53
53
|
d = dummy.first.restrict!('!')
|
54
54
|
d.number.should == nil
|
55
55
|
d[:number].should == nil
|
56
|
-
|
56
|
+
read_attribute(d, :number).should_not == nil
|
57
57
|
d.string.should == 'zomgstring'
|
58
58
|
end
|
59
59
|
end
|
@@ -184,13 +184,13 @@ shared_examples_for "a model" do
|
|
184
184
|
|
185
185
|
it "marks blocked" do
|
186
186
|
d = dummy.first
|
187
|
-
d
|
187
|
+
assign!(d, string: 'bam', number: 1)
|
188
188
|
d.restrict!('!').updatable?.should == false
|
189
189
|
end
|
190
190
|
|
191
191
|
it "invalidates" do
|
192
192
|
d = dummy.first.restrict!('!')
|
193
|
-
d
|
193
|
+
assign!(d, string: 'bam', number: 1)
|
194
194
|
d.should invalidate
|
195
195
|
end
|
196
196
|
end
|
@@ -206,25 +206,25 @@ shared_examples_for "a model" do
|
|
206
206
|
|
207
207
|
it "marks blocked" do
|
208
208
|
d = dummy.first
|
209
|
-
d
|
209
|
+
assign!(d, string: 'bam', number: 1)
|
210
210
|
d.restrict!('!').updatable?.should == false
|
211
211
|
end
|
212
212
|
|
213
213
|
it "marks allowed" do
|
214
214
|
d = dummy.first
|
215
|
-
d
|
215
|
+
assign!(d, string: 'bam')
|
216
216
|
d.restrict!('!').updatable?.should == true
|
217
217
|
end
|
218
218
|
|
219
219
|
it "invalidates" do
|
220
220
|
d = dummy.first.restrict!('!')
|
221
|
-
d
|
221
|
+
assign!(d, string: 'bam', number: 1)
|
222
222
|
d.should invalidate
|
223
223
|
end
|
224
224
|
|
225
225
|
it "validates" do
|
226
226
|
d = dummy.first.restrict!('!')
|
227
|
-
d
|
227
|
+
assign!(d, string: 'bam')
|
228
228
|
d.should validate
|
229
229
|
end
|
230
230
|
end
|
@@ -240,25 +240,25 @@ shared_examples_for "a model" do
|
|
240
240
|
|
241
241
|
it "marks blocked" do
|
242
242
|
d = dummy.first
|
243
|
-
d
|
243
|
+
assign!(d, string: 'bam')
|
244
244
|
d.restrict!('!').updatable?.should == false
|
245
245
|
end
|
246
246
|
|
247
247
|
it "marks allowed" do
|
248
248
|
d = dummy.first
|
249
|
-
d
|
249
|
+
assign!(d, string: '12345')
|
250
250
|
d.restrict!('!').updatable?.should == true
|
251
251
|
end
|
252
252
|
|
253
253
|
it "invalidates" do
|
254
254
|
d = dummy.first.restrict!('!')
|
255
|
-
d
|
255
|
+
assign!(d, string: 'bam')
|
256
256
|
d.should invalidate
|
257
257
|
end
|
258
258
|
|
259
259
|
it "validates" do
|
260
260
|
d = dummy.first.restrict!('!')
|
261
|
-
d
|
261
|
+
assign!(d, string: '12345')
|
262
262
|
d.should validate
|
263
263
|
end
|
264
264
|
end
|
@@ -274,25 +274,25 @@ shared_examples_for "a model" do
|
|
274
274
|
|
275
275
|
it "marks blocked" do
|
276
276
|
d = dummy.first
|
277
|
-
d
|
277
|
+
assign!(d, number: 500)
|
278
278
|
d.restrict!('!').updatable?.should == false
|
279
279
|
end
|
280
280
|
|
281
281
|
it "marks allowed" do
|
282
282
|
d = dummy.first
|
283
|
-
d
|
283
|
+
assign!(d, number: 2)
|
284
284
|
d.restrict!('!').updatable?.should == true
|
285
285
|
end
|
286
286
|
|
287
287
|
it "invalidates" do
|
288
288
|
d = dummy.first.restrict!('!')
|
289
|
-
d
|
289
|
+
assign!(d, number: 500)
|
290
290
|
d.should invalidate
|
291
291
|
end
|
292
292
|
|
293
293
|
it "validates" do
|
294
294
|
d = dummy.first.restrict!('!')
|
295
|
-
d
|
295
|
+
assign!(d, number: 2)
|
296
296
|
d.should validate
|
297
297
|
end
|
298
298
|
end
|
@@ -323,7 +323,8 @@ shared_examples_for "a model" do
|
|
323
323
|
protect do; end
|
324
324
|
end
|
325
325
|
|
326
|
-
dummy.
|
326
|
+
d = dummy.create.restrict!('!')
|
327
|
+
d.should survive
|
327
328
|
end
|
328
329
|
|
329
330
|
it "validates" do
|
@@ -331,9 +332,8 @@ shared_examples_for "a model" do
|
|
331
332
|
protect do; can :destroy; end
|
332
333
|
end
|
333
334
|
|
334
|
-
d = dummy.create
|
335
|
-
d.
|
336
|
-
d.destroyed?.should == true
|
335
|
+
d = dummy.create.restrict!('!')
|
336
|
+
d.should destroy
|
337
337
|
end
|
338
338
|
end
|
339
339
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Staal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -59,22 +59,34 @@ files:
|
|
59
59
|
- gemfiles/AR_3.2.gemfile.lock
|
60
60
|
- gemfiles/AR_4.gemfile
|
61
61
|
- gemfiles/AR_4.gemfile.lock
|
62
|
+
- gemfiles/Mongoid.gemfile
|
63
|
+
- gemfiles/Mongoid.gemfile.lock
|
64
|
+
- gemfiles/Sequel.gemfile
|
65
|
+
- gemfiles/Sequel.gemfile.lock
|
62
66
|
- lib/protector.rb
|
63
67
|
- lib/protector/adapters/active_record.rb
|
64
68
|
- lib/protector/adapters/active_record/association.rb
|
65
69
|
- lib/protector/adapters/active_record/base.rb
|
66
70
|
- lib/protector/adapters/active_record/preloader.rb
|
67
71
|
- lib/protector/adapters/active_record/relation.rb
|
72
|
+
- lib/protector/adapters/sequel.rb
|
73
|
+
- lib/protector/adapters/sequel/dataset.rb
|
74
|
+
- lib/protector/adapters/sequel/eager_graph_loader.rb
|
75
|
+
- lib/protector/adapters/sequel/model.rb
|
68
76
|
- lib/protector/dsl.rb
|
69
77
|
- lib/protector/version.rb
|
70
78
|
- locales/en.yml
|
71
79
|
- migrations/active_record.rb
|
72
|
-
-
|
80
|
+
- migrations/sequel.rb
|
81
|
+
- perf/active_record_perf.rb
|
73
82
|
- perf/perf_helpers/boot.rb
|
83
|
+
- perf/sequel_perf.rb
|
74
84
|
- protector.gemspec
|
75
85
|
- spec/lib/adapters/active_record_spec.rb
|
86
|
+
- spec/lib/adapters/sequel_spec.rb
|
76
87
|
- spec/lib/dsl_spec.rb
|
77
88
|
- spec/spec_helpers/adapters/active_record.rb
|
89
|
+
- spec/spec_helpers/adapters/sequel.rb
|
78
90
|
- spec/spec_helpers/boot.rb
|
79
91
|
- spec/spec_helpers/examples/model.rb
|
80
92
|
homepage: https://github.com/inossidabile/protector
|
@@ -104,7 +116,9 @@ summary: 'Protector is a successor to the Heimdallr gem: it hits the same goals
|
|
104
116
|
the Ruby way'
|
105
117
|
test_files:
|
106
118
|
- spec/lib/adapters/active_record_spec.rb
|
119
|
+
- spec/lib/adapters/sequel_spec.rb
|
107
120
|
- spec/lib/dsl_spec.rb
|
108
121
|
- spec/spec_helpers/adapters/active_record.rb
|
122
|
+
- spec/spec_helpers/adapters/sequel.rb
|
109
123
|
- spec/spec_helpers/boot.rb
|
110
124
|
- spec/spec_helpers/examples/model.rb
|