rack.git  about / heads / tags
a modular Ruby webserver interface
blob ee7000495e6af27e690903d07235a0a38902a2e2 2934 bytes (raw)
$ git show chunk:test/spec_auth_basic.rb	# shows this blob on the CLI

  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
 
# frozen_string_literal: true

require_relative 'helper'

separate_testing do
  require_relative '../lib/rack/auth/basic'
  require_relative '../lib/rack/mock_request'
  require_relative '../lib/rack/lint'
end

describe Rack::Auth::Basic do
  def realm
    'WallysWorld'
  end

  def unprotected_app
    Rack::Lint.new lambda { |env|
      [ 200, { 'content-type' => 'text/plain' }, ["Hi #{env['REMOTE_USER']}"] ]
    }
  end

  def protected_app
    app = Rack::Auth::Basic.new(unprotected_app) { |username, password| 'Boss' == username }
    app.realm = realm
    app
  end

  before do
    @request = Rack::MockRequest.new(protected_app)
  end

  def request_with_basic_auth(username, password, &block)
    request 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack("m*"), &block
  end

  def request(headers = {})
    yield @request.get('/', headers)
  end

  def assert_basic_auth_challenge(response)
    response.must_be :client_error?
    response.status.must_equal 401
    response.must_include 'www-authenticate'
    response.headers['www-authenticate'].must_match(/Basic realm="#{Regexp.escape(realm)}"/)
    response.body.must_be :empty?
  end

  it 'challenge correctly when no credentials are specified' do
    request do |response|
      assert_basic_auth_challenge response
    end
  end

  it 'rechallenge if incorrect credentials are specified' do
    request_with_basic_auth 'joe', 'password' do |response|
      assert_basic_auth_challenge response
    end
  end

  it 'return application output if correct credentials are specified' do
    request_with_basic_auth 'Boss', 'password' do |response|
      response.status.must_equal 200
      response.body.to_s.must_equal 'Hi Boss'
    end
  end

  it 'return 400 Bad Request if different auth scheme used' do
    request 'HTTP_AUTHORIZATION' => 'Digest params' do |response|
      response.must_be :client_error?
      response.status.must_equal 400
      response.wont_include 'www-authenticate'
    end
  end

  it 'return 400 Bad Request for a malformed authorization header' do
    request 'HTTP_AUTHORIZATION' => '' do |response|
      response.must_be :client_error?
      response.status.must_equal 400
      response.wont_include 'www-authenticate'
    end
  end

  it 'return 401 Bad Request for a nil authorization header' do
    request 'HTTP_AUTHORIZATION' => nil do |response|
      response.must_be :client_error?
      response.status.must_equal 401
    end
  end

  it 'return 400 Bad Request for a authorization header with only username' do
    auth = 'Basic ' + ['foo'].pack("m*")
    request 'HTTP_AUTHORIZATION' => auth do |response|
      response.must_be :client_error?
      response.status.must_equal 400
      response.wont_include 'www-authenticate'
    end
  end

  it 'takes realm as optional constructor arg' do
    app = Rack::Auth::Basic.new(unprotected_app, realm) { true }
    realm.must_equal app.realm
  end
end

git clone https://yhbt.net/rack.git