diff --git a/config/feature_flags/gitlab_com_derisk/go_get_handle_401_error.yml b/config/feature_flags/gitlab_com_derisk/go_get_handle_401_error.yml new file mode 100644 index 0000000000000000000000000000000000000000..237eaaaf5888e988c2f689dea710a2d051ed3f5e --- /dev/null +++ b/config/feature_flags/gitlab_com_derisk/go_get_handle_401_error.yml @@ -0,0 +1,9 @@ +--- +name: go_get_handle_401_error +feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/493732 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167640 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/496539 +milestone: '17.5' +group: group::source code +type: gitlab_com_derisk +default_enabled: false diff --git a/lib/gitlab/middleware/go.rb b/lib/gitlab/middleware/go.rb index cc4ae4c994d2cdf7f6504d330d6aff52ae00f5ca..ef8004f73d363786ad6fee87ec2d970c009c4ec6 100644 --- a/lib/gitlab/middleware/go.rb +++ b/lib/gitlab/middleware/go.rb @@ -131,6 +131,10 @@ def project_for_path(path_info) def can_read_project?(request, project) return true if project.public? + if Feature.enabled?(:go_get_handle_401_error, Feature.current_request) && !has_basic_credentials?(request) + return false + end + login, password = user_name_and_password(request) auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, request: request) diff --git a/spec/lib/gitlab/middleware/go_spec.rb b/spec/lib/gitlab/middleware/go_spec.rb index f5325506de0db25dba97dffaa4e348d55e9e0dbd..ace21ba91338df88556a332c9fa6e2e7aa03ddca 100644 --- a/spec/lib/gitlab/middleware/go_spec.rb +++ b/spec/lib/gitlab/middleware/go_spec.rb @@ -60,6 +60,27 @@ it 'returns the 2-segment path' do expect_response_with_path(go, enabled_protocol, project.full_path) end + + context 'when instance does not allow password authentication for Git over HTTP(S)' do + before do + stub_application_setting(password_authentication_enabled_for_git: false) + end + + it 'returns the 2-segment path' do + expect_response_with_path(go, enabled_protocol, project.full_path) + end + + context 'when "go_get_handle_401_error" feature flag disabled' do + before do + stub_feature_flags(go_get_handle_401_error: false) + end + + it 'returns 401 error response' do + response = go + expect(response[0]).to eq(401) + end + end + end end context 'when authorization header is present but invalid' do