instiki/vendor/plugins/rack/test/spec_rack_auth_digest.rb
Jacques Distler 4e14ccc74d Instiki 0.16.3: Rails 2.3.0
Instiki now runs on the Rails 2.3.0 Candidate Release.
Among other improvements, this means that it now 
automagically selects between WEBrick and Mongrel.

Just run

    ./instiki --daemon
2009-02-04 14:26:08 -06:00

170 lines
4.7 KiB
Ruby

require 'test/spec'
require 'rack/auth/digest/md5'
require 'rack/mock'
context 'Rack::Auth::Digest::MD5' do
def realm
'WallysWorld'
end
def unprotected_app
lambda do |env|
[ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ]
end
end
def protected_app
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
{ 'Alice' => 'correct-password' }[username]
end
app.realm = realm
app.opaque = 'this-should-be-secret'
app
end
def protected_app_with_hashed_passwords
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
username == 'Alice' ? Digest::MD5.hexdigest("Alice:#{realm}:correct-password") : nil
end
app.realm = realm
app.opaque = 'this-should-be-secret'
app.passwords_hashed = true
app
end
setup do
@request = Rack::MockRequest.new(protected_app)
end
def request(path, headers = {}, &block)
response = @request.get(path, headers)
block.call(response) if block
return response
end
class MockDigestRequest
def initialize(params)
@params = params
end
def method_missing(sym)
if @params.has_key? k = sym.to_s
return @params[k]
end
super
end
def method
'GET'
end
def response(password)
Rack::Auth::Digest::MD5.new(nil).send :digest, self, password
end
end
def request_with_digest_auth(path, username, password, options = {}, &block)
response = request('/')
return response unless response.status == 401
if wait = options.delete(:wait)
sleep wait
end
challenge = response['WWW-Authenticate'].split(' ', 2).last
params = Rack::Auth::Digest::Params.parse(challenge)
params['username'] = username
params['nc'] = '00000001'
params['cnonce'] = 'nonsensenonce'
params['uri'] = path
params.update options
params['response'] = MockDigestRequest.new(params).response(password)
request(path, { 'HTTP_AUTHORIZATION' => "Digest #{params}" }, &block)
end
def assert_digest_auth_challenge(response)
response.should.be.a.client_error
response.status.should.equal 401
response.should.include 'WWW-Authenticate'
response.headers['WWW-Authenticate'].should =~ /^Digest /
response.body.should.be.empty
end
def assert_bad_request(response)
response.should.be.a.client_error
response.status.should.equal 400
response.should.not.include 'WWW-Authenticate'
end
specify 'should challenge when no credentials are specified' do
request '/' do |response|
assert_digest_auth_challenge response
end
end
specify 'should return application output if correct credentials given' do
request_with_digest_auth '/', 'Alice', 'correct-password' do |response|
response.status.should.equal 200
response.body.to_s.should.equal 'Hi Alice'
end
end
specify 'should return application output if correct credentials given (hashed passwords)' do
@request = Rack::MockRequest.new(protected_app_with_hashed_passwords)
request_with_digest_auth '/', 'Alice', 'correct-password' do |response|
response.status.should.equal 200
response.body.to_s.should.equal 'Hi Alice'
end
end
specify 'should rechallenge if incorrect username given' do
request_with_digest_auth '/', 'Bob', 'correct-password' do |response|
assert_digest_auth_challenge response
end
end
specify 'should rechallenge if incorrect password given' do
request_with_digest_auth '/', 'Alice', 'wrong-password' do |response|
assert_digest_auth_challenge response
end
end
specify 'should rechallenge with stale parameter if nonce is stale' do
begin
Rack::Auth::Digest::Nonce.time_limit = 1
request_with_digest_auth '/', 'Alice', 'correct-password', :wait => 2 do |response|
assert_digest_auth_challenge response
response.headers['WWW-Authenticate'].should =~ /\bstale=true\b/
end
ensure
Rack::Auth::Digest::Nonce.time_limit = nil
end
end
specify 'should return 400 Bad Request if incorrect qop given' do
request_with_digest_auth '/', 'Alice', 'correct-password', 'qop' => 'auth-int' do |response|
assert_bad_request response
end
end
specify 'should return 400 Bad Request if incorrect uri given' do
request_with_digest_auth '/', 'Alice', 'correct-password', 'uri' => '/foo' do |response|
assert_bad_request response
end
end
specify 'should return 400 Bad Request if different auth scheme used' do
request '/', 'HTTP_AUTHORIZATION' => 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==' do |response|
assert_bad_request response
end
end
end