From 8981d93023ea8b2b442a0afded6e202d81ab1a2e Mon Sep 17 00:00:00 2001 From: Ryan Wold <64987852+ryanwoldatwork@users.noreply.github.com> Date: Mon, 15 May 2023 11:21:29 -0700 Subject: [PATCH] refactor submissions table and tags * update api key * ensure registry records can be published if they don't have a contact (for legacy records) --- .env.sample | 6 + .../admin/digital_products_controller.rb | 7 +- .../digital_service_accounts_controller.rb | 9 +- app/models/user.rb | 2 + .../submissions/_responses_by_status.html.erb | 3 - .../admin/submissions/_submissions.html.erb | 2 +- .../components/_responses_by_status.html.erb | 121 ++++++++---------- config/environments/development.rb | 5 + config/environments/production.rb | 5 + config/environments/staging.rb | 5 + config/environments/test.rb | 5 + db/migrate/20230511190351_user_api_keys.rb | 9 ++ db/schema.rb | 2 +- spec/features/admin/digital_products_spec.rb | 14 ++ .../admin/digital_service_accounts_spec.rb | 14 ++ 15 files changed, 133 insertions(+), 76 deletions(-) create mode 100644 db/migrate/20230511190351_user_api_keys.rb diff --git a/.env.sample b/.env.sample index e4c08d894..c0e0bbbd5 100644 --- a/.env.sample +++ b/.env.sample @@ -39,6 +39,12 @@ LOGIN_GOV_OPENID_CERT_URL='https://idp.int.identitysandbox.gov/api/openid_connec # For New Relic NEW_RELIC_KEY=YOUR-NEW-RELIC-KEY-HERE +# See: rails db:encryption:init +# Also see: rails credentials:help +RAILS_ACTIVE_RECORD_PRIMARY_KEY= +RAILS_ACTIVE_RECORD_DETERMINISTIC_KEY= +RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT= + # Redis cache store REDIS_URL=redis://localhost:6379/1 diff --git a/app/controllers/admin/digital_products_controller.rb b/app/controllers/admin/digital_products_controller.rb index ab58ad8a4..a446d51d8 100644 --- a/app/controllers/admin/digital_products_controller.rb +++ b/app/controllers/admin/digital_products_controller.rb @@ -163,11 +163,16 @@ def publish if @digital_product.publish! Event.log_event(Event.names[:digital_product_published], 'Digital Product', @digital_product.id, "Digital Product #{@digital_product.name} published at #{DateTime.now}", current_user.id) + @account_contacts = [] + if @digital_product.roles.first + @account_contacts = @digital_product.roles.first.users.collect(&:email) + end + UserMailer.notification( title: 'Digital Product has been published', body: "Digital Product #{@digital_product.name} published at #{DateTime.now} by #{current_user.email}", path: admin_digital_product_url(@digital_product), - emails: (User.admins.collect(&:email) + User.registry_managers.collect(&:email) + @digital_product.roles.first.users.collect(&:email)).uniq, + emails: (User.admins.collect(&:email) + User.registry_managers.collect(&:email) + @account_contacts).uniq, ).deliver_later redirect_to admin_digital_product_path(@digital_product), notice: "Digital Product #{@digital_product.name} was published." diff --git a/app/controllers/admin/digital_service_accounts_controller.rb b/app/controllers/admin/digital_service_accounts_controller.rb index 7666bc10a..b9602c81b 100644 --- a/app/controllers/admin/digital_service_accounts_controller.rb +++ b/app/controllers/admin/digital_service_accounts_controller.rb @@ -191,12 +191,17 @@ def publish 'Digital Service Account', @digital_service_account.id, "Digital Service Account #{@digital_service_account.name} published at #{DateTime.now}", current_user.id) - + + @account_contacts = [] + if @digital_service_account.roles.first + @account_contacts = @digital_service_account.roles.first.users.collect(&:email) + end + UserMailer.notification( title: 'Digital Service Account was published', body: "Digital Service Account #{@digital_service_account.name} published at #{DateTime.now} by #{current_user.email}", path: admin_digital_service_account_url(@digital_service_account), - emails: (User.admins.collect(&:email) + User.registry_managers.collect(&:email) + @digital_service_account.roles.first.users.collect(&:email)).uniq, + emails: (User.admins.collect(&:email) + User.registry_managers.collect(&:email) + @account_contacts).uniq ).deliver_later redirect_to admin_digital_service_account_path(@digital_service_account), notice: "Digital Service Account #{@digital_service_account.name} was published." diff --git a/app/models/user.rb b/app/models/user.rb index 168ae93f1..494c89d31 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class User < ApplicationRecord + encrypts :api_key, deterministic: true + rolify # Include default devise modules. Others available are: # :lockable diff --git a/app/views/admin/submissions/_responses_by_status.html.erb b/app/views/admin/submissions/_responses_by_status.html.erb index 0f517eca1..49aad95d7 100644 --- a/app/views/admin/submissions/_responses_by_status.html.erb +++ b/app/views/admin/submissions/_responses_by_status.html.erb @@ -1,4 +1 @@ - <%= render 'components/responses_by_status', submissions: form.submissions %> diff --git a/app/views/admin/submissions/_submissions.html.erb b/app/views/admin/submissions/_submissions.html.erb index 04eb5bd95..88abef26b 100644 --- a/app/views/admin/submissions/_submissions.html.erb +++ b/app/views/admin/submissions/_submissions.html.erb @@ -15,7 +15,7 @@ Filter by tag

- <% @tags.each do | tag | %> + <% @tags.uniq.each do | tag | %> <%= tag.name %> diff --git a/app/views/components/_responses_by_status.html.erb b/app/views/components/_responses_by_status.html.erb index 01d952401..9c362949f 100644 --- a/app/views/components/_responses_by_status.html.erb +++ b/app/views/components/_responses_by_status.html.erb @@ -1,70 +1,55 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + +
- - Total - - Received - - Acknowledged - - Dispatched - - Responded - - Flagged -
- Active - - <%= submissions.non_archived.size %> - - <%= submissions.non_archived.where(aasm_state: "received").size %> - - <%= submissions.non_archived.where(aasm_state: "acknowledged").size %> - - <%= submissions.non_archived.where(aasm_state: "dispatched").size %> - - <%= submissions.non_archived.where(aasm_state: "responded").size %> - - <%= submissions.non_archived.where(flagged: true).size %> -
- Archived - - <%= submissions.archived.size %> - - <%= submissions.archived.where(aasm_state: "received").size %> - - <%= submissions.archived.where(aasm_state: "acknowledged").size %> - - <%= submissions.archived.where(aasm_state: "dispatched").size %> - - <%= submissions.archived.where(aasm_state: "responded").size %> - - <%= submissions.archived.where(flagged: true).size %> -
+ Received + + Acknowledged + + Dispatched + + Responded + + Archived + + Flagged + + Total +
+ <%= submissions.select { |s| s.aasm_state == "received" }.size %> + + <%= submissions.select { |s| s.acknowledged? }.size %> + + <%= submissions.select { |s| s.dispatched? }.size %> + + <%= submissions.select { |s| s.responded? }.size %> + + <%= submissions.archived.size %> + + <%= submissions.where(flagged: true).size %> + + <%= submissions.size %> +
diff --git a/config/environments/development.rb b/config/environments/development.rb index c5788110f..9b93f5850 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -100,4 +100,9 @@ # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true + + config.active_record.encryption.primary_key = ENV.fetch("RAILS_ACTIVE_RECORD_PRIMARY_KEY") + config.active_record.encryption.deterministic_key = ENV.fetch("RAILS_ACTIVE_RECORD_DETERMINISTIC_KEY") + config.active_record.encryption.key_derivation_salt = ENV.fetch("RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT") + config.active_record.encryption.support_unencrypted_data = true end diff --git a/config/environments/production.rb b/config/environments/production.rb index 4823e7194..7a10bd274 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -137,4 +137,9 @@ # config.active_record.database_selector = { delay: 2.seconds } # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session + + config.active_record.encryption.primary_key = ENV.fetch("RAILS_ACTIVE_RECORD_PRIMARY_KEY") + config.active_record.encryption.deterministic_key = ENV.fetch("RAILS_ACTIVE_RECORD_DETERMINISTIC_KEY") + config.active_record.encryption.key_derivation_salt = ENV.fetch("RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT") + config.active_record.encryption.support_unencrypted_data = true end diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 9be4a93de..bc635dc43 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -111,4 +111,9 @@ config.action_mailer.delivery_method = :ses config.action_mailer.perform_deliveries = true + + config.active_record.encryption.primary_key = ENV.fetch("RAILS_ACTIVE_RECORD_PRIMARY_KEY") + config.active_record.encryption.deterministic_key = ENV.fetch("RAILS_ACTIVE_RECORD_DETERMINISTIC_KEY") + config.active_record.encryption.key_derivation_salt = ENV.fetch("RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT") + config.active_record.encryption.support_unencrypted_data = true end diff --git a/config/environments/test.rb b/config/environments/test.rb index 1c16615ff..8fd4c86ae 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -73,4 +73,9 @@ # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true + + config.active_record.encryption.primary_key = ENV.fetch("RAILS_ACTIVE_RECORD_PRIMARY_KEY") + config.active_record.encryption.deterministic_key = ENV.fetch("RAILS_ACTIVE_RECORD_DETERMINISTIC_KEY") + config.active_record.encryption.key_derivation_salt = ENV.fetch("RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT") + config.active_record.encryption.support_unencrypted_data = true end diff --git a/db/migrate/20230511190351_user_api_keys.rb b/db/migrate/20230511190351_user_api_keys.rb new file mode 100644 index 000000000..8bb739191 --- /dev/null +++ b/db/migrate/20230511190351_user_api_keys.rb @@ -0,0 +1,9 @@ +class UserApiKeys < ActiveRecord::Migration[7.0] + def change + User.where("api_key IS NOT NULL").each do |user| + @existing_key = user.api_key + user.update(api_key: "") + user.update(api_key: @existing_key) + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 584d6eee5..4f2282ee8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_03_23_222925) do +ActiveRecord::Schema[7.0].define(version: 2023_05_11_190351) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/features/admin/digital_products_spec.rb b/spec/features/admin/digital_products_spec.rb index bef6b94af..5b332cc6d 100644 --- a/spec/features/admin/digital_products_spec.rb +++ b/spec/features/admin/digital_products_spec.rb @@ -72,6 +72,20 @@ end end + describe '#publish' do + let!(:submitted_digital_product) { FactoryBot.create(:digital_product, name: 'Test1', service: 'Gov Mobile App', aasm_state: 'submitted') } + + before do + visit admin_digital_product_path(submitted_digital_product) + end + + it 'can publish digital product record' do + expect(page).to have_content('Mobile App') + click_on("Publish") + expect(page).to have_content("Digital Product #{digital_product.name} was published.") + end + end + describe '#delete' do before do visit admin_digital_product_path(digital_product) diff --git a/spec/features/admin/digital_service_accounts_spec.rb b/spec/features/admin/digital_service_accounts_spec.rb index 0b7a06878..6ce5efa38 100644 --- a/spec/features/admin/digital_service_accounts_spec.rb +++ b/spec/features/admin/digital_service_accounts_spec.rb @@ -236,6 +236,20 @@ end end + describe '#publish' do + let(:digital_service_account) { FactoryBot.create(:digital_service_account, aasm_state: :submitted) } + + before do + visit admin_digital_service_account_path(digital_service_account) + end + + it 'can publish digital service account' do + expect(page).to have_content('Social Media Account') + click_on("Publish") + expect(page).to have_content("Digital Service Account #{digital_service_account.name} was published.") + end + end + describe '#delete' do let(:digital_service_account) { FactoryBot.create(:digital_service_account) }