Skip to content

Add table for the dependency proxy packages settings

🐻 Context

We're working on the very first version of the dependency proxy for packages. See #407460 (comment 1373731852) for all the details from the technical investigation.

This MR is the very first one and we're implementing the first step: Database model for the dependency proxy settings (#410714 - closed).

Note that we're starting with maven packages first so the settings are for this format only but down the road (follow up iterations), we will add support for other formats.

🤔 What does this MR do and why?

  • Add the table and model for the dependency proxy (packages) settings.
    • We're starting with maven packages first so only 3 settings need to be saved:
      • the external maven registry url.
      • the credentials (username/password).
    • The dependency proxy for packages is a EE only feature. The model class is thus in the ee folder only.
  • Add the related specs.

One note on the credentials. Obviously, we're going to encrypt those following https://docs.gitlab.com/ee/development/secure_coding_guidelines.html#handling-credentials.

We have been following the discussions in #26243 and the overall conclusion is that we should jump to https://edgeguides.rubyonrails.org/active_record_encryption.html when possible. The problem is that this depends on rails 7.0 that is currently planned to be delivered in %16.1.

So the plan for those encrypted attributes is the following due to the fact that this first iteration is gated behind a feature flag:

🖼 Screenshots or screen recordings

It's a model, so nothing to see 😸

How to set up and validate locally

Again, it's just a model so not much to play with. Still, you can check the spec factory and play around with the validators:

s = FactoryBot.create(:dependency_proxy_packages_setting, project: Project.first, maven_external_registry_username: 'test', maven_external_registry_password: '7357', maven_external_registry_url: "http://test.maven")

s.maven_external_registry_username
=> "test"

s.maven_external_registry_password
=> "7357"

s.destroy!

s = FactoryBot.create(:dependency_proxy_packages_setting, project: Project.first, maven_external_registry_url: "kaboom!")
ActiveRecord::RecordInvalid: Validation failed: Maven external registry url is blocked: Only allowed schemes are http, https

🏎 MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

💾 Database review

Migration up

main: == [advisory_lock_connection] object_id: 277200, pg_backend_pid: 38756
main: == 20230516125656 CreateDependencyProxyPackagesSettings: migrating ============
main: -- transaction_open?()
main:    -> 0.0001s
main: -- create_table(:dependency_proxy_packages_settings, {:id=>false, :if_not_exists=>true})
main: -- quote_column_name(:maven_external_registry_url)
main:    -> 0.0000s
main:    -> 0.0346s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings\nADD CONSTRAINT check_353c7ecafd\nCHECK ( octet_length(encrypted_maven_external_registry_username) <= 1020 )\nNOT VALID;\n")
main:    -> 0.0004s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0001s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings VALIDATE CONSTRAINT check_353c7ecafd;")
main:    -> 0.0002s
main: -- execute("RESET statement_timeout")
main:    -> 0.0002s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings\nADD CONSTRAINT check_fd5def68ba\nCHECK ( octet_length(encrypted_maven_external_registry_username_iv) <= 1020 )\nNOT VALID;\n")
main:    -> 0.0002s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings VALIDATE CONSTRAINT check_fd5def68ba;")
main:    -> 0.0002s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings\nADD CONSTRAINT check_c6f700648d\nCHECK ( octet_length(encrypted_maven_external_registry_password) <= 1020 )\nNOT VALID;\n")
main:    -> 0.0002s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings VALIDATE CONSTRAINT check_c6f700648d;")
main:    -> 0.0002s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings\nADD CONSTRAINT check_cdf5f9a434\nCHECK ( octet_length(encrypted_maven_external_registry_password_iv) <= 1020 )\nNOT VALID;\n")
main:    -> 0.0005s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings VALIDATE CONSTRAINT check_cdf5f9a434;")
main:    -> 0.0002s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- transaction_open?()
main:    -> 0.0000s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings\nADD CONSTRAINT check_14a2818907\nCHECK ( (num_nulls(encrypted_maven_external_registry_username, encrypted_maven_external_registry_password) = 0)\n       OR\n       (num_nulls(encrypted_maven_external_registry_username, encrypted_maven_external_registry_password) = 2) )\nNOT VALID;\n")
main:    -> 0.0005s
main: -- execute("ALTER TABLE dependency_proxy_packages_settings VALIDATE CONSTRAINT check_14a2818907;")
main:    -> 0.0002s
main: == 20230516125656 CreateDependencyProxyPackagesSettings: migrated (0.1429s) ===

main: == [advisory_lock_connection] object_id: 277200, pg_backend_pid: 38756

Migration down

main: == [advisory_lock_connection] object_id: 277260, pg_backend_pid: 38369
main: == 20230516125656 CreateDependencyProxyPackagesSettings: reverting ============
main: -- drop_table(:dependency_proxy_packages_settings)
main:    -> 0.0086s
main: == 20230516125656 CreateDependencyProxyPackagesSettings: reverted (0.0378s) ===

main: == [advisory_lock_connection] object_id: 277260, pg_backend_pid: 38369
Edited by David Fernandez

Merge request reports