Commit b32f8ffb authored by Giorgenes Gelatti's avatar Giorgenes Gelatti

Move package permissions to core

Move project policy declarations
regarding packages to core.
Prep work for upcoming move of packages to core
parent 1f256b6c
...@@ -65,6 +65,7 @@ class Project < ApplicationRecord ...@@ -65,6 +65,7 @@ class Project < ApplicationRecord
cache_markdown_field :description, pipeline: :description cache_markdown_field :description, pipeline: :description
default_value_for :packages_enabled, true
default_value_for :archived, false default_value_for :archived, false
default_value_for :resolve_outdated_diff_discussions, false default_value_for :resolve_outdated_diff_discussions, false
default_value_for :container_registry_enabled, gitlab_config_features.container_registry default_value_for :container_registry_enabled, gitlab_config_features.container_registry
...@@ -445,6 +446,7 @@ class Project < ApplicationRecord ...@@ -445,6 +446,7 @@ class Project < ApplicationRecord
# Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name # Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name
scope :projects_order_id_desc, -> { reorder(self.arel_table['id'].desc) } scope :projects_order_id_desc, -> { reorder(self.arel_table['id'].desc) }
scope :with_packages, -> { joins(:packages) }
scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) } scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) }
...@@ -851,6 +853,15 @@ class Project < ApplicationRecord ...@@ -851,6 +853,15 @@ class Project < ApplicationRecord
end end
end end
# Because we use default_value_for we need to be sure
# packages_enabled= method does exist even if we rollback migration.
# Otherwise many tests from spec/migrations will fail.
def packages_enabled=(value)
if has_attribute?(:packages_enabled)
write_attribute(:packages_enabled, value)
end
end
def cleanup def cleanup
@repository = nil @repository = nil
end end
......
...@@ -154,6 +154,9 @@ class ProjectPolicy < BasePolicy ...@@ -154,6 +154,9 @@ class ProjectPolicy < BasePolicy
::Feature.enabled?(:build_service_proxy, @subject) ::Feature.enabled?(:build_service_proxy, @subject)
end end
with_scope :subject
condition(:packages_disabled) { !@subject.packages_enabled }
features = %w[ features = %w[
merge_requests merge_requests
issues issues
...@@ -259,6 +262,7 @@ class ProjectPolicy < BasePolicy ...@@ -259,6 +262,7 @@ class ProjectPolicy < BasePolicy
enable :read_metrics_dashboard_annotation enable :read_metrics_dashboard_annotation
enable :metrics_dashboard enable :metrics_dashboard
enable :read_confidential_issues enable :read_confidential_issues
enable :read_package
end end
# We define `:public_user_access` separately because there are cases in gitlab-ee # We define `:public_user_access` separately because there are cases in gitlab-ee
...@@ -295,12 +299,17 @@ class ProjectPolicy < BasePolicy ...@@ -295,12 +299,17 @@ class ProjectPolicy < BasePolicy
enable :read_metrics_user_starred_dashboard enable :read_metrics_user_starred_dashboard
end end
rule { packages_disabled | repository_disabled }.policy do
prevent(*create_read_update_admin_destroy(:package))
end
rule { owner | admin | guest | group_member }.prevent :request_access rule { owner | admin | guest | group_member }.prevent :request_access
rule { ~request_access_enabled }.prevent :request_access rule { ~request_access_enabled }.prevent :request_access
rule { can?(:developer_access) & can?(:create_issue) }.enable :import_issues rule { can?(:developer_access) & can?(:create_issue) }.enable :import_issues
rule { can?(:developer_access) }.policy do rule { can?(:developer_access) }.policy do
enable :create_package
enable :admin_board enable :admin_board
enable :admin_merge_request enable :admin_merge_request
enable :admin_milestone enable :admin_milestone
...@@ -341,6 +350,7 @@ class ProjectPolicy < BasePolicy ...@@ -341,6 +350,7 @@ class ProjectPolicy < BasePolicy
end end
rule { can?(:maintainer_access) }.policy do rule { can?(:maintainer_access) }.policy do
enable :destroy_package
enable :admin_board enable :admin_board
enable :push_to_delete_protected_branch enable :push_to_delete_protected_branch
enable :update_snippet enable :update_snippet
...@@ -475,6 +485,7 @@ class ProjectPolicy < BasePolicy ...@@ -475,6 +485,7 @@ class ProjectPolicy < BasePolicy
end end
rule { can?(:public_access) }.policy do rule { can?(:public_access) }.policy do
enable :read_package
enable :read_project enable :read_project
enable :read_board enable :read_board
enable :read_list enable :read_list
......
...@@ -132,7 +132,6 @@ module EE ...@@ -132,7 +132,6 @@ module EE
scope :with_active_prometheus_service, -> { joins(:prometheus_service).merge(PrometheusService.active) } scope :with_active_prometheus_service, -> { joins(:prometheus_service).merge(PrometheusService.active) }
scope :with_enabled_error_tracking, -> { joins(:error_tracking_setting).where(project_error_tracking_settings: { enabled: true }) } scope :with_enabled_error_tracking, -> { joins(:error_tracking_setting).where(project_error_tracking_settings: { enabled: true }) }
scope :with_tracing_enabled, -> { joins(:tracing_setting) } scope :with_tracing_enabled, -> { joins(:tracing_setting) }
scope :with_packages, -> { joins(:packages) }
scope :mirrored_with_enabled_pipelines, -> do scope :mirrored_with_enabled_pipelines, -> do
joins(:project_feature).mirror.where(mirror_trigger_builds: true, joins(:project_feature).mirror.where(mirror_trigger_builds: true,
project_features: { builds_access_level: ::ProjectFeature::ENABLED }) project_features: { builds_access_level: ::ProjectFeature::ENABLED })
...@@ -181,8 +180,6 @@ module EE ...@@ -181,8 +180,6 @@ module EE
validates :mirror_user, presence: true validates :mirror_user, presence: true
end end
default_value_for :packages_enabled, true
accepts_nested_attributes_for :tracing_setting, update_only: true, allow_destroy: true accepts_nested_attributes_for :tracing_setting, update_only: true, allow_destroy: true
accepts_nested_attributes_for :status_page_setting, update_only: true, allow_destroy: true accepts_nested_attributes_for :status_page_setting, update_only: true, allow_destroy: true
accepts_nested_attributes_for :compliance_framework_setting, update_only: true, allow_destroy: true accepts_nested_attributes_for :compliance_framework_setting, update_only: true, allow_destroy: true
...@@ -608,15 +605,6 @@ module EE ...@@ -608,15 +605,6 @@ module EE
feature_available?(:protected_environments) feature_available?(:protected_environments)
end end
# Because we use default_value_for we need to be sure
# packages_enabled= method does exist even if we rollback migration.
# Otherwise many tests from spec/migrations will fail.
def packages_enabled=(value)
if has_attribute?(:packages_enabled)
write_attribute(:packages_enabled, value)
end
end
# Update the default branch querying the remote to determine its HEAD # Update the default branch querying the remote to determine its HEAD
def update_root_ref(remote_name) def update_root_ref(remote_name)
root_ref = repository.find_remote_root_ref(remote_name) root_ref = repository.find_remote_root_ref(remote_name)
......
...@@ -27,9 +27,6 @@ module EE ...@@ -27,9 +27,6 @@ module EE
with_scope :subject with_scope :subject
condition(:deploy_board_disabled) { !@subject.feature_available?(:deploy_board) } condition(:deploy_board_disabled) { !@subject.feature_available?(:deploy_board) }
with_scope :subject
condition(:packages_disabled) { !@subject.packages_enabled }
with_scope :subject with_scope :subject
condition(:iterations_available) { @subject.feature_available?(:iterations) } condition(:iterations_available) { @subject.feature_available?(:iterations) }
...@@ -227,7 +224,6 @@ module EE ...@@ -227,7 +224,6 @@ module EE
enable :read_deploy_board enable :read_deploy_board
enable :admin_issue_link enable :admin_issue_link
enable :admin_epic_issue enable :admin_epic_issue
enable :read_package
enable :read_group_timelogs enable :read_group_timelogs
end end
...@@ -237,7 +233,6 @@ module EE ...@@ -237,7 +233,6 @@ module EE
enable :create_vulnerability_feedback enable :create_vulnerability_feedback
enable :destroy_vulnerability_feedback enable :destroy_vulnerability_feedback
enable :update_vulnerability_feedback enable :update_vulnerability_feedback
enable :create_package
enable :read_feature_flag enable :read_feature_flag
enable :create_feature_flag enable :create_feature_flag
enable :update_feature_flag enable :update_feature_flag
...@@ -253,8 +248,6 @@ module EE ...@@ -253,8 +248,6 @@ module EE
enable :admin_iteration enable :admin_iteration
end end
rule { can?(:public_access) }.enable :read_package
rule { can?(:read_project) & iterations_available }.enable :read_iteration rule { can?(:read_project) & iterations_available }.enable :read_iteration
rule { security_dashboard_enabled & can?(:developer_access) }.policy do rule { security_dashboard_enabled & can?(:developer_access) }.policy do
...@@ -290,10 +283,6 @@ module EE ...@@ -290,10 +283,6 @@ module EE
rule { deploy_board_disabled & ~is_development }.prevent :read_deploy_board rule { deploy_board_disabled & ~is_development }.prevent :read_deploy_board
rule { packages_disabled | repository_disabled }.policy do
prevent(*create_read_update_admin_destroy(:package))
end
rule { feature_flags_disabled | repository_disabled }.policy do rule { feature_flags_disabled | repository_disabled }.policy do
prevent(*create_read_update_admin_destroy(:feature_flag)) prevent(*create_read_update_admin_destroy(:feature_flag))
prevent(:admin_feature_flags_user_lists) prevent(:admin_feature_flags_user_lists)
...@@ -303,7 +292,6 @@ module EE ...@@ -303,7 +292,6 @@ module EE
enable :push_code_to_protected_branches enable :push_code_to_protected_branches
enable :admin_path_locks enable :admin_path_locks
enable :update_approvers enable :update_approvers
enable :destroy_package
enable :admin_feature_flags_client enable :admin_feature_flags_client
enable :modify_approvers_rules enable :modify_approvers_rules
enable :modify_approvers_list enable :modify_approvers_list
......
...@@ -39,8 +39,6 @@ RSpec.describe Project do ...@@ -39,8 +39,6 @@ RSpec.describe Project do
it { is_expected.to have_many(:approvers).dependent(:destroy) } it { is_expected.to have_many(:approvers).dependent(:destroy) }
it { is_expected.to have_many(:approver_users).through(:approvers) } it { is_expected.to have_many(:approver_users).through(:approvers) }
it { is_expected.to have_many(:approver_groups).dependent(:destroy) } it { is_expected.to have_many(:approver_groups).dependent(:destroy) }
it { is_expected.to have_many(:packages).class_name('Packages::Package') }
it { is_expected.to have_many(:package_files).class_name('Packages::PackageFile') }
it { is_expected.to have_many(:upstream_project_subscriptions) } it { is_expected.to have_many(:upstream_project_subscriptions) }
it { is_expected.to have_many(:upstream_projects) } it { is_expected.to have_many(:upstream_projects) }
it { is_expected.to have_many(:downstream_project_subscriptions) } it { is_expected.to have_many(:downstream_project_subscriptions) }
...@@ -1982,12 +1980,6 @@ RSpec.describe Project do ...@@ -1982,12 +1980,6 @@ RSpec.describe Project do
end end
end end
describe '#packages_enabled' do
subject { create(:project).packages_enabled }
it { is_expected.to be true }
end
describe '#update_root_ref' do describe '#update_root_ref' do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
...@@ -2439,33 +2431,6 @@ RSpec.describe Project do ...@@ -2439,33 +2431,6 @@ RSpec.describe Project do
.and_return(host: host) .and_return(host: host)
end end
describe '#package_already_taken?' do
let(:namespace) { create(:namespace) }
let(:project) { create(:project, :public, namespace: namespace) }
let!(:package) { create(:npm_package, project: project, name: "@#{namespace.path}/foo") }
context 'no package exists with the same name' do
it 'returns false' do
result = project.package_already_taken?("@#{namespace.path}/bar")
expect(result).to be false
end
it 'returns false if it is the project that the package belongs to' do
result = project.package_already_taken?("@#{namespace.path}/foo")
expect(result).to be false
end
end
context 'a package already exists with the same name' do
let(:alt_project) { create(:project, :public, namespace: namespace) }
it 'returns true' do
result = alt_project.package_already_taken?("@#{namespace.path}/foo")
expect(result).to be true
end
end
end
describe '#ancestor_marked_for_deletion' do describe '#ancestor_marked_for_deletion' do
context 'adjourned deletion feature is not available' do context 'adjourned deletion feature is not available' do
before do before do
......
...@@ -607,64 +607,6 @@ RSpec.describe ProjectPolicy do ...@@ -607,64 +607,6 @@ RSpec.describe ProjectPolicy do
end end
end end
describe 'read_package' do
context 'with admin' do
let(:current_user) { admin }
it { is_expected.to be_allowed(:read_package) }
context 'when repository is disabled' do
before do
project.project_feature.update(repository_access_level: ProjectFeature::DISABLED)
end
it { is_expected.to be_disallowed(:read_package) }
end
end
context 'with owner' do
let(:current_user) { owner }
it { is_expected.to be_allowed(:read_package) }
end
context 'with maintainer' do
let(:current_user) { maintainer }
it { is_expected.to be_allowed(:read_package) }
end
context 'with developer' do
let(:current_user) { developer }
it { is_expected.to be_allowed(:read_package) }
end
context 'with reporter' do
let(:current_user) { reporter }
it { is_expected.to be_allowed(:read_package) }
end
context 'with guest' do
let(:current_user) { guest }
it { is_expected.to be_allowed(:read_package) }
end
context 'with non member' do
let(:current_user) { create(:user) }
it { is_expected.to be_allowed(:read_package) }
end
context 'with anonymous' do
let(:current_user) { nil }
it { is_expected.to be_allowed(:read_package) }
end
end
describe 'remove_project when default_project_deletion_protection is set to true' do describe 'remove_project when default_project_deletion_protection is set to true' do
before do before do
allow(Gitlab::CurrentSettings.current_application_settings) allow(Gitlab::CurrentSettings.current_application_settings)
......
...@@ -119,6 +119,8 @@ RSpec.describe Project do ...@@ -119,6 +119,8 @@ RSpec.describe Project do
it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:project) } it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:project) }
it { is_expected.to have_many(:repository_storage_moves) } it { is_expected.to have_many(:repository_storage_moves) }
it { is_expected.to have_many(:reviews).inverse_of(:project) } it { is_expected.to have_many(:reviews).inverse_of(:project) }
it { is_expected.to have_many(:packages).class_name('Packages::Package') }
it { is_expected.to have_many(:package_files).class_name('Packages::PackageFile') }
it_behaves_like 'model with repository' do it_behaves_like 'model with repository' do
let_it_be(:container) { create(:project, :repository, path: 'somewhere') } let_it_be(:container) { create(:project, :repository, path: 'somewhere') }
...@@ -6111,6 +6113,39 @@ RSpec.describe Project do ...@@ -6111,6 +6113,39 @@ RSpec.describe Project do
end end
end end
describe '#packages_enabled' do
subject { create(:project).packages_enabled }
it { is_expected.to be true }
end
describe '#package_already_taken?' do
let(:namespace) { create(:namespace) }
let(:project) { create(:project, :public, namespace: namespace) }
let!(:package) { create(:npm_package, project: project, name: "@#{namespace.path}/foo") }
context 'no package exists with the same name' do
it 'returns false' do
result = project.package_already_taken?("@#{namespace.path}/bar")
expect(result).to be false
end
it 'returns false if it is the project that the package belongs to' do
result = project.package_already_taken?("@#{namespace.path}/foo")
expect(result).to be false
end
end
context 'a package already exists with the same name' do
let(:alt_project) { create(:project, :public, namespace: namespace) }
it 'returns true' do
result = alt_project.package_already_taken?("@#{namespace.path}/foo")
expect(result).to be true
end
end
end
describe '#design_management_enabled?' do describe '#design_management_enabled?' do
let(:project) { build(:project) } let(:project) { build(:project) }
......
...@@ -941,4 +941,64 @@ RSpec.describe ProjectPolicy do ...@@ -941,4 +941,64 @@ RSpec.describe ProjectPolicy do
it { is_expected.to be_disallowed(:read_build_report_results) } it { is_expected.to be_disallowed(:read_build_report_results) }
end end
end end
describe 'read_package' do
subject { described_class.new(current_user, project) }
context 'with admin' do
let(:current_user) { admin }
it { is_expected.to be_allowed(:read_package) }
context 'when repository is disabled' do
before do
project.project_feature.update(repository_access_level: ProjectFeature::DISABLED)
end
it { is_expected.to be_disallowed(:read_package) }
end
end
context 'with owner' do
let(:current_user) { owner }
it { is_expected.to be_allowed(:read_package) }
end
context 'with maintainer' do
let(:current_user) { maintainer }
it { is_expected.to be_allowed(:read_package) }
end
context 'with developer' do
let(:current_user) { developer }
it { is_expected.to be_allowed(:read_package) }
end
context 'with reporter' do
let(:current_user) { reporter }
it { is_expected.to be_allowed(:read_package) }
end
context 'with guest' do
let(:current_user) { guest }
it { is_expected.to be_allowed(:read_package) }
end
context 'with non member' do
let(:current_user) { create(:user) }
it { is_expected.to be_allowed(:read_package) }
end
context 'with anonymous' do
let(:current_user) { nil }
it { is_expected.to be_allowed(:read_package) }
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