strelka 0.0.1.pre.244 → 0.0.1.pre.252
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.tar.gz.sig +0 -0
- data/ChangeLog +57 -3
- data/Manifest.txt +3 -4
- data/Rakefile +1 -1
- data/bin/strelka +4 -7
- data/examples/.env +4 -0
- data/examples/Procfile +8 -0
- data/examples/apps/auth-demo +3 -5
- data/examples/apps/auth-demo2 +10 -9
- data/{data/strelka → examples}/apps/hello-world +1 -2
- data/examples/apps/sessions-demo +2 -2
- data/examples/config.yml +12 -1
- data/examples/gen-config.rb +5 -6
- data/examples/templates/auth-form.tmpl +4 -0
- data/examples/templates/auth-success.tmpl +3 -1
- data/lib/strelka.rb +15 -21
- data/lib/strelka/app.rb +53 -31
- data/lib/strelka/app/auth.rb +260 -132
- data/lib/strelka/app/sessions.rb +25 -31
- data/lib/strelka/authprovider/basic.rb +33 -9
- data/lib/strelka/authprovider/hostaccess.rb +1 -1
- data/lib/strelka/constants.rb +0 -11
- data/lib/strelka/cookie.rb +17 -1
- data/lib/strelka/httpresponse/negotiation.rb +1 -1
- data/lib/strelka/session/db.rb +49 -25
- data/lib/strelka/session/default.rb +39 -19
- data/spec/lib/helpers.rb +3 -24
- data/spec/strelka/app/auth_spec.rb +461 -177
- data/spec/strelka/app/sessions_spec.rb +7 -26
- data/spec/strelka/app_spec.rb +3 -3
- data/spec/strelka/authprovider/basic_spec.rb +4 -4
- data/spec/strelka/httprequest/session_spec.rb +1 -1
- data/spec/strelka/httpresponse/session_spec.rb +1 -1
- data/spec/strelka/session/db_spec.rb +6 -1
- data/spec/strelka/session/default_spec.rb +3 -3
- metadata +7 -8
- metadata.gz.sig +2 -2
- data/examples/apps/ws-echo +0 -17
- data/lib/strelka/logging.rb +0 -301
- data/spec/strelka/logging_spec.rb +0 -74
data/spec/lib/helpers.rb
CHANGED
@@ -28,6 +28,7 @@ if ENV['COVERAGE']
|
|
28
28
|
end
|
29
29
|
|
30
30
|
require 'loggability'
|
31
|
+
require 'loggability/spechelpers'
|
31
32
|
require 'configurability'
|
32
33
|
require 'pathname'
|
33
34
|
require 'tmpdir'
|
@@ -55,30 +56,6 @@ module Strelka::SpecHelpers
|
|
55
56
|
end
|
56
57
|
|
57
58
|
|
58
|
-
### Reset the logging subsystem to its default state.
|
59
|
-
def reset_logging
|
60
|
-
Loggability.formatter = nil
|
61
|
-
Loggability.output_to( $stderr )
|
62
|
-
Loggability.level = :fatal
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
### Alter the output of the default log formatter to be pretty in SpecMate output
|
67
|
-
def setup_logging( level=:fatal )
|
68
|
-
|
69
|
-
# Only do this when executing from a spec in TextMate
|
70
|
-
if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
|
71
|
-
logarray = []
|
72
|
-
Thread.current['logger-output'] = logarray
|
73
|
-
Loggability.output_to( logarray )
|
74
|
-
Loggability.format_as( :html )
|
75
|
-
Loggability.level = :debug
|
76
|
-
else
|
77
|
-
Loggability.level = level
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
59
|
### Set up a Mongrel2 configuration database according to the specified +dbspec+.
|
83
60
|
### Set up a Mongrel2 configuration database in memory.
|
84
61
|
def setup_config_db
|
@@ -272,8 +249,10 @@ RSpec.configure do |c|
|
|
272
249
|
|
273
250
|
c.mock_with( :rspec )
|
274
251
|
|
252
|
+
c.extend( Strelka::TestConstants )
|
275
253
|
c.extend( Strelka::TestConstants )
|
276
254
|
c.include( Strelka::TestConstants )
|
255
|
+
c.include( Loggability::SpecHelpers )
|
277
256
|
c.include( Mongrel2::SpecHelpers )
|
278
257
|
c.include( Strelka::SpecHelpers )
|
279
258
|
# c.include( Strelka::Matchers )
|
@@ -89,12 +89,12 @@ describe Strelka::App::Auth do
|
|
89
89
|
end
|
90
90
|
|
91
91
|
|
92
|
-
it "applies
|
92
|
+
it "applies authentication and authorization to every request by default" do
|
93
93
|
app = @app.new
|
94
94
|
req = @request_factory.get( '/api/v1' )
|
95
95
|
|
96
96
|
app.auth_provider.should_receive( :authenticate ).and_return( 'anonymous' )
|
97
|
-
app.auth_provider.should_receive( :authorize )
|
97
|
+
app.auth_provider.should_receive( :authorize )
|
98
98
|
|
99
99
|
res = app.handle( req )
|
100
100
|
|
@@ -117,300 +117,584 @@ describe Strelka::App::Auth do
|
|
117
117
|
end
|
118
118
|
|
119
119
|
it "has its auth config inherited by subclasses" do
|
120
|
-
@app.class_eval do
|
121
|
-
auth_provider :hostaccess
|
122
|
-
authz_callback { true }
|
123
|
-
end
|
124
120
|
subclass = Class.new( @app )
|
125
121
|
|
126
|
-
subclass.auth_provider.should == @app.auth_provider
|
127
|
-
subclass.authz_callback.should == @app.authz_callback
|
128
122
|
subclass.positive_auth_criteria.should == @app.positive_auth_criteria
|
129
123
|
subclass.positive_auth_criteria.should_not equal( @app.positive_auth_criteria )
|
130
124
|
subclass.negative_auth_criteria.should == @app.negative_auth_criteria
|
131
125
|
subclass.negative_auth_criteria.should_not equal( @app.negative_auth_criteria )
|
126
|
+
subclass.positive_perms_criteria.should == @app.positive_perms_criteria
|
127
|
+
subclass.positive_perms_criteria.should_not equal( @app.positive_perms_criteria )
|
128
|
+
subclass.negative_perms_criteria.should == @app.negative_perms_criteria
|
129
|
+
subclass.negative_perms_criteria.should_not equal( @app.negative_perms_criteria )
|
132
130
|
end
|
133
131
|
|
134
132
|
|
135
|
-
|
133
|
+
it "allows auth criteria to be declared with a string" do
|
134
|
+
@app.require_auth_for( '/string' )
|
135
|
+
app = @app.new
|
136
136
|
|
137
|
-
|
138
|
-
|
139
|
-
|
137
|
+
req = @request_factory.get( '/api/v1/string' )
|
138
|
+
app.request_should_auth?( req ).should be_true()
|
139
|
+
req = @request_factory.get( '/api/v1/strong' )
|
140
|
+
app.request_should_auth?( req ).should be_false()
|
141
|
+
req = @request_factory.get( '/api/v1/stri' )
|
142
|
+
app.request_should_auth?( req ).should be_false()
|
143
|
+
req = @request_factory.get( '/api/v1/string/long' )
|
144
|
+
app.request_should_auth?( req ).should be_false()
|
145
|
+
end
|
140
146
|
|
141
|
-
|
142
|
-
|
147
|
+
it "allows auth criteria to be declared with a regexp" do
|
148
|
+
@app.require_auth_for( %r{/str[io]} )
|
149
|
+
app = @app.new
|
150
|
+
|
151
|
+
req = @request_factory.get( '/api/v1/stri' )
|
152
|
+
app.request_should_auth?( req ).should be_true()
|
153
|
+
req = @request_factory.get( '/api/v1/stro' )
|
154
|
+
app.request_should_auth?( req ).should be_true()
|
155
|
+
req = @request_factory.get( '/api/v1/string' ) # not right-bound
|
156
|
+
app.request_should_auth?( req ).should be_true()
|
157
|
+
req = @request_factory.get( '/api/v1/string/long' )
|
158
|
+
app.request_should_auth?( req ).should be_true()
|
159
|
+
req = @request_factory.get( '/api/v1/other/string/long' ) # Not left-bound
|
160
|
+
app.request_should_auth?( req ).should be_true()
|
161
|
+
req = @request_factory.get( '/api/v1/chatlog' ) # Not left-bound
|
162
|
+
app.request_should_auth?( req ).should be_false()
|
163
|
+
end
|
164
|
+
|
165
|
+
it "allows auth criteria to be declared with a string and a block" do
|
166
|
+
@app.require_auth_for( 'string' ) do |req|
|
167
|
+
req.verb != :GET
|
143
168
|
end
|
144
169
|
|
145
|
-
|
146
|
-
req = @request_factory.get( '/api/v1/' )
|
170
|
+
app = @app.new
|
147
171
|
|
148
|
-
|
149
|
-
|
150
|
-
|
172
|
+
req = @request_factory.get( '/api/v1/string' )
|
173
|
+
app.request_should_auth?( req ).should be_false()
|
174
|
+
req = @request_factory.post( '/api/v1/string' )
|
175
|
+
app.request_should_auth?( req ).should be_true()
|
176
|
+
req = @request_factory.put( '/api/v1/string' )
|
177
|
+
app.request_should_auth?( req ).should be_true()
|
178
|
+
req = @request_factory.delete( '/api/v1/string' )
|
179
|
+
app.request_should_auth?( req ).should be_true()
|
180
|
+
req = @request_factory.options( '/api/v1/string' )
|
181
|
+
app.request_should_auth?( req ).should be_true()
|
182
|
+
end
|
151
183
|
|
152
|
-
|
184
|
+
it "allows auth criteria to be declared with a regexp and a block" do
|
185
|
+
@app.require_auth_for( %r{/regexp(?:/(?<username>\w+))?} ) do |req, match|
|
186
|
+
match[:username] ? true : false
|
153
187
|
end
|
154
188
|
|
155
|
-
|
156
|
-
req = @request_factory.get( '/api/v1/console' )
|
189
|
+
app = @app.new
|
157
190
|
|
158
|
-
|
159
|
-
|
160
|
-
|
191
|
+
req = @request_factory.get( '/api/v1/regexp' )
|
192
|
+
app.request_should_auth?( req ).should be_false()
|
193
|
+
req = @request_factory.get( '/api/v1/regexp/a_username' )
|
194
|
+
app.request_should_auth?( req ).should be_true()
|
195
|
+
req = @request_factory.get( '/api/v1/regexp/%20not+a+username' )
|
196
|
+
app.request_should_auth?( req ).should be_false()
|
197
|
+
end
|
161
198
|
|
162
|
-
|
199
|
+
it "allows auth criteria to be declared with just a block" do
|
200
|
+
@app.require_auth_for do |req|
|
201
|
+
path = req.app_path.gsub( %r{^/+|/+$}, '' )
|
202
|
+
|
203
|
+
(
|
204
|
+
path == 'strong' or
|
205
|
+
path =~ %r{^marlon_brando$}i or
|
206
|
+
req.verb == :POST or
|
207
|
+
req.content_type == 'application/x-www-form-urlencoded'
|
208
|
+
)
|
163
209
|
end
|
164
210
|
|
211
|
+
app = @app.new
|
212
|
+
|
213
|
+
req = @request_factory.get( '/api/v1/strong' )
|
214
|
+
app.request_should_auth?( req ).should be_true()
|
215
|
+
req = @request_factory.get( '/api/v1/marlon_brando' )
|
216
|
+
app.request_should_auth?( req ).should be_true()
|
217
|
+
req = @request_factory.post( '/api/v1/somewhere' )
|
218
|
+
app.request_should_auth?( req ).should be_true()
|
219
|
+
req = @request_factory.put( '/api/v1/somewhere' )
|
220
|
+
req.content_type = 'application/x-www-form-urlencoded'
|
221
|
+
app.request_should_auth?( req ).should be_true()
|
222
|
+
|
223
|
+
req = @request_factory.get( '/api/v1/string' )
|
224
|
+
app.request_should_auth?( req ).should be_false()
|
225
|
+
req = @request_factory.get( '/api/v1/marlon_brando/2' )
|
226
|
+
app.request_should_auth?( req ).should be_false()
|
227
|
+
req = @request_factory.put( '/api/v1/somewhere' )
|
228
|
+
app.request_should_auth?( req ).should be_false()
|
229
|
+
|
165
230
|
end
|
166
231
|
|
167
|
-
context "that has negative auth criteria" do
|
168
232
|
|
169
|
-
|
170
|
-
|
171
|
-
|
233
|
+
it "allows negative auth criteria to be declared with a string" do
|
234
|
+
@app.no_auth_for( '/string' )
|
235
|
+
app = @app.new
|
172
236
|
|
173
|
-
|
174
|
-
|
175
|
-
|
237
|
+
req = @request_factory.get( '/api/v1/string' )
|
238
|
+
app.request_should_auth?( req ).should be_false()
|
239
|
+
req = @request_factory.get( '/api/v1/strong' )
|
240
|
+
app.request_should_auth?( req ).should be_true()
|
241
|
+
req = @request_factory.get( '/api/v1/stri' )
|
242
|
+
app.request_should_auth?( req ).should be_true()
|
243
|
+
req = @request_factory.get( '/api/v1/string/long' )
|
244
|
+
app.request_should_auth?( req ).should be_true()
|
245
|
+
end
|
176
246
|
|
177
|
-
|
178
|
-
|
247
|
+
it "allows negative auth criteria to be declared with a regexp" do
|
248
|
+
@app.no_auth_for( %r{/str[io]} )
|
249
|
+
app = @app.new
|
179
250
|
|
180
|
-
|
181
|
-
|
182
|
-
|
251
|
+
req = @request_factory.get( '/api/v1/stri' )
|
252
|
+
app.request_should_auth?( req ).should be_false()
|
253
|
+
req = @request_factory.get( '/api/v1/stro' )
|
254
|
+
app.request_should_auth?( req ).should be_false()
|
255
|
+
req = @request_factory.get( '/api/v1/string' ) # not right-bound
|
256
|
+
app.request_should_auth?( req ).should be_false()
|
257
|
+
req = @request_factory.get( '/api/v1/string/long' )
|
258
|
+
app.request_should_auth?( req ).should be_false()
|
259
|
+
req = @request_factory.get( '/api/v1/other/string/long' ) # Not left-bound
|
260
|
+
app.request_should_auth?( req ).should be_false()
|
261
|
+
req = @request_factory.get( '/api/v1/chat' )
|
262
|
+
app.request_should_auth?( req ).should be_true()
|
263
|
+
end
|
183
264
|
|
184
|
-
|
265
|
+
it "allows negative auth criteria to be declared with a string and a block" do
|
266
|
+
@app.no_auth_for( 'string' ) do |req|
|
267
|
+
Strelka.log.debug "Checking request verb: %p" % [ req.verb ]
|
268
|
+
req.verb == :GET
|
185
269
|
end
|
186
270
|
|
187
|
-
|
188
|
-
req = @request_factory.get( '/api/v1/console' )
|
271
|
+
app = @app.new
|
189
272
|
|
190
|
-
|
191
|
-
|
192
|
-
|
273
|
+
req = @request_factory.get( '/api/v1/string' )
|
274
|
+
app.request_should_auth?( req ).should be_false()
|
275
|
+
req = @request_factory.get( '/api/v1/strong' )
|
276
|
+
app.request_should_auth?( req ).should be_true()
|
277
|
+
req = @request_factory.post( '/api/v1/string' )
|
278
|
+
app.request_should_auth?( req ).should be_true()
|
279
|
+
req = @request_factory.put( '/api/v1/string' )
|
280
|
+
app.request_should_auth?( req ).should be_true()
|
281
|
+
req = @request_factory.delete( '/api/v1/string' )
|
282
|
+
app.request_should_auth?( req ).should be_true()
|
283
|
+
req = @request_factory.options( '/api/v1/string' )
|
284
|
+
app.request_should_auth?( req ).should be_true()
|
285
|
+
end
|
193
286
|
|
194
|
-
|
287
|
+
it "allows negative auth criteria to be declared with a regexp and a block" do
|
288
|
+
@app.no_auth_for( %r{/regexp(?:/(?<username>\w+))?} ) do |req, match|
|
289
|
+
match[:username] == 'guest'
|
195
290
|
end
|
196
291
|
|
197
|
-
|
292
|
+
app = @app.new
|
198
293
|
|
199
|
-
|
294
|
+
req = @request_factory.get( '/api/v1/regexp' )
|
295
|
+
app.request_should_auth?( req ).should be_true()
|
296
|
+
req = @request_factory.get( '/api/v1/regexp/a_username' )
|
297
|
+
app.request_should_auth?( req ).should be_true()
|
298
|
+
req = @request_factory.get( '/api/v1/regexp/%20not+a+username' )
|
299
|
+
app.request_should_auth?( req ).should be_true()
|
300
|
+
req = @request_factory.get( '/api/v1/regexp/guest' )
|
301
|
+
app.request_should_auth?( req ).should be_false()
|
302
|
+
end
|
200
303
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
304
|
+
it "allows negative auth criteria to be declared with just a block" do
|
305
|
+
@app.no_auth_for do |req|
|
306
|
+
req.app_path == '/foom' &&
|
307
|
+
req.verb == :GET &&
|
308
|
+
req.headers.accept.include?( 'text/plain' )
|
205
309
|
end
|
206
310
|
|
207
|
-
|
208
|
-
@app.should have_auth_criteria()
|
209
|
-
end
|
311
|
+
app = @app.new
|
210
312
|
|
211
|
-
|
212
|
-
|
213
|
-
|
313
|
+
req = @request_factory.get( '/api/v1/foom' )
|
314
|
+
app.request_should_auth?( req ).should be_true()
|
315
|
+
req = @request_factory.post( '/api/v1/foom', :accept => 'text/plain, text/html; q=0.5' )
|
316
|
+
app.request_should_auth?( req ).should be_true()
|
317
|
+
req = @request_factory.get( '/api/v1/foom', :accept => 'text/plain, text/html; q=0.5' )
|
318
|
+
app.request_should_auth?( req ).should be_false()
|
214
319
|
|
215
|
-
|
216
|
-
app.auth_provider.should_not_receive( :authenticate )
|
217
|
-
app.auth_provider.should_not_receive( :authorize )
|
320
|
+
end
|
218
321
|
|
219
|
-
app.handle( req )
|
220
|
-
end
|
221
322
|
|
222
|
-
|
223
|
-
|
224
|
-
|
323
|
+
it "allows perms criteria to be declared with a string" do
|
324
|
+
@app.require_perms_for( '/string', :stringperm )
|
325
|
+
app = @app.new
|
225
326
|
|
226
|
-
|
227
|
-
|
228
|
-
|
327
|
+
req = @request_factory.get( '/api/v1/string' )
|
328
|
+
app.required_perms_for( req ).should == [ :stringperm ]
|
329
|
+
req = @request_factory.get( '/api/v1/strong' )
|
330
|
+
app.required_perms_for( req ).should == []
|
331
|
+
end
|
229
332
|
|
230
|
-
|
231
|
-
|
333
|
+
it "allows perms criteria to be declared with a regexp" do
|
334
|
+
@app.require_perms_for( %r{^/admin}, :admin )
|
335
|
+
@app.require_perms_for( %r{/grant}, :grant )
|
336
|
+
app = @app.new
|
232
337
|
|
338
|
+
req = @request_factory.get( '/api/v1/admin' )
|
339
|
+
app.required_perms_for( req ).should == [ :admin ]
|
340
|
+
req = @request_factory.get( '/api/v1/admin/grant' )
|
341
|
+
app.required_perms_for( req ).should == [ :admin, :grant ]
|
342
|
+
req = @request_factory.get( '/api/v1/users' )
|
343
|
+
app.required_perms_for( req ).should == []
|
344
|
+
req = @request_factory.get( '/api/v1/users/grant' )
|
345
|
+
app.required_perms_for( req ).should == [ :grant ]
|
233
346
|
end
|
234
347
|
|
348
|
+
it "allows perms criteria to be declared with a string and a block" do
|
349
|
+
@app.require_perms_for( '/string' ) do |req|
|
350
|
+
perms = [:stringperm, :otherperm]
|
351
|
+
perms << :rawdata if req.headers.accept && req.headers.accept =~ /json/i
|
352
|
+
perms
|
353
|
+
end
|
354
|
+
app = @app.new
|
235
355
|
|
236
|
-
|
356
|
+
req = @request_factory.get( '/api/v1/string' )
|
357
|
+
app.required_perms_for( req ).should == [ :stringperm, :otherperm ]
|
358
|
+
req = @request_factory.get( '/api/v1/strong' )
|
359
|
+
app.required_perms_for( req ).should == []
|
360
|
+
end
|
237
361
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
362
|
+
it "allows perms criteria to be declared with a regexp and a block" do
|
363
|
+
@app.require_perms_for( %r{^/admin(/(?<username>\w+))?} ) do |req, match|
|
364
|
+
perms = [:admin]
|
365
|
+
perms << match[:username].to_sym if match[:username]
|
366
|
+
perms
|
242
367
|
end
|
368
|
+
app = @app.new
|
369
|
+
|
370
|
+
req = @request_factory.get( '/api/v1/admin' )
|
371
|
+
app.required_perms_for( req ).should == [ :admin ]
|
372
|
+
req = @request_factory.get( '/api/v1/admin/jzero' )
|
373
|
+
app.required_perms_for( req ).should == [ :admin, :jzero ]
|
374
|
+
req = @request_factory.get( '/api/v1/users' )
|
375
|
+
app.required_perms_for( req ).should == []
|
376
|
+
end
|
243
377
|
|
244
|
-
|
245
|
-
|
378
|
+
it "allows perms criteria to be declared with just a block" do
|
379
|
+
@app.require_perms_for do |req|
|
380
|
+
req.app_path.scan( %r{/(\w+)} ).flatten.map( &:to_sym )
|
246
381
|
end
|
382
|
+
app = @app.new
|
247
383
|
|
248
|
-
|
249
|
-
|
384
|
+
req = @request_factory.get( '/api/v1/admin' )
|
385
|
+
app.required_perms_for( req ).should == [ :admin ]
|
386
|
+
req = @request_factory.get( '/api/v1/admin/jzero' )
|
387
|
+
app.required_perms_for( req ).should == [ :admin, :jzero ]
|
388
|
+
req = @request_factory.get( '/api/v1/users' )
|
389
|
+
app.required_perms_for( req ).should == [ :users ]
|
390
|
+
end
|
250
391
|
|
251
|
-
|
252
|
-
|
253
|
-
|
392
|
+
it "allows negative perms criteria to be declared with a string" do
|
393
|
+
@app.no_perms_for( '/string' )
|
394
|
+
app = @app.new
|
254
395
|
|
255
|
-
|
256
|
-
|
396
|
+
req = @request_factory.get( '/api/v1/string' )
|
397
|
+
app.required_perms_for( req ).should be_empty()
|
398
|
+
req = @request_factory.get( '/api/v1/strong' )
|
399
|
+
app.required_perms_for( req ).should == [ :auth_test ] # default == appid
|
400
|
+
end
|
257
401
|
|
258
|
-
|
259
|
-
|
402
|
+
it "allows negative perms criteria to be declared with a regexp" do
|
403
|
+
@app.no_perms_for( %r{^/signup} )
|
404
|
+
app = @app.new
|
260
405
|
|
261
|
-
|
262
|
-
|
263
|
-
|
406
|
+
req = @request_factory.get( '/api/v1/signup' )
|
407
|
+
app.required_perms_for( req ).should be_empty()
|
408
|
+
req = @request_factory.get( '/api/v1/signup/reapply' )
|
409
|
+
app.required_perms_for( req ).should be_empty()
|
410
|
+
req = @request_factory.get( '/api/v1/index' )
|
411
|
+
app.required_perms_for( req ).should == [ :auth_test ]
|
412
|
+
end
|
264
413
|
|
265
|
-
|
414
|
+
it "allows negative perms criteria to be declared with a string and a block" do
|
415
|
+
@app.no_perms_for( '/' ) do |req|
|
416
|
+
req.verb == :GET
|
266
417
|
end
|
418
|
+
app = @app.new
|
267
419
|
|
268
|
-
|
269
|
-
|
420
|
+
req = @request_factory.get( '/api/v1' )
|
421
|
+
app.required_perms_for( req ).should be_empty()
|
422
|
+
req = @request_factory.post( '/api/v1' )
|
423
|
+
app.required_perms_for( req ).should == [ :auth_test ] # default == appid
|
424
|
+
req = @request_factory.get( '/api/v1/users' )
|
425
|
+
app.required_perms_for( req ).should == [ :auth_test ]
|
426
|
+
end
|
270
427
|
|
271
|
-
|
272
|
-
|
273
|
-
|
428
|
+
it "allows negative perms criteria to be declared with a regexp and a block" do
|
429
|
+
@app.no_perms_for( %r{^/collection/(?<collname>[^/]+)} ) do |req, match|
|
430
|
+
public_collections = %w[degasse ione champhion]
|
431
|
+
collname = match[:collname]
|
432
|
+
if public_collections.include?( collname )
|
433
|
+
true
|
434
|
+
else
|
435
|
+
false
|
436
|
+
end
|
437
|
+
end
|
438
|
+
app = @app.new
|
274
439
|
|
275
|
-
|
440
|
+
req = @request_factory.get( '/api/v1/collection' )
|
441
|
+
app.required_perms_for( req ).should == [ :auth_test ]
|
442
|
+
req = @request_factory.get( '/api/v1/collection/degasse' )
|
443
|
+
app.required_perms_for( req ).should be_empty()
|
444
|
+
req = @request_factory.get( '/api/v1/collection/ione' )
|
445
|
+
app.required_perms_for( req ).should be_empty()
|
446
|
+
req = @request_factory.get( '/api/v1/collection/champhion' )
|
447
|
+
app.required_perms_for( req ).should be_empty()
|
448
|
+
req = @request_factory.get( '/api/v1/collection/calindra' )
|
449
|
+
app.required_perms_for( req ).should == [ :auth_test ]
|
450
|
+
end
|
451
|
+
|
452
|
+
it "allows negative perms criteria to be declared with just a block" do
|
453
|
+
@app.no_perms_for do |req|
|
454
|
+
intranet = IPAddr.new( '10.0.0.0/8' )
|
455
|
+
intranet.include?( req.remote_ip )
|
276
456
|
end
|
457
|
+
app = @app.new
|
277
458
|
|
459
|
+
req = @request_factory.get( '/api/v1/collection', x_forwarded_for: '10.0.1.68' )
|
460
|
+
app.required_perms_for( req ).should be_empty()
|
461
|
+
req = @request_factory.get( '/api/v1/collection', x_forwarded_for: '192.0.43.10' )
|
462
|
+
app.required_perms_for( req ).should == [ :auth_test ]
|
278
463
|
end
|
279
464
|
|
280
465
|
|
281
466
|
context "that has positive auth criteria" do
|
282
467
|
|
283
468
|
before( :each ) do
|
284
|
-
@app.require_auth_for( '/
|
469
|
+
@app.require_auth_for( '/onlyauth' )
|
470
|
+
@app.require_auth_for( '/both' )
|
285
471
|
end
|
286
472
|
|
287
|
-
|
288
|
-
@app.should have_auth_criteria()
|
289
|
-
end
|
473
|
+
context "and positive perms criteria" do
|
290
474
|
|
291
|
-
|
292
|
-
|
475
|
+
before( :each ) do
|
476
|
+
@app.require_perms_for( '/both' )
|
477
|
+
@app.require_perms_for( '/onlyperms' )
|
478
|
+
end
|
293
479
|
|
294
|
-
|
295
|
-
|
296
|
-
app.auth_provider.should_receive( :authorize ).and_return( true )
|
480
|
+
it "authorizes a request that only matches the perms criteria" do
|
481
|
+
req = @request_factory.get( '/api/v1/onlyperms' )
|
297
482
|
|
298
|
-
|
299
|
-
|
483
|
+
app = @app.new
|
484
|
+
app.auth_provider.should_not_receive( :authenticate )
|
485
|
+
app.auth_provider.should_receive( :authorize )
|
300
486
|
|
301
|
-
|
302
|
-
|
487
|
+
app.handle( req )
|
488
|
+
end
|
303
489
|
|
304
|
-
|
305
|
-
|
306
|
-
app.auth_provider.should_not_receive( :authorize )
|
490
|
+
it "authenticates a request that only matches the auth criteria" do
|
491
|
+
req = @request_factory.get( '/api/v1/onlyauth' )
|
307
492
|
|
308
|
-
|
309
|
-
|
310
|
-
|
493
|
+
app = @app.new
|
494
|
+
app.auth_provider.should_receive( :authenticate )
|
495
|
+
app.auth_provider.should_not_receive( :authorize )
|
311
496
|
|
497
|
+
app.handle( req )
|
498
|
+
end
|
312
499
|
|
313
|
-
|
500
|
+
it "authenticates and authorizes a request that matches both" do
|
501
|
+
req = @request_factory.get( '/api/v1/both' )
|
314
502
|
|
315
|
-
|
316
|
-
|
317
|
-
|
503
|
+
app = @app.new
|
504
|
+
app.auth_provider.should_receive( :authenticate )
|
505
|
+
app.auth_provider.should_receive( :authorize )
|
506
|
+
|
507
|
+
app.handle( req )
|
318
508
|
end
|
319
|
-
end
|
320
509
|
|
321
|
-
|
322
|
-
|
323
|
-
end
|
510
|
+
it "doesn't do either for a request that doesn't match either" do
|
511
|
+
req = @request_factory.get( '/api/v1/neither' )
|
324
512
|
|
325
|
-
|
326
|
-
|
327
|
-
|
513
|
+
app = @app.new
|
514
|
+
app.auth_provider.should_not_receive( :authenticate )
|
515
|
+
app.auth_provider.should_not_receive( :authorize )
|
328
516
|
|
329
|
-
|
330
|
-
|
331
|
-
app.auth_provider.should_receive( :authorize ).and_return( true )
|
517
|
+
app.handle( req )
|
518
|
+
end
|
332
519
|
|
333
|
-
app.handle( req )
|
334
520
|
end
|
335
521
|
|
336
|
-
|
337
|
-
req = @request_factory.get( '/api/v1/console' )
|
338
|
-
req.notes[:require_auth] = false
|
522
|
+
context "and negative perms criteria" do
|
339
523
|
|
340
|
-
|
341
|
-
|
342
|
-
|
524
|
+
before( :each ) do
|
525
|
+
@app.no_perms_for( '/both' )
|
526
|
+
@app.no_perms_for( '/onlyperms' )
|
527
|
+
end
|
528
|
+
|
529
|
+
it "doesn't do either for a request that only matches the perms criteria" do
|
530
|
+
req = @request_factory.get( '/api/v1/onlyperms' )
|
531
|
+
|
532
|
+
app = @app.new
|
533
|
+
app.auth_provider.should_not_receive( :authenticate )
|
534
|
+
app.auth_provider.should_not_receive( :authorize )
|
535
|
+
|
536
|
+
app.handle( req )
|
537
|
+
end
|
538
|
+
|
539
|
+
it "authenticates and authorizes a request that only matches the auth criteria"do
|
540
|
+
req = @request_factory.get( '/api/v1/onlyauth' )
|
541
|
+
|
542
|
+
app = @app.new
|
543
|
+
app.auth_provider.should_receive( :authenticate )
|
544
|
+
app.auth_provider.should_receive( :authorize )
|
545
|
+
|
546
|
+
app.handle( req )
|
547
|
+
end
|
548
|
+
|
549
|
+
it "only authenticates a request that matches both" do
|
550
|
+
req = @request_factory.get( '/api/v1/both' )
|
551
|
+
|
552
|
+
app = @app.new
|
553
|
+
app.auth_provider.should_receive( :authenticate )
|
554
|
+
app.auth_provider.should_not_receive( :authorize )
|
555
|
+
|
556
|
+
app.handle( req )
|
557
|
+
end
|
558
|
+
|
559
|
+
it "only authorizes a request that doesn't match either" do
|
560
|
+
req = @request_factory.get( '/api/v1/neither' )
|
561
|
+
|
562
|
+
app = @app.new
|
563
|
+
app.auth_provider.should_not_receive( :authenticate )
|
564
|
+
app.auth_provider.should_receive( :authorize )
|
565
|
+
|
566
|
+
app.handle( req )
|
567
|
+
end
|
343
568
|
|
344
|
-
app.handle( req )
|
345
569
|
end
|
570
|
+
|
346
571
|
end
|
347
572
|
|
348
573
|
|
349
|
-
context "that has
|
574
|
+
context "that has negative auth criteria" do
|
350
575
|
|
351
576
|
before( :each ) do
|
352
|
-
@app.
|
353
|
-
|
354
|
-
end
|
577
|
+
@app.no_auth_for( '/onlyauth' )
|
578
|
+
@app.no_auth_for( '/both' )
|
355
579
|
end
|
356
580
|
|
357
|
-
|
358
|
-
@app.should have_auth_criteria()
|
359
|
-
end
|
581
|
+
context "and positive perms criteria" do
|
360
582
|
|
361
|
-
|
362
|
-
|
583
|
+
before( :each ) do
|
584
|
+
@app.require_perms_for( '/both' )
|
585
|
+
@app.require_perms_for( '/onlyperms' )
|
586
|
+
end
|
363
587
|
|
364
|
-
|
365
|
-
|
366
|
-
app.auth_provider.should_receive( :authorize ).and_return( true )
|
588
|
+
it "authenticates and authorizes a request that only matches the perms criteria" do
|
589
|
+
req = @request_factory.get( '/api/v1/onlyperms' )
|
367
590
|
|
368
|
-
|
369
|
-
|
591
|
+
app = @app.new
|
592
|
+
app.auth_provider.should_receive( :authenticate )
|
593
|
+
app.auth_provider.should_receive( :authorize )
|
370
594
|
|
371
|
-
|
372
|
-
|
595
|
+
app.handle( req )
|
596
|
+
end
|
373
597
|
|
374
|
-
|
375
|
-
|
376
|
-
app.auth_provider.should_not_receive( :authorize )
|
598
|
+
it "doesn't do either for a request that only matches the auth criteria" do
|
599
|
+
req = @request_factory.get( '/api/v1/onlyauth' )
|
377
600
|
|
378
|
-
|
379
|
-
|
601
|
+
app = @app.new
|
602
|
+
app.auth_provider.should_not_receive( :authenticate )
|
603
|
+
app.auth_provider.should_not_receive( :authorize )
|
380
604
|
|
381
|
-
|
382
|
-
|
605
|
+
app.handle( req )
|
606
|
+
end
|
383
607
|
|
384
|
-
|
385
|
-
|
386
|
-
|
608
|
+
it "authorizes a request that matches both" do
|
609
|
+
req = @request_factory.get( '/api/v1/both' )
|
610
|
+
|
611
|
+
app = @app.new
|
612
|
+
app.auth_provider.should_not_receive( :authenticate )
|
613
|
+
app.auth_provider.should_receive( :authorize )
|
614
|
+
|
615
|
+
app.handle( req )
|
616
|
+
end
|
617
|
+
|
618
|
+
it "authenticates a request that doesn't match either" do
|
619
|
+
req = @request_factory.get( '/api/v1/neither' )
|
620
|
+
|
621
|
+
app = @app.new
|
622
|
+
app.auth_provider.should_receive( :authenticate )
|
623
|
+
app.auth_provider.should_not_receive( :authorize )
|
624
|
+
|
625
|
+
app.handle( req )
|
626
|
+
end
|
387
627
|
|
388
|
-
app.handle( req )
|
389
628
|
end
|
390
629
|
|
391
|
-
|
630
|
+
context "and negative perms criteria" do
|
392
631
|
|
632
|
+
before( :each ) do
|
633
|
+
@app.no_perms_for( '/both' )
|
634
|
+
@app.no_perms_for( '/onlyperms' )
|
635
|
+
end
|
393
636
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
637
|
+
it "authenticates for a request that only matches the perms criteria" do
|
638
|
+
req = @request_factory.get( '/api/v1/onlyperms' )
|
639
|
+
|
640
|
+
app = @app.new
|
641
|
+
app.auth_provider.should_receive( :authenticate )
|
642
|
+
app.auth_provider.should_not_receive( :authorize )
|
643
|
+
|
644
|
+
app.handle( req )
|
645
|
+
end
|
646
|
+
|
647
|
+
it "authorizes a request that only matches the auth criteria" do
|
648
|
+
req = @request_factory.get( '/api/v1/onlyauth' )
|
649
|
+
|
650
|
+
app = @app.new
|
651
|
+
app.auth_provider.should_not_receive( :authenticate )
|
652
|
+
app.auth_provider.should_receive( :authorize )
|
653
|
+
|
654
|
+
app.handle( req )
|
655
|
+
end
|
656
|
+
|
657
|
+
it "doesn't do either for a request that matches both" do
|
658
|
+
req = @request_factory.get( '/api/v1/both' )
|
659
|
+
|
660
|
+
app = @app.new
|
661
|
+
app.auth_provider.should_not_receive( :authenticate )
|
662
|
+
app.auth_provider.should_not_receive( :authorize )
|
663
|
+
|
664
|
+
app.handle( req )
|
665
|
+
end
|
666
|
+
|
667
|
+
it "authenticates and authorizes a request that doesn't match either" do
|
668
|
+
req = @request_factory.get( '/api/v1/neither' )
|
669
|
+
|
670
|
+
app = @app.new
|
671
|
+
app.auth_provider.should_receive( :authenticate )
|
672
|
+
app.auth_provider.should_receive( :authorize )
|
673
|
+
|
674
|
+
app.handle( req )
|
675
|
+
end
|
676
|
+
|
677
|
+
end
|
398
678
|
|
399
|
-
it "can register an authorization callback with a callable object" do
|
400
|
-
callback = Proc.new { :authz }
|
401
|
-
@app.authz_callback( callback )
|
402
|
-
@app.authz_callback.should == callback
|
403
679
|
end
|
404
680
|
|
405
681
|
|
406
|
-
context "that has
|
682
|
+
context "that has overlapping perms criteria" do
|
407
683
|
|
408
684
|
before( :each ) do
|
409
|
-
@app.
|
685
|
+
@app.require_perms_for( %r{^/admin.*}, :admin )
|
686
|
+
@app.require_perms_for( %r{^/admin/upload.*}, :upload )
|
410
687
|
end
|
411
688
|
|
412
|
-
it "
|
413
|
-
|
689
|
+
it "authorizes with a union of the permissions of both of the criteria" do
|
690
|
+
req = @request_factory.get( '/api/v1/admin/upload' )
|
691
|
+
|
692
|
+
app = @app.new
|
693
|
+
app.auth_provider.stub!( :authenticate ).and_return( :credentials )
|
694
|
+
app.auth_provider.should_receive( :authorize ).with( :credentials, req, [:admin, :upload] )
|
695
|
+
|
696
|
+
app.handle( req )
|
697
|
+
end
|
414
698
|
|
415
699
|
end
|
416
700
|
|