From bfe8b96874c66c54e2e4c1a66a520087b217e9e7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 26 Jul 2017 12:34:52 +0200 Subject: Add specs --- spec/features/oauth_login_spec.rb | 2 +- spec/lib/gitlab/request_forgery_protection_spec.rb | 89 ++++++++++++++++++++++ spec/requests/api/helpers_spec.rb | 50 ++++++++++-- spec/support/forgery_protection.rb | 11 +++ 4 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 spec/lib/gitlab/request_forgery_protection_spec.rb create mode 100644 spec/support/forgery_protection.rb diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index 0064c9ef25e..49d8e52f861 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'OAuth Login', js: true do +feature 'OAuth Login', :js, :allow_forgery_protection do include DeviseHelpers def enter_code(code) diff --git a/spec/lib/gitlab/request_forgery_protection_spec.rb b/spec/lib/gitlab/request_forgery_protection_spec.rb new file mode 100644 index 00000000000..305de613866 --- /dev/null +++ b/spec/lib/gitlab/request_forgery_protection_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper' + +describe Gitlab::RequestForgeryProtection, :allow_forgery_protection do + let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) } + let(:env) do + { + 'rack.input' => '', + 'rack.session' => { + _csrf_token: csrf_token + } + } + end + + describe '.call' do + context 'when the request method is GET' do + before do + env['REQUEST_METHOD'] = 'GET' + end + + it 'does not raise an exception' do + expect { described_class.call(env) }.not_to raise_exception + end + end + + context 'when the request method is POST' do + before do + env['REQUEST_METHOD'] = 'POST' + end + + context 'when the CSRF token is valid' do + before do + env['HTTP_X_CSRF_TOKEN'] = csrf_token + end + + it 'does not raise an exception' do + expect { described_class.call(env) }.not_to raise_exception + end + end + + context 'when the CSRF token is invalid' do + before do + env['HTTP_X_CSRF_TOKEN'] = 'foo' + end + + it 'raises an ActionController::InvalidAuthenticityToken exception' do + expect { described_class.call(env) }.to raise_exception(ActionController::InvalidAuthenticityToken) + end + end + end + end + + describe '.verified?' do + context 'when the request method is GET' do + before do + env['REQUEST_METHOD'] = 'GET' + end + + it 'returns true' do + expect(described_class.verified?(env)).to be_truthy + end + end + + context 'when the request method is POST' do + before do + env['REQUEST_METHOD'] = 'POST' + end + + context 'when the CSRF token is valid' do + before do + env['HTTP_X_CSRF_TOKEN'] = csrf_token + end + + it 'returns true' do + expect(described_class.verified?(env)).to be_truthy + end + end + + context 'when the CSRF token is invalid' do + before do + env['HTTP_X_CSRF_TOKEN'] = 'foo' + end + + it 'returns false' do + expect(described_class.verified?(env)).to be_falsey + end + end + end + end +end diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index 25ec44fa036..7a1bd76af7a 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -10,8 +10,16 @@ describe API::Helpers do let(:key) { create(:key, user: user) } let(:params) { {} } - let(:env) { { 'REQUEST_METHOD' => 'GET' } } - let(:request) { Rack::Request.new(env) } + let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) } + let(:env) do + { + 'rack.input' => '', + 'rack.session' => { + _csrf_token: csrf_token + }, + 'REQUEST_METHOD' => 'GET' + } + end let(:header) { } before do @@ -58,7 +66,7 @@ describe API::Helpers do describe ".current_user" do subject { current_user } - describe "Warden authentication" do + describe "Warden authentication", :allow_forgery_protection do before do doorkeeper_guard_returns false end @@ -99,7 +107,17 @@ describe API::Helpers do env['REQUEST_METHOD'] = 'PUT' end - it { is_expected.to be_nil } + context 'without CSRF token' do + it { is_expected.to be_nil } + end + + context 'with CSRF token' do + before do + env['HTTP_X_CSRF_TOKEN'] = csrf_token + end + + it { is_expected.to eq(user) } + end end context "POST request" do @@ -107,7 +125,17 @@ describe API::Helpers do env['REQUEST_METHOD'] = 'POST' end - it { is_expected.to be_nil } + context 'without CSRF token' do + it { is_expected.to be_nil } + end + + context 'with CSRF token' do + before do + env['HTTP_X_CSRF_TOKEN'] = csrf_token + end + + it { is_expected.to eq(user) } + end end context "DELETE request" do @@ -115,7 +143,17 @@ describe API::Helpers do env['REQUEST_METHOD'] = 'DELETE' end - it { is_expected.to be_nil } + context 'without CSRF token' do + it { is_expected.to be_nil } + end + + context 'with CSRF token' do + before do + env['HTTP_X_CSRF_TOKEN'] = csrf_token + end + + it { is_expected.to eq(user) } + end end end end diff --git a/spec/support/forgery_protection.rb b/spec/support/forgery_protection.rb new file mode 100644 index 00000000000..a5e7b761651 --- /dev/null +++ b/spec/support/forgery_protection.rb @@ -0,0 +1,11 @@ +RSpec.configure do |config| + config.around(:each, :allow_forgery_protection) do |example| + begin + ActionController::Base.allow_forgery_protection = true + + example.call + ensure + ActionController::Base.allow_forgery_protection = false + end + end +end -- cgit v1.2.1