Commit 98738377 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'rd-6804-bug-unable-to-delete-branches-when-repo-reaches-the-size-limit' into 'master'

Fix a bug where user was unable to delete a branch when repo size was above the limit

Closes #6804

See merge request gitlab-org/gitlab-ee!6373
parents e9be9d36 5b202aee
---
title: Fix a bug where user was unable to delete a branch when repo size was above the limit
merge_request: 6373
author:
type: fixed
This diff is collapsed.
......@@ -5,6 +5,7 @@ module Gitlab
prepend ::EE::Gitlab::GitAccess
include ActionView::Helpers::SanitizeHelper
include PathLocksHelper
include Gitlab::Utils::StrongMemoize
UnauthorizedError = Class.new(StandardError)
NotFoundError = Class.new(StandardError)
......@@ -30,7 +31,7 @@ module Gitlab
PUSH_COMMANDS = %w{ git-receive-pack }.freeze
ALL_COMMANDS = DOWNLOAD_COMMANDS + PUSH_COMMANDS
attr_reader :actor, :project, :protocol, :authentication_abilities, :namespace_path, :project_path, :redirected_path, :auth_result_type
attr_reader :actor, :project, :protocol, :authentication_abilities, :namespace_path, :project_path, :redirected_path, :auth_result_type, :changes
def initialize(actor, project, protocol, authentication_abilities:, namespace_path: nil, project_path: nil, redirected_path: nil, auth_result_type: nil)
@actor = actor
......@@ -44,6 +45,8 @@ module Gitlab
end
def check(cmd, changes)
@changes = changes
check_protocol!
check_valid_actor!
check_active_user!
......@@ -62,7 +65,7 @@ module Gitlab
when *DOWNLOAD_COMMANDS
check_download_access!
when *PUSH_COMMANDS
check_push_access!(changes)
check_push_access!
end
true
......@@ -223,7 +226,7 @@ module Gitlab
end
# TODO: please clean this up
def check_push_access!(changes)
def check_push_access!
if project.repository_read_only?
raise UnauthorizedError, ERROR_MESSAGES[:read_only]
end
......@@ -240,7 +243,7 @@ module Gitlab
return if changes.blank? # Allow access this is needed for EE.
if project.above_size_limit?
if check_size_limit? && project.above_size_limit?
raise UnauthorizedError, Gitlab::RepositorySizeError.new(project).push_error
end
......@@ -249,17 +252,15 @@ module Gitlab
raise UnauthorizedError, strip_tags(message)
end
check_change_access!(changes)
check_change_access!
end
def check_change_access!(changes)
def check_change_access!
# If there are worktrees with a HEAD pointing to a non-existent object,
# calls to `git rev-list --all` will fail in git 2.15+. This should also
# clear stale lock files.
project.repository.clean_stale_repository_files
changes_list = Gitlab::ChangesList.new(changes)
push_size_in_bytes = 0
# Iterate over all changes to find if user allowed all of them to be applied
......@@ -275,7 +276,7 @@ module Gitlab
end
end
if project.changes_will_exceed_size_limit?(push_size_in_bytes)
if check_size_limit? && project.changes_will_exceed_size_limit?(push_size_in_bytes)
raise UnauthorizedError, Gitlab::RepositorySizeError.new(project).new_changes_error
end
end
......@@ -368,6 +369,18 @@ module Gitlab
protected
def check_size_limit?
strong_memoize(:check_size_limit) do
changes_list.any? do |change|
change[:newrev] && change[:newrev] != ::Gitlab::Git::BLANK_SHA
end
end
end
def changes_list
@changes_list ||= Gitlab::ChangesList.new(changes)
end
def user
return @user if defined?(@user)
......
......@@ -13,14 +13,6 @@ describe Gitlab::GitAccess do
let(:authentication_abilities) { %i[read_project download_code push_code] }
let(:redirected_path) { nil }
let(:auth_result_type) { nil }
let(:access) do
described_class.new(actor, project,
protocol, authentication_abilities: authentication_abilities,
namespace_path: namespace_path, project_path: project_path,
redirected_path: redirected_path, auth_result_type: auth_result_type)
end
let(:changes) { '_any' }
let(:push_access_check) { access.check('git-receive-pack', changes) }
let(:pull_access_check) { access.check('git-upload-pack', changes) }
......@@ -786,7 +778,7 @@ describe Gitlab::GitAccess do
aggregate_failures do
matrix.each do |action, allowed|
check = -> { access.send(:check_push_access!, changes[action]) }
check = -> { push_changes(changes[action]) }
if allowed
expect(&check).not_to raise_error,
......@@ -811,7 +803,7 @@ describe Gitlab::GitAccess do
aggregate_failures do
matrix.each do |action, allowed|
check = -> { access.send(:check_push_access!, changes[action]) }
check = -> { push_changes(changes[action]) }
if allowed
expect(&check).not_to raise_error,
......@@ -1280,6 +1272,17 @@ describe Gitlab::GitAccess do
private
def access
described_class.new(actor, project, protocol,
authentication_abilities: authentication_abilities,
namespace_path: namespace_path, project_path: project_path,
redirected_path: redirected_path, auth_result_type: auth_result_type)
end
def push_changes(changes)
access.check('git-receive-pack', changes)
end
def raise_unauthorized(message)
raise_error(Gitlab::GitAccess::UnauthorizedError, message)
end
......
......@@ -792,23 +792,6 @@ describe 'Git HTTP requests' do
end
end
context "when repository is above size limit" do
let(:env) { { user: user.username, password: user.password } }
before do
project.add_master(user)
end
it 'responds with status 403 Forbidden' do
allow_any_instance_of(EE::Project)
.to receive(:above_size_limit?).and_return(true)
upload(path, env) do |response|
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when license is not provided' do
let(:env) { { user: user.username, password: user.password } }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment