From 00aa4323fd06b33a130c3d953f9a28c7cd48e0cb Mon Sep 17 00:00:00 2001 From: Quinn James <35753203+qcjames53@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:47:44 -0400 Subject: [PATCH] Fixes #37634 - Prevent users from editing container push repositories (#11071) --- .../registry/registry_proxies_controller.rb | 1 + app/models/katello/repository.rb | 12 ++++- app/models/katello/root_repository.rb | 19 +++++++ .../api/v2/repositories/show.json.rabl | 2 + .../details/views/repository-info.html | 53 ++++++++++--------- test/actions/katello/environment_test.rb | 2 +- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/app/controllers/katello/api/registry/registry_proxies_controller.rb b/app/controllers/katello/api/registry/registry_proxies_controller.rb index 34b4bb50e9e..fa21f42727c 100644 --- a/app/controllers/katello/api/registry/registry_proxies_controller.rb +++ b/app/controllers/katello/api/registry/registry_proxies_controller.rb @@ -383,6 +383,7 @@ def save_pulp_push_repository_href :not_found ) end + instance_repo.update!(version_href: latest_version_href) # The Pulp repository should not change after first creation if root_repository.repository_references.empty? diff --git a/app/models/katello/repository.rb b/app/models/katello/repository.rb index c1a91518f54..e713452454d 100644 --- a/app/models/katello/repository.rb +++ b/app/models/katello/repository.rb @@ -32,6 +32,8 @@ class Repository < Katello::Model EXPORTABLE_TYPES = [YUM_TYPE, FILE_TYPE, ANSIBLE_COLLECTION_TYPE, DOCKER_TYPE, DEB_TYPE].freeze + ALLOWED_UPDATE_FIELDS = ['version_href', 'last_indexed'].freeze + define_model_callbacks :sync, :only => :after belongs_to :root, :inverse_of => :repositories, :class_name => "Katello::RootRepository" @@ -119,6 +121,7 @@ class Repository < Katello::Model before_validation :set_pulp_id before_validation :set_container_repository_name, :unless => :skip_container_name? + before_update :prevent_updates, :unless => :allow_updates? scope :has_url, -> { joins(:root).where.not("#{RootRepository.table_name}.url" => nil) } scope :not_uln, -> { joins(:root).where("#{RootRepository.table_name}.url NOT LIKE 'uln%'") } @@ -180,7 +183,7 @@ class Repository < Katello::Model :deb_components, :deb_architectures, :ssl_ca_cert_id, :ssl_ca_cert, :ssl_client_cert, :ssl_client_cert_id, :ssl_client_key_id, :os_versions, :ssl_client_key, :ignorable_content, :description, :include_tags, :exclude_tags, :ansible_collection_requirements, :ansible_collection_auth_url, :ansible_collection_auth_token, - :http_proxy_policy, :http_proxy_id, :to => :root + :http_proxy_policy, :http_proxy_id, :prevent_updates, :to => :root delegate :content_id, to: :root, allow_nil: true delegate :repository_type, to: :root @@ -1011,6 +1014,7 @@ def index_content(options = {}) repository_type.index_additional_data_proc&.call(self) end self.update!(last_indexed: DateTime.now) + true end @@ -1052,6 +1056,12 @@ def remove_docker_content(manifests) DockerMetaTag.cleanup_tags end + def allow_updates? + # allow the update if this repo is not in the default view + return true unless in_default_view? + root.allow_updates?(::Katello::Repository::ALLOWED_UPDATE_FIELDS) + end + apipie :class, desc: "A class representing #{model_name.human} object" do name 'Repository' refs 'Repository' diff --git a/app/models/katello/root_repository.rb b/app/models/katello/root_repository.rb index 3304e775abb..ae96e73e224 100644 --- a/app/models/katello/root_repository.rb +++ b/app/models/katello/root_repository.rb @@ -46,6 +46,8 @@ class RootRepository < Katello::Model MIRRORING_POLICY_COMPLETE = 'mirror_complete'.freeze MIRRORING_POLICIES = [MIRRORING_POLICY_ADDITIVE, MIRRORING_POLICY_COMPLETE, MIRRORING_POLICY_CONTENT].freeze + ALLOWED_UPDATE_FIELDS = ['updated_at', 'content_id'].freeze + belongs_to :product, :inverse_of => :root_repositories, :class_name => "Katello::Product" has_one :provider, :through => :product @@ -115,6 +117,7 @@ class RootRepository < Katello::Model } validates :container_push_name_format, inclusion: { in: ['label', 'id'].freeze, allow_nil: true} + before_update :prevent_updates, :unless => :allow_updates? scope :subscribable, -> { where(content_type: RootRepository::SUBSCRIBABLE_TYPES) } scope :skipable_metadata_check, -> { where(content_type: RootRepository::SKIPABLE_METADATA_TYPES) } @@ -455,6 +458,22 @@ def format_arches end end + def allow_updates?(additional_allowed_fields = []) + # allow updates for non-container-push repos, repos not in default view, and + # repos with a library instance + return true unless is_container_push && library_instance.present? + + # let updates that contain ONLY allowed strings through + allowed_fields = ::Katello::RootRepository::ALLOWED_UPDATE_FIELDS + additional_allowed_fields + return true if (changed - allowed_fields).empty? + + false + end + + def prevent_updates + fail _("Cannot update properties of a container push repository") + end + apipie :class, desc: 'A class representing Repository object' do name 'Repository' refs 'Repository' diff --git a/app/views/katello/api/v2/repositories/show.json.rabl b/app/views/katello/api/v2/repositories/show.json.rabl index a6713b13f8d..4d7ac98e0d4 100644 --- a/app/views/katello/api/v2/repositories/show.json.rabl +++ b/app/views/katello/api/v2/repositories/show.json.rabl @@ -28,6 +28,8 @@ glue(@resource.root) do attributes :http_proxy_name attributes :retain_package_versions_count attributes :metadata_expire + attributes :allow_updates? => :allow_updates + attributes :is_container_push? => :is_container_push node :http_proxy do attributes :id => @resource.root&.http_proxy&.id, :name => @resource.root&.http_proxy&.name, :policy => @resource.root&.http_proxy_policy diff --git a/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html b/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html index a0e1fbe2e2b..397a11d0fd8 100644 --- a/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +++ b/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html @@ -8,7 +8,7 @@