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.
- We're starting with maven packages first so only 3 settings need to be saved:
- 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:
- use
attr_encrypted
for now to unblock further work. - once rails 7.0 lands on GitLab, switch to AR encryption. I opened Dependency proxy for packages: update how the c... (#413034) for this.
- We will do this before rolling out the 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.
-
I have evaluated the MR acceptance checklist for this MR.
💾 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