spec/integration/cors_spec.rb
require 'spec_helper'
RSpec.describe 'CORS', type: :integration do
before(:all) do
start_cc
end
after(:all) do
stop_cc
end
let(:authed_headers) do
{
'Authorization' => "bearer #{admin_token}",
'Accept' => 'application/json',
'Content-Type' => 'application/json'
}
end
describe 'v3 rails app' do
let(:test_path) { '/v3/processes' }
context 'when the Origin header is not present' do
it 'does not return any Access-Control headers (the request is not a CORS request)' do
response = make_get_request(test_path, authed_headers)
expect(response.code).to eq('200')
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers)
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'when the Origin header is present' do
describe 'a preflight request' do
def make_preflight_request_with_origin(origin, method=nil, extra_headers={})
headers = {}
headers = headers.merge({ 'Origin' => origin })
headers = headers.merge({ 'Access-Control-Request-Method' => method }) unless method.nil?
headers = headers.merge(extra_headers)
make_options_request(test_path, headers)
end
context 'and the origin is not in the whitelist' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://corblimey.com', 'GET', authed_headers
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request ( there is no options method for /v3/processes so we get a 404 )' do
response = make_preflight_request_with_origin 'http://corblimey.com', 'GET', authed_headers
expect(response.code).to eq('404')
end
end
context 'and the origin is a subset of a domain in the whitelist, but does not match' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://talkoncorners.com.extra', 'GET', authed_headers
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request ( there is no options method for /v3/processes so we get a 404 )' do
response = make_preflight_request_with_origin 'http://talkoncorners.com.extra', 'GET', authed_headers
expect(response.code).to eq('404')
end
end
context 'and the origin matches a domain in the whitelist' do
context 'but no Access-Control-Request-Method header is present' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://wildcarded.inblue.net', nil, authed_headers
expect(response['Access-Control']).to be_nil
end
end
context 'and the Access-Control-Request-Method header is present' do
it 'returns a 200 code and does not process the original request' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response.code).to eq('200')
expect(response.body).to eq('')
end
it 'sets the Content-Type: text/plain header' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response.code).to eq('200')
expect(response.body).to eq('')
expect(response['Content-Type']).to eq('text/plain')
end
it 'returns a Vary: Origin header to ensure response is not cached for different origins' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Vary']).to eq('Origin')
end
it 'returns an Access-Control-Allow-Origin header containing the requested origin domain' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Origin']).to eq('http://bar.baz.inblue.net')
end
it 'allows credentials to be supplied' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Credentials']).to eq('true')
end
it 'returns the valid request methods in the Access-Control-Allow-Methods header' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Methods'].split(',')).to contain_exactly(
'PUT', 'POST', 'DELETE', 'GET'
)
end
it 'returns a max-age header with a large value (since these headers rarely change' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Max-Age'].to_i).to be > 600
end
it 'allows custom headers to be returned' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Expose-Headers'].split(',')).
to contain_exactly('x-cf-warnings', 'x-app-staging-log', 'range', 'location', VCAP::Request::HEADER_NAME.downcase)
end
it 'allows needed request headers to be included' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Headers'].split(',')).to contain_exactly(
'origin',
'content-type',
'authorization'
)
end
context 'when the request asks to allow additional request headers' do
let(:extra_headers) { { 'Access-Control-Request-Headers' => 'foo, bar, baz, Authorization' } }
it 'allows that by adding them to the Allow-Headers list' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers.merge(extra_headers)
expect(response['Access-Control-Allow-Headers'].split(',')).to contain_exactly(
'origin',
'content-type',
'authorization',
'foo', 'bar', 'baz'
)
end
end
end
end
end
describe 'a simple request or actual request' do
context 'and the origin is not in the whitelist' do
it 'does not return any Access-Control headers' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://corblimey.com' }))
expect(response.code).to eq('200')
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://corblimey.com' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'and the origin is a subset of a domain in the whitelist, but does not match' do
it 'does not return any Access-Control headers' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://talkoncorners.com.extra' }))
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://talkoncorners.com.extra' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'and the origin matches an entry in the whitelist' do
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
it 'returns an Access-Control-Allow-Origin header containing the requested origin domain' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Allow-Origin']).to eq('http://foo.inblue.net')
end
it 'allows credentials to be supplied' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Allow-Credentials']).to eq('true')
end
it 'allows custom headers to be returned' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Expose-Headers'].split(',')).
to contain_exactly('x-cf-warnings', 'x-app-staging-log', 'range', 'location', VCAP::Request::HEADER_NAME.downcase)
end
end
end
end
end
describe 'v2 sinatra app' do
let(:test_path) { '/v2/info' }
context 'when the Origin header is not present' do
it 'does not return any Access-Control headers (the request is not a CORS request)' do
response = make_get_request(test_path, authed_headers)
expect(response.code).to eq('200')
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers)
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'when the Origin header is present' do
describe 'a preflight request' do
def make_preflight_request_with_origin(origin, method=nil, extra_headers={})
headers = {}
headers = headers.merge({ 'Origin' => origin })
headers = headers.merge({ 'Access-Control-Request-Method' => method }) unless method.nil?
headers = headers.merge(extra_headers)
make_options_request(test_path, headers)
end
context 'and the origin is not in the whitelist' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://corblimey.com', 'GET', authed_headers
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request ( there is no options method for /v2/info so we get a 404 )' do
response = make_preflight_request_with_origin 'http://corblimey.com', 'GET', authed_headers
expect(response.code).to eq('404')
end
end
context 'and the origin is a subset of a domain in the whitelist, but does not match' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://talkoncorners.com.extra', 'GET', authed_headers
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request ( there is no options method for /v2/info so we get a 404 )' do
response = make_preflight_request_with_origin 'http://talkoncorners.com.extra', 'GET', authed_headers
expect(response.code).to eq('404')
end
end
context 'and the origin matches a domain in the whitelist' do
context 'but no Access-Control-Request-Method header is present' do
it 'does not return any Access-Control headers' do
response = make_preflight_request_with_origin 'http://wildcarded.inblue.net', nil, authed_headers
expect(response['Access-Control']).to be_nil
end
end
context 'and the Access-Control-Request-Method header is present' do
it 'returns a 200 code and does not process the original request' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response.code).to eq('200')
expect(response.body).to eq('')
end
it 'sets the Content-Type: text/plain header' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response.code).to eq('200')
expect(response.body).to eq('')
expect(response['Content-Type']).to eq('text/plain')
end
it 'returns a Vary: Origin header to ensure response is not cached for different origins' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Vary']).to eq('Origin')
end
it 'returns an Access-Control-Allow-Origin header containing the requested origin domain' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Origin']).to eq('http://bar.baz.inblue.net')
end
it 'allows credentials to be supplied' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Credentials']).to eq('true')
end
it 'returns the valid request methods in the Access-Control-Allow-Methods header' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Methods'].split(',')).to contain_exactly(
'PUT', 'POST', 'DELETE', 'GET'
)
end
it 'returns a max-age header with a large value (since these headers rarely change' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Max-Age'].to_i).to be > 600
end
it 'allows custom headers to be returned' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Expose-Headers'].split(',')).
to contain_exactly('x-cf-warnings', 'x-app-staging-log', 'range', 'location', VCAP::Request::HEADER_NAME.downcase)
end
it 'allows needed request headers to be included' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers
expect(response['Access-Control-Allow-Headers'].split(',')).to contain_exactly(
'origin',
'content-type',
'authorization'
)
end
context 'when the request asks to allow additional request headers' do
let(:extra_headers) { { 'Access-Control-Request-Headers' => 'foo, bar, baz, Authorization' } }
it 'allows that by adding them to the Allow-Headers list' do
response = make_preflight_request_with_origin 'http://bar.baz.inblue.net', 'PUT', authed_headers.merge(extra_headers)
expect(response['Access-Control-Allow-Headers'].split(',')).to contain_exactly(
'origin',
'content-type',
'authorization',
'foo', 'bar', 'baz'
)
end
end
end
end
end
describe 'a simple request or actual request' do
context 'and the origin is not in the whitelist' do
it 'does not return any Access-Control headers' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://corblimey.com' }))
expect(response.code).to eq('200')
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://corblimey.com' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'and the origin is a subset of a domain in the whitelist, but does not match' do
it 'does not return any Access-Control headers' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://talkoncorners.com.extra' }))
expect(response['Access-Control']).to be_nil
end
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://talkoncorners.com.extra' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
end
context 'and the origin matches an entry in the whitelist' do
it 'delegates to the initial request' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response.json_body).to be_a(Hash)
end
it 'returns an Access-Control-Allow-Origin header containing the requested origin domain' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Allow-Origin']).to eq('http://foo.inblue.net')
end
it 'allows credentials to be supplied' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Allow-Credentials']).to eq('true')
end
it 'allows custom headers to be returned' do
response = make_get_request(test_path, authed_headers.merge({ 'Origin' => 'http://foo.inblue.net' }))
expect(response.code).to eq('200')
expect(response['Access-Control-Expose-Headers'].split(',')).
to contain_exactly('x-cf-warnings', 'x-app-staging-log', 'range', 'location', VCAP::Request::HEADER_NAME.downcase)
end
end
end
end
end
end