Commit edcba1aa authored by Tomasz Maczukin's avatar Tomasz Maczukin

Allow HTTP(s) when git request is made by GitLab CI

parent b15dd5df
...@@ -7,6 +7,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController ...@@ -7,6 +7,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
attr_reader :authentication_result, :redirected_path attr_reader :authentication_result, :redirected_path
delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true
delegate :type, to: :authentication_result, allow_nil: true, prefix: :auth_result
alias_method :user, :actor alias_method :user, :actor
alias_method :authenticated_user, :actor alias_method :authenticated_user, :actor
......
...@@ -64,7 +64,7 @@ class Projects::GitHttpController < Projects::GitHttpClientController ...@@ -64,7 +64,7 @@ class Projects::GitHttpController < Projects::GitHttpClientController
@access ||= access_klass.new(access_actor, project, @access ||= access_klass.new(access_actor, project,
'http', authentication_abilities: authentication_abilities, 'http', authentication_abilities: authentication_abilities,
namespace_path: params[:namespace_id], project_path: project_path, namespace_path: params[:namespace_id], project_path: project_path,
redirected_path: redirected_path) redirected_path: redirected_path, auth_result_type: auth_result_type)
end end
def access_actor def access_actor
......
...@@ -29,9 +29,9 @@ module Gitlab ...@@ -29,9 +29,9 @@ 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 attr_reader :actor, :project, :protocol, :authentication_abilities, :namespace_path, :project_path, :redirected_path, :auth_result_type
def initialize(actor, project, protocol, authentication_abilities:, namespace_path: nil, project_path: nil, redirected_path: 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
@project = project @project = project
@protocol = protocol @protocol = protocol
...@@ -39,6 +39,7 @@ module Gitlab ...@@ -39,6 +39,7 @@ module Gitlab
@namespace_path = namespace_path @namespace_path = namespace_path
@project_path = project_path @project_path = project_path
@redirected_path = redirected_path @redirected_path = redirected_path
@auth_result_type = auth_result_type
end end
def check(cmd, changes) def check(cmd, changes)
...@@ -78,6 +79,12 @@ module Gitlab ...@@ -78,6 +79,12 @@ module Gitlab
authentication_abilities.include?(:build_download_code) && user_access.can_do_action?(:build_download_code) authentication_abilities.include?(:build_download_code) && user_access.can_do_action?(:build_download_code)
end end
def request_from_ci_build?
return false unless protocol == 'http'
auth_result_type == :build || auth_result_type == :ci
end
def protocol_allowed? def protocol_allowed?
Gitlab::ProtocolAccess.allowed?(protocol) Gitlab::ProtocolAccess.allowed?(protocol)
end end
...@@ -93,6 +100,8 @@ module Gitlab ...@@ -93,6 +100,8 @@ module Gitlab
end end
def check_protocol! def check_protocol!
return if request_from_ci_build?
unless protocol_allowed? unless protocol_allowed?
raise UnauthorizedError, "Git access over #{protocol.upcase} is not allowed" raise UnauthorizedError, "Git access over #{protocol.upcase} is not allowed"
end end
......
...@@ -10,12 +10,13 @@ describe Gitlab::GitAccess do ...@@ -10,12 +10,13 @@ describe Gitlab::GitAccess do
let(:protocol) { 'ssh' } let(:protocol) { 'ssh' }
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(:access) do let(:access) do
described_class.new(actor, project, described_class.new(actor, project,
protocol, authentication_abilities: authentication_abilities, protocol, authentication_abilities: authentication_abilities,
namespace_path: namespace_path, project_path: project_path, namespace_path: namespace_path, project_path: project_path,
redirected_path: redirected_path) redirected_path: redirected_path, auth_result_type: auth_result_type)
end end
let(:changes) { '_any' } let(:changes) { '_any' }
...@@ -45,6 +46,7 @@ describe Gitlab::GitAccess do ...@@ -45,6 +46,7 @@ describe Gitlab::GitAccess do
before do before do
disable_protocol('http') disable_protocol('http')
project.add_master(user)
end end
it 'blocks http push and pull' do it 'blocks http push and pull' do
...@@ -53,6 +55,26 @@ describe Gitlab::GitAccess do ...@@ -53,6 +55,26 @@ describe Gitlab::GitAccess do
expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed') expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
end end
end end
context 'when request is made from CI' do
let(:auth_result_type) { :build }
it "doesn't block http pull" do
aggregate_failures do
expect { pull_access_check }.not_to raise_unauthorized('Git access over HTTP is not allowed')
end
end
context 'when legacy CI credentials are used' do
let(:auth_result_type) { :ci }
it "doesn't block http pull" do
aggregate_failures do
expect { pull_access_check }.not_to raise_unauthorized('Git access over HTTP is not allowed')
end
end
end
end
end end
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