diff --git a/app/graphql/mutations/namespace/package_settings/update.rb b/app/graphql/mutations/namespace/package_settings/update.rb index e499e6467814668022f1deac3942ca555fa10f7c..ea72b71715c4fee5caa267db7cab62677af28c68 100644 --- a/app/graphql/mutations/namespace/package_settings/update.rb +++ b/app/graphql/mutations/namespace/package_settings/update.rb @@ -35,6 +35,36 @@ class Update < Mutations::BaseMutation required: false, description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicate_exception_regex) + argument :maven_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :maven_package_requests_forwarding) + + argument :npm_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :npm_package_requests_forwarding) + + argument :pypi_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :pypi_package_requests_forwarding) + + argument :lock_maven_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :lock_maven_package_requests_forwarding) + + argument :lock_npm_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :lock_npm_package_requests_forwarding) + + argument :lock_pypi_package_requests_forwarding, + GraphQL::Types::Boolean, + required: false, + description: copy_field_description(Types::Namespace::PackageSettingsType, :lock_pypi_package_requests_forwarding) + field :package_settings, Types::Namespace::PackageSettingsType, null: true, diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb index 7a0abe619a5aac3864b68a1d9c62e3380dbb1fe0..84becba800172e569019fdadcd32c826702aa42a 100644 --- a/app/graphql/types/namespace/package_settings_type.rb +++ b/app/graphql/types/namespace/package_settings_type.rb @@ -8,9 +8,50 @@ class Namespace::PackageSettingsType < BaseObject authorize :admin_package - field :generic_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' - field :generic_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate generic packages are allowed for this namespace.' - field :maven_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' - field :maven_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate Maven packages are allowed for this namespace.' + field :generic_duplicate_exception_regex, Types::UntrustedRegexp, + null: true, + description: 'When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' + field :generic_duplicates_allowed, GraphQL::Types::Boolean, + null: false, + description: 'Indicates whether duplicate generic packages are allowed for this namespace.' + field :maven_duplicate_exception_regex, Types::UntrustedRegexp, + null: true, + description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' + field :maven_duplicates_allowed, GraphQL::Types::Boolean, + null: false, + description: 'Indicates whether duplicate Maven packages are allowed for this namespace.' + + field :maven_package_requests_forwarding, GraphQL::Types::Boolean, + null: true, + description: 'Indicates whether Maven package forwarding is allowed for this namespace.' + field :npm_package_requests_forwarding, GraphQL::Types::Boolean, + null: true, + description: 'Indicates whether npm package forwarding is allowed for this namespace.' + field :pypi_package_requests_forwarding, GraphQL::Types::Boolean, + null: true, + description: 'Indicates whether PyPI package forwarding is allowed for this namespace.' + + field :lock_maven_package_requests_forwarding, GraphQL::Types::Boolean, + null: false, + description: 'Indicates whether Maven package forwarding is locked for all descendent namespaces.' + field :lock_npm_package_requests_forwarding, GraphQL::Types::Boolean, + null: false, + description: 'Indicates whether npm package forwarding is locked for all descendent namespaces.' + field :lock_pypi_package_requests_forwarding, GraphQL::Types::Boolean, + null: false, + description: 'Indicates whether PyPI package forwarding is locked for all descendent namespaces.' + + field :maven_package_requests_forwarding_locked, GraphQL::Types::Boolean, + null: false, + method: :maven_package_requests_forwarding_locked?, + description: 'Indicates whether Maven package forwarding settings are locked by a parent namespace.' + field :npm_package_requests_forwarding_locked, GraphQL::Types::Boolean, + null: false, + method: :npm_package_requests_forwarding_locked?, + description: 'Indicates whether npm package forwarding settings are locked by a parent namespace.' + field :pypi_package_requests_forwarding_locked, GraphQL::Types::Boolean, + null: false, + method: :pypi_package_requests_forwarding_locked?, + description: 'Indicates whether PyPI package forwarding settings are locked by a parent namespace.' end end diff --git a/app/services/namespaces/package_settings/update_service.rb b/app/services/namespaces/package_settings/update_service.rb index c0af090045003b303378da0a16c4e3d078e2404f..0c6fcee911382fb250d9dcfa9b74d76fb6f89f33 100644 --- a/app/services/namespaces/package_settings/update_service.rb +++ b/app/services/namespaces/package_settings/update_service.rb @@ -8,7 +8,13 @@ class UpdateService < BaseContainerService ALLOWED_ATTRIBUTES = %i[maven_duplicates_allowed maven_duplicate_exception_regex generic_duplicates_allowed - generic_duplicate_exception_regex].freeze + generic_duplicate_exception_regex + maven_package_requests_forwarding + npm_package_requests_forwarding + pypi_package_requests_forwarding + lock_maven_package_requests_forwarding + lock_npm_package_requests_forwarding + lock_pypi_package_requests_forwarding].freeze def execute return ServiceResponse.error(message: 'Access Denied', http_status: 403) unless allowed? diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 869d1fd61375d7e730ff2ff86bdecf0c3204393e..2cface169828d0fbfbb9cfc81b3e7c9b25e6ac8c 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -5408,9 +5408,15 @@ Input type: `UpdateNamespacePackageSettingsInput` | <a id="mutationupdatenamespacepackagesettingsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationupdatenamespacepackagesettingsgenericduplicateexceptionregex"></a>`genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. | | <a id="mutationupdatenamespacepackagesettingsgenericduplicatesallowed"></a>`genericDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. | +| <a id="mutationupdatenamespacepackagesettingslockmavenpackagerequestsforwarding"></a>`lockMavenPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether Maven package forwarding is locked for all descendent namespaces. | +| <a id="mutationupdatenamespacepackagesettingslocknpmpackagerequestsforwarding"></a>`lockNpmPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether npm package forwarding is locked for all descendent namespaces. | +| <a id="mutationupdatenamespacepackagesettingslockpypipackagerequestsforwarding"></a>`lockPypiPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether PyPI package forwarding is locked for all descendent namespaces. | | <a id="mutationupdatenamespacepackagesettingsmavenduplicateexceptionregex"></a>`mavenDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. | | <a id="mutationupdatenamespacepackagesettingsmavenduplicatesallowed"></a>`mavenDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate Maven packages are allowed for this namespace. | +| <a id="mutationupdatenamespacepackagesettingsmavenpackagerequestsforwarding"></a>`mavenPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether Maven package forwarding is allowed for this namespace. | | <a id="mutationupdatenamespacepackagesettingsnamespacepath"></a>`namespacePath` | [`ID!`](#id) | Namespace path where the namespace package setting is located. | +| <a id="mutationupdatenamespacepackagesettingsnpmpackagerequestsforwarding"></a>`npmPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether npm package forwarding is allowed for this namespace. | +| <a id="mutationupdatenamespacepackagesettingspypipackagerequestsforwarding"></a>`pypiPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether PyPI package forwarding is allowed for this namespace. | #### Fields @@ -15759,8 +15765,17 @@ Namespace-level Package Registry settings. | ---- | ---- | ----------- | | <a id="packagesettingsgenericduplicateexceptionregex"></a>`genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. | | <a id="packagesettingsgenericduplicatesallowed"></a>`genericDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. | +| <a id="packagesettingslockmavenpackagerequestsforwarding"></a>`lockMavenPackageRequestsForwarding` | [`Boolean!`](#boolean) | Indicates whether Maven package forwarding is locked for all descendent namespaces. | +| <a id="packagesettingslocknpmpackagerequestsforwarding"></a>`lockNpmPackageRequestsForwarding` | [`Boolean!`](#boolean) | Indicates whether npm package forwarding is locked for all descendent namespaces. | +| <a id="packagesettingslockpypipackagerequestsforwarding"></a>`lockPypiPackageRequestsForwarding` | [`Boolean!`](#boolean) | Indicates whether PyPI package forwarding is locked for all descendent namespaces. | | <a id="packagesettingsmavenduplicateexceptionregex"></a>`mavenDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. | | <a id="packagesettingsmavenduplicatesallowed"></a>`mavenDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate Maven packages are allowed for this namespace. | +| <a id="packagesettingsmavenpackagerequestsforwarding"></a>`mavenPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether Maven package forwarding is allowed for this namespace. | +| <a id="packagesettingsmavenpackagerequestsforwardinglocked"></a>`mavenPackageRequestsForwardingLocked` | [`Boolean!`](#boolean) | Indicates whether Maven package forwarding settings are locked by a parent namespace. | +| <a id="packagesettingsnpmpackagerequestsforwarding"></a>`npmPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether npm package forwarding is allowed for this namespace. | +| <a id="packagesettingsnpmpackagerequestsforwardinglocked"></a>`npmPackageRequestsForwardingLocked` | [`Boolean!`](#boolean) | Indicates whether npm package forwarding settings are locked by a parent namespace. | +| <a id="packagesettingspypipackagerequestsforwarding"></a>`pypiPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether PyPI package forwarding is allowed for this namespace. | +| <a id="packagesettingspypipackagerequestsforwardinglocked"></a>`pypiPackageRequestsForwardingLocked` | [`Boolean!`](#boolean) | Indicates whether PyPI package forwarding settings are locked by a parent namespace. | ### `PackageTag` diff --git a/spec/graphql/mutations/namespace/package_settings/update_spec.rb b/spec/graphql/mutations/namespace/package_settings/update_spec.rb index 631e02ff3dc1789691221a3136bc581ea239d298..09ac1c99b10b674f07aa27646150f21c0eff306b 100644 --- a/spec/graphql/mutations/namespace/package_settings/update_spec.rb +++ b/spec/graphql/mutations/namespace/package_settings/update_spec.rb @@ -26,8 +26,29 @@ RSpec.shared_examples 'updating the namespace package setting' do it_behaves_like 'updating the namespace package setting attributes', - from: { maven_duplicates_allowed: true, maven_duplicate_exception_regex: 'SNAPSHOT', generic_duplicates_allowed: true, generic_duplicate_exception_regex: 'foo' }, - to: { maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'RELEASE', generic_duplicates_allowed: false, generic_duplicate_exception_regex: 'bar' } + from: { + maven_duplicates_allowed: true, + maven_duplicate_exception_regex: 'SNAPSHOT', + generic_duplicates_allowed: true, + generic_duplicate_exception_regex: 'foo', + maven_package_requests_forwarding: nil, + lock_maven_package_requests_forwarding: false, + npm_package_requests_forwarding: nil, + lock_npm_package_requests_forwarding: false, + pypi_package_requests_forwarding: nil, + lock_pypi_package_requests_forwarding: false + }, to: { + maven_duplicates_allowed: false, + maven_duplicate_exception_regex: 'RELEASE', + generic_duplicates_allowed: false, + generic_duplicate_exception_regex: 'bar', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true + } it_behaves_like 'returning a success' @@ -59,11 +80,19 @@ context 'with existing namespace package setting' do let_it_be(:package_settings) { create(:namespace_package_setting, namespace: namespace) } let_it_be(:params) do - { namespace_path: namespace.full_path, + { + namespace_path: namespace.full_path, maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'RELEASE', generic_duplicates_allowed: false, - generic_duplicate_exception_regex: 'bar' } + generic_duplicate_exception_regex: 'bar', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true + } end where(:user_role, :shared_examples_name) do diff --git a/spec/graphql/types/namespace/package_settings_type_spec.rb b/spec/graphql/types/namespace/package_settings_type_spec.rb index f63a0a7010f85e53742d36099158927f79d9a9cd..5039f2d6153d23305aa9027f36c22da0acda959f 100644 --- a/spec/graphql/types/namespace/package_settings_type_spec.rb +++ b/spec/graphql/types/namespace/package_settings_type_spec.rb @@ -14,4 +14,24 @@ it { is_expected.to have_graphql_type(Types::UntrustedRegexp) } end + + it 'includes package setting fields' do + expected_fields = %w[ + maven_duplicates_allowed + maven_duplicate_exception_regex + generic_duplicates_allowed + generic_duplicate_exception_regex + maven_package_requests_forwarding + lock_maven_package_requests_forwarding + npm_package_requests_forwarding + lock_npm_package_requests_forwarding + pypi_package_requests_forwarding + lock_pypi_package_requests_forwarding + maven_package_requests_forwarding_locked + npm_package_requests_forwarding_locked + pypi_package_requests_forwarding_locked + ] + + expect(described_class).to include_graphql_fields(*expected_fields) + end end diff --git a/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb b/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb index 194e42bf59db1fc521171db99428e8bb7e316929..567d8799d931dff501a87d94a8968df769147e6b 100644 --- a/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb +++ b/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb @@ -14,7 +14,13 @@ maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'foo-.*', generic_duplicates_allowed: false, - generic_duplicate_exception_regex: 'bar-.*' + generic_duplicate_exception_regex: 'bar-.*', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true } end @@ -26,6 +32,12 @@ mavenDuplicateExceptionRegex genericDuplicatesAllowed genericDuplicateExceptionRegex + mavenPackageRequestsForwarding + lockMavenPackageRequestsForwarding + npmPackageRequestsForwarding + lockNpmPackageRequestsForwarding + pypiPackageRequestsForwarding + lockPypiPackageRequestsForwarding } errors QL @@ -46,6 +58,12 @@ expect(package_settings_response['mavenDuplicateExceptionRegex']).to eq(params[:maven_duplicate_exception_regex]) expect(package_settings_response['genericDuplicatesAllowed']).to eq(params[:generic_duplicates_allowed]) expect(package_settings_response['genericDuplicateExceptionRegex']).to eq(params[:generic_duplicate_exception_regex]) + expect(package_settings_response['mavenPackageRequestsForwarding']).to eq(params[:maven_package_requests_forwarding]) + expect(package_settings_response['lockMavenPackageRequestsForwarding']).to eq(params[:lock_maven_package_requests_forwarding]) + expect(package_settings_response['pypiPackageRequestsForwarding']).to eq(params[:pypi_package_requests_forwarding]) + expect(package_settings_response['lockPypiPackageRequestsForwarding']).to eq(params[:lock_pypi_package_requests_forwarding]) + expect(package_settings_response['npmPackageRequestsForwarding']).to eq(params[:npm_package_requests_forwarding]) + expect(package_settings_response['lockNpmPackageRequestsForwarding']).to eq(params[:lock_npm_package_requests_forwarding]) end end @@ -75,8 +93,29 @@ RSpec.shared_examples 'accepting the mutation request updating the package settings' do it_behaves_like 'updating the namespace package setting attributes', - from: { maven_duplicates_allowed: true, maven_duplicate_exception_regex: 'SNAPSHOT', generic_duplicates_allowed: true, generic_duplicate_exception_regex: 'foo' }, - to: { maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'foo-.*', generic_duplicates_allowed: false, generic_duplicate_exception_regex: 'bar-.*' } + from: { + maven_duplicates_allowed: true, + maven_duplicate_exception_regex: 'SNAPSHOT', + generic_duplicates_allowed: true, + generic_duplicate_exception_regex: 'foo', + maven_package_requests_forwarding: nil, + lock_maven_package_requests_forwarding: false, + npm_package_requests_forwarding: nil, + lock_npm_package_requests_forwarding: false, + pypi_package_requests_forwarding: nil, + lock_pypi_package_requests_forwarding: false + }, to: { + maven_duplicates_allowed: false, + maven_duplicate_exception_regex: 'foo-.*', + generic_duplicates_allowed: false, + generic_duplicate_exception_regex: 'bar-.*', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true + } it_behaves_like 'returning a success' it_behaves_like 'rejecting invalid regex' diff --git a/spec/services/namespaces/package_settings/update_service_spec.rb b/spec/services/namespaces/package_settings/update_service_spec.rb index ed385f1cd7f6800aa48d98acb39fc11329f84c8e..10926c5ef57eb6b2e938420883a9d9373b5b8b76 100644 --- a/spec/services/namespaces/package_settings/update_service_spec.rb +++ b/spec/services/namespaces/package_settings/update_service_spec.rb @@ -33,8 +33,29 @@ shared_examples 'updating the namespace package setting' do it_behaves_like 'updating the namespace package setting attributes', - from: { maven_duplicates_allowed: true, maven_duplicate_exception_regex: 'SNAPSHOT', generic_duplicates_allowed: true, generic_duplicate_exception_regex: 'foo' }, - to: { maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'RELEASE', generic_duplicates_allowed: false, generic_duplicate_exception_regex: 'bar' } + from: { + maven_duplicates_allowed: true, + maven_duplicate_exception_regex: 'SNAPSHOT', + generic_duplicates_allowed: true, + generic_duplicate_exception_regex: 'foo', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: false, + npm_package_requests_forwarding: nil, + lock_npm_package_requests_forwarding: false, + pypi_package_requests_forwarding: nil, + lock_pypi_package_requests_forwarding: false + }, to: { + maven_duplicates_allowed: false, + maven_duplicate_exception_regex: 'RELEASE', + generic_duplicates_allowed: false, + generic_duplicate_exception_regex: 'bar', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true + } it_behaves_like 'returning a success' @@ -63,10 +84,18 @@ context 'with existing namespace package setting' do let_it_be(:package_settings) { create(:namespace_package_setting, namespace: namespace) } let_it_be(:params) do - { maven_duplicates_allowed: false, + { + maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'RELEASE', generic_duplicates_allowed: false, - generic_duplicate_exception_regex: 'bar' } + generic_duplicate_exception_regex: 'bar', + maven_package_requests_forwarding: true, + lock_maven_package_requests_forwarding: true, + npm_package_requests_forwarding: true, + lock_npm_package_requests_forwarding: true, + pypi_package_requests_forwarding: true, + lock_pypi_package_requests_forwarding: true + } end where(:user_role, :shared_examples_name) do