1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
require 'abstract_unit'
class HttpBasicAuthenticationTest < ActionController::TestCase
class DummyController < ActionController::Base
before_action :authenticate, only: :index
before_action :authenticate_with_request, only: :display
before_action :authenticate_long_credentials, only: :show
http_basic_authenticate_with :name => "David", :password => "Goliath", :only => :search
def index
render :text => "Hello Secret"
end
def display
render :text => 'Definitely Maybe'
end
def show
render :text => 'Only for loooooong credentials'
end
def search
render :text => 'All inline'
end
private
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == 'lifo' && password == 'world'
end
end
def authenticate_with_request
if authenticate_with_http_basic { |username, password| username == 'pretty' && password == 'please' }
@logged_in = true
else
request_http_basic_authentication("SuperSecret")
end
end
def authenticate_long_credentials
authenticate_or_request_with_http_basic do |username, password|
username == '1234567890123456789012345678901234567890' && password == '1234567890123456789012345678901234567890'
end
end
end
AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
tests DummyController
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials('lifo', 'world')
get :index
assert_response :success
assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
end
test "successful authentication with #{header.downcase} and long credentials" do
@request.env[header] = encode_credentials('1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890')
get :show
assert_response :success
assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials('h4x0r', 'world')
get :index
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
end
test "unsuccessful authentication with #{header.downcase} and long credentials" do
@request.env[header] = encode_credentials('h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r', 'worldworldworldworldworldworldworldworld')
get :show
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header} and long credentials"
end
test "unsuccessful authentication with #{header.downcase} and no credentials" do
get :show
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header} and no credentials"
end
end
def test_encode_credentials_has_no_newline
username = 'laskjdfhalksdjfhalkjdsfhalksdjfhklsdjhalksdjfhalksdjfhlakdsjfh'
password = 'kjfhueyt9485osdfasdkljfh4lkjhakldjfhalkdsjf'
result = ActionController::HttpAuthentication::Basic.encode_credentials(
username, password)
assert_no_match(/\n/, result)
end
test "authentication request without credential" do
get :display
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body
assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
end
test "authentication request with invalid credential" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'foo')
get :display
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body
assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
end
test "authentication request with valid credential" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'please')
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authenticate with class method" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'Goliath')
get :search
assert_response :success
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'WRONG!')
get :search
assert_response :unauthorized
end
test "authentication request with wrong scheme" do
header = 'Bearer ' + encode_credentials('David', 'Goliath').split(' ', 2)[1]
@request.env['HTTP_AUTHORIZATION'] = header
get :search
assert_response :unauthorized
end
private
def encode_credentials(username, password)
"Basic #{::Base64.encode64("#{username}:#{password}")}"
end
end
|