Skip to content
Snippets Groups Projects
Select Git revision
  • move-gl-dropdown
  • improve-table-pagination-spec
  • move-markdown-preview
  • winh-fix-merge-request-spec
  • master default
  • index-namespaces-lower-name
  • winh-single-karma-test
  • 10-3-stable
  • 36782-replace-team-user-role-with-add_role-user-in-specs
  • winh-modal-internal-state
  • tz-ide-file-icons
  • 38869-milestone-select
  • update-autodevops-template
  • jivl-activate-repo-cookie-preferences
  • qa-add-deploy-key
  • docs-move-article-ldap
  • 40780-choose-file
  • 22643-manual-job-page
  • refactor-cluster-show-page-conservative
  • dm-sidekiq-versioning
  • v10.4.0.pre
  • v10.3.0
  • v10.3.0-rc5
  • v10.3.0-rc4
  • v10.3.0-rc3
  • v10.3.0-rc2
  • v10.2.5
  • v10.3.0-rc1
  • v10.0.7
  • v10.1.5
  • v10.2.4
  • v10.2.3
  • v10.2.2
  • v10.2.1
  • v10.3.0.pre
  • v10.2.0
  • v10.2.0-rc4
  • v10.2.0-rc3
  • v10.1.4
  • v10.2.0-rc2
40 results

grack_auth_spec.rb

Blame
  • Forked from GitLab.org / GitLab FOSS
    37246 commits behind the upstream repository.
    grack_auth_spec.rb 6.02 KiB
    require "spec_helper"
    
    describe Grack::Auth do
      let(:user)    { create(:user) }
      let(:project) { create(:project) }
    
      let(:app)   { lambda { |env| [200, {}, "Success!"] } }
      let!(:auth) { Grack::Auth.new(app) }
      let(:env) {
        {
          "rack.input" => "",
          "REQUEST_METHOD" => "GET",
          "QUERY_STRING" => "service=git-upload-pack"
        }
      }
      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)
            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)
              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)
              end
            end
          end
        end
    
        context "when the project exists" do
          before do
            env["PATH_INFO"] = project.path_with_namespace + ".git"
          end
    
          context "when the project is public" do
            before do
              project.update_attribute(:visibility_level, Project::PUBLIC)
            end
    
            it "responds with status 200" do
              expect(status).to eq(200)
            end
          end
    
          context "when the project is private" do
            before do
              project.update_attribute(:visibility_level, Project::PRIVATE)
            end
    
            context "when no authentication is provided" do
              it "responds with status 401" do
                expect(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)
                end
    
                context "when the user is IP banned" do
                  before 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)
                  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
                      user.block
                      project.team << [user, :master]
                    end
    
                    it "responds with status 404" do
                      expect(status).to eq(404)
                    end
                  end
    
                  context "when the user isn't blocked" do
                    before do
                     expect(Rack::Attack::Allow2Ban).to receive(:reset)
                    end
    
                    it "responds with status 200" do
                      expect(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
                    end
    
                    it "repeated attempts followed by successful attempt" do
                      for n in 0..maxretry do
                        expect(attempt_login(false)).to eq(401)
                      end
    
                      expect(attempt_login(true)).to eq(200)
                      expect(Rack::Attack::Allow2Ban.send(:banned?, ip)).to eq(nil)
    
                      for n in 0..maxretry do
                        expect(attempt_login(false)).to eq(401)
                      end
                    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)
                  end
                end
              end
            end
    
            context "when a gitlab ci token is provided" do
              let(:token) { "123" }
    
              before do
                gitlab_ci_service = project.build_gitlab_ci_service
                gitlab_ci_service.active = true
                gitlab_ci_service.token = token
                gitlab_ci_service.project_url = "http://google.com"
                gitlab_ci_service.save
    
                env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token)
              end
    
              it "responds with status 200" do
                expect(status).to eq(200)
              end
            end
          end
        end
      end
    end