Commit b98bff13 authored by Rubén Dávila's avatar Rubén Dávila

Backport some changes from EE

parent 3edda4c2
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# class return an instance of `GitlabAccessStatus` # class return an instance of `GitlabAccessStatus`
module Gitlab module Gitlab
class GitAccess class GitAccess
include Gitlab::Utils::StrongMemoize
UnauthorizedError = Class.new(StandardError) UnauthorizedError = Class.new(StandardError)
NotFoundError = Class.new(StandardError) NotFoundError = Class.new(StandardError)
ProjectCreationError = Class.new(StandardError) ProjectCreationError = Class.new(StandardError)
...@@ -26,7 +28,7 @@ module Gitlab ...@@ -26,7 +28,7 @@ module Gitlab
PUSH_COMMANDS = %w{ git-receive-pack }.freeze PUSH_COMMANDS = %w{ git-receive-pack }.freeze
ALL_COMMANDS = DOWNLOAD_COMMANDS + PUSH_COMMANDS 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) def initialize(actor, project, protocol, authentication_abilities:, namespace_path: nil, project_path: nil, redirected_path: nil, auth_result_type: nil)
@actor = actor @actor = actor
...@@ -40,6 +42,8 @@ module Gitlab ...@@ -40,6 +42,8 @@ module Gitlab
end end
def check(cmd, changes) def check(cmd, changes)
@changes = changes
check_protocol! check_protocol!
check_valid_actor! check_valid_actor!
check_active_user! check_active_user!
...@@ -58,7 +62,7 @@ module Gitlab ...@@ -58,7 +62,7 @@ module Gitlab
when *DOWNLOAD_COMMANDS when *DOWNLOAD_COMMANDS
check_download_access! check_download_access!
when *PUSH_COMMANDS when *PUSH_COMMANDS
check_push_access!(changes) check_push_access!
end end
true true
...@@ -218,7 +222,7 @@ module Gitlab ...@@ -218,7 +222,7 @@ module Gitlab
end end
end end
def check_push_access!(changes) def check_push_access!
if project.repository_read_only? if project.repository_read_only?
raise UnauthorizedError, ERROR_MESSAGES[:read_only] raise UnauthorizedError, ERROR_MESSAGES[:read_only]
end end
...@@ -235,17 +239,15 @@ module Gitlab ...@@ -235,17 +239,15 @@ module Gitlab
return if changes.blank? # Allow access this is needed for EE. return if changes.blank? # Allow access this is needed for EE.
check_change_access!(changes) check_change_access!
end end
def check_change_access!(changes) def check_change_access!
# If there are worktrees with a HEAD pointing to a non-existent object, # 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 # calls to `git rev-list --all` will fail in git 2.15+. This should also
# clear stale lock files. # clear stale lock files.
project.repository.clean_stale_repository_files project.repository.clean_stale_repository_files
changes_list = Gitlab::ChangesList.new(changes)
# Iterate over all changes to find if user allowed all of them to be applied # Iterate over all changes to find if user allowed all of them to be applied
changes_list.each.with_index do |change, index| changes_list.each.with_index do |change, index|
first_change = index == 0 first_change = index == 0
...@@ -321,6 +323,10 @@ module Gitlab ...@@ -321,6 +323,10 @@ module Gitlab
protected protected
def changes_list
@changes_list ||= Gitlab::ChangesList.new(changes)
end
def user def user
return @user if defined?(@user) return @user if defined?(@user)
......
...@@ -13,14 +13,6 @@ describe Gitlab::GitAccess do ...@@ -13,14 +13,6 @@ describe Gitlab::GitAccess do
let(:authentication_abilities) { %i[read_project download_code push_code] } let(:authentication_abilities) { %i[read_project download_code push_code] }
let(:redirected_path) { nil } let(:redirected_path) { nil }
let(:auth_result_type) { 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(:changes) { '_any' }
let(:push_access_check) { access.check('git-receive-pack', changes) } let(:push_access_check) { access.check('git-receive-pack', changes) }
let(:pull_access_check) { access.check('git-upload-pack', changes) } let(:pull_access_check) { access.check('git-upload-pack', changes) }
...@@ -724,10 +716,11 @@ describe Gitlab::GitAccess do ...@@ -724,10 +716,11 @@ describe Gitlab::GitAccess do
end end
describe '#check_push_access!' do describe '#check_push_access!' do
let(:unprotected_branch) { 'unprotected_branch' }
before do before do
merge_into_protected_branch merge_into_protected_branch
end end
let(:unprotected_branch) { 'unprotected_branch' }
let(:changes) do let(:changes) do
{ push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow", { push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow",
...@@ -785,7 +778,7 @@ describe Gitlab::GitAccess do ...@@ -785,7 +778,7 @@ describe Gitlab::GitAccess do
aggregate_failures do aggregate_failures do
matrix.each do |action, allowed| matrix.each do |action, allowed|
check = -> { access.send(:check_push_access!, changes[action]) } check = -> { push_changes(changes[action]) }
if allowed if allowed
expect(&check).not_to raise_error, expect(&check).not_to raise_error,
...@@ -1152,6 +1145,17 @@ describe Gitlab::GitAccess do ...@@ -1152,6 +1145,17 @@ describe Gitlab::GitAccess do
private 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) def raise_unauthorized(message)
raise_error(Gitlab::GitAccess::UnauthorizedError, message) raise_error(Gitlab::GitAccess::UnauthorizedError, message)
end end
......
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