Skip to content
This repository
tree: c1bdf027d8
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 189 lines (152 sloc) 5.292 kb
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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
require File.dirname(__FILE__) + '/../abstract_unit'
require 'digest/sha1'

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
end

module RequestForgeryProtectionTests
  def teardown
    ActionController::Base.request_forgery_protection_token = nil
  end
  
  def test_should_render_form_with_token_tag
    get :index
    assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
  end
  
  def test_should_render_button_to_with_token_tag
    get :show_button
    assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
  end

  def test_should_allow_get
    get :index
    assert_response :success
  end
  
  def test_should_allow_post_without_token_on_unsafe_action
    post :unsafe
    assert_response :success
  end
  
  def test_should_not_allow_post_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { post :index }
  end
  
  def test_should_not_allow_put_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { put :index }
  end
  
  def test_should_not_allow_delete_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { delete :index }
  end
  
  def test_should_not_allow_xhr_post_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { xhr :post, :index }
  end
  
  def test_should_not_allow_xhr_put_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { xhr :put, :index }
  end
  
  def test_should_not_allow_xhr_delete_without_token
    assert_raises(ActionController::InvalidAuthenticityToken) { xhr :delete, :index }
  end
  
  def test_should_allow_post_with_token
    post :index, :authenticity_token => @token
    assert_response :success
  end
  
  def test_should_allow_put_with_token
    put :index, :authenticity_token => @token
    assert_response :success
  end
  
  def test_should_allow_delete_with_token
    delete :index, :authenticity_token => @token
    assert_response :success
  end
  
  def test_should_allow_post_with_xml
    post :index, :format => 'xml'
    assert_response :success
  end
  
  def test_should_allow_put_with_xml
    put :index, :format => 'xml'
    assert_response :success
  end
  
  def test_should_allow_delete_with_xml
    delete :index, :format => 'xml'
    assert_response :success
  end
end

module RequestForgeryProtectionActions
  def index
    render :inline => "<%= form_tag('/') {} %>"
  end
  
  def show_button
    render :inline => "<%= button_to('New', '/') {} %>"
  end
  
  def unsafe
    render :text => 'pwn'
  end
  
  def rescue_action(e) raise e end
end

class RequestForgeryProtectionController < ActionController::Base
  include RequestForgeryProtectionActions
  protect_from_forgery :only => :index, :secret => 'abc'
end

class RequestForgeryProtectionControllerTest < Test::Unit::TestCase
  include RequestForgeryProtectionTests
  def setup
    @controller = RequestForgeryProtectionController.new
    @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new
    class << @request.session
      def session_id() '123' end
    end
    @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
    ActionController::Base.request_forgery_protection_token = :authenticity_token
  end
end

# no token is given, assume the cookie store is used
class CsrfCookieMonsterController < ActionController::Base
  include RequestForgeryProtectionActions
  protect_from_forgery :only => :index
end

class FreeCookieController < CsrfCookieMonsterController
  self.allow_forgery_protection = false
  
  def index
    render :inline => "<%= form_tag('/') {} %>"
  end
  
  def show_button
    render :inline => "<%= button_to('New', '/') {} %>"
  end
end

class FakeSessionDbMan
  def self.generate_digest(data)
    Digest::SHA1.hexdigest("secure")
  end
end

class CsrfCookieMonsterControllerTest < Test::Unit::TestCase
  include RequestForgeryProtectionTests
  def setup
    @controller = CsrfCookieMonsterController.new
    @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new
    # simulate a cookie session store
    @request.session.instance_variable_set(:@dbman, FakeSessionDbMan)
    class << @request.session
      attr_reader :dbman
    end
    @token = Digest::SHA1.hexdigest("secure")
    ActionController::Base.request_forgery_protection_token = :authenticity_token
  end
end

class FreeCookieControllerTest < Test::Unit::TestCase
  
  def setup
    @controller = FreeCookieController.new
    @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new
    @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
  end
  
  def test_should_not_render_form_with_token_tag
    get :index
    assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
  end
  
  def test_should_not_render_button_to_with_token_tag
    get :show_button
    assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
  end
  
  def test_should_allow_all_methods_without_token
    [:post, :put, :delete].each do |method|
      assert_nothing_raised { send(method, :index)}
    end
  end
  
end
Something went wrong with that request. Please try again.