protector 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|