summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-29 14:13:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-29 14:13:29 +0000
commitbb51b8a098aa17b226d1e7941218512f8c835e08 (patch)
treef8765bb77a206b8213b3a777252ce8e2e21642e0
parent5c4639afa1f53d7ed6f682168fda0b491c16e844 (diff)
downloadgitlab-ce-bb51b8a098aa17b226d1e7941218512f8c835e08.tar.gz
Add latest changes from gitlab-org/security/gitlab@15-1-stable-ee
-rw-r--r--app/finders/packages/conan/package_finder.rb2
-rw-r--r--app/helpers/timeboxes_helper.rb4
-rw-r--r--app/views/shared/milestones/_milestone.html.haml2
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml2
-rw-r--r--db/migrate/20220520120637_add_installable_conan_packages_index_to_packages.rb25
-rw-r--r--db/schema_migrations/202205201206371
-rw-r--r--db/structure.sql2
-rw-r--r--spec/finders/packages/conan/package_finder_spec.rb51
-rw-r--r--spec/helpers/timeboxes_helper_spec.rb19
-rw-r--r--spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb67
10 files changed, 143 insertions, 32 deletions
diff --git a/app/finders/packages/conan/package_finder.rb b/app/finders/packages/conan/package_finder.rb
index 8ebdd358ba6..210b37635b3 100644
--- a/app/finders/packages/conan/package_finder.rb
+++ b/app/finders/packages/conan/package_finder.rb
@@ -25,7 +25,7 @@ module Packages
end
def projects_visible_to_current_user
- ::Project.public_or_visible_to_user(current_user)
+ ::Project.public_or_visible_to_user(current_user, ::Gitlab::Access::REPORTER)
end
end
end
diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb
index c81fbcbfd11..39993bbfb44 100644
--- a/app/helpers/timeboxes_helper.rb
+++ b/app/helpers/timeboxes_helper.rb
@@ -153,11 +153,11 @@ module TimeboxesHelper
n_("%{releases} release", "%{releases} releases", count) % { releases: count }
end
- def recent_releases_with_counts(milestone)
+ def recent_releases_with_counts(milestone, user)
total_count = milestone.releases.size
return [[], 0, 0] if total_count == 0
- recent_releases = milestone.releases.recent.to_a
+ recent_releases = milestone.releases.recent.filter { |release| Ability.allowed?(user, :read_release, release) }
more_count = total_count - recent_releases.size
[recent_releases, total_count, more_count]
end
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 3082c6bb4db..59d1537aa2b 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -14,7 +14,7 @@
- if milestone.due_date || milestone.start_date
.text-tertiary.gl-mb-2
= milestone_date_range(milestone)
- - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone, current_user)
- unless total_count == 0
.text-tertiary.gl-mb-2.milestone-release-links
= sprite_icon("rocket", size: 12)
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index 12026b89429..6a65909b1c2 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -138,7 +138,7 @@
= milestone.merge_requests.merged.count
- if project
- - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone, current_user)
.block.releases
.sidebar-collapsed-icon.has-tooltip{ title: milestone_releases_tooltip_text(milestone), data: { container: 'body', placement: 'left', boundary: 'viewport' } }
%strong
diff --git a/db/migrate/20220520120637_add_installable_conan_packages_index_to_packages.rb b/db/migrate/20220520120637_add_installable_conan_packages_index_to_packages.rb
new file mode 100644
index 00000000000..b26d1f5429a
--- /dev/null
+++ b/db/migrate/20220520120637_add_installable_conan_packages_index_to_packages.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class AddInstallableConanPackagesIndexToPackages < Gitlab::Database::Migration[2.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'idx_installable_conan_pkgs_on_project_id_id'
+ # as defined by Packages::Package.package_types
+ CONAN_PACKAGE_TYPE = 3
+
+ # as defined by Packages::Package::INSTALLABLE_STATUSES
+ DEFAULT_STATUS = 0
+ HIDDEN_STATUS = 1
+
+ def up
+ where = "package_type = #{CONAN_PACKAGE_TYPE} AND status IN (#{DEFAULT_STATUS}, #{HIDDEN_STATUS})"
+ add_concurrent_index :packages_packages,
+ [:project_id, :id],
+ where: where,
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_packages, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20220520120637 b/db/schema_migrations/20220520120637
new file mode 100644
index 00000000000..f379ef0d581
--- /dev/null
+++ b/db/schema_migrations/20220520120637
@@ -0,0 +1 @@
+1fdb60b1c72b687aa8bede083ac7038097d538dc815e334d74296b1d39c2acb8 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 4b17fa31b59..c58ff5d47ba 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -26822,6 +26822,8 @@ CREATE UNIQUE INDEX idx_external_audit_event_destination_id_key_uniq ON audit_ev
CREATE INDEX idx_geo_con_rep_updated_events_on_container_repository_id ON geo_container_repository_updated_events USING btree (container_repository_id);
+CREATE INDEX idx_installable_conan_pkgs_on_project_id_id ON packages_packages USING btree (project_id, id) WHERE ((package_type = 3) AND (status = ANY (ARRAY[0, 1])));
+
CREATE INDEX idx_installable_helm_pkgs_on_project_id_id ON packages_packages USING btree (project_id, id);
CREATE INDEX idx_installable_npm_pkgs_on_project_id_name_version_id ON packages_packages USING btree (project_id, name, version, id) WHERE ((package_type = 2) AND (status = 0));
diff --git a/spec/finders/packages/conan/package_finder_spec.rb b/spec/finders/packages/conan/package_finder_spec.rb
index b26f8900090..6848786818b 100644
--- a/spec/finders/packages/conan/package_finder_spec.rb
+++ b/spec/finders/packages/conan/package_finder_spec.rb
@@ -2,22 +2,53 @@
require 'spec_helper'
RSpec.describe ::Packages::Conan::PackageFinder do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be_with_reload(:project) { create(:project) }
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :public) }
+ let_it_be(:private_project) { create(:project, :private) }
+
+ let_it_be(:conan_package) { create(:conan_package, project: project) }
+ let_it_be(:conan_package2) { create(:conan_package, project: project) }
+ let_it_be(:errored_package) { create(:conan_package, :error, project: project) }
+ let_it_be(:private_package) { create(:conan_package, project: private_project) }
describe '#execute' do
- let!(:conan_package) { create(:conan_package, project: project) }
- let!(:conan_package2) { create(:conan_package, project: project) }
+ let(:query) { "#{conan_package.name.split('/').first[0, 3]}%" }
+ let(:finder) { described_class.new(user, query: query) }
+
+ subject { finder.execute }
+
+ where(:visibility, :role, :packages_visible) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | false
+ :private | :anonymous | false
+
+ :internal | :maintainer | true
+ :internal | :developer | true
+ :internal | :reporter | true
+ :internal | :guest | true
+ :internal | :anonymous | false
+
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | true
+ end
- subject { described_class.new(user, query: query).execute }
+ with_them do
+ let(:expected_packages) { packages_visible ? [conan_package, conan_package2] : [] }
+ let(:user) { role == :anonymous ? nil : super() }
- context 'packages that are not installable' do
- let!(:conan_package3) { create(:conan_package, :error, project: project) }
- let!(:non_visible_project) { create(:project, :private) }
- let!(:non_visible_conan_package) { create(:conan_package, project: non_visible_project) }
- let(:query) { "#{conan_package.name.split('/').first[0, 3]}%" }
+ before do
+ project.update_column(:visibility_level, Gitlab::VisibilityLevel.string_options[visibility.to_s])
+ project.add_user(user, role) unless role == :anonymous
+ end
- it { is_expected.to eq [conan_package, conan_package2] }
+ it { is_expected.to eq(expected_packages) }
end
end
end
diff --git a/spec/helpers/timeboxes_helper_spec.rb b/spec/helpers/timeboxes_helper_spec.rb
index e31f2df7372..f9fb40a616b 100644
--- a/spec/helpers/timeboxes_helper_spec.rb
+++ b/spec/helpers/timeboxes_helper_spec.rb
@@ -38,4 +38,23 @@ RSpec.describe TimeboxesHelper do
end
end
end
+
+ describe "#recent_releases_with_counts" do
+ let_it_be(:milestone) { create(:milestone) }
+ let_it_be(:project) { milestone.project }
+ let_it_be(:user) { create(:user) }
+
+ subject { helper.recent_releases_with_counts(milestone, user) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ it "returns releases with counts" do
+ _old_releases = create_list(:release, 2, project: project, milestones: [milestone])
+ recent_public_releases = create_list(:release, 3, project: project, milestones: [milestone], released_at: '2022-01-01T18:00:00Z')
+
+ is_expected.to match([match_array(recent_public_releases), 5, 2])
+ end
+ end
end
diff --git a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
index 135fa4cf5a4..e6b0772aec1 100644
--- a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
@@ -19,33 +19,66 @@ RSpec.shared_examples 'conan ping endpoint' do
end
RSpec.shared_examples 'conan search endpoint' do
- before do
- project.update_column(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
-
- # Do not pass the HTTP_AUTHORIZATION header,
- # in order to test that this public project's packages
- # are visible to anonymous search.
- get api(url), params: params
- end
+ using RSpec::Parameterized::TableSyntax
subject { json_response['results'] }
- context 'returns packages with a matching name' do
- let(:params) { { q: package.conan_recipe } }
+ context 'with a public project' do
+ before do
+ project.update!(visibility: 'public')
+
+ # Do not pass the HTTP_AUTHORIZATION header,
+ # in order to test that this public project's packages
+ # are visible to anonymous search.
+ get api(url), params: params
+ end
+
+ context 'returns packages with a matching name' do
+ let(:params) { { q: package.conan_recipe } }
+
+ it { is_expected.to contain_exactly(package.conan_recipe) }
+ end
+
+ context 'returns packages using a * wildcard' do
+ let(:params) { { q: "#{package.name[0, 3]}*" } }
- it { is_expected.to contain_exactly(package.conan_recipe) }
+ it { is_expected.to contain_exactly(package.conan_recipe) }
+ end
+
+ context 'does not return non-matching packages' do
+ let(:params) { { q: "foo" } }
+
+ it { is_expected.to be_blank }
+ end
end
- context 'returns packages using a * wildcard' do
+ context 'with a private project' do
let(:params) { { q: "#{package.name[0, 3]}*" } }
- it { is_expected.to contain_exactly(package.conan_recipe) }
- end
+ where(:role, :packages_visible) do
+ :maintainer | true
+ :developer | true
+ :reporter | true
+ :guest | false
+ :anonymous | false
+ end
- context 'does not return non-matching packages' do
- let(:params) { { q: "foo" } }
+ with_them do
+ before do
+ project.update!(visibility: 'private')
+ project.team.truncate
+ user.project_authorizations.delete_all
+ project.add_user(user, role) unless role == :anonymous
+
+ get api(url), params: params, headers: headers
+ end
- it { is_expected.to be_blank }
+ if params[:packages_visible]
+ it { is_expected.to contain_exactly(package.conan_recipe) }
+ else
+ it { is_expected.to be_blank }
+ end
+ end
end
end