require_relative "../spec_helper"
begin
require 'rack/csrf'
rescue LoadError
warn "rack_csrf not installed, skipping csrf plugin test"
else
describe "csrf plugin" do
include CookieJar
it "adds csrf protection and csrf helper methods" do
app(:bare) do
use(*DEFAULT_SESSION_MIDDLEWARE_ARGS)
plugin :csrf, :skip=>['POST:/foo']
route do |r|
r.get do
response['TAG'] = csrf_tag
response['METATAG'] = csrf_metatag
response['TOKEN'] = csrf_token
response['FIELD'] = csrf_field
response['HEADER'] = csrf_header
'g'
end
r.post 'foo' do
'bar'
end
r.post do
'p'
end
end
end
io = StringIO.new
status('REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 403
body('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 'bar'
s, h, b = req
s.must_equal 200
field = h['FIELD']
token = Regexp.escape(h['TOKEN'])
h['TAG'].must_match(/\A\z/)
h['METATAG'].must_match(/\A\z/)
b.must_equal ['g']
s, _, b = req('REQUEST_METHOD'=>'POST', 'rack.input'=>io, "HTTP_#{h['HEADER']}"=>h['TOKEN'])
s.must_equal 200
b.must_equal ['p']
app.plugin :csrf
body('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 'bar'
end
it "can optionally skip setting up the middleware" do
sub_app = Class.new(Roda)
sub_app.class_eval do
plugin :csrf, :skip_middleware=>true
route do |r|
r.get do
response['TAG'] = csrf_tag
response['METATAG'] = csrf_metatag
response['TOKEN'] = csrf_token
response['FIELD'] = csrf_field
response['HEADER'] = csrf_header
'g'
end
r.post 'bar' do
'foobar'
end
r.post do
'p'
end
end
end
app(:bare) do
use(*DEFAULT_SESSION_MIDDLEWARE_ARGS)
plugin :csrf, :skip=>['POST:/foo/bar']
route do |r|
r.on 'foo' do
r.run sub_app
end
end
end
io = StringIO.new
status('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 403
body('/foo/bar', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 'foobar'
s, h, b = req('/foo')
s.must_equal 200
field = h['FIELD']
token = Regexp.escape(h['TOKEN'])
h['TAG'].must_match(/\A\z/)
h['METATAG'].must_match(/\A\z/)
b.must_equal ['g']
s, _, b = req('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io, "HTTP_#{h['HEADER']}"=>h['TOKEN'])
s.must_equal 200
b.must_equal ['p']
sub_app.plugin :csrf, :skip_middleware=>true
body('/foo/bar', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 'foobar'
@app = sub_app
s, _, b = req('/bar', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io)
s.must_equal 200
b.must_equal ['foobar']
end
end
end