Skip to content

Commit c851757

Browse files
author
Michel Benevento
committed
improve tests
1 parent c09693c commit c851757

6 files changed

+74
-87
lines changed

lib/roda/plugins/auth.rb

+10-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def self.configure(app, *args)
2929
strategies = [:basic]
3030
when :form
3131
strategies = [:password]
32+
options[:csrf] = true
3233
when :token
3334
strategies = [:token, :password]
3435
end
@@ -69,9 +70,11 @@ def self.setup_cookie(app, user_class, options)
6970
Warden::Manager.serialize_from_session do |id|
7071
user_class.find_by_id(id)
7172
end
72-
app.plugin :csrf, raise: true, skip_if: lambda { |request|
73-
request.env.key? 'HTTP_AUTHORIZATION'
74-
}
73+
if options[:csrf]
74+
app.plugin :csrf, raise: true, skip_if: lambda { |request|
75+
request.env.key? 'HTTP_AUTHORIZATION'
76+
}
77+
end
7578
end
7679

7780
def self.setup_omniauth(app, options)
@@ -170,7 +173,7 @@ def credentials_from_basic
170173
end
171174

172175
def credentials_from_form
173-
request.media_type == "application/x-www-form-urlencoded" && params
176+
request.media_type == "application/x-www-form-urlencoded" && request.params
174177
end
175178

176179
def credentials_from_body
@@ -202,7 +205,7 @@ def valid?
202205
private
203206

204207
def credentials
205-
@credentials ||= credentials_from_form || credentials_from_body || {}
208+
@credentials ||= credentials_from_form || {}
206209
end
207210

208211
end
@@ -229,13 +232,13 @@ def credentials
229232
class Token < Base
230233

231234
def valid?
232-
credentials['token']
235+
credentials['token'] || (credentials['username'] && credentials['password'])
233236
end
234237

235238
private
236239

237240
def credentials
238-
@credentials ||= token_from_auth_header || {}
241+
@credentials ||= token_from_auth_header || credentials_from_body || {}
239242
end
240243

241244
end

test/auth_basic_test.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@ def setup
2626
end
2727

2828
def test_public
29-
assert_equal 200, status('/public')
29+
assert_equal 200, request.get('/public').status
3030
end
3131

3232
def test_private_refused
33-
assert_equal 401, status('/private')
34-
assert_equal "Basic realm=\"/private\"", header('WWW-AUTHENTICATE', '/private')
33+
assert_equal 401, request.get('/private').status
34+
assert_equal "Basic realm=\"/private\"", request.get('/private').headers['WWW-AUTHENTICATE']
3535
end
3636

3737
def test_private_accepted
38-
assert_equal 200, status('/private', {"HTTP_AUTHORIZATION" => "Basic #{http_auth(valid_credentials)}"})
38+
assert_equal 200, request.get('/private', {"HTTP_AUTHORIZATION" => "Basic #{http_auth(valid_credentials)}"}).status
3939
end
4040

4141
end

test/auth_form_test.rb

+10-18
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,25 @@ def setup
2828
end
2929

3030
def test_public
31-
assert_equal 200, status('/public')
31+
assert_equal 200, request.get('/public').status
3232
end
3333

3434
def test_private_refuse_redirect
35-
r = req('/private')
36-
assert_equal 302, r[0]
37-
assert_equal "/login", r[1]['LOCATION']
35+
response = request.get('/private')
36+
assert_equal 302, response.status
37+
assert_equal "/login", response.headers['LOCATION']
3838
end
3939

4040
def test_private_accepted
41-
req('/logout')
42-
cookie = login
43-
assert_equal 200, status('/private', {'HTTP_COOKIE' => cookie})
41+
cookie = form_login.headers['Set-Cookie']
42+
response = request.get('/private')
43+
assert_equal 200, request.get('/private', {'HTTP_COOKIE' => cookie}).status
4444
end
4545

4646
def test_private_error
47-
req('/logout')
48-
cookie = login(invalid_credentials)
49-
assert_equal 302, status('/private', {'HTTP_COOKIE' => cookie})
50-
end
51-
52-
private
53-
54-
def login(cred = valid_credentials)
55-
status, headers = req('/login', {'REQUEST_METHOD' => 'POST', 'rack.input' => save_args(cred)})
56-
status == 200 && headers["Set-Cookie"]
57-
end
47+
cookie = form_login(invalid_credentials).headers['Set-Cookie']
48+
assert_equal 302, request.get('/private', {'HTTP_COOKIE' => cookie}).status
49+
end
5850

5951
end
6052

test/auth_omniauth_test.rb

+10-9
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,25 @@ def setup
2929
end
3030

3131
def test_unprotected_access
32-
assert_equal "public", body('/public')
33-
assert_equal 200, status('/public')
32+
response = request.get('/public')
33+
assert_equal "public", response.body
34+
assert_equal 200, response.status
3435
end
3536

3637
def test_protected_error
37-
assert_equal 401, status('/private')
38+
assert_equal 401, request.get('/private').status
3839
end
3940

4041
def test_twitter_redirect
41-
status, headers = req('/auth/twitter', {'rack.input' => []})
42-
assert_equal 302, status
43-
assert_equal "api.twitter.com", URI(headers['LOCATION']).host
42+
response = request.get('/auth/twitter')
43+
assert_equal 302, response.status
44+
assert_equal "api.twitter.com", URI(response.headers['LOCATION']).host
4445
end
4546

4647
def test_facebook_redirect
47-
status, headers = req('/auth/facebook', {'rack.input' => ""})
48-
assert_equal 302, status
49-
assert_equal "www.facebook.com", URI(headers['LOCATION']).host
48+
response = request.get('/auth/facebook')
49+
assert_equal 302, response.status
50+
assert_equal "www.facebook.com", URI(response.headers['LOCATION']).host
5051
end
5152

5253

test/auth_token_test.rb

+31-24
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ class AuthTokenTest < Minitest::Test
66

77

88
def setup
9-
u = User.new(valid_credentials)
10-
User.db[:users][u.username] = u
9+
@u = User.new(valid_credentials)
10+
User.db[:users][@u.username] = @u
11+
User.db[:tokens]['1234token'] = @u
1112

1213
app :bare do |app|
1314

@@ -17,59 +18,65 @@ def setup
1718
r.on 'public' do
1819
'public'
1920
end
20-
r.post('session') { sign_in.to_json }
21+
r.post('session') do |args|
22+
sign_in
23+
{'token' => current_user.token}.to_json
24+
end
2125
authenticate!
2226
r.is('session', method: :delete) { sign_out }
2327
r.on 'private' do
24-
"private #{current_user.username}"
28+
"private #{current_user.token}"
2529
end
2630
end
2731
end
2832
end
2933

3034
def test_unprotected_access
31-
assert_equal "public", body('/public')
32-
assert_equal 200, status('/public')
35+
response = request.get '/public'
36+
assert_equal "public", response.body
37+
assert_equal 200, response.status
3338
end
3439

3540

3641
def test_protected_error
37-
assert_equal 401, status('/private')
42+
response = request.get '/private'
43+
assert_equal 401, response.status
3844
end
3945

4046
def test_login_body
41-
assert_equal 200, status('/session', {'REQUEST_METHOD' => 'POST', 'rack.input' => save_args(valid_credentials)})
47+
response = json_login
48+
assert_equal 200, response.status
4249
end
4350

4451
def test_login_body_invalid
45-
assert_equal 401, status('/session', {'REQUEST_METHOD' => 'POST', 'rack.input' => save_args(invalid_credentials)})
52+
response = json_login(invalid_credentials)
53+
assert_equal 401, response.status
4654
end
4755

4856
def test_token_response
49-
json = body('/session', {'REQUEST_METHOD' => 'POST', 'rack.input' => save_args(valid_credentials)})
50-
args = JSON.parse(json)
51-
assert_equal valid_credentials[:username], args['username']
52-
assert args['token']
57+
session = JSON.parse(json_login.body)
58+
assert_equal @u.token, session['token']
5359
end
5460

5561
def test_token_access
56-
user_args = login
57-
assert_equal 200, status('/private', {"HTTP_AUTHORIZATION" => "Auth #{user_args['token']}"})
58-
assert_equal "private #{user_args['username']}", body('/private', {"HTTP_AUTHORIZATION" => "Auth #{user_args['token']}"})
62+
session = JSON.parse(json_login.body)
63+
response = request.get('/private', {'HTTP_AUTHORIZATION' => "Auth #{session['token']}"})
64+
assert_equal 200, response.status
65+
assert_equal "private #{session['token']}", response.body
5966
end
6067

6168
def test_logout
62-
user_args = login
63-
assert_equal 204, status('/session', {'REQUEST_METHOD' => 'DELETE', "HTTP_AUTHORIZATION" => "Auth #{user_args['token']}"})
69+
session = JSON.parse(json_login.body)
70+
response = request.delete('/session', {'HTTP_AUTHORIZATION' => "Auth #{session['token']}"})
71+
assert_equal 204, response.status
6472
end
65-
73+
6674
private
67-
68-
def login
69-
env = {'REQUEST_METHOD' => 'POST', 'rack.input' => save_args(valid_credentials)}
70-
body = body('/session', env)
71-
JSON.parse(body)
75+
76+
def json_login(cred = valid_credentials)
77+
request.post('/session', params: cred.to_json)
7278
end
79+
7380

7481
end
7582

test/test_helpers.rb

+9-25
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,22 @@ def app(type=nil, &block)
2222
@app ||= _app{route(&block)}
2323
end
2424
end
25-
26-
def req(path='/', env={})
27-
if path.is_a?(Hash)
28-
env = path
29-
else
30-
env['PATH_INFO'] = path
31-
end
32-
env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => "/", "SCRIPT_NAME" => ""}.merge(env)
33-
setup_csrf(env)
34-
@app.call(env)
35-
end
36-
37-
def status(path='/', env={})
38-
req(path, env)[0]
39-
end
40-
41-
def header(name, path='/', env={})
42-
req(path, env)[1][name]
43-
end
44-
45-
def body(path='/', env={})
46-
req(path, env)[2].join
25+
26+
def request
27+
Rack::MockRequest.new(@app)
4728
end
48-
29+
4930
def _app(&block)
5031
c = Class.new(Roda)
5132
c.class_eval(&block)
5233
c
5334
end
5435

55-
def save_args(args)
56-
StringIO.new(args.to_json)
36+
def form_login(cred = valid_credentials)
37+
opts = setup_csrf :params => cred
38+
request.post('/login', opts)
5739
end
40+
5841

5942
def valid_credentials
6043
{username:'foo', password:'bar'}
@@ -74,6 +57,7 @@ def setup_csrf(env)
7457
token = Rack::Csrf.token(env)
7558
env['HTTP_X_CSRF_TOKEN'] = token
7659
end
60+
env
7761
end
7862

7963
class Mock

0 commit comments

Comments
 (0)