diff options
-rw-r--r-- | spec/requests/git_http_spec.rb (renamed from spec/lib/gitlab/backend/grack_auth_spec.rb) | 161 |
1 files changed, 71 insertions, 90 deletions
diff --git a/spec/lib/gitlab/backend/grack_auth_spec.rb b/spec/requests/git_http_spec.rb index cd26dca0998..7e274b4209b 100644 --- a/spec/lib/gitlab/backend/grack_auth_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -1,83 +1,60 @@ require "spec_helper" -describe Grack::Auth, lib: true do +describe 'Git HTTP requests', lib: true do let(:user) { create(:user) } let(:project) { create(:project) } - let(:app) { lambda { |env| [200, {}, "Success!"] } } - let!(:auth) { Grack::Auth.new(app) } - let(:env) do - { - 'rack.input' => '', - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'service=git-upload-pack' - } - end - let(:status) { auth.call(env).first } - describe "#call" do context "when the project doesn't exist" do - before do - env["PATH_INFO"] = "doesnt/exist.git" - end - context "when no authentication is provided" do it "responds with status 401" do - expect(status).to eq(401) + clone_get '/doesnt/exist.git/info/refs' + + expect(response.status).to eq(401) end end context "when username and password are provided" do context "when authentication fails" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, "nope") - end - it "responds with status 401" do - expect(status).to eq(401) + clone_get '/doesnt/exist.git/info/refs', user: user.username, password: "nope" + + expect(response.status).to eq(401) end end context "when authentication succeeds" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) - end - it "responds with status 404" do - expect(status).to eq(404) + clone_get '/doesnt/exist.git/info/refs', user: user.username, password: user.password + + expect(response.status).to eq(404) end end end end context "when the Wiki for a project exists" do - before do - @wiki = ProjectWiki.new(project) - env["PATH_INFO"] = "#{@wiki.repository.path_with_namespace}.git/info/refs" + it "responds with the right project" do + wiki = ProjectWiki.new(project) project.update_attribute(:visibility_level, Project::PUBLIC) - end - it "responds with the right project" do - response = auth.call(env) - json_body = ActiveSupport::JSON.decode(response[2][0]) + clone_get "/#{wiki.repository.path_with_namespace}.git/info/refs" + json_body = ActiveSupport::JSON.decode(response.body) - expect(response.first).to eq(200) - expect(json_body['RepoPath']).to include(@wiki.repository.path_with_namespace) + expect(response.status).to eq(200) + expect(json_body['RepoPath']).to include(wiki.repository.path_with_namespace) end end context "when the project exists" do - before do - env["PATH_INFO"] = project.path_with_namespace + ".git" - end + let(:path) { clone_path(project) } context "when the project is public" do - before do + it "responds with status 200" do project.update_attribute(:visibility_level, Project::PUBLIC) - end + clone_get path - it "responds with status 200" do - expect(status).to eq(200) + expect(response.status).to eq(200) end end @@ -88,85 +65,74 @@ describe Grack::Auth, lib: true do context "when no authentication is provided" do it "responds with status 401" do - expect(status).to eq(401) + clone_get path + + expect(response.status).to eq(401) end end context "when username and password are provided" do context "when authentication fails" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, "nope") - end - it "responds with status 401" do - expect(status).to eq(401) + clone_get path, user: user.username, password: 'nope' + + expect(response.status).to eq(401) end context "when the user is IP banned" do - before do + it "responds with status 401" do expect(Rack::Attack::Allow2Ban).to receive(:filter).and_return(true) allow_any_instance_of(Rack::Request).to receive(:ip).and_return('1.2.3.4') - end - it "responds with status 401" do - expect(status).to eq(401) + clone_get path, user: user.username, password: 'nope' + + expect(response.status).to eq(401) end end end context "when authentication succeeds" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) - end - context "when the user has access to the project" do before do project.team << [user, :master] end context "when the user is blocked" do - before do + it "responds with status 404" do user.block project.team << [user, :master] - end - it "responds with status 404" do - expect(status).to eq(404) + clone_get path, user: user.username, password: user.password + + expect(response.status).to eq(404) end end context "when the user isn't blocked" do - before do + it "responds with status 200" do expect(Rack::Attack::Allow2Ban).to receive(:reset) - end - it "responds with status 200" do - expect(status).to eq(200) + clone_get path, user: user.username, password: user.password + + expect(response.status).to eq(200) end end context "when blank password attempts follow a valid login" do - let(:options) { Gitlab.config.rack_attack.git_basic_auth } - let(:maxretry) { options[:maxretry] - 1 } - let(:ip) { '1.2.3.4' } - - before do - allow_any_instance_of(Rack::Request).to receive(:ip).and_return(ip) - Rack::Attack::Allow2Ban.reset(ip, options) - end - - after do - Rack::Attack::Allow2Ban.reset(ip, options) - end - def attempt_login(include_password) password = include_password ? user.password : "" - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, password) - Grack::Auth.new(app) - auth.call(env).first + clone_get path, user: user.username, password: password + response.status end it "repeated attempts followed by successful attempt" do + options = Gitlab.config.rack_attack.git_basic_auth + maxretry = options[:maxretry] - 1 + ip = '1.2.3.4' + + allow_any_instance_of(Rack::Request).to receive(:ip).and_return(ip) + Rack::Attack::Allow2Ban.reset(ip, options) + maxretry.times.each do expect(attempt_login(false)).to eq(401) end @@ -177,33 +143,48 @@ describe Grack::Auth, lib: true do maxretry.times.each do expect(attempt_login(false)).to eq(401) end + + Rack::Attack::Allow2Ban.reset(ip, options) end end end context "when the user doesn't have access to the project" do it "responds with status 404" do - expect(status).to eq(404) + clone_get path, user: user.username, password: user.password + + expect(response.status).to eq(404) end end end end context "when a gitlab ci token is provided" do - let(:token) { "123" } - let(:project) { FactoryGirl.create :empty_project } - - before do + it "responds with status 200" do + token = "123" + project = FactoryGirl.create :empty_project project.update_attributes(runners_token: token, builds_enabled: true) - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token) - end + clone_get clone_path(project), user: 'gitlab-ci-token', password: token - it "responds with status 200" do - expect(status).to eq(200) + expect(response.status).to eq(200) end end end end end + + def clone_get(url, user: nil, password: nil) + if user && password + env = { 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password) } + else + env = {} + end + + get url, { 'service' => 'git-upload-pack' }, env + end + + def clone_path(project) + "/#{project.path_with_namespace}.git/info/refs" + end end |