/
authenticity_token_spec.rb
104 lines (85 loc) · 3.67 KB
/
authenticity_token_spec.rb
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
describe Rack::Protection::AuthenticityToken do
let(:token) { described_class.random_token }
let(:masked_token) { described_class.token(session) }
let(:bad_token) { Base64.strict_encode64("badtoken") }
let(:session) { {:csrf => token} }
it_behaves_like "any rack application"
it "denies post requests without any token" do
expect(post('/')).not_to be_ok
end
it "accepts post requests with correct X-CSRF-Token header" do
post('/', {}, 'rack.session' => session, 'HTTP_X_CSRF_TOKEN' => token)
expect(last_response).to be_ok
end
it "accepts post requests with masked X-CSRF-Token header" do
post('/', {}, 'rack.session' => session, 'HTTP_X_CSRF_TOKEN' => masked_token)
expect(last_response).to be_ok
end
it "denies post requests with wrong X-CSRF-Token header" do
post('/', {}, 'rack.session' => session, 'HTTP_X_CSRF_TOKEN' => bad_token)
expect(last_response).not_to be_ok
end
it "accepts post form requests with correct authenticity_token field" do
post('/', {"authenticity_token" => token}, 'rack.session' => session)
expect(last_response).to be_ok
end
it "accepts post form requests with masked authenticity_token field" do
post('/', {"authenticity_token" => masked_token}, 'rack.session' => session)
expect(last_response).to be_ok
end
it "denies post form requests with wrong authenticity_token field" do
post('/', {"authenticity_token" => bad_token}, 'rack.session' => session)
expect(last_response).not_to be_ok
end
it "accepts post form requests with a valid per form token" do
token = Rack::Protection::AuthenticityToken.token(session, path: '/foo')
post('/foo', {"authenticity_token" => token}, 'rack.session' => session)
expect(last_response).to be_ok
end
it "denies post form requests with an invalid per form token" do
token = Rack::Protection::AuthenticityToken.token(session, path: '/foo')
post('/bar', {"authenticity_token" => token}, 'rack.session' => session)
expect(last_response).not_to be_ok
end
it "prevents ajax requests without a valid token" do
expect(post('/', {}, "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")).not_to be_ok
end
it "allows for a custom authenticity token param" do
mock_app do
use Rack::Protection::AuthenticityToken, :authenticity_param => 'csrf_param'
run proc { |e| [200, {'Content-Type' => 'text/plain'}, ['hi']] }
end
post('/', {"csrf_param" => token}, 'rack.session' => {:csrf => token})
expect(last_response).to be_ok
end
it "sets a new csrf token for the session in env, even after a 'safe' request" do
get('/', {}, {})
expect(env['rack.session'][:csrf]).not_to be_nil
end
it "allows for a custom token session key" do
mock_app do
use Rack::Session::Cookie, :key => 'rack.session'
use Rack::Protection::AuthenticityToken, :key => :_csrf
run DummyApp
end
get '/'
expect(env['rack.session'][:_csrf]).not_to be_nil
end
describe ".token" do
it "returns a unique masked version of the authenticity token" do
expect(Rack::Protection::AuthenticityToken.token(session)).not_to eq(masked_token)
end
it "sets a session authenticity token if one does not exist" do
session = {}
allow(Rack::Protection::AuthenticityToken).to receive(:random_token).and_return(token)
allow_any_instance_of(Rack::Protection::AuthenticityToken).to receive(:mask_token).and_return(masked_token)
Rack::Protection::AuthenticityToken.token(session)
expect(session[:csrf]).to eq(token)
end
end
describe ".random_token" do
it "generates a base64 encoded 32 character string" do
expect(Base64.urlsafe_decode64(token).length).to eq(32)
end
end
end