Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-15 00:10:32 +00:00
parent db2275b561
commit 0a977c1034
7 changed files with 57 additions and 126 deletions

View File

@ -71,23 +71,9 @@ class MergeRequest < ApplicationRecord
belongs_to :latest_merge_request_diff, class_name: 'MergeRequestDiff'
manual_inverse_association :latest_merge_request_diff, :merge_request
# method overriden in EE
def suggested_reviewer_users
return User.none unless predictions && predictions.suggested_reviewers.is_a?(Hash)
usernames = Array.wrap(suggested_reviewers["reviewers"])
return User.none if usernames.empty?
# Preserve the orginal order of suggested usernames
join_sql = MergeRequest.sanitize_sql_array(
[
'JOIN UNNEST(ARRAY[?]::varchar[]) WITH ORDINALITY AS t(username, ord) USING(username)',
usernames
]
)
project.authorized_users.active
.joins(Arel.sql(join_sql))
.order('t.ord')
User.none
end
# This is the same as latest_merge_request_diff unless:

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class PreparePartialTrigramIndexesForIssuesAttempt2 < Gitlab::Database::Migration[2.0]
TITLE_INDEX_NAME = 'index_issues_on_title_trigram_non_latin'
DESCRIPTION_INDEX_NAME = 'index_issues_on_description_trigram_non_latin'
def up
prepare_async_index :issues, :title,
name: TITLE_INDEX_NAME,
using: :gin, opclass: { description: :gin_trgm_ops },
where: "title NOT SIMILAR TO '[\\u0000-\\u02FF\\u1E00-\\u1EFF\\u2070-\\u218F]*' " \
"OR description NOT SIMILAR TO '[\\u0000-\\u02FF\\u1E00-\\u1EFF\\u2070-\\u218F]*'"
prepare_async_index :issues, :description,
name: DESCRIPTION_INDEX_NAME,
using: :gin, opclass: { description: :gin_trgm_ops },
where: "title NOT SIMILAR TO '[\\u0000-\\u02FF\\u1E00-\\u1EFF\\u2070-\\u218F]*' " \
"OR description NOT SIMILAR TO '[\\u0000-\\u02FF\\u1E00-\\u1EFF\\u2070-\\u218F]*'"
end
def down
unprepare_async_index_by_name :issues, DESCRIPTION_INDEX_NAME
unprepare_async_index_by_name :issues, TITLE_INDEX_NAME
end
end

View File

@ -0,0 +1 @@
0ad92f76e14b2e9286b2f77f32c00dba8ae29b64035f79641451edfdc725c92a

View File

@ -40,7 +40,7 @@ module API
params do
requires :name, type: String, desc: 'The name of the environment to be created'
optional :external_url, type: String, desc: 'URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }
optional :slug, absence: { message: "is automatically generated and cannot be changed" }, documentation: { hidden: true }
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created'
end
post ':id/environments' do
@ -64,7 +64,7 @@ module API
# TODO: disallow renaming via the API https://gitlab.com/gitlab-org/gitlab/-/issues/338897
optional :name, type: String, desc: 'DEPRECATED: Renaming environment can lead to errors, this will be removed in 15.0'
optional :external_url, type: String, desc: 'The new URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }
optional :slug, absence: { message: "is automatically generated and cannot be changed" }, documentation: { hidden: true }
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created'
end
put ':id/environments/:environment_id' do

View File

@ -2,9 +2,6 @@
# A dumb middleware that returns a Go HTML document if the go-get=1 query string
# is used irrespective if the namespace/project exists
#
# In order to prevent the project from being exposed,
# auth failure (401 & 403) is regarded as not found (404)
module Gitlab
module Middleware
class Go
@ -24,16 +21,15 @@ module Gitlab
rescue Gitlab::Auth::IpBlacklisted
Gitlab::AuthLogger.error(
message: 'Rack_Attack',
status: 403,
env: :blocklist,
remote_ip: request.ip,
request_method: request.request_method,
path: request.fullpath
)
Rack::Response.new('', 404).finish
Rack::Response.new('', 403).finish
rescue Gitlab::Auth::MissingPersonalAccessTokenError
Rack::Response.new('', 404).finish
rescue ActiveRecord::RecordNotFound
Rack::Response.new('', 404).finish
Rack::Response.new('', 401).finish
end
private
@ -104,6 +100,7 @@ module Gitlab
# We find all potential project paths out of the path segments
path_segments = path.split('/')
simple_project_path = path_segments.first(2).join('/')
project_paths = []
begin
@ -113,18 +110,28 @@ module Gitlab
# We see if a project exists with any of these potential paths
project = project_for_paths(project_paths, request)
# If a project is found and the user has access, we return the full project path
[project.full_path, project.default_branch]
if project
# If a project is found and the user has access, we return the full project path
[project.full_path, project.default_branch]
else
# If not, we return the first two components as if it were a simple `namespace/project` path,
# so that we don't reveal the existence of a nested project the user doesn't have access to.
# This means that for an unauthenticated request to `group/subgroup/project/subpackage`
# for a private `group/subgroup/project` with subpackage path `subpackage`, GitLab will respond
# as if the user is looking for project `group/subgroup`, with subpackage path `project/subpackage`.
# Since `go get` doesn't authenticate by default, this means that
# `go get gitlab.com/group/subgroup/project/subpackage` will not work for private projects.
# `go get gitlab.com/group/subgroup/project.git/subpackage` will work, since Go is smart enough
# to figure that out. `import 'gitlab.com/...'` behaves the same as `go get`.
[simple_project_path, 'master']
end
end
def project_for_paths(paths, request)
project = Project.where_full_path_in(paths).first
raise ActiveRecord::RecordNotFound unless project
unless authentication_result(request, project).can_perform_action_on_project?(:read_project, project)
raise Gitlab::Auth::MissingPersonalAccessTokenError
end
return unless authentication_result(request, project).can_perform_action_on_project?(:read_project, project)
project
end

View File

@ -32,7 +32,7 @@ RSpec.describe Gitlab::Middleware::Go do
shared_examples 'go-get=1' do |enabled_protocol:|
context 'with simple 2-segment project path' do
let!(:project) { create(:project, :public, :repository) }
let!(:project) { create(:project, :private, :repository) }
context 'with subpackages' do
let(:path) { "#{project.full_path}/subpackage" }
@ -51,16 +51,6 @@ RSpec.describe Gitlab::Middleware::Go do
end
end
context 'with nonexistent path' do
let(:path) { 'nonexistent-group/nonexistent-project' }
it 'responses not found' do
status_code, _headers, body = go
expect(status_code).to eq(404)
expect(body).to match_array([''])
end
end
context 'with a nested project path' do
let(:group) { create(:group, :nested) }
let!(:project) { create(:project, :public, :repository, namespace: group) }
@ -78,10 +68,8 @@ RSpec.describe Gitlab::Middleware::Go do
end
shared_examples 'unauthorized' do
it 'returns unauthorized' do
status_code, _headers, body = go
expect(status_code).to eq(404)
expect(body).to match_array([''])
it 'returns the 2-segment group path' do
expect_response_with_path(go, enabled_protocol, group.full_path, project.default_branch)
end
end
@ -153,7 +141,7 @@ RSpec.describe Gitlab::Middleware::Go do
expect(Gitlab::Auth).to receive(:find_for_git_client).and_raise(Gitlab::Auth::IpBlacklisted)
response = go
expect(response[0]).to eq(404)
expect(response[0]).to eq(403)
expect(response[1]['Content-Length']).to be_nil
expect(response[2]).to eq([''])
end
@ -170,7 +158,7 @@ RSpec.describe Gitlab::Middleware::Go do
expect(Gitlab::Auth).to receive(:find_for_git_client).and_raise(Gitlab::Auth::MissingPersonalAccessTokenError)
response = go
expect(response[0]).to eq(404)
expect(response[0]).to eq(401)
expect(response[1]['Content-Length']).to be_nil
expect(response[2]).to eq([''])
end

View File

@ -5416,82 +5416,6 @@ RSpec.describe MergeRequest, factory_default: :keep do
subject(:suggested_reviewer_users) { merge_request.suggested_reviewer_users }
shared_examples 'blank suggestions' do
it 'returns an empty relation' do
expect(suggested_reviewer_users).to be_empty
end
end
context 'when predictions is nil' do
it_behaves_like 'blank suggestions'
end
context 'when predictions is not nil' do
before do
merge_request.build_predictions
end
context 'when predictions is a non hash' do
before do
merge_request.build_predictions
merge_request.predictions.suggested_reviewers = 1
end
it_behaves_like 'blank suggestions'
end
context 'when predictions is an empty hash' do
before do
merge_request.predictions.suggested_reviewers = {}
end
it_behaves_like 'blank suggestions'
end
context 'when suggests a user who is not a member' do
let_it_be(:non_member) { create(:user) }
before do
merge_request.predictions.suggested_reviewers = { 'reviewers' => [non_member.username] }
end
it_behaves_like 'blank suggestions'
end
context 'when suggests users who are members' do
let_it_be(:first_member) { create(:user) }
let_it_be(:second_member) { create(:user) }
before_all do
project.add_developer(first_member)
project.add_developer(second_member)
end
before do
merge_request.predictions.suggested_reviewers = {
'reviewers' => [
second_member.username,
first_member.username
]
}
end
context 'when a user is inactive' do
before do
second_member.deactivate
end
it 'returns only active users' do
expect(suggested_reviewer_users).to eq([first_member])
end
end
context 'when all users are active' do
it 'returns users in correct suggested order' do
expect(suggested_reviewer_users).to eq([second_member, first_member])
end
end
end
end
it { is_expected.to be_empty }
end
end