~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/test/controller/http_digest_authentication_test.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'abstract_unit'
2
 
 
3
 
class HttpDigestAuthenticationTest < ActionController::TestCase
4
 
  class DummyDigestController < ActionController::Base
5
 
    before_filter :authenticate, :only => :index
6
 
    before_filter :authenticate_with_request, :only => :display
7
 
 
8
 
    USERS = { 'lifo' => 'world', 'pretty' => 'please',
9
 
              'dhh' => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":"))}
10
 
 
11
 
    def index
12
 
      render :text => "Hello Secret"
13
 
    end
14
 
 
15
 
    def display
16
 
      render :text => 'Definitely Maybe'
17
 
    end
18
 
 
19
 
    private
20
 
 
21
 
    def authenticate
22
 
      authenticate_or_request_with_http_digest("SuperSecret") do |username|
23
 
        # Return the password
24
 
        USERS[username]
25
 
      end
26
 
    end
27
 
 
28
 
    def authenticate_with_request
29
 
      if authenticate_with_http_digest("SuperSecret")  { |username| USERS[username] }
30
 
        @logged_in = true
31
 
      else
32
 
        request_http_digest_authentication("SuperSecret", "Authentication Failed")
33
 
      end
34
 
    end
35
 
  end
36
 
 
37
 
  AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
38
 
 
39
 
  tests DummyDigestController
40
 
 
41
 
  AUTH_HEADERS.each do |header|
42
 
    test "successful authentication with #{header.downcase}" do
43
 
      @request.env[header] = encode_credentials(:username => 'lifo', :password => 'world')
44
 
      get :index
45
 
 
46
 
      assert_response :success
47
 
      assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
48
 
    end
49
 
  end
50
 
 
51
 
  AUTH_HEADERS.each do |header|
52
 
    test "unsuccessful authentication with #{header.downcase}" do
53
 
      @request.env[header] = encode_credentials(:username => 'h4x0r', :password => 'world')
54
 
      get :index
55
 
 
56
 
      assert_response :unauthorized
57
 
      assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
58
 
    end
59
 
  end
60
 
 
61
 
  test "authentication request without credential" do
62
 
    get :display
63
 
 
64
 
    assert_response :unauthorized
65
 
    assert_equal "Authentication Failed", @response.body
66
 
    credentials = decode_credentials(@response.headers['WWW-Authenticate'])
67
 
    assert_equal 'SuperSecret', credentials[:realm]
68
 
  end
69
 
 
70
 
  test "authentication request with nil credentials" do
71
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
72
 
    get :index
73
 
 
74
 
    assert_response :unauthorized
75
 
    assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request"
76
 
    assert_not_equal 'Hello Secret', @response.body, "Authentication didn't fail for request"
77
 
  end
78
 
 
79
 
  test "authentication request with invalid password" do
80
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo')
81
 
    get :display
82
 
 
83
 
    assert_response :unauthorized
84
 
    assert_equal "Authentication Failed", @response.body
85
 
  end
86
 
 
87
 
  test "authentication request with invalid nonce" do
88
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :nonce => "xxyyzz")
89
 
    get :display
90
 
 
91
 
    assert_response :unauthorized
92
 
    assert_equal "Authentication Failed", @response.body
93
 
  end
94
 
 
95
 
  test "authentication request with missing nonce should return 401" do
96
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :remove_nonce => true)
97
 
    get :display
98
 
 
99
 
    assert_response :unauthorized
100
 
    assert_equal "Authentication Failed", @response.body
101
 
  end
102
 
 
103
 
  test "authentication request with Basic auth credentials should return 401" do
104
 
    ActionController::Base.session_options[:secret] = "session_options_secret"
105
 
    @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials('pretty', 'please')
106
 
    get :display
107
 
 
108
 
    assert_response :unauthorized
109
 
    assert_equal "Authentication Failed", @response.body
110
 
  end
111
 
 
112
 
  test "authentication request with invalid opaque" do
113
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :opaque => "xxyyzz")
114
 
    get :display
115
 
 
116
 
    assert_response :unauthorized
117
 
    assert_equal "Authentication Failed", @response.body
118
 
  end
119
 
 
120
 
  test "authentication request with invalid realm" do
121
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :realm => "NotSecret")
122
 
    get :display
123
 
 
124
 
    assert_response :unauthorized
125
 
    assert_equal "Authentication Failed", @response.body
126
 
  end
127
 
 
128
 
  test "authentication request with valid credential" do
129
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
130
 
    get :display
131
 
 
132
 
    assert_response :success
133
 
    assert assigns(:logged_in)
134
 
    assert_equal 'Definitely Maybe', @response.body
135
 
  end
136
 
 
137
 
  test "authentication request with valid credential and nil session" do
138
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
139
 
 
140
 
    # session_id = "" in functional test, but is +nil+ in real life
141
 
    @request.session.session_id = nil
142
 
    get :display
143
 
 
144
 
    assert_response :success
145
 
    assert assigns(:logged_in)
146
 
    assert_equal 'Definitely Maybe', @response.body
147
 
  end
148
 
 
149
 
  test "authentication request with request-uri that doesn't match credentials digest-uri" do
150
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
151
 
    @request.env['REQUEST_URI'] = "/http_digest_authentication_test/dummy_digest/altered/uri"
152
 
    get :display
153
 
 
154
 
    assert_response :unauthorized
155
 
    assert_equal "Authentication Failed", @response.body
156
 
  end
157
 
 
158
 
  test "authentication request with absolute request uri (as in webrick)" do
159
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
160
 
    @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest"
161
 
 
162
 
    get :display
163
 
 
164
 
    assert_response :success
165
 
    assert assigns(:logged_in)
166
 
    assert_equal 'Definitely Maybe', @response.body
167
 
  end
168
 
 
169
 
  test "authentication request with absolute uri in credentials (as in IE)" do
170
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
171
 
                                                            :username => 'pretty', :password => 'please')
172
 
 
173
 
    get :display
174
 
 
175
 
    assert_response :success
176
 
    assert assigns(:logged_in)
177
 
    assert_equal 'Definitely Maybe', @response.body
178
 
  end
179
 
 
180
 
  test "authentication request with absolute uri in both request and credentials (as in Webrick with IE)" do
181
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
182
 
                                                            :username => 'pretty', :password => 'please')
183
 
    @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest"
184
 
 
185
 
    get :display
186
 
 
187
 
    assert_response :success
188
 
    assert assigns(:logged_in)
189
 
    assert_equal 'Definitely Maybe', @response.body
190
 
  end
191
 
 
192
 
  test "authentication request with password stored as ha1 digest hash" do
193
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'dhh',
194
 
                                           :password => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":")),
195
 
                                           :password_is_ha1 => true)
196
 
    get :display
197
 
 
198
 
    assert_response :success
199
 
    assert assigns(:logged_in)
200
 
    assert_equal 'Definitely Maybe', @response.body
201
 
  end
202
 
 
203
 
  test "authentication request with _method" do
204
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :method => :post)
205
 
    @request.env['rack.methodoverride.original_method'] = 'POST'
206
 
    put :display
207
 
 
208
 
    assert_response :success
209
 
    assert assigns(:logged_in)
210
 
    assert_equal 'Definitely Maybe', @response.body
211
 
  end
212
 
 
213
 
  test "validate_digest_response should fail with nil returning password_procedure" do
214
 
    @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
215
 
    assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
216
 
  end
217
 
 
218
 
  private
219
 
 
220
 
  def encode_credentials(options)
221
 
    options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b", :password_is_ha1 => false)
222
 
    password = options.delete(:password)
223
 
 
224
 
    # Set in /initializers/session_store.rb. Used as secret in generating nonce
225
 
    # to prevent tampering of timestamp
226
 
    ActionController::Base.session_options[:secret] = "session_options_secret"
227
 
 
228
 
    # Perform unauthenticated request to retrieve digest parameters to use on subsequent request
229
 
    method = options.delete(:method) || 'GET'
230
 
 
231
 
    case method.to_s.upcase
232
 
    when 'GET'
233
 
      get :index
234
 
    when 'POST'
235
 
      post :index
236
 
    end
237
 
 
238
 
    assert_response :unauthorized
239
 
 
240
 
    remove_nonce = options.delete(:remove_nonce)
241
 
 
242
 
    credentials = decode_credentials(@response.headers['WWW-Authenticate'])
243
 
    credentials.merge!(options)
244
 
    credentials.merge!(:uri => @request.env['REQUEST_URI'].to_s)
245
 
 
246
 
    credentials.delete(:nonce) if remove_nonce
247
 
 
248
 
    ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
249
 
  end
250
 
 
251
 
  def decode_credentials(header)
252
 
    ActionController::HttpAuthentication::Digest.decode_credentials(@response.headers['WWW-Authenticate'])
253
 
  end
254
 
end