diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 745166869213ea37ebe6d487af62dc972c5c7b98..c0c1e62e9103f4a7e1fd2127311d8979339fde1b 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -1,508 +1,517 @@
 require "spec_helper"
 
 describe 'Git HTTP requests', lib: true do
+  include GitHttpHelpers
   include WorkhorseHelpers
 
-  let(:user)    { create(:user) }
-  let(:project) { create(:project, path: 'project.git-project') }
-
   it "gives WWW-Authenticate hints" do
     clone_get('doesnt/exist.git')
 
     expect(response.header['WWW-Authenticate']).to start_with('Basic ')
   end
 
-  context "when the project doesn't exist" do
-    context "when no authentication is provided" do
-      it "responds with status 401 (no project existence information leak)" do
-        download('doesnt/exist.git') do |response|
-          expect(response).to have_http_status(401)
-        end
-      end
-    end
+  describe "User with no identities" do
+    let(:user)    { create(:user) }
+    let(:project) { create(:project, path: 'project.git-project') }
 
-    context "when username and password are provided" do
-      context "when authentication fails" do
-        it "responds with status 401" do
-          download('doesnt/exist.git', user: user.username, password: "nope") do |response|
+    context "when the project doesn't exist" do
+      context "when no authentication is provided" do
+        it "responds with status 401 (no project existence information leak)" do
+          download('doesnt/exist.git') do |response|
             expect(response).to have_http_status(401)
           end
         end
       end
 
-      context "when authentication succeeds" do
-        it "responds with status 404" do
-          download('/doesnt/exist.git', user: user.username, password: user.password) do |response|
-            expect(response).to have_http_status(404)
+      context "when username and password are provided" do
+        context "when authentication fails" do
+          it "responds with status 401" do
+            download('doesnt/exist.git', user: user.username, password: "nope") do |response|
+              expect(response).to have_http_status(401)
+            end
           end
         end
-      end
-    end
-  end
-
-  context "when the Wiki for a project exists" do
-    it "responds with the right project" do
-      wiki = ProjectWiki.new(project)
-      project.update_attribute(:visibility_level, Project::PUBLIC)
 
-      download("/#{wiki.repository.path_with_namespace}.git") do |response|
-        json_body = ActiveSupport::JSON.decode(response.body)
-
-        expect(response).to have_http_status(200)
-        expect(json_body['RepoPath']).to include(wiki.repository.path_with_namespace)
-        expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+        context "when authentication succeeds" do
+          it "responds with status 404" do
+            download('/doesnt/exist.git', user: user.username, password: user.password) do |response|
+              expect(response).to have_http_status(404)
+            end
+          end
+        end
       end
     end
-  end
 
-  context "when the project exists" do
-    let(:path) { "#{project.path_with_namespace}.git" }
-
-    context "when the project is public" do
-      before do
+    context "when the Wiki for a project exists" do
+      it "responds with the right project" do
+        wiki = ProjectWiki.new(project)
         project.update_attribute(:visibility_level, Project::PUBLIC)
-      end
 
-      it "downloads get status 200" do
-        download(path, {}) do |response|
+        download("/#{wiki.repository.path_with_namespace}.git") do |response|
+          json_body = ActiveSupport::JSON.decode(response.body)
+
           expect(response).to have_http_status(200)
+          expect(json_body['RepoPath']).to include(wiki.repository.path_with_namespace)
           expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
         end
       end
+    end
+
+    context "when the project exists" do
+      let(:path) { "#{project.path_with_namespace}.git" }
 
-      it "uploads get status 401" do
-        upload(path, {}) do |response|
-          expect(response).to have_http_status(401)
+      context "when the project is public" do
+        before do
+          project.update_attribute(:visibility_level, Project::PUBLIC)
         end
-      end
 
-      context "with correct credentials" do
-        let(:env) { { user: user.username, password: user.password } }
+        it "downloads get status 200" do
+          download(path, {}) do |response|
+            expect(response).to have_http_status(200)
+            expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+          end
+        end
 
-        it "uploads get status 403" do
-          upload(path, env) do |response|
-            expect(response).to have_http_status(403)
+        it "uploads get status 401" do
+          upload(path, {}) do |response|
+            expect(response).to have_http_status(401)
           end
         end
 
-        context 'but git-receive-pack is disabled' do
-          it "responds with status 404" do
-            allow(Gitlab.config.gitlab_shell).to receive(:receive_pack).and_return(false)
+        context "with correct credentials" do
+          let(:env) { { user: user.username, password: user.password } }
 
+          it "uploads get status 403" do
             upload(path, env) do |response|
               expect(response).to have_http_status(403)
             end
           end
-        end
-      end
 
-      context 'but git-upload-pack is disabled' do
-        it "responds with status 404" do
-          allow(Gitlab.config.gitlab_shell).to receive(:upload_pack).and_return(false)
+          context 'but git-receive-pack is disabled' do
+            it "responds with status 404" do
+              allow(Gitlab.config.gitlab_shell).to receive(:receive_pack).and_return(false)
 
-          download(path, {}) do |response|
-            expect(response).to have_http_status(404)
+              upload(path, env) do |response|
+                expect(response).to have_http_status(403)
+              end
+            end
           end
         end
-      end
-      
-      context 'when the request is not from gitlab-workhorse' do
-        it 'raises an exception' do
-          expect do
-            get("/#{project.path_with_namespace}.git/info/refs?service=git-upload-pack")
-          end.to raise_error(JWT::DecodeError)
-        end
-      end
-    end
 
-    context "when the project is private" do
-      before do
-        project.update_attribute(:visibility_level, Project::PRIVATE)
-      end
+        context 'but git-upload-pack is disabled' do
+          it "responds with status 404" do
+            allow(Gitlab.config.gitlab_shell).to receive(:upload_pack).and_return(false)
 
-      context "when no authentication is provided" do
-        it "responds with status 401 to downloads" do
-          download(path, {}) do |response|
-            expect(response).to have_http_status(401)
+            download(path, {}) do |response|
+              expect(response).to have_http_status(404)
+            end
           end
         end
 
-        it "responds with status 401 to uploads" do
-          upload(path, {}) do |response|
-            expect(response).to have_http_status(401)
+        context 'when the request is not from gitlab-workhorse' do
+          it 'raises an exception' do
+            expect do
+              get("/#{project.path_with_namespace}.git/info/refs?service=git-upload-pack")
+            end.to raise_error(JWT::DecodeError)
           end
         end
       end
 
-      context "when username and password are provided" do
-        let(:env) { { user: user.username, password: 'nope' } }
+      context "when the project is private" do
+        before do
+          project.update_attribute(:visibility_level, Project::PRIVATE)
+        end
 
-        context "when authentication fails" do
-          it "responds with status 401" do
-            download(path, env) do |response|
+        context "when no authentication is provided" do
+          it "responds with status 401 to downloads" do
+            download(path, {}) do |response|
               expect(response).to have_http_status(401)
             end
           end
 
-          context "when the user is IP banned" 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')
-
-              clone_get(path, env)
-
+          it "responds with status 401 to uploads" do
+            upload(path, {}) do |response|
               expect(response).to have_http_status(401)
             end
           end
         end
 
-        context "when authentication succeeds" do
-          let(:env) { { user: user.username, password: user.password } }
+        context "when username and password are provided" do
+          let(:env) { { user: user.username, password: 'nope' } }
 
-          context "when the user has access to the project" do
-            before do
-              project.team << [user, :master]
+          context "when authentication fails" do
+            it "responds with status 401" do
+              download(path, env) do |response|
+                expect(response).to have_http_status(401)
+              end
             end
 
-            context "when the user is blocked" do
-              it "responds with status 404" do
-                user.block
-                project.team << [user, :master]
+            context "when the user is IP banned" 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')
 
-                download(path, env) do |response|
-                  expect(response).to have_http_status(404)
-                end
+                clone_get(path, env)
+
+                expect(response).to have_http_status(401)
               end
             end
+          end
 
-            context "when the user isn't blocked" do
-              it "downloads get status 200" do
-                expect(Rack::Attack::Allow2Ban).to receive(:reset)
+          context "when authentication succeeds" do
+            let(:env) { { user: user.username, password: user.password } }
 
-                clone_get(path, env)
+            context "when the user has access to the project" do
+              before do
+                project.team << [user, :master]
+              end
 
-                expect(response).to have_http_status(200)
-                expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+              context "when the user is blocked" do
+                it "responds with status 404" do
+                  user.block
+                  project.team << [user, :master]
+
+                  download(path, env) do |response|
+                    expect(response).to have_http_status(404)
+                  end
+                end
               end
 
-              it "uploads get status 200" do
-                upload(path, env) do |response|
+              context "when the user isn't blocked" do
+                it "downloads get status 200" do
+                  expect(Rack::Attack::Allow2Ban).to receive(:reset)
+
+                  clone_get(path, env)
+
                   expect(response).to have_http_status(200)
                   expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
                 end
-              end
-            end
 
-            context "when an oauth token is provided" do
-              before do
-                application = Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user)
-                @token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id)
+                it "uploads get status 200" do
+                  upload(path, env) do |response|
+                    expect(response).to have_http_status(200)
+                    expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+                  end
+                end
               end
 
-              it "downloads get status 200" do
-                clone_get "#{project.path_with_namespace}.git", user: 'oauth2', password: @token.token
+              context "when an oauth token is provided" do
+                before do
+                  application = Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user)
+                  @token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id)
+                end
 
-                expect(response).to have_http_status(200)
-                expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
-              end
+                it "downloads get status 200" do
+                  clone_get "#{project.path_with_namespace}.git", user: 'oauth2', password: @token.token
 
-              it "uploads get status 401 (no project existence information leak)" do
-                push_get "#{project.path_with_namespace}.git", user: 'oauth2', password: @token.token
+                  expect(response).to have_http_status(200)
+                  expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+                end
 
-                expect(response).to have_http_status(401)
+                it "uploads get status 401 (no project existence information leak)" do
+                  push_get "#{project.path_with_namespace}.git", user: 'oauth2', password: @token.token
+
+                  expect(response).to have_http_status(401)
+                end
               end
-            end
 
-            context 'when user has 2FA enabled' do
-              let(:user) { create(:user, :two_factor) }
-              let(:access_token) { create(:personal_access_token, user: user) }
+              context 'when user has 2FA enabled' do
+                let(:user) { create(:user, :two_factor) }
+                let(:access_token) { create(:personal_access_token, user: user) }
 
-              before do
-                project.team << [user, :master]
-              end
+                before do
+                  project.team << [user, :master]
+                end
 
-              context 'when username and password are provided' do
-                it 'rejects the clone attempt' do
-                  download("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
-                    expect(response).to have_http_status(401)
-                    expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+                context 'when username and password are provided' do
+                  it 'rejects the clone attempt' do
+                    download("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
+                      expect(response).to have_http_status(401)
+                      expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+                    end
                   end
-                end
 
-                it 'rejects the push attempt' do
-                  upload("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
-                    expect(response).to have_http_status(401)
-                    expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+                  it 'rejects the push attempt' do
+                    upload("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
+                      expect(response).to have_http_status(401)
+                      expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+                    end
                   end
                 end
-              end
 
-              context 'when username and personal access token are provided' do
-                it 'allows clones' do
-                  download("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
-                    expect(response).to have_http_status(200)
+                context 'when username and personal access token are provided' do
+                  it 'allows clones' do
+                    download("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
+                      expect(response).to have_http_status(200)
+                    end
                   end
-                end
 
-                it 'allows pushes' do
-                  upload("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
-                    expect(response).to have_http_status(200)
+                  it 'allows pushes' do
+                    upload("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
+                      expect(response).to have_http_status(200)
+                    end
                   end
                 end
               end
-            end
 
-            context "when blank password attempts follow a valid login" do
-              def attempt_login(include_password)
-                password = include_password ? user.password : ""
-                clone_get path, user: user.username, password: password
-                response.status
-              end
+              context "when blank password attempts follow a valid login" do
+                def attempt_login(include_password)
+                  password = include_password ? user.password : ""
+                  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'
+                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)
+                  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
+                  maxretry.times.each do
+                    expect(attempt_login(false)).to eq(401)
+                  end
 
-                expect(attempt_login(true)).to eq(200)
-                expect(Rack::Attack::Allow2Ban.banned?(ip)).to be_falsey
+                  expect(attempt_login(true)).to eq(200)
+                  expect(Rack::Attack::Allow2Ban.banned?(ip)).to be_falsey
 
-                maxretry.times.each do
-                  expect(attempt_login(false)).to eq(401)
-                end
+                  maxretry.times.each do
+                    expect(attempt_login(false)).to eq(401)
+                  end
 
-                Rack::Attack::Allow2Ban.reset(ip, options)
+                  Rack::Attack::Allow2Ban.reset(ip, options)
+                end
               end
             end
-          end
 
-          context "when the user doesn't have access to the project" do
-            it "downloads get status 404" do
-              download(path, user: user.username, password: user.password) do |response|
-                expect(response).to have_http_status(404)
+            context "when the user doesn't have access to the project" do
+              it "downloads get status 404" do
+                download(path, user: user.username, password: user.password) do |response|
+                  expect(response).to have_http_status(404)
+                end
               end
-            end
 
-            it "uploads get status 404" do
-              upload(path, user: user.username, password: user.password) do |response|
-                expect(response).to have_http_status(404)
+              it "uploads get status 404" do
+                upload(path, user: user.username, password: user.password) do |response|
+                  expect(response).to have_http_status(404)
+                end
               end
             end
           end
         end
-      end
-
-      context "when a gitlab ci token is provided" do
-        let(:build) { create(:ci_build, :running) }
-        let(:project) { build.project }
-        let(:other_project) { create(:empty_project) }
-
-        before do
-          project.project_feature.update_attributes(builds_access_level: ProjectFeature::ENABLED)
-        end
-
-        context 'when build created by system is authenticated' do
-          it "downloads get status 200" do
-            clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
-
-            expect(response).to have_http_status(200)
-            expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
-          end
-
-          it "uploads get status 401 (no project existence information leak)" do
-            push_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
-
-            expect(response).to have_http_status(401)
-          end
-
-          it "downloads from other project get status 404" do
-            clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
 
-            expect(response).to have_http_status(404)
-          end
-        end
+        context "when a gitlab ci token is provided" do
+          let(:build) { create(:ci_build, :running) }
+          let(:project) { build.project }
+          let(:other_project) { create(:empty_project) }
 
-        context 'and build created by' do
           before do
-            build.update(user: user)
-            project.team << [user, :reporter]
+            project.project_feature.update_attributes(builds_access_level: ProjectFeature::ENABLED)
           end
 
-          shared_examples 'can download code only' do
-            it 'downloads get status 200' do
+          context 'when build created by system is authenticated' do
+            it "downloads get status 200" do
               clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
 
               expect(response).to have_http_status(200)
               expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
             end
 
-            it 'uploads get status 403' do
+            it "uploads get status 401 (no project existence information leak)" do
               push_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
 
               expect(response).to have_http_status(401)
             end
+
+            it "downloads from other project get status 404" do
+              clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+
+              expect(response).to have_http_status(404)
+            end
           end
 
-          context 'administrator' do
-            let(:user) { create(:admin) }
+          context 'and build created by' do
+            before do
+              build.update(user: user)
+              project.team << [user, :reporter]
+            end
 
-            it_behaves_like 'can download code only'
+            shared_examples 'can download code only' do
+              it 'downloads get status 200' do
+                clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
 
-            it 'downloads from other project get status 403' do
-              clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+                expect(response).to have_http_status(200)
+                expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+              end
 
-              expect(response).to have_http_status(403)
+              it 'uploads get status 403' do
+                push_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+
+                expect(response).to have_http_status(401)
+              end
             end
-          end
 
-          context 'regular user' do
-            let(:user) { create(:user) }
+            context 'administrator' do
+              let(:user) { create(:admin) }
 
-            it_behaves_like 'can download code only'
+              it_behaves_like 'can download code only'
 
-            it 'downloads from other project get status 404' do
-              clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+              it 'downloads from other project get status 403' do
+                clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
 
-              expect(response).to have_http_status(404)
+                expect(response).to have_http_status(403)
+              end
+            end
+
+            context 'regular user' do
+              let(:user) { create(:user) }
+
+              it_behaves_like 'can download code only'
+
+              it 'downloads from other project get status 404' do
+                clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+
+                expect(response).to have_http_status(404)
+              end
             end
           end
         end
       end
     end
-  end
 
-  context "when the project path doesn't end in .git" do
-    context "GET info/refs" do
-      let(:path) { "/#{project.path_with_namespace}/info/refs" }
+    context "when the project path doesn't end in .git" do
+      context "GET info/refs" do
+        let(:path) { "/#{project.path_with_namespace}/info/refs" }
 
-      context "when no params are added" do
-        before { get path }
+        context "when no params are added" do
+          before { get path }
 
-        it "redirects to the .git suffix version" do
-          expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
+          it "redirects to the .git suffix version" do
+            expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
+          end
         end
-      end
 
-      context "when the upload-pack service is requested" do
-        let(:params) { { service: 'git-upload-pack' } }
-        before { get path, params }
+        context "when the upload-pack service is requested" do
+          let(:params) { { service: 'git-upload-pack' } }
+          before { get path, params }
 
-        it "redirects to the .git suffix version" do
-          expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+          it "redirects to the .git suffix version" do
+            expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+          end
         end
-      end
 
-      context "when the receive-pack service is requested" do
-        let(:params) { { service: 'git-receive-pack' } }
-        before { get path, params }
+        context "when the receive-pack service is requested" do
+          let(:params) { { service: 'git-receive-pack' } }
+          before { get path, params }
 
-        it "redirects to the .git suffix version" do
-          expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+          it "redirects to the .git suffix version" do
+            expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+          end
         end
-      end
 
-      context "when the params are anything else" do
-        let(:params) { { service: 'git-implode-pack' } }
-        before { get path, params }
+        context "when the params are anything else" do
+          let(:params) { { service: 'git-implode-pack' } }
+          before { get path, params }
 
-        it "redirects to the sign-in page" do
-          expect(response).to redirect_to(new_user_session_path)
+          it "redirects to the sign-in page" do
+            expect(response).to redirect_to(new_user_session_path)
+          end
         end
       end
-    end
 
-    context "POST git-upload-pack" do
-      it "fails to find a route" do
-        expect { clone_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+      context "POST git-upload-pack" do
+        it "fails to find a route" do
+          expect { clone_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+        end
       end
-    end
 
-    context "POST git-receive-pack" do
-      it "failes to find a route" do
-        expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+      context "POST git-receive-pack" do
+        it "failes to find a route" do
+          expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+        end
       end
     end
-  end
 
-  context "retrieving an info/refs file" do
-    before { project.update_attribute(:visibility_level, Project::PUBLIC) }
+    context "retrieving an info/refs file" do
+      before { project.update_attribute(:visibility_level, Project::PUBLIC) }
 
-    context "when the file exists" do
-      before do
-        # Provide a dummy file in its place
-        allow_any_instance_of(Repository).to receive(:blob_at).and_call_original
-        allow_any_instance_of(Repository).to receive(:blob_at).with('5937ac0a7beb003549fc5fd26fc247adbce4a52e', 'info/refs') do
-          Gitlab::Git::Blob.find(project.repository, 'master', '.gitignore')
-        end
+      context "when the file exists" do
+        before do
+          # Provide a dummy file in its place
+          allow_any_instance_of(Repository).to receive(:blob_at).and_call_original
+          allow_any_instance_of(Repository).to receive(:blob_at).with('5937ac0a7beb003549fc5fd26fc247adbce4a52e', 'info/refs') do
+            Gitlab::Git::Blob.find(project.repository, 'master', '.gitignore')
+          end
 
-        get "/#{project.path_with_namespace}/blob/master/info/refs"
-      end
+          get "/#{project.path_with_namespace}/blob/master/info/refs"
+        end
 
-      it "returns the file" do
-        expect(response).to have_http_status(200)
+        it "returns the file" do
+          expect(response).to have_http_status(200)
+        end
       end
-    end
 
-    context "when the file does not exist" do
-      before { get "/#{project.path_with_namespace}/blob/master/info/refs" }
+      context "when the file does not exist" do
+        before { get "/#{project.path_with_namespace}/blob/master/info/refs" }
 
-      it "returns not found" do
-        expect(response).to have_http_status(404)
+        it "returns not found" do
+          expect(response).to have_http_status(404)
+        end
       end
     end
   end
 
-  def clone_get(project, options = {})
-    get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
-  end
-
-  def clone_post(project, options = {})
-    post "/#{project}/git-upload-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
-  end
-
-  def push_get(project, options = {})
-    get "/#{project}/info/refs", { service: 'git-receive-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
-  end
-
-  def push_post(project, options = {})
-    post "/#{project}/git-receive-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
-  end
+  describe "User with LDAP identity" do
+    let(:user) { create(:omniauth_user, extern_uid: dn) }
+    let(:dn) { 'uid=john,ou=people,dc=example,dc=com' }
 
-  def download(project, user: nil, password: nil, spnego_request_token: nil)
-    args = [project, { user: user, password: password, spnego_request_token: spnego_request_token }]
+    before do
+      allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
+      allow(Gitlab::LDAP::Authentication).to receive(:login).and_return(nil)
+      allow(Gitlab::LDAP::Authentication).to receive(:login).with(user.username, user.password).and_return(user)
+    end
 
-    clone_get(*args)
-    yield response
+    context "when authentication fails" do
+      context "when no authentication is provided" do
+        it "responds with status 401" do
+          download('doesnt/exist.git') do |response|
+            expect(response).to have_http_status(401)
+          end
+        end
+      end
 
-    clone_post(*args)
-    yield response
-  end
+      context "when username and invalid password are provided" do
+        it "responds with status 401" do
+          download('doesnt/exist.git', user: user.username, password: "nope") do |response|
+            expect(response).to have_http_status(401)
+          end
+        end
+      end
+    end
 
-  def upload(project, user: nil, password: nil, spnego_request_token: nil)
-    args = [project, { user: user, password: password, spnego_request_token: spnego_request_token }]
+    context "when authentication succeeds" do
+      context "when the project doesn't exist" do
+        it "responds with status 404" do
+          download('/doesnt/exist.git', user: user.username, password: user.password) do |response|
+            expect(response).to have_http_status(404)
+          end
+        end
+      end
 
-    push_get(*args)
-    yield response
+      context "when the project exists" do
+        let(:project) { create(:project, path: 'project.git-project') }
 
-    push_post(*args)
-    yield response
-  end
+        before do
+          project.team << [user, :master]
+        end
 
-  def auth_env(user, password, spnego_request_token)
-    env = workhorse_internal_api_request_header
-    if user && password
-      env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user, password)
-    elsif spnego_request_token
-      env['HTTP_AUTHORIZATION'] = "Negotiate #{::Base64.strict_encode64('opaque_request_token')}"
+        it "responds with status 200" do
+          clone_get(path, user: user.username, password: user.password) do |response|
+            expect(response).to have_http_status(200)
+          end
+        end
+      end
     end
-
-    env
   end
 end
diff --git a/spec/support/git_http_helpers.rb b/spec/support/git_http_helpers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..46b686fce942ab7bc4e11a56774423f3bf5e37f5
--- /dev/null
+++ b/spec/support/git_http_helpers.rb
@@ -0,0 +1,48 @@
+module GitHttpHelpers
+  def clone_get(project, options = {})
+    get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+  end
+
+  def clone_post(project, options = {})
+    post "/#{project}/git-upload-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+  end
+
+  def push_get(project, options = {})
+    get "/#{project}/info/refs", { service: 'git-receive-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+  end
+
+  def push_post(project, options = {})
+    post "/#{project}/git-receive-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+  end
+
+  def download(project, user: nil, password: nil, spnego_request_token: nil)
+    args = [project, { user: user, password: password, spnego_request_token: spnego_request_token }]
+
+    clone_get(*args)
+    yield response
+
+    clone_post(*args)
+    yield response
+  end
+
+  def upload(project, user: nil, password: nil, spnego_request_token: nil)
+    args = [project, { user: user, password: password, spnego_request_token: spnego_request_token }]
+
+    push_get(*args)
+    yield response
+
+    push_post(*args)
+    yield response
+  end
+
+  def auth_env(user, password, spnego_request_token)
+    env = workhorse_internal_api_request_header
+    if user && password
+      env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user, password)
+    elsif spnego_request_token
+      env['HTTP_AUTHORIZATION'] = "Negotiate #{::Base64.strict_encode64('opaque_request_token')}"
+    end
+
+    env
+  end
+end