diff options
author | Arturo Herrero <arturo.herrero@gmail.com> | 2019-11-05 13:08:31 +0300 |
---|---|---|
committer | Arturo Herrero <arturo.herrero@gmail.com> | 2019-11-21 16:09:26 +0300 |
commit | 03ae75179400ea3e68e9ed491eaad316cc5b631c (patch) | |
tree | bbdb0c997e6e2097784a88ef198dbe9cf3696a60 /spec | |
parent | 89b093996a9c40b7df15f208140ace578073fa42 (diff) |
Encrypt application setting tokens
This is the plan to encrypt the plaintext tokens:
First release (this commit):
1. Create new encrypted fields in the database.
2. Start populating new encrypted fields, read the encrypted fields or
fallback to the plaintext fields.
3. Backfill the data removing the plaintext fields to the encrypted fields.
Second release:
4. Remove the virtual attribute (created in step 2).
5. Drop plaintext columns from the database (empty columns after step 3).
Diffstat (limited to 'spec')
-rw-r--r-- | spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb | 58 | ||||
-rw-r--r-- | spec/models/application_setting_spec.rb | 44 |
2 files changed, 102 insertions, 0 deletions
diff --git a/spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb b/spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb new file mode 100644 index 00000000000..6435e43f38c --- /dev/null +++ b/spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20191120115530_encrypt_plaintext_attributes_on_application_settings.rb') + +describe EncryptPlaintextAttributesOnApplicationSettings, :migration do + let(:migration) { described_class.new } + let(:application_settings) { table(:application_settings) } + let(:plaintext) { 'secret-token' } + + PLAINTEXT_ATTRIBUTES = %w[ + akismet_api_key + elasticsearch_aws_secret_access_key + recaptcha_private_key + recaptcha_site_key + slack_app_secret + slack_app_verification_token + ].freeze + + describe '#up' do + it 'encrypts token, saves it and removes plaintext token' do + application_setting = application_settings.create + application_setting.update_columns( + PLAINTEXT_ATTRIBUTES.each_with_object({}) do |plaintext_attribute, attributes| + attributes[plaintext_attribute] = plaintext + end + ) + + migration.up + + application_setting.reload + PLAINTEXT_ATTRIBUTES.each do |plaintext_attribute| + expect(application_setting[plaintext_attribute]).to be_nil + expect(application_setting["encrypted_#{plaintext_attribute}"]).not_to be_nil + expect(application_setting["encrypted_#{plaintext_attribute}_iv"]).not_to be_nil + end + end + end + + describe '#down' do + it 'decrypts encrypted token and saves it' do + application_setting = application_settings.create( + PLAINTEXT_ATTRIBUTES.each_with_object({}) do |plaintext_attribute, attributes| + attributes[plaintext_attribute] = plaintext + end + ) + + migration.down + + application_setting.reload + PLAINTEXT_ATTRIBUTES.each do |plaintext_attribute| + expect(application_setting[plaintext_attribute]).to eq(plaintext) + expect(application_setting["encrypted_#{plaintext_attribute}"]).to be_nil + expect(application_setting["encrypted_#{plaintext_attribute}_iv"]).to be_nil + end + end + end +end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index ba3b99f4421..7b1ebe586cd 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -15,6 +15,50 @@ describe ApplicationSetting do it { expect(setting.uuid).to be_present } it { expect(setting).to have_db_column(:auto_devops_enabled) } + context "with existing plaintext attributes" do + before do + setting.update_columns( + akismet_api_key: "akismet_api_key", + elasticsearch_aws_secret_access_key: "elasticsearch_aws_secret_access_key", + recaptcha_private_key: "recaptcha_private_key", + recaptcha_site_key: "recaptcha_site_key", + slack_app_secret: "slack_app_secret", + slack_app_verification_token: "slack_app_verification_token" + ) + end + + it "returns the attributes" do + expect(setting.akismet_api_key).to eq("akismet_api_key") + expect(setting.elasticsearch_aws_secret_access_key).to eq("elasticsearch_aws_secret_access_key") + expect(setting.recaptcha_private_key).to eq("recaptcha_private_key") + expect(setting.recaptcha_site_key).to eq("recaptcha_site_key") + expect(setting.slack_app_secret).to eq("slack_app_secret") + expect(setting.slack_app_verification_token).to eq("slack_app_verification_token") + end + end + + context "with encrypted attributes" do + before do + setting.update( + akismet_api_key: "akismet_api_key", + elasticsearch_aws_secret_access_key: "elasticsearch_aws_secret_access_key", + recaptcha_private_key: "recaptcha_private_key", + recaptcha_site_key: "recaptcha_site_key", + slack_app_secret: "slack_app_secret", + slack_app_verification_token: "slack_app_verification_token" + ) + end + + it "returns the attributes" do + expect(setting.akismet_api_key).to eq("akismet_api_key") + expect(setting.elasticsearch_aws_secret_access_key).to eq("elasticsearch_aws_secret_access_key") + expect(setting.recaptcha_private_key).to eq("recaptcha_private_key") + expect(setting.recaptcha_site_key).to eq("recaptcha_site_key") + expect(setting.slack_app_secret).to eq("slack_app_secret") + expect(setting.slack_app_verification_token).to eq("slack_app_verification_token") + end + end + describe 'validations' do let(:http) { 'http://example.com' } let(:https) { 'https://example.com' } |