Convert credit card validation data to hashes in database
What does this MR do and why?
- Resolves sub-task 1 of https://gitlab.com/gitlab-org/gitlab/-/issues/413525
- Create 4 columns,
last_digits_hash
,expiration_date_hash
,holder_name_hash
andnetwork_hash
to store the data we currently have in the Users::CreditCardValidation table as hashes instead of plain-text. - Create a background migration to convert plain-text data into hashes.
- Update
Users::CreditCardValidation
model to save hashed data when a record is created/updated - Update the
Users::UpsertCreditCardValidationService
to usesave
method to save records to the database, instead ofupsert
, sinceupsert
doesn't instantiate the model.
Screenshots or screen recordings
db:migrate
main: == 20230815072912 AddHashesToCreditCardValidations: migrating =================
main: -- transaction_open?()
main: -> 0.0000s
main: -- add_column(:user_credit_card_validations, :last_digits_hash, :text, {:if_not_exists=>true})
main: -> 0.0050s
main: -- add_column(:user_credit_card_validations, :holder_name_hash, :text, {:if_not_exists=>true})
main: -> 0.0030s
main: -- add_column(:user_credit_card_validations, :expiration_date_hash, :text, {:if_not_exists=>true})
main: -> 0.0031s
main: -- add_column(:user_credit_card_validations, :network_hash, :text, {:if_not_exists=>true})
main: -> 0.0028s
main: -- transaction_open?()
main: -> 0.0000s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE user_credit_card_validations\nADD CONSTRAINT check_f5c35b1a6e\nCHECK ( char_length(last_digits_hash) <= 44 )\nNOT VALID;\n")
main: -> 0.0011s
main: -- transaction_open?()
main: -> 0.0000s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE user_credit_card_validations\nADD CONSTRAINT check_aca7c2607c\nCHECK ( char_length(holder_name_hash) <= 44 )\nNOT VALID;\n")
main: -> 0.0010s
main: -- transaction_open?()
main: -> 0.0000s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE user_credit_card_validations\nADD CONSTRAINT check_83f1e2ace3\nCHECK ( char_length(expiration_date_hash) <= 44 )\nNOT VALID;\n")
main: -> 0.0009s
main: -- transaction_open?()
main: -> 0.0000s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE user_credit_card_validations\nADD CONSTRAINT check_7721e1961a\nCHECK ( char_length(network_hash) <= 44 )\nNOT VALID;\n")
main: -> 0.0008s
main: == 20230815072912 AddHashesToCreditCardValidations: migrated (0.0489s) ========
main: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: migrating =====
main: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: migrated (0.0535s)
main: == [advisory_lock_connection] object_id: 38187840, pg_backend_pid: 10170
ci: == [advisory_lock_connection] object_id: 38188100, pg_backend_pid: 10172
ci: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: migrating =====
ci: -- The migration is skipped since it modifies the schemas: [:gitlab_main].
ci: -- This database can only apply migrations in one of the following schemas: [:gitlab_ci, :gitlab_internal, :gitlab_shared].
ci: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: migrated (0.0230s)
db:rollback
main: == 20230815072912 AddHashesToCreditCardValidations: reverting =================
main: -- transaction_open?()
main: -> 0.0000s
main: -- remove_column(:user_credit_card_validations, :last_digits_hash, {:if_exists=>true})
main: -> 0.0033s
main: -- remove_column(:user_credit_card_validations, :holder_name_hash, {:if_exists=>true})
main: -> 0.0028s
main: -- remove_column(:user_credit_card_validations, :expiration_date_hash, {:if_exists=>true})
main: -> 0.0025s
main: -- remove_column(:user_credit_card_validations, :network_hash, {:if_exists=>true})
main: -> 0.0023s
main: == 20230815072912 AddHashesToCreditCardValidations: reverted (0.0186s) ========
main: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: reverting =====
main: == 20230821081603 QueueConvertCreditCardValidationDataToHashes: reverted (0.0516s)
Results of the db:gitlabcom-database-testing pipeline - !129350 (comment 1513858652)
How to set up and validate locally
- Run the migrations
- Create a credit card validation record in the rails console:
> Users::CreditCardValidation.create(user_id: 1, last_digits: 1111, credit_card_validated_at: Date.today, expiration_date: Date.today, holder_name: 'John Doe', network: 'Visa')
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.
Related to #413525
Edited by Hinam Mehra