From 2450f822a7bfc0b2402a84fe21fe19e0ff74584f Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Fri, 29 Mar 2024 11:33:42 -0500 Subject: [PATCH 01/17] Enable MutableConstants rubocop rule changelog: Internal, Performance, Freeze constants Co-authored-by: Zach Margolis --- .rubocop.yml | 5 +++++ app/components/alert_icon_component.rb | 2 +- app/controllers/idv/unavailable_controller.rb | 2 +- app/forms/idv/doc_pii_form.rb | 3 ++- app/jobs/get_usps_proofing_results_job.rb | 4 ++-- app/models/gpo_confirmation.rb | 2 +- app/services/doc_auth/error_generator.rb | 6 +++--- app/services/doc_auth/errors.rb | 2 +- app/services/doc_auth/response.rb | 2 +- app/services/doc_auth/selfie_concern.rb | 4 ++-- app/services/openid_connect_attribute_scoper.rb | 4 ++-- app/services/personal_key_formatter.rb | 3 ++- app/services/proofing/lexis_nexis/ddp/proofer.rb | 2 +- .../proofing/lexis_nexis/ddp/response_redacter.rb | 2 +- app/services/proofing/mock/ddp_mock_client.rb | 2 +- app/services/recaptcha_validator.rb | 4 ++-- app/services/service_provider_updater.rb | 2 +- config/initializers/rack_attack.rb | 4 ++-- lib/analytics_events_documenter.rb | 2 +- lib/deploy/activate.rb | 2 +- lib/identity_config.rb | 11 ++++++----- lib/idp/constants.rb | 2 +- lib/linters/analytics_event_name_linter.rb | 2 +- lib/linters/errors_add_linter.rb | 2 +- lib/linters/image_size_linter.rb | 2 +- lib/linters/redirect_back_linter.rb | 2 +- lib/session_encryptor.rb | 2 +- scripts/changelog_check.rb | 2 +- spec/i18n_spec.rb | 2 +- spec/support/features/doc_auth_helper.rb | 8 ++++---- spec/support/saml_auth_helper.rb | 2 ++ 31 files changed, 53 insertions(+), 43 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c04b6c3133b..0f64fb7301b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1428,3 +1428,8 @@ Style/WhileUntilDo: Style/YodaCondition: Enabled: true EnforcedStyle: forbid_for_all_comparison_operators + +Style/MutableConstant: + Enabled: true + # maybe? + # EnforcedStyle: strict diff --git a/app/components/alert_icon_component.rb b/app/components/alert_icon_component.rb index 74b146c6c83..c85c53db461 100644 --- a/app/components/alert_icon_component.rb +++ b/app/components/alert_icon_component.rb @@ -8,7 +8,7 @@ class AlertIconComponent < BaseComponent personal_key: 'status/personal-key.svg', info_question: 'status/info-question.svg', delete: 'status/delete.svg', - } + }.freeze DEFAULT_WIDTH = 88 DEFAULT_HEIGHT = 88 diff --git a/app/controllers/idv/unavailable_controller.rb b/app/controllers/idv/unavailable_controller.rb index a3fba15759b..2c546fdbd7c 100644 --- a/app/controllers/idv/unavailable_controller.rb +++ b/app/controllers/idv/unavailable_controller.rb @@ -2,7 +2,7 @@ module Idv class UnavailableController < ApplicationController - ALLOWED_FROM_LOCATIONS = [SignUp::RegistrationsController::CREATE_ACCOUNT] + ALLOWED_FROM_LOCATIONS = [SignUp::RegistrationsController::CREATE_ACCOUNT].freeze before_action :redirect_if_idv_available_and_from_create_account diff --git a/app/forms/idv/doc_pii_form.rb b/app/forms/idv/doc_pii_form.rb index b37946160a2..6b62481c092 100644 --- a/app/forms/idv/doc_pii_form.rb +++ b/app/forms/idv/doc_pii_form.rb @@ -78,7 +78,8 @@ def self.present_error(existing_errors) private - PII_ERROR_KEYS = %i[name dob address1 state zipcode jurisdiction state_id_number dob_min_age] + PII_ERROR_KEYS = %i[name dob address1 state zipcode jurisdiction state_id_number + dob_min_age].freeze attr_reader :pii_from_doc diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index d7222a3856a..05543772d32 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -11,10 +11,10 @@ class GetUspsProofingResultsJob < ApplicationJob SUPPORTED_ID_TYPES = [ "State driver's license", "State non-driver's identification card", - ] + ].freeze SUPPORTED_SECONDARY_ID_TYPES = [ 'Visual Inspection of Name and Address on Primary ID Match', - ] + ].freeze queue_as :long_running diff --git a/app/models/gpo_confirmation.rb b/app/models/gpo_confirmation.rb index 04a99d6e903..6d69cbca090 100644 --- a/app/models/gpo_confirmation.rb +++ b/app/models/gpo_confirmation.rb @@ -3,7 +3,7 @@ class GpoConfirmation < ApplicationRecord self.table_name = 'usps_confirmations' - ENTRY_ATTRIBUTES = %i[otp address1 city state zipcode] + ENTRY_ATTRIBUTES = %i[otp address1 city state zipcode].freeze ENTRY_ATTRIBUTES.each do |attr| define_method(:"entry_#{attr}") do entry[attr] diff --git a/app/services/doc_auth/error_generator.rb b/app/services/doc_auth/error_generator.rb index 74f56ec6e05..16e080d026b 100644 --- a/app/services/doc_auth/error_generator.rb +++ b/app/services/doc_auth/error_generator.rb @@ -11,7 +11,7 @@ def handle(response_info) class IdTypeErrorHandler < ErrorHandler SUPPORTED_ID_CLASSNAME = ['Identification Card', 'Drivers License'].freeze ACCEPTED_ISSUER_TYPES = [DocAuth::LexisNexis::IssuerTypes::STATE_OR_PROVINCE.name, - DocAuth::LexisNexis::IssuerTypes::UNKNOWN.name] + DocAuth::LexisNexis::IssuerTypes::UNKNOWN.name].freeze def handle(response_info) get_id_type_errors(response_info[:classification_info]) end @@ -121,7 +121,7 @@ def is_generic_selfie_error?(error) back: [Errors::MULTIPLE_BACK_ID_FAILURES], selfie: [Errors::SELFIE_FAILURE], hints: false, - } + }.freeze private @@ -252,7 +252,7 @@ class ErrorGenerator GENERAL = :general ACCEPTED_ISSUER_TYPES = [DocAuth::LexisNexis::IssuerTypes::STATE_OR_PROVINCE.name, - DocAuth::LexisNexis::IssuerTypes::UNKNOWN.name] + DocAuth::LexisNexis::IssuerTypes::UNKNOWN.name].freeze ERROR_KEYS = [ ID, diff --git a/app/services/doc_auth/errors.rb b/app/services/doc_auth/errors.rb index bf645210e15..fef2d141e80 100644 --- a/app/services/doc_auth/errors.rb +++ b/app/services/doc_auth/errors.rb @@ -123,7 +123,7 @@ module Errors SELFIE_FAILURE => { long_msg: SELFIE_FAILURE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_NOT_LIVE => { long_msg: SELFIE_NOT_LIVE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_POOR_QUALITY => { long_msg: SELFIE_POOR_QUALITY, field_msg: SELFIE_FAILURE, hints: false }, - } + }.freeze # rubocop:enable Layout/LineLength end end diff --git a/app/services/doc_auth/response.rb b/app/services/doc_auth/response.rb index 64e60231114..cee56818514 100644 --- a/app/services/doc_auth/response.rb +++ b/app/services/doc_auth/response.rb @@ -10,7 +10,7 @@ class Response ID_TYPE_SLUGS = { 'Identification Card' => 'state_id_card', 'Drivers License' => 'drivers_license', - } + }.freeze def initialize( success:, diff --git a/app/services/doc_auth/selfie_concern.rb b/app/services/doc_auth/selfie_concern.rb index 9cbc24fbada..0c518e0118c 100644 --- a/app/services/doc_auth/selfie_concern.rb +++ b/app/services/doc_auth/selfie_concern.rb @@ -33,13 +33,13 @@ def selfie_check_performed? private - SELFIE_PERFORMED_STATUSES = %i[success fail] + SELFIE_PERFORMED_STATUSES = %i[success fail].freeze ERROR_TEXTS = { success: 'Successful. Liveness: Live', not_live: 'Liveness: NotLive', poor_quality: 'Liveness: PoorQuality', - } + }.freeze # @param [Object] portrait_match_results trueid portait match info def get_portrait_error(portrait_match_results) diff --git a/app/services/openid_connect_attribute_scoper.rb b/app/services/openid_connect_attribute_scoper.rb index 81a869b230d..7956823c487 100644 --- a/app/services/openid_connect_attribute_scoper.rb +++ b/app/services/openid_connect_attribute_scoper.rb @@ -6,7 +6,7 @@ class OpenidConnectAttributeScoper x509:subject x509:issuer x509:presented - ] + ].freeze IAL2_SCOPES = %w[ address @@ -15,7 +15,7 @@ class OpenidConnectAttributeScoper profile:name profile:birthdate social_security_number - ] + ].freeze VALID_SCOPES = %w[ email diff --git a/app/services/personal_key_formatter.rb b/app/services/personal_key_formatter.rb index 8b80d962067..c8742dab4d5 100644 --- a/app/services/personal_key_formatter.rb +++ b/app/services/personal_key_formatter.rb @@ -7,6 +7,7 @@ class PersonalKeyFormatter VALID_WORD = "#{VALID_CHAR}{#{CHAR_COUNT}}".freeze REGEXP_STRING = "(?:#{VALID_WORD}([\\s\\-])?){#{WORD_COUNT - 1}}#{VALID_WORD}".freeze REGEXP = /\A#{REGEXP_STRING}\Z/o + CODE_LENGTH = CHAR_COUNT * WORD_COUNT + (WORD_COUNT - 1) def self.regexp REGEXP @@ -17,6 +18,6 @@ def self.regexp_string end def self.code_length - CHAR_COUNT * WORD_COUNT + (WORD_COUNT - 1) + CODE_LENGTH end end diff --git a/app/services/proofing/lexis_nexis/ddp/proofer.rb b/app/services/proofing/lexis_nexis/ddp/proofer.rb index 246c6957955..6b7d296c312 100644 --- a/app/services/proofing/lexis_nexis/ddp/proofer.rb +++ b/app/services/proofing/lexis_nexis/ddp/proofer.rb @@ -4,7 +4,7 @@ module Proofing module LexisNexis module Ddp class Proofer - VALID_REVIEW_STATUSES = %w[pass review reject] + VALID_REVIEW_STATUSES = %w[pass review reject].freeze attr_reader :config diff --git a/app/services/proofing/lexis_nexis/ddp/response_redacter.rb b/app/services/proofing/lexis_nexis/ddp/response_redacter.rb index 377f13e0b5b..fb9cda806d9 100644 --- a/app/services/proofing/lexis_nexis/ddp/response_redacter.rb +++ b/app/services/proofing/lexis_nexis/ddp/response_redacter.rb @@ -191,7 +191,7 @@ class ResponseRedacter true_ip_score true_ip_worst_score unknown_session - ] + ].freeze # @param [Hash, nil] parsed JSON response body def self.redact(hash) diff --git a/app/services/proofing/mock/ddp_mock_client.rb b/app/services/proofing/mock/ddp_mock_client.rb index 18282101261..772443a48b6 100644 --- a/app/services/proofing/mock/ddp_mock_client.rb +++ b/app/services/proofing/mock/ddp_mock_client.rb @@ -37,7 +37,7 @@ def stage 'proofing', 'lexis_nexis', 'ddp', - ) + ).freeze TRANSACTION_ID = 'ddp-mock-transaction-id-123' def initialize(response_fixture_file: 'successful_response.json') diff --git a/app/services/recaptcha_validator.rb b/app/services/recaptcha_validator.rb index 95769a31473..b9af5e24232 100644 --- a/app/services/recaptcha_validator.rb +++ b/app/services/recaptcha_validator.rb @@ -2,8 +2,8 @@ class RecaptchaValidator VERIFICATION_ENDPOINT = 'https://www.google.com/recaptcha/api/siteverify' - RESULT_ERRORS = ['missing-input-secret', 'invalid-input-secret'] - VALID_RECAPTCHA_VERSIONS = [2, 3] + RESULT_ERRORS = ['missing-input-secret', 'invalid-input-secret'].freeze + VALID_RECAPTCHA_VERSIONS = [2, 3].freeze attr_reader :recaptcha_version, :recaptcha_action, diff --git a/app/services/service_provider_updater.rb b/app/services/service_provider_updater.rb index f8bbab9effa..c3a9a8d6bc2 100644 --- a/app/services/service_provider_updater.rb +++ b/app/services/service_provider_updater.rb @@ -10,7 +10,7 @@ class ServiceProviderUpdater SP_IGNORED_ATTRIBUTES = %i[ cert - ] + ].freeze def run(service_provider = nil) if service_provider.present? diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 9c4ac5e881c..6afe9eb731d 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -9,8 +9,8 @@ class Attack end EMAIL_REGISTRATION_PATHS = ['/sign_up/enter_email', '/en/sign_up/enter_email', - '/es/sign_up/enter_email', '/fr/sign_up/enter_email'] - SIGN_IN_PATHS = ['/', '/en', '/es', '/fr'] + '/es/sign_up/enter_email', '/fr/sign_up/enter_email'].freeze + SIGN_IN_PATHS = ['/', '/en', '/es', '/fr'].freeze # If the app is behind a load balancer, `ip` will return the IP of the # load balancer instead of the actual IP the request came from, and since diff --git a/lib/analytics_events_documenter.rb b/lib/analytics_events_documenter.rb index a3b7ecf775d..09ccf8bcf77 100644 --- a/lib/analytics_events_documenter.rb +++ b/lib/analytics_events_documenter.rb @@ -15,7 +15,7 @@ class AnalyticsEventsDocumenter DOCUMENTATION_OPTIONAL_PARAMS = %w[ pii_like_keypaths - ] + ].freeze attr_reader :database_path, :class_name diff --git a/lib/deploy/activate.rb b/lib/deploy/activate.rb index a57feb4ea7d..ea256ff3bab 100644 --- a/lib/deploy/activate.rb +++ b/lib/deploy/activate.rb @@ -10,7 +10,7 @@ module Deploy class Activate FILES_TO_LINK = %w[agencies iaa_gtcs iaa_orders iaa_statuses integration_statuses integrations - partner_account_statuses partner_accounts service_providers] + partner_account_statuses partner_accounts service_providers].freeze attr_reader :logger, :s3_client diff --git a/lib/identity_config.rb b/lib/identity_config.rb index aaf25e09e66..3838f96ff60 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -7,7 +7,7 @@ class IdentityConfig GIT_TAG = `git tag --points-at HEAD`.chomp.split("\n").first GIT_BRANCH = `git rev-parse --abbrev-ref HEAD`.chomp - VENDOR_STATUS_OPTIONS = %i[operational partial_outage full_outage] + VENDOR_STATUS_OPTIONS = %i[operational partial_outage full_outage].freeze class << self attr_reader :store, :key_types, :unused_keys @@ -60,7 +60,7 @@ class << self Time.parse(value) # rubocop:enable Rails/TimeZone end, - } + }.freeze attr_reader :key_types @@ -81,7 +81,7 @@ def add(key, type: :string, allow_nil: false, enum: nil, options: {}) raise "unexpected #{key}: #{value}, expected one of #{enum}" end - @written_env[key] = converted_value + @written_env[key] = converted_value.freeze @written_env end @@ -510,8 +510,9 @@ def self.build_store(config_map) config.add(:weekly_auth_funnel_report_config, type: :json) config.add(:x509_presented_hash_attribute_requested_issuers, type: :json) - @key_types = config.key_types - @unused_keys = config_map.keys - config.written_env.keys + @key_types = config.key_types.freeze + @unused_keys = (config_map.keys - config.written_env.keys).freeze + config.written_env.freeze @store = RedactedStruct.new('IdentityConfig', *config.written_env.keys, keyword_init: true). new(**config.written_env) end diff --git a/lib/idp/constants.rb b/lib/idp/constants.rb index 78b043696f6..7c56c623e06 100644 --- a/lib/idp/constants.rb +++ b/lib/idp/constants.rb @@ -2,7 +2,7 @@ module Idp module Constants - AVAILABLE_LOCALES = %w[en es fr] + AVAILABLE_LOCALES = %w[en es fr].freeze UUID_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ KMS_LOG_FILENAME = 'kms.log' diff --git a/lib/linters/analytics_event_name_linter.rb b/lib/linters/analytics_event_name_linter.rb index 8bd9aa8f5d4..eed859cd3d4 100644 --- a/lib/linters/analytics_event_name_linter.rb +++ b/lib/linters/analytics_event_name_linter.rb @@ -4,7 +4,7 @@ module RuboCop module Cop module IdentityIdp class AnalyticsEventNameLinter < RuboCop::Cop::Cop - RESTRICT_ON_SEND = [:track_event] + RESTRICT_ON_SEND = [:track_event].freeze # DO NOT ADD TO THIS LIST OR YOU WILL MAKE A KITTEN CRY! LEGACY_EVENT_NAMES = %w[ diff --git a/lib/linters/errors_add_linter.rb b/lib/linters/errors_add_linter.rb index a6298430c40..3c36112fe4d 100644 --- a/lib/linters/errors_add_linter.rb +++ b/lib/linters/errors_add_linter.rb @@ -17,7 +17,7 @@ module IdentityIdp class ErrorsAddLinter < RuboCop::Cop::Cop MSG = 'Please set a unique key for this error' - RESTRICT_ON_SEND = [:add] + RESTRICT_ON_SEND = [:add].freeze def_node_matcher :errors_add_match?, <<~PATTERN (send (send nil? :errors) :add $...) diff --git a/lib/linters/image_size_linter.rb b/lib/linters/image_size_linter.rb index d5be254c484..b5f37076489 100644 --- a/lib/linters/image_size_linter.rb +++ b/lib/linters/image_size_linter.rb @@ -18,7 +18,7 @@ module IdentityIdp class ImageSizeLinter < RuboCop::Cop::Cop MSG = 'Assign width and height to images' - RESTRICT_ON_SEND = [:image_tag] + RESTRICT_ON_SEND = [:image_tag].freeze def on_send(node) add_offense(node, location: :expression) if !valid?(node) diff --git a/lib/linters/redirect_back_linter.rb b/lib/linters/redirect_back_linter.rb index 81fea5c0eca..cc756ebd54d 100644 --- a/lib/linters/redirect_back_linter.rb +++ b/lib/linters/redirect_back_linter.rb @@ -19,7 +19,7 @@ module IdentityIdp class RedirectBackLinter < RuboCop::Cop::Cop MSG = 'Please set a fallback_location and the allow_other_host parameter to false' - RESTRICT_ON_SEND = [:redirect_back] + RESTRICT_ON_SEND = [:redirect_back].freeze def_node_matcher :redirect_back_matcher, <<~PATTERN (send nil? :redirect_back $...) diff --git a/lib/session_encryptor.rb b/lib/session_encryptor.rb index 919c06475d3..3966d830682 100644 --- a/lib/session_encryptor.rb +++ b/lib/session_encryptor.rb @@ -30,7 +30,7 @@ class SensitiveValueError < StandardError; end ['flash', 'flashes', 'personal_key'], ['flash', 'flashes', 'email'], ['email'], - ] + ].freeze SENSITIVE_DEFAULT_FIELDS = Idp::Constants::MOCK_IDV_APPLICANT.slice( :last_name, diff --git a/scripts/changelog_check.rb b/scripts/changelog_check.rb index 4d5cd9e5a6d..204e1924d57 100755 --- a/scripts/changelog_check.rb +++ b/scripts/changelog_check.rb @@ -11,7 +11,7 @@ 'Bug Fixes', 'Internal', 'Upcoming Features', -] +].freeze MAX_CATEGORY_DISTANCE = 3 SKIP_CHANGELOG_MESSAGE = '[skip changelog]' DEPENDABOT_COMMIT_MESSAGE = 'Signed-off-by: dependabot[bot] ' diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb index 34f4dedeb6b..cd99f9d23de 100644 --- a/spec/i18n_spec.rb +++ b/spec/i18n_spec.rb @@ -6,7 +6,7 @@ # List of keys allowed to contain different interpolation arguments across locales ALLOWED_INTERPOLATION_MISMATCH_KEYS = [ 'time.formats.event_timestamp_js', -] +].freeze # A set of patterns which are expected to only occur within specific locales. This is an imperfect # solution based on current content, intended to help prevent accidents when adding new translated diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb index 3ef2fb5377e..134774a4e99 100644 --- a/spec/support/features/doc_auth_helper.rb +++ b/spec/support/features/doc_auth_helper.rb @@ -8,10 +8,10 @@ module DocAuthHelper include UserAgentHelper GOOD_SSN = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] - GOOD_SSN_MASKED = '9**-**-***4' - SAMPLE_TMX_SUMMARY_REASON_CODE = { tmx_summary_reason_code: ['Identity_Negative_History'] } - SSN_THAT_FAILS_RESOLUTION = '123-45-6666' - SSN_THAT_RAISES_EXCEPTION = '000-00-0000' + GOOD_SSN_MASKED = '9**-**-***4'.freeze + SAMPLE_TMX_SUMMARY_REASON_CODE = { tmx_summary_reason_code: ['Identity_Negative_History'] }.freeze + SSN_THAT_FAILS_RESOLUTION = '123-45-6666'.freeze + SSN_THAT_RAISES_EXCEPTION = '000-00-0000'.freeze def clear_and_fill_in(field_name, text) fill_in field_name, with: '' diff --git a/spec/support/saml_auth_helper.rb b/spec/support/saml_auth_helper.rb index a59b36d44ec..8db5adbbd2b 100644 --- a/spec/support/saml_auth_helper.rb +++ b/spec/support/saml_auth_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'saml_idp_constants' ## GET /api/saml/auth helper methods From d1a500de48ae05a59567ead06d506d6f0f7a6f02 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Fri, 29 Mar 2024 11:33:55 -0500 Subject: [PATCH 02/17] update rubocop --- Gemfile | 2 +- Gemfile.lock | 14 +++++++------- .../options_controller_spec.rb | 4 ++-- spec/features/account_connected_apps_spec.rb | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index c89b14189e1..ee8fd4bdcbb 100644 --- a/Gemfile +++ b/Gemfile @@ -115,7 +115,7 @@ group :development, :test do gem 'psych' gem 'rspec', '~> 3.12.0' gem 'rspec-rails', '~> 6.0' - gem 'rubocop', '~> 1.59.0', require: false + gem 'rubocop', '~> 1.62.0', require: false gem 'rubocop-performance', '~> 1.20.2', require: false gem 'rubocop-rails', '>= 2.5.2', require: false gem 'rubocop-rspec', require: false diff --git a/Gemfile.lock b/Gemfile.lock index d0258b2095f..4b07a48e50b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -456,7 +456,7 @@ GEM openssl (> 2.0, < 3.1) orm_adapter (0.5.0) parallel (1.24.0) - parser (3.3.0.0) + parser (3.3.0.5) ast (~> 2.4.1) racc pg (1.5.4) @@ -611,19 +611,19 @@ GEM rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.59.0) + rubocop (1.62.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) + rubocop-ast (1.31.2) + parser (>= 3.3.0.4) rubocop-capybara (2.19.0) rubocop (~> 1.41) rubocop-factory_bot (2.24.0) @@ -842,7 +842,7 @@ DEPENDENCIES rspec-rails (~> 6.0) rspec-retry rspec_junit_formatter - rubocop (~> 1.59.0) + rubocop (~> 1.62.0) rubocop-performance (~> 1.20.2) rubocop-rails (>= 2.5.2) rubocop-rspec diff --git a/spec/controllers/two_factor_authentication/options_controller_spec.rb b/spec/controllers/two_factor_authentication/options_controller_spec.rb index ca715171b2a..6159c46e7ef 100644 --- a/spec/controllers/two_factor_authentication/options_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/options_controller_spec.rb @@ -27,7 +27,7 @@ it 'redirects to login_two_factor_url if user selects sms' do post :create, params: { two_factor_options_form: { selection: 'sms' } } - expect(response).to redirect_to otp_send_url( \ + expect(response).to redirect_to otp_send_url( otp_delivery_selection_form: { otp_delivery_preference: 'sms' }, ) end @@ -35,7 +35,7 @@ it 'redirects to login_two_factor_url if user selects voice' do post :create, params: { two_factor_options_form: { selection: 'voice' } } - expect(response).to redirect_to otp_send_url( \ + expect(response).to redirect_to otp_send_url( otp_delivery_selection_form: { otp_delivery_preference: 'voice' }, ) end diff --git a/spec/features/account_connected_apps_spec.rb b/spec/features/account_connected_apps_spec.rb index f4ac013270c..ff8581a4ea3 100644 --- a/spec/features/account_connected_apps_spec.rb +++ b/spec/features/account_connected_apps_spec.rb @@ -42,13 +42,13 @@ ) expect(page).to_not have_link(identity_without_link.display_name) - expect(page).to have_content( \ + expect(page).to have_content( t( 'event_types.authenticated_at_html', service_provider_link_html: identity_with_link.display_name, ), ) - expect(page).to have_link( \ + expect(page).to have_link( identity_with_link.display_name, href: 'http://localhost:3000' ) From 95e6385b31e15b4d17e058d7c2bdd32abee3ec77 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Fri, 29 Mar 2024 12:35:27 -0500 Subject: [PATCH 03/17] enable strict style --- .rubocop.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0f64fb7301b..96686cf9fc9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1218,6 +1218,10 @@ Style/MultilineMemoization: Style/MultilineWhenThen: Enabled: true +Style/MutableConstant: + Enabled: true + EnforcedStyle: strict + Style/NegatedWhile: Enabled: true @@ -1428,8 +1432,3 @@ Style/WhileUntilDo: Style/YodaCondition: Enabled: true EnforcedStyle: forbid_for_all_comparison_operators - -Style/MutableConstant: - Enabled: true - # maybe? - # EnforcedStyle: strict From cc88fd5c5bf48792cf1d5047f33802ee0803e8f5 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Fri, 29 Mar 2024 14:47:15 -0500 Subject: [PATCH 04/17] Convert SELFIE_GENERAL_FAILURE_ERROR to method because it is mutated --- app/services/doc_auth/error_generator.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/services/doc_auth/error_generator.rb b/app/services/doc_auth/error_generator.rb index 16e080d026b..89dacadb736 100644 --- a/app/services/doc_auth/error_generator.rb +++ b/app/services/doc_auth/error_generator.rb @@ -114,14 +114,15 @@ def is_generic_selfie_error?(error) error == Errors::SELFIE_FAILURE end - SELFIE_GENERAL_FAILURE_ERROR = + def selfie_general_failure_error { general: [Errors::SELFIE_FAILURE], front: [Errors::MULTIPLE_FRONT_ID_FAILURES], back: [Errors::MULTIPLE_BACK_ID_FAILURES], selfie: [Errors::SELFIE_FAILURE], hints: false, - }.freeze + } + end private @@ -317,7 +318,7 @@ def generate_doc_auth_errors(response_info) # if selfie itself is ok, but we have selfie related error if selfie_error_handler.is_generic_selfie_error?(selfie_error) - return SelfieErrorHandler::SELFIE_GENERAL_FAILURE_ERROR + return selfie_error_handler.selfie_general_failure_error end # other vendor response detail error From b82a8b07f13a89d691ad6414213104626531a1aa Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Fri, 29 Mar 2024 16:45:55 -0500 Subject: [PATCH 05/17] stricter freeze --- .../one_time_code_input_component.rb | 2 +- app/components/spinner_button_component.rb | 2 +- .../analytics_events_controller.rb | 2 +- .../concerns/two_factor_authenticatable.rb | 2 +- app/controllers/idv/please_call_controller.rb | 2 +- app/forms/openid_connect_token_form.rb | 2 +- app/jobs/get_usps_proofing_results_job.rb | 4 +-- app/models/service_provider_identity.rb | 2 +- app/presenters/account_show_presenter.rb | 2 +- .../in_person/ready_to_verify_presenter.rb | 2 +- .../verification_results_email_presenter.rb | 2 +- app/services/browser_cache.rb | 2 ++ app/services/doc_auth/lexis_nexis/config.rb | 2 +- app/services/doc_auth/mock/config.rb | 2 +- .../document_capture_session_result.rb | 2 +- .../encryption/contextless_kms_client.rb | 2 +- .../encryption/encryptors/pii_encryptor.rb | 2 +- app/services/encryption/kms_client.rb | 2 +- app/services/encryption/password_verifier.rb | 2 +- .../encryption/regional_ciphertext_pair.rb | 2 +- .../encryption/uak_password_verifier.rb | 2 +- .../openid_connect_attribute_scoper.rb | 10 +++---- app/services/personal_key_formatter.rb | 4 +-- app/services/phone_number_capabilities.rb | 4 +-- app/services/pii/attributes.rb | 2 +- app/services/proofing/aamva/proofer.rb | 2 +- app/services/proofing/lexis_nexis/config.rb | 2 +- app/services/request_password_reset.rb | 2 +- .../usps_in_person_proofing/proofer.rb | 2 +- app/services/vot/component_value.rb | 2 +- app/services/vot/legacy_component_values.rb | 26 +++++++++--------- app/services/vot/parser.rb | 2 +- .../vot/supported_component_values.rb | 14 +++++----- app/validators/form_password_validator.rb | 2 +- config/initializers/01_redis.rb | 4 +-- config/initializers/ab_tests.rb | 6 ++--- config/initializers/rack_attack.rb | 2 +- config/initializers/rack_timeout.rb | 4 +-- lib/identity_config.rb | 6 ++--- lib/pwned_password_downloader.rb | 2 +- lib/saml_idp_constants.rb | 2 +- lib/session_encryptor.rb | 2 +- lib/telephony/pinpoint/sms_sender.rb | 2 +- lib/telephony/pinpoint/voice_sender.rb | 2 +- spec/spec_helper.rb | 2 +- spec/support/fake_analytics.rb | 4 +-- spec/support/features/doc_auth_helper.rb | 2 +- spec/support/features/in_person_helper.rb | 27 ++++++++++--------- 48 files changed, 94 insertions(+), 91 deletions(-) diff --git a/app/components/one_time_code_input_component.rb b/app/components/one_time_code_input_component.rb index a0bbbc2c57f..a3247b49c19 100644 --- a/app/components/one_time_code_input_component.rb +++ b/app/components/one_time_code_input_component.rb @@ -16,7 +16,7 @@ class OneTimeCodeInputComponent < BaseComponent alias_method :autofocus?, :autofocus # @see https://tc39.es/ecma262/#prod-SyntaxCharacter - JS_REGEXP_SYNTAX_CHARACTER = Regexp.union(%w[^ $ \ . * + ? ( ) [ ] { } |]) + JS_REGEXP_SYNTAX_CHARACTER = Regexp.union(%w[^ $ \ . * + ? ( ) [ ] { } |]).freeze # @param [FormBuilder] form Form builder instance. # @param [Symbol] name Field name. Defaults to `:code`. diff --git a/app/components/spinner_button_component.rb b/app/components/spinner_button_component.rb index 64beda14bb8..b536f5c92f6 100644 --- a/app/components/spinner_button_component.rb +++ b/app/components/spinner_button_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class SpinnerButtonComponent < BaseComponent - DEFAULT_LONG_WAIT_DURATION = 15.seconds + DEFAULT_LONG_WAIT_DURATION = 15.seconds.freeze attr_reader :action_message, :button_options, diff --git a/app/controllers/analytics_events_controller.rb b/app/controllers/analytics_events_controller.rb index fb24dd24e01..55a2070d69d 100644 --- a/app/controllers/analytics_events_controller.rb +++ b/app/controllers/analytics_events_controller.rb @@ -6,7 +6,7 @@ class AnalyticsEventsController < ApplicationController prepend_before_action :skip_session_expiration skip_before_action :disable_caching - JSON_FILE = Rails.public_path.join('api', '_analytics-events.json') + JSON_FILE = Rails.public_path.join('api', '_analytics-events.json').freeze def index if File.exist?(JSON_FILE) diff --git a/app/controllers/concerns/two_factor_authenticatable.rb b/app/controllers/concerns/two_factor_authenticatable.rb index 90b46dbe4e0..31ae84c059c 100644 --- a/app/controllers/concerns/two_factor_authenticatable.rb +++ b/app/controllers/concerns/two_factor_authenticatable.rb @@ -9,7 +9,7 @@ module TwoFactorAuthenticatable DIRECT_OTP_LENGTH = 6 PROOFING_DIRECT_OTP_LENGTH = 6 ALLOWED_OTP_DRIFT_SECONDS = 30 - DIRECT_OTP_VALID_FOR_MINUTES = IdentityConfig.store.otp_valid_for + DIRECT_OTP_VALID_FOR_MINUTES = IdentityConfig.store.otp_valid_for.freeze DIRECT_OTP_VALID_FOR_SECONDS = DIRECT_OTP_VALID_FOR_MINUTES * 60 REMEMBER_2FA_COOKIE = 'remember_tfa' diff --git a/app/controllers/idv/please_call_controller.rb b/app/controllers/idv/please_call_controller.rb index 5b3eb66be19..00c027b2cb1 100644 --- a/app/controllers/idv/please_call_controller.rb +++ b/app/controllers/idv/please_call_controller.rb @@ -9,7 +9,7 @@ class PleaseCallController < ApplicationController before_action :handle_fraud_rejection before_action :confirm_fraud_pending - FRAUD_REVIEW_CONTACT_WITHIN_DAYS = 14.days + FRAUD_REVIEW_CONTACT_WITHIN_DAYS = 14.days.freeze def show analytics.idv_please_call_visited diff --git a/app/forms/openid_connect_token_form.rb b/app/forms/openid_connect_token_form.rb index d9af0890798..404887ba55e 100644 --- a/app/forms/openid_connect_token_form.rb +++ b/app/forms/openid_connect_token_form.rb @@ -5,7 +5,7 @@ class OpenidConnectTokenForm include ActionView::Helpers::TranslationHelper include Rails.application.routes.url_helpers - ISSUED_AT_LEEWAY_SECONDS = 10.seconds.to_i + ISSUED_AT_LEEWAY_SECONDS = 10.seconds.to_i.freeze ATTRS = %i[ client_assertion diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 05543772d32..d0322525ad8 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -57,8 +57,8 @@ def perform(_now) attr_accessor :enrollment_outcomes DEFAULT_EMAIL_DELAY_IN_HOURS = 1 - REQUEST_DELAY_IN_SECONDS = IdentityConfig.store. - get_usps_proofing_results_job_request_delay_milliseconds / MILLISECONDS_PER_SECOND + REQUEST_DELAY_IN_SECONDS = (IdentityConfig.store. + get_usps_proofing_results_job_request_delay_milliseconds / MILLISECONDS_PER_SECOND).freeze def proofer @proofer ||= UspsInPersonProofing::EnrollmentHelper.usps_proofer diff --git a/app/models/service_provider_identity.rb b/app/models/service_provider_identity.rb index 84dcc6d148a..2c1bb0272b4 100644 --- a/app/models/service_provider_identity.rb +++ b/app/models/service_provider_identity.rb @@ -18,7 +18,7 @@ class ServiceProviderIdentity < ApplicationRecord scope :not_deleted, -> { where(deleted_at: nil) } - CONSENT_EXPIRATION = 1.year + CONSENT_EXPIRATION = 1.year.freeze def deactivate update!(session_uuid: nil) diff --git a/app/presenters/account_show_presenter.rb b/app/presenters/account_show_presenter.rb index 0b944d8f4f4..109bc1286c5 100644 --- a/app/presenters/account_show_presenter.rb +++ b/app/presenters/account_show_presenter.rb @@ -89,7 +89,7 @@ def totp_content :dob, :phone, keyword_init: true, - ) + ).freeze def obfuscated_pii_accessor PiiAccessor.new( diff --git a/app/presenters/idv/in_person/ready_to_verify_presenter.rb b/app/presenters/idv/in_person/ready_to_verify_presenter.rb index c84b0eb2e57..36efbcb2b49 100644 --- a/app/presenters/idv/in_person/ready_to_verify_presenter.rb +++ b/app/presenters/idv/in_person/ready_to_verify_presenter.rb @@ -4,7 +4,7 @@ module Idv module InPerson class ReadyToVerifyPresenter # WILLFIX: With LG-6881, confirm timezone or use deadline from enrollment response. - USPS_SERVER_TIMEZONE = ActiveSupport::TimeZone['America/New_York'] + USPS_SERVER_TIMEZONE = ActiveSupport::TimeZone['America/New_York'].dup.freeze attr_reader :barcode_image_url diff --git a/app/presenters/idv/in_person/verification_results_email_presenter.rb b/app/presenters/idv/in_person/verification_results_email_presenter.rb index 2a11a73351a..e7466dd025d 100644 --- a/app/presenters/idv/in_person/verification_results_email_presenter.rb +++ b/app/presenters/idv/in_person/verification_results_email_presenter.rb @@ -8,7 +8,7 @@ class VerificationResultsEmailPresenter attr_reader :enrollment, :url_options # update to user's time zone when out of pilot - USPS_SERVER_TIMEZONE = ActiveSupport::TimeZone['America/New_York'] + USPS_SERVER_TIMEZONE = (ActiveSupport::TimeZone['America/New_York']).freeze def initialize(enrollment:, url_options:) @enrollment = enrollment diff --git a/app/services/browser_cache.rb b/app/services/browser_cache.rb index 802a7ba40f3..71bdf379430 100644 --- a/app/services/browser_cache.rb +++ b/app/services/browser_cache.rb @@ -2,7 +2,9 @@ class BrowserCache @cache = LruRedux::Cache.new(1_000) + # rubocop:disable Style/MutableConstant DEFAULT_BROWSER = Browser.new(nil) + # rubocop:enable Style/MutableConstant USER_AGENT_SIZE = Browser.user_agent_size_limit - 1 # Detects browser attributes from User-Agent, truncated to 2047 bytes due diff --git a/app/services/doc_auth/lexis_nexis/config.rb b/app/services/doc_auth/lexis_nexis/config.rb index 52a5ee050be..f689212eb9e 100644 --- a/app/services/doc_auth/lexis_nexis/config.rb +++ b/app/services/doc_auth/lexis_nexis/config.rb @@ -39,6 +39,6 @@ def validate! raise 'config missing base_url' if !base_url raise 'config missing locale' if !locale end - end + end.freeze end end diff --git a/app/services/doc_auth/mock/config.rb b/app/services/doc_auth/mock/config.rb index 1976cae432d..6f50f497bba 100644 --- a/app/services/doc_auth/mock/config.rb +++ b/app/services/doc_auth/mock/config.rb @@ -13,6 +13,6 @@ module Mock :sharpness_threshold, :glare_threshold, ], - ) + ).freeze end end diff --git a/app/services/document_capture_session_result.rb b/app/services/document_capture_session_result.rb index 4c50a0ce2d4..31ddc9b5e0b 100644 --- a/app/services/document_capture_session_result.rb +++ b/app/services/document_capture_session_result.rb @@ -45,4 +45,4 @@ def selfie_status return self[member_name]&.include?(fingerprint) end end -end +end.freeze diff --git a/app/services/encryption/contextless_kms_client.rb b/app/services/encryption/contextless_kms_client.rb index 23494bfef0d..3500b968fcb 100644 --- a/app/services/encryption/contextless_kms_client.rb +++ b/app/services/encryption/contextless_kms_client.rb @@ -12,7 +12,7 @@ class ContextlessKmsClient instance_profile_credentials_timeout: 1, # defaults to 1 second instance_profile_credentials_retries: 5, # defaults to 0 retries ) - end + end.freeze KEY_TYPE = { KMS: 'KMSx', diff --git a/app/services/encryption/encryptors/pii_encryptor.rb b/app/services/encryption/encryptors/pii_encryptor.rb index 0a74c3e9903..c577f04b9b0 100644 --- a/app/services/encryption/encryptors/pii_encryptor.rb +++ b/app/services/encryption/encryptors/pii_encryptor.rb @@ -33,7 +33,7 @@ def self.extract_encrypted_data(parsed_json) ) decode(encoded_encrypted_data) end - end + end.freeze def initialize(password) @password = password diff --git a/app/services/encryption/kms_client.rb b/app/services/encryption/kms_client.rb index 7d059229373..308606a7d1c 100644 --- a/app/services/encryption/kms_client.rb +++ b/app/services/encryption/kms_client.rb @@ -22,7 +22,7 @@ class KmsClient instance_profile_credentials_retries: 5, # defaults to 0 retries region: IdentityConfig.store.aws_region, # The region in which the client is being instantiated ) - end + end.freeze # rubocop:enable Layout/LineLength attr_reader :kms_key_id diff --git a/app/services/encryption/password_verifier.rb b/app/services/encryption/password_verifier.rb index d8bd2ec082f..95f0a52d6e9 100644 --- a/app/services/encryption/password_verifier.rb +++ b/app/services/encryption/password_verifier.rb @@ -29,7 +29,7 @@ def to_s def uak_password_digest? encryption_key.present? end - end + end.freeze def initialize @aes_cipher = AesCipher.new diff --git a/app/services/encryption/regional_ciphertext_pair.rb b/app/services/encryption/regional_ciphertext_pair.rb index a3d3a6ef370..09db686c95b 100644 --- a/app/services/encryption/regional_ciphertext_pair.rb +++ b/app/services/encryption/regional_ciphertext_pair.rb @@ -10,4 +10,4 @@ def to_ary def multi_or_single_region_ciphertext multi_region_ciphertext.presence || single_region_ciphertext end -end +end.freeze diff --git a/app/services/encryption/uak_password_verifier.rb b/app/services/encryption/uak_password_verifier.rb index fad98691fd0..c5c91cf0e80 100644 --- a/app/services/encryption/uak_password_verifier.rb +++ b/app/services/encryption/uak_password_verifier.rb @@ -28,7 +28,7 @@ def to_s password_cost: password_cost, }.to_json end - end + end.freeze def self.digest(password) salt = SecureRandom.hex(32) diff --git a/app/services/openid_connect_attribute_scoper.rb b/app/services/openid_connect_attribute_scoper.rb index 7956823c487..0886ab7230c 100644 --- a/app/services/openid_connect_attribute_scoper.rb +++ b/app/services/openid_connect_attribute_scoper.rb @@ -17,19 +17,19 @@ class OpenidConnectAttributeScoper social_security_number ].freeze - VALID_SCOPES = %w[ + VALID_SCOPES = (%w[ email all_emails openid profile:verified_at - ] + X509_SCOPES + IAL2_SCOPES + ] + X509_SCOPES + IAL2_SCOPES).freeze - VALID_IAL1_SCOPES = %w[ + VALID_IAL1_SCOPES = (%w[ email all_emails openid profile:verified_at - ] + X509_SCOPES + ] + X509_SCOPES).freeze ATTRIBUTE_SCOPES_MAP = { email: %w[email], @@ -58,7 +58,7 @@ class OpenidConnectAttributeScoper end end.with_indifferent_access.freeze - CLAIMS = ATTRIBUTE_SCOPES_MAP.keys + CLAIMS = ATTRIBUTE_SCOPES_MAP.keys.freeze attr_reader :scopes diff --git a/app/services/personal_key_formatter.rb b/app/services/personal_key_formatter.rb index c8742dab4d5..64d92a760b6 100644 --- a/app/services/personal_key_formatter.rb +++ b/app/services/personal_key_formatter.rb @@ -2,12 +2,12 @@ class PersonalKeyFormatter CHAR_COUNT = RandomPhrase::WORD_LENGTH - WORD_COUNT = IdentityConfig.store.recovery_code_length + WORD_COUNT = IdentityConfig.store.recovery_code_length.freeze VALID_CHAR = '[a-zA-Z0-9]' VALID_WORD = "#{VALID_CHAR}{#{CHAR_COUNT}}".freeze REGEXP_STRING = "(?:#{VALID_WORD}([\\s\\-])?){#{WORD_COUNT - 1}}#{VALID_WORD}".freeze REGEXP = /\A#{REGEXP_STRING}\Z/o - CODE_LENGTH = CHAR_COUNT * WORD_COUNT + (WORD_COUNT - 1) + CODE_LENGTH = (CHAR_COUNT * WORD_COUNT + (WORD_COUNT - 1)).freeze def self.regexp REGEXP diff --git a/app/services/phone_number_capabilities.rb b/app/services/phone_number_capabilities.rb index f29298e0a36..0318433cc35 100644 --- a/app/services/phone_number_capabilities.rb +++ b/app/services/phone_number_capabilities.rb @@ -9,7 +9,7 @@ def self.load_config INTERNATIONAL_CODES = load_config.freeze ADDRESS_IDENTITY_PROOFING_SUPPORTED_COUNTRY_CODES = - IdentityConfig.store.address_identity_proofing_supported_country_codes + IdentityConfig.store.address_identity_proofing_supported_country_codes.freeze attr_reader :phone, :phone_confirmed @@ -34,7 +34,7 @@ def self.translated_international_codes translated_intl_codes_data[I18n.locale] if translated_intl_codes_data end - TRANSLATED_INTL_CODES_DATA = generate_translated_international_codes_data + TRANSLATED_INTL_CODES_DATA = generate_translated_international_codes_data.freeze def initialize(phone, phone_confirmed:) @phone = phone diff --git a/app/services/pii/attributes.rb b/app/services/pii/attributes.rb index c9edf807fce..47c7dc3a9aa 100644 --- a/app/services/pii/attributes.rb +++ b/app/services/pii/attributes.rb @@ -42,5 +42,5 @@ def eql?(other) def ==(other) eql?(other) end - end + end.freeze end diff --git a/app/services/proofing/aamva/proofer.rb b/app/services/proofing/aamva/proofer.rb index 0daa79f0e08..c73841282d8 100644 --- a/app/services/proofing/aamva/proofer.rb +++ b/app/services/proofing/aamva/proofer.rb @@ -19,7 +19,7 @@ class Proofer :verification_request_timeout, :verification_url, ], - ) + ).freeze attr_reader :config diff --git a/app/services/proofing/lexis_nexis/config.rb b/app/services/proofing/lexis_nexis/config.rb index a09f4e3fd25..e650a58053b 100644 --- a/app/services/proofing/lexis_nexis/config.rb +++ b/app/services/proofing/lexis_nexis/config.rb @@ -23,6 +23,6 @@ module LexisNexis :request_mode, :request_timeout, ], - ) + ).freeze end end diff --git a/app/services/request_password_reset.rb b/app/services/request_password_reset.rb index d69741d6548..c5b9505f049 100644 --- a/app/services/request_password_reset.rb +++ b/app/services/request_password_reset.rb @@ -85,4 +85,4 @@ def email_address_record EmailAddress.find_with_confirmed_or_unconfirmed_email(email) end end -end +end.freeze diff --git a/app/services/usps_in_person_proofing/proofer.rb b/app/services/usps_in_person_proofing/proofer.rb index b4f52e5e8ee..0ad3a48f13c 100644 --- a/app/services/usps_in_person_proofing/proofer.rb +++ b/app/services/usps_in_person_proofing/proofer.rb @@ -4,7 +4,7 @@ module UspsInPersonProofing class Proofer AUTH_TOKEN_CACHE_KEY = :usps_ippaas_api_auth_token # Automatically refresh our auth token if it is within this many minutes of expiring - AUTH_TOKEN_PREEMPTIVE_EXPIRY_MINUTES = 1.minute + AUTH_TOKEN_PREEMPTIVE_EXPIRY_MINUTES = 1.minute.freeze # Makes HTTP request to get nearby in-person proofing facilities # Requires address, city, state and zip code. diff --git a/app/services/vot/component_value.rb b/app/services/vot/component_value.rb index 2eccdf1efec..01c3785350a 100644 --- a/app/services/vot/component_value.rb +++ b/app/services/vot/component_value.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Vot - ComponentValue = Data.define(:name, :description, :implied_component_values, :requirements) + ComponentValue = Data.define(:name, :description, :implied_component_values, :requirements).freeze end diff --git a/app/services/vot/legacy_component_values.rb b/app/services/vot/legacy_component_values.rb index 9d0a905cd3b..5f3d2db3459 100644 --- a/app/services/vot/legacy_component_values.rb +++ b/app/services/vot/legacy_component_values.rb @@ -8,31 +8,31 @@ module LegacyComponentValues description: 'Legacy LOA1', implied_component_values: [], requirements: [], - ) + ).freeze LOA3 = ComponentValue.new( name: Saml::Idp::Constants::LOA3_AUTHN_CONTEXT_CLASSREF, description: 'Legacy LOA3', implied_component_values: [], requirements: [:aal2, :identity_proofing], - ) + ).freeze IAL1 = ComponentValue.new( name: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, description: 'Legacy IAL1', implied_component_values: [], requirements: [], - ) + ).freeze IAL2 = ComponentValue.new( name: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, description: 'Legacy IAL2', implied_component_values: [], requirements: [:aal2, :identity_proofing], - ) + ).freeze IALMAX = ComponentValue.new( name: Saml::Idp::Constants::IALMAX_AUTHN_CONTEXT_CLASSREF, description: 'Legacy IALMAX', implied_component_values: [], requirements: [:aal2, :ialmax], - ) + ).freeze ## Authentication ACR values DEFAULT = ComponentValue.new( @@ -40,48 +40,48 @@ module LegacyComponentValues description: 'Legacy default authentication', implied_component_values: [], requirements: [], - ) + ).freeze AAL1 = ComponentValue.new( name: Saml::Idp::Constants::AAL1_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL1', implied_component_values: [], requirements: [], - ) + ).freeze AAL2 = ComponentValue.new( name: Saml::Idp::Constants::AAL2_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL2', implied_component_values: [], requirements: [:aal2], - ) + ).freeze AAL2_PHISHING_RESISTANT = ComponentValue.new( name: Saml::Idp::Constants::AAL2_PHISHING_RESISTANT_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL2 with phishing resistance', implied_component_values: [], requirements: [:aal2, :phishing_resistant], - ) + ).freeze AAL2_HSPD12 = ComponentValue.new( name: Saml::Idp::Constants::AAL2_HSPD12_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL2 with HSPD12', implied_component_values: [], requirements: [:aal2, :hspd12], - ) + ).freeze AAL3 = ComponentValue.new( name: Saml::Idp::Constants::AAL3_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL3', implied_component_values: [], requirements: [:aal2, :phishing_resistant], - ) + ).freeze AAL3_HSPD12 = ComponentValue.new( name: Saml::Idp::Constants::AAL3_HSPD12_AUTHN_CONTEXT_CLASSREF, description: 'Legacy AAL3 with HSPD12', implied_component_values: [], requirements: [:aal2, :hspd12], - ) + ).freeze NAME_HASH = constants.map do |constant| component_value = const_get(constant) [component_value.name, component_value] - end.to_h + end.to_h.freeze def self.by_name NAME_HASH diff --git a/app/services/vot/parser.rb b/app/services/vot/parser.rb index 2931d3cd9d5..80e7cbee65d 100644 --- a/app/services/vot/parser.rb +++ b/app/services/vot/parser.rb @@ -32,7 +32,7 @@ def identity_proofing_or_ialmax? def expanded_component_values component_values.map(&:name).join('.') end - end + end.freeze attr_reader :vector_of_trust, :acr_values diff --git a/app/services/vot/supported_component_values.rb b/app/services/vot/supported_component_values.rb index 9f41950bb63..d946e355945 100644 --- a/app/services/vot/supported_component_values.rb +++ b/app/services/vot/supported_component_values.rb @@ -7,42 +7,42 @@ module SupportedComponentValues description: 'Multi-factor authentication', implied_component_values: [], requirements: [], - ) + ).freeze C2 = ComponentValue.new( name: 'C2', description: 'AAL2 conformant features are engaged', implied_component_values: [C1], requirements: [:aal2], - ) + ).freeze Ca = ComponentValue.new( name: 'Ca', description: 'A phishing resistant authenticator is required', implied_component_values: [C1], requirements: [:phishing_resistant], - ) + ).freeze Cb = ComponentValue.new( name: 'Cb', description: 'A PIV/CAC card is required', implied_component_values: [C1], requirements: [:hspd12], - ) + ).freeze P1 = ComponentValue.new( name: 'P1', description: 'Identity proofing is performed', implied_component_values: [C2], requirements: [:identity_proofing], - ) + ).freeze Pb = ComponentValue.new( name: 'Pb', description: 'A biometric comparison is required as part of identity proofing', implied_component_values: [P1], requirements: [:biometric_comparison], - ) + ).freeze NAME_HASH = constants.map do |constant| component_value = const_get(constant) [component_value.name, component_value] - end.to_h + end.to_h.freeze def self.by_name NAME_HASH diff --git a/app/validators/form_password_validator.rb b/app/validators/form_password_validator.rb index 0c7dcc906c6..7268e039ea9 100644 --- a/app/validators/form_password_validator.rb +++ b/app/validators/form_password_validator.rb @@ -20,7 +20,7 @@ module FormPasswordValidator private - ZXCVBN_TESTER = ::Zxcvbn::Tester.new + ZXCVBN_TESTER = ::Zxcvbn::Tester.new.freeze def strong_password return unless errors.messages.blank? && password_score.score < min_password_score diff --git a/config/initializers/01_redis.rb b/config/initializers/01_redis.rb index 0c1303739a7..39851d84299 100644 --- a/config/initializers/01_redis.rb +++ b/config/initializers/01_redis.rb @@ -4,8 +4,8 @@ # This is done because rack_attack.rb needs to reference the Throttle pool defined here. REDIS_POOL = ConnectionPool.new(size: IdentityConfig.store.redis_pool_size) do Redis.new(url: IdentityConfig.store.redis_url) -end +end.freeze REDIS_THROTTLE_POOL = ConnectionPool.new(size: IdentityConfig.store.redis_throttle_pool_size) do Redis.new(url: IdentityConfig.store.redis_throttle_url) -end +end.freeze diff --git a/config/initializers/ab_tests.rb b/config/initializers/ab_tests.rb index acedc4faf4f..096647a52c4 100644 --- a/config/initializers/ab_tests.rb +++ b/config/initializers/ab_tests.rb @@ -10,7 +10,7 @@ module AbTests IdentityConfig.store.doc_auth_vendor_randomize_percent : 0, }.compact, - ) + ).freeze ACUANT_SDK = AbTestBucket.new( experiment_name: 'Acuant SDK Upgrade', @@ -19,7 +19,7 @@ module AbTests IdentityConfig.store.idv_acuant_sdk_upgrade_a_b_testing_percent : 0, }, - ) + ).freeze LEXISNEXIS_INSTANT_VERIFY_WORKFLOW = AbTestBucket.new( experiment_name: 'LexisNexis Instant Verify Workflow', @@ -29,5 +29,5 @@ module AbTests IdentityConfig.store.lexisnexis_instant_verify_workflow_ab_testing_percent : 0, }, - ) + ).freeze end diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 6afe9eb731d..486e24b92d3 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -6,7 +6,7 @@ module Rack class Attack ALLOWED_CIDR_BLOCKS = IdentityConfig.store.requests_per_ip_cidr_allowlist.map do |x| IPAddr.new(x) - end + end.freeze EMAIL_REGISTRATION_PATHS = ['/sign_up/enter_email', '/en/sign_up/enter_email', '/es/sign_up/enter_email', '/fr/sign_up/enter_email'].freeze diff --git a/config/initializers/rack_timeout.rb b/config/initializers/rack_timeout.rb index b378cb3bcf1..4c76e637430 100644 --- a/config/initializers/rack_timeout.rb +++ b/config/initializers/rack_timeout.rb @@ -4,14 +4,14 @@ module Rack class Timeout - EXCLUDES = [ + EXCLUDES = ([ '/verify/verify_info', '/verify/phone', '/verify/document_capture', '/verify/link_sent', ].flat_map do |path| [path] + Idp::Constants::AVAILABLE_LOCALES.map { |locale| "/#{locale}#{path}" } - end + ['/api/verify/images'] + end + ['/api/verify/images']).freeze def call_with_excludes(env) if EXCLUDES.any? { |path| env['REQUEST_URI']&.start_with?(path) } diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 3838f96ff60..28d828ceff9 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -3,9 +3,9 @@ require 'csv' class IdentityConfig - GIT_SHA = `git rev-parse --short=8 HEAD`.chomp - GIT_TAG = `git tag --points-at HEAD`.chomp.split("\n").first - GIT_BRANCH = `git rev-parse --abbrev-ref HEAD`.chomp + GIT_SHA = `git rev-parse --short=8 HEAD`.chomp.freeze + GIT_TAG = `git tag --points-at HEAD`.chomp.split("\n").first.freeze + GIT_BRANCH = `git rev-parse --abbrev-ref HEAD`.chomp.freeze VENDOR_STATUS_OPTIONS = %i[operational partial_outage full_outage].freeze diff --git a/lib/pwned_password_downloader.rb b/lib/pwned_password_downloader.rb index 7b4371d18da..21699aed998 100755 --- a/lib/pwned_password_downloader.rb +++ b/lib/pwned_password_downloader.rb @@ -18,7 +18,7 @@ class PwnedPasswordDownloader RANGE_API_ROOT = 'https://api.pwnedpasswords.com/range/' SHA1_LENGTH = 40 HASH_PREFIX_LENGTH = 5 - OCCURRENCE_OFFSET = SHA1_LENGTH - HASH_PREFIX_LENGTH + ':'.length + OCCURRENCE_OFFSET = (SHA1_LENGTH - HASH_PREFIX_LENGTH + ':'.length).freeze def initialize( destination: 'tmp/pwned', diff --git a/lib/saml_idp_constants.rb b/lib/saml_idp_constants.rb index f210d301b82..b50d4e02454 100644 --- a/lib/saml_idp_constants.rb +++ b/lib/saml_idp_constants.rb @@ -34,7 +34,7 @@ module Constants REQUESTED_ATTRIBUTES_CLASSREF = 'http://idmanagement.gov/ns/requested_attributes?ReqAttr=' - VALID_AUTHN_CONTEXTS = IdentityConfig.store.valid_authn_contexts + VALID_AUTHN_CONTEXTS = IdentityConfig.store.valid_authn_contexts.freeze IAL2_AUTHN_CONTEXTS = [IAL2_AUTHN_CONTEXT_CLASSREF, LOA3_AUTHN_CONTEXT_CLASSREF].freeze AUTHN_CONTEXT_CLASSREF_TO_IAL = { diff --git a/lib/session_encryptor.rb b/lib/session_encryptor.rb index 3966d830682..c7fd896a456 100644 --- a/lib/session_encryptor.rb +++ b/lib/session_encryptor.rb @@ -38,7 +38,7 @@ class SensitiveValueError < StandardError; end :city, :dob, :state_id_expiration, - ).values + ).values.freeze SENSITIVE_REGEX = %r{#{SENSITIVE_DEFAULT_FIELDS.join('|')}}i def load(value) diff --git a/lib/telephony/pinpoint/sms_sender.rb b/lib/telephony/pinpoint/sms_sender.rb index ce0700f4f53..39b48d17534 100644 --- a/lib/telephony/pinpoint/sms_sender.rb +++ b/lib/telephony/pinpoint/sms_sender.rb @@ -27,7 +27,7 @@ class SmsSender credentials: credentials, ) end - end + end.freeze # rubocop:disable Metrics/BlockLength # rubocop:disable Lint/UnusedMethodArgument diff --git a/lib/telephony/pinpoint/voice_sender.rb b/lib/telephony/pinpoint/voice_sender.rb index 738e4e0d9a5..55fffac0ce9 100644 --- a/lib/telephony/pinpoint/voice_sender.rb +++ b/lib/telephony/pinpoint/voice_sender.rb @@ -16,7 +16,7 @@ class VoiceSender credentials: credentials, ) end - end + end.freeze # rubocop:disable Lint/UnusedMethodArgument # rubocop:disable Metrics/BlockLength diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d66cd7f1c9c..104cd27bb60 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,7 +9,7 @@ require 'active_support/core_ext/object/blank' require 'active_support' -RSPEC_RUNNING_IN_PARALLEL = ENV['PARALLEL_PID_FILE'].present? +RSPEC_RUNNING_IN_PARALLEL = ENV['PARALLEL_PID_FILE'].present?.freeze RSpec.configure do |config| # see more settings at spec/rails_helper.rb diff --git a/spec/support/fake_analytics.rb b/spec/support/fake_analytics.rb index a0a1acf0c2b..8276bdba3d9 100644 --- a/spec/support/fake_analytics.rb +++ b/spec/support/fake_analytics.rb @@ -1,5 +1,5 @@ class FakeAnalytics < Analytics - PiiDetected = Class.new(StandardError) + PiiDetected = Class.new(StandardError).freeze include AnalyticsEvents prepend Idv::AnalyticsEventsEnhancer @@ -69,7 +69,7 @@ def track_event(event, original_attributes = {}) end end - UndocumentedParams = Class.new(StandardError) + UndocumentedParams = Class.new(StandardError).freeze module UndocumentedParamsChecker mattr_accessor :allowed_extra_analytics diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb index 134774a4e99..4d99e12d389 100644 --- a/spec/support/features/doc_auth_helper.rb +++ b/spec/support/features/doc_auth_helper.rb @@ -7,7 +7,7 @@ module DocAuthHelper include DocumentCaptureStepHelper include UserAgentHelper - GOOD_SSN = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] + GOOD_SSN = (Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn]).freeze GOOD_SSN_MASKED = '9**-**-***4'.freeze SAMPLE_TMX_SUMMARY_REASON_CODE = { tmx_summary_reason_code: ['Identity_Negative_History'] }.freeze SSN_THAT_FAILS_RESOLUTION = '123-45-6666'.freeze diff --git a/spec/support/features/in_person_helper.rb b/spec/support/features/in_person_helper.rb index b9df37ae853..98cedc76a37 100644 --- a/spec/support/features/in_person_helper.rb +++ b/spec/support/features/in_person_helper.rb @@ -5,31 +5,32 @@ module InPersonHelper include IdvStepHelper include DocAuthHelper - GOOD_FIRST_NAME = Idp::Constants::MOCK_IDV_APPLICANT[:first_name] - GOOD_LAST_NAME = Idp::Constants::MOCK_IDV_APPLICANT[:last_name] + GOOD_FIRST_NAME = (Idp::Constants::MOCK_IDV_APPLICANT[:first_name]).freeze + GOOD_LAST_NAME = (Idp::Constants::MOCK_IDV_APPLICANT[:last_name]).freeze # the date in the format '1938-10-06' - GOOD_DOB = Idp::Constants::MOCK_IDV_APPLICANT[:dob] + GOOD_DOB = (Idp::Constants::MOCK_IDV_APPLICANT[:dob]).freeze # the date in the format 'October 6, 1938' GOOD_DOB_FORMATTED_EVENT = I18n.l( Date.parse(GOOD_DOB), format: I18n.t('time.formats.event_date') - ) + ).freeze GOOD_STATE_ID_JURISDICTION = Idp::Constants::MOCK_IDV_APPLICANT_FULL_STATE_ID_JURISDICTION - GOOD_STATE_ID_NUMBER = Idp::Constants::MOCK_IDV_APPLICANT[:state_id_number] + GOOD_STATE_ID_NUMBER = (Idp::Constants::MOCK_IDV_APPLICANT[:state_id_number]).freeze - GOOD_ADDRESS1 = Idp::Constants::MOCK_IDV_APPLICANT[:address1] - GOOD_ADDRESS2 = Idp::Constants::MOCK_IDV_APPLICANT[:address2] - GOOD_CITY = Idp::Constants::MOCK_IDV_APPLICANT[:city] - GOOD_ZIPCODE = Idp::Constants::MOCK_IDV_APPLICANT[:zipcode] + GOOD_ADDRESS1 = (Idp::Constants::MOCK_IDV_APPLICANT[:address1]).freeze + GOOD_ADDRESS2 = (Idp::Constants::MOCK_IDV_APPLICANT[:address2]).freeze + GOOD_CITY = (Idp::Constants::MOCK_IDV_APPLICANT[:city]).freeze + GOOD_ZIPCODE = (Idp::Constants::MOCK_IDV_APPLICANT[:zipcode]).freeze GOOD_STATE = Idp::Constants::MOCK_IDV_APPLICANT_FULL_STATE GOOD_IDENTITY_DOC_ADDRESS1 = - Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_address1] + (Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_address1]).freeze GOOD_IDENTITY_DOC_ADDRESS2 = - Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_address2] + (Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_address2]).freeze GOOD_IDENTITY_DOC_ADDRESS_STATE = Idp::Constants::MOCK_IDV_APPLICANT_FULL_IDENTITY_DOC_ADDRESS_STATE - GOOD_IDENTITY_DOC_CITY = Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_city] + GOOD_IDENTITY_DOC_CITY = + (Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_city]).freeze GOOD_IDENTITY_DOC_ZIPCODE = - Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_zipcode] + (Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_zipcode]).freeze def fill_out_state_id_form_ok(same_address_as_id: false) fill_in t('in_person_proofing.form.state_id.first_name'), with: GOOD_FIRST_NAME From 190623df142da4033e5f7ff589054c4277309be1 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Mon, 1 Apr 2024 13:23:51 -0500 Subject: [PATCH 06/17] Update app/presenters/idv/in_person/verification_results_email_presenter.rb Co-authored-by: Zach Margolis --- .../idv/in_person/verification_results_email_presenter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/presenters/idv/in_person/verification_results_email_presenter.rb b/app/presenters/idv/in_person/verification_results_email_presenter.rb index e7466dd025d..3fae3d98a69 100644 --- a/app/presenters/idv/in_person/verification_results_email_presenter.rb +++ b/app/presenters/idv/in_person/verification_results_email_presenter.rb @@ -8,7 +8,7 @@ class VerificationResultsEmailPresenter attr_reader :enrollment, :url_options # update to user's time zone when out of pilot - USPS_SERVER_TIMEZONE = (ActiveSupport::TimeZone['America/New_York']).freeze + USPS_SERVER_TIMEZONE = ActiveSupport::TimeZone['America/New_York'].dup.freeze def initialize(enrollment:, url_options:) @enrollment = enrollment From d39c8c253c866c0d03fa4266ef391f87375f0864 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 13:05:49 -0500 Subject: [PATCH 07/17] More deeply freeze hash Co-authored-by: Zach Margolis --- app/services/doc_auth/errors.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/doc_auth/errors.rb b/app/services/doc_auth/errors.rb index fef2d141e80..24709599216 100644 --- a/app/services/doc_auth/errors.rb +++ b/app/services/doc_auth/errors.rb @@ -123,7 +123,7 @@ module Errors SELFIE_FAILURE => { long_msg: SELFIE_FAILURE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_NOT_LIVE => { long_msg: SELFIE_NOT_LIVE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_POOR_QUALITY => { long_msg: SELFIE_POOR_QUALITY, field_msg: SELFIE_FAILURE, hints: false }, - }.freeze + }.each { |_k, v| v.freeze }.freeze # rubocop:enable Layout/LineLength end end From 4cd1db1ad8ab7ef97dc749012f2cd8efb9d72606 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 14:22:06 -0500 Subject: [PATCH 08/17] Update app/services/doc_auth/errors.rb Co-authored-by: Zach Margolis --- app/services/doc_auth/errors.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/doc_auth/errors.rb b/app/services/doc_auth/errors.rb index 24709599216..262b0ed3590 100644 --- a/app/services/doc_auth/errors.rb +++ b/app/services/doc_auth/errors.rb @@ -123,7 +123,7 @@ module Errors SELFIE_FAILURE => { long_msg: SELFIE_FAILURE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_NOT_LIVE => { long_msg: SELFIE_NOT_LIVE, field_msg: SELFIE_FAILURE, hints: false }, SELFIE_POOR_QUALITY => { long_msg: SELFIE_POOR_QUALITY, field_msg: SELFIE_FAILURE, hints: false }, - }.each { |_k, v| v.freeze }.freeze + }.transform_values(&:freeze).freeze # rubocop:enable Layout/LineLength end end From ab71f6fd2ea1fdcfd257e0ca184061a9600d0926 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 14:37:04 -0500 Subject: [PATCH 09/17] Fix sms sender spec --- .../lib/telephony/pinpoint/sms_sender_spec.rb | 64 ++++++------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/spec/lib/telephony/pinpoint/sms_sender_spec.rb b/spec/lib/telephony/pinpoint/sms_sender_spec.rb index 4ea38e7d289..5bba0ff5ff5 100644 --- a/spec/lib/telephony/pinpoint/sms_sender_spec.rb +++ b/spec/lib/telephony/pinpoint/sms_sender_spec.rb @@ -24,19 +24,13 @@ def ==(other) let(:status_message) { 'some status message' } before do - mock_build_client + mock_build_clients(mock_client, nil) Pinpoint::MockClient.message_response_result_status_code = status_code Pinpoint::MockClient.message_response_result_delivery_status = delivery_status Pinpoint::MockClient.message_response_result_status_message = status_message end - around do |ex| - ex.run - ensure - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear - end - context 'when endpoint is a duplicate' do let(:delivery_status) { 'DUPLICATE' } @@ -177,17 +171,11 @@ def ==(other) } end - around do |ex| - ex.run - ensure - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear - end - context 'in a country with sender_id' do let(:country_code) { 'PH' } it 'sends a message with a sender_id and no origination number' do - mock_build_client + mock_build_clients(mock_client, nil) response = subject.deliver( message: 'This is a test!', to: '+1 (604) 456-7890', @@ -219,7 +207,7 @@ def ==(other) context 'in the US' do it 'sends a message with a shortcode and no sender_id' do - mock_build_client + mock_build_clients(mock_client, nil) response = subject.deliver( message: 'This is a test!', to: '+1 (414) 456-7890', @@ -253,7 +241,7 @@ def ==(other) let(:country_code) { 'PR' } it 'sends a message with a longcode and no sender_id' do - mock_build_client + mock_build_clients(mock_client, nil) response = subject.deliver( message: 'This is a test!', to: '+1 (939) 456-7890', @@ -287,7 +275,7 @@ def ==(other) let(:country_code) { 'MX' } it 'sends a message with a longcode and no sender_id' do - mock_build_client + mock_build_clients(mock_client, nil) response = subject.deliver( message: 'This is a test!', to: '+525555555555', @@ -326,14 +314,7 @@ def ==(other) sms.application_id = 'backup-sms-application-id' end - mock_build_client - mock_build_backup_client - end - - around do |ex| - ex.run - ensure - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear + mock_build_clients end context 'when the first config succeeds' do @@ -448,17 +429,12 @@ def ==(other) end before do - mock_build_client - mock_build_backup_client + mock_build_clients(mock_client, nil) allow(mock_client).to receive(:send_messages).and_return(phone_numbers) allow(backup_mock_client).to receive(:send_messages).and_return(phone_numbers) end - after do - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear - end - it 'does not include the phone number in the results' do response = subject.deliver( message: 'This is a test!', @@ -471,13 +447,19 @@ def ==(other) end end - def mock_build_client(client = mock_client) - Telephony::Pinpoint::SmsSender::CLIENT_POOL[sms_config] = FakeConnectionPool.new { client } - end + def mock_build_clients(client = mock_client, backup_client = backup_mock_client) + clients = { + sms_config => FakeConnectionPool.new { client }, + } + + if backup_client + clients[backup_sms_config] = FakeConnectionPool.new { backup_client } + end - def mock_build_backup_client(client = backup_mock_client) - Telephony::Pinpoint::SmsSender::CLIENT_POOL[backup_sms_config] = - FakeConnectionPool.new { client } + stub_const( + 'Telephony::Pinpoint::SmsSender::CLIENT_POOL', + clients, + ) end describe '#phone_info' do @@ -496,13 +478,7 @@ def mock_build_backup_client(client = backup_mock_client) sms.application_id = 'backup-sms-application-id' end - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear - mock_build_client(pinpoint_client) - mock_build_backup_client(pinpoint_client) - end - - after do - Telephony::Pinpoint::SmsSender::CLIENT_POOL.clear + mock_build_clients(pinpoint_client, pinpoint_client) end context 'successful network requests' do From 7bcc0ad758579b159bbc9364d837e27a140516a1 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 14:50:21 -0500 Subject: [PATCH 10/17] fix voice sender spec --- .../telephony/pinpoint/voice_sender_spec.rb | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/spec/lib/telephony/pinpoint/voice_sender_spec.rb b/spec/lib/telephony/pinpoint/voice_sender_spec.rb index bf73199dfdb..d3ea4adfa92 100644 --- a/spec/lib/telephony/pinpoint/voice_sender_spec.rb +++ b/spec/lib/telephony/pinpoint/voice_sender_spec.rb @@ -11,14 +11,19 @@ let(:backup_pinpoint_client) { Aws::PinpointSMSVoice::Client.new(stub_responses: true) } let(:backup_voice_config) { Telephony.config.pinpoint.voice_configs.last } - def mock_build_client - Telephony::Pinpoint::VoiceSender::CLIENT_POOL[voice_config] = - FakeConnectionPool.new { pinpoint_client } - end + def mock_build_clients(client = pinpoint_client, backup_client = backup_pinpoint_client) + clients = { + voice_config => FakeConnectionPool.new { client }, + } + + if backup_client + clients[backup_voice_config] = FakeConnectionPool.new { backup_client } + end - def mock_build_backup_client - Telephony::Pinpoint::VoiceSender::CLIENT_POOL[backup_voice_config] = - FakeConnectionPool.new { backup_pinpoint_client } + stub_const( + 'Telephony::Pinpoint::VoiceSender::CLIENT_POOL', + clients, + ) end describe '#deliver' do @@ -46,12 +51,7 @@ def mock_build_backup_client # More deterministic sending phone Telephony.config.pinpoint.voice_configs.first.longcode_pool = [sending_phone] - Telephony::Pinpoint::VoiceSender::CLIENT_POOL.clear - mock_build_client - end - - after do - Telephony::Pinpoint::VoiceSender::CLIENT_POOL.clear + mock_build_clients(pinpoint_client, nil) end it 'initializes a pinpoint sms and voice client and uses that to send a message' do @@ -203,7 +203,7 @@ def mock_build_backup_client voice.longcode_pool = [backup_longcode] end - mock_build_backup_client + mock_build_clients end let(:backup_longcode) { '+18881112222' } From 886a616f1874da681d0082d3771f83947915c27b Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 15:23:13 -0500 Subject: [PATCH 11/17] do not freeze pinpoint pools --- lib/telephony/pinpoint/sms_sender.rb | 4 +++- lib/telephony/pinpoint/voice_sender.rb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/telephony/pinpoint/sms_sender.rb b/lib/telephony/pinpoint/sms_sender.rb index 39b48d17534..c9321fc02fb 100644 --- a/lib/telephony/pinpoint/sms_sender.rb +++ b/lib/telephony/pinpoint/sms_sender.rb @@ -17,6 +17,7 @@ class SmsSender # One connection pool per config (aka per-region) # @param [Hash>] + # rubocop:disable Style/MutableConstant CLIENT_POOL = Hash.new do |h, sms_config| h[sms_config] = ConnectionPool.new(size: IdentityConfig.store.pinpoint_voice_pool_size) do credentials = AwsCredentialBuilder.new(sms_config).call @@ -27,7 +28,8 @@ class SmsSender credentials: credentials, ) end - end.freeze + end + # rubocop:enable Style/MutableConstant # rubocop:disable Metrics/BlockLength # rubocop:disable Lint/UnusedMethodArgument diff --git a/lib/telephony/pinpoint/voice_sender.rb b/lib/telephony/pinpoint/voice_sender.rb index 55fffac0ce9..0a371936616 100644 --- a/lib/telephony/pinpoint/voice_sender.rb +++ b/lib/telephony/pinpoint/voice_sender.rb @@ -6,6 +6,7 @@ module Telephony module Pinpoint class VoiceSender # One connection pool per config (aka per-region) + # rubocop:disable Style/MutableConstant CLIENT_POOL = Hash.new do |h, voice_config| h[voice_config] = ConnectionPool.new(size: IdentityConfig.store.pinpoint_voice_pool_size) do credentials = AwsCredentialBuilder.new(voice_config).call @@ -16,7 +17,8 @@ class VoiceSender credentials: credentials, ) end - end.freeze + end + # rubocop:enable Style/MutableConstant # rubocop:disable Lint/UnusedMethodArgument # rubocop:disable Metrics/BlockLength From 89aa7a0125c8484bf5c93e52cc2a434b78612119 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 15:26:55 -0500 Subject: [PATCH 12/17] use keyword arguments --- spec/lib/telephony/pinpoint/sms_sender_spec.rb | 16 ++++++++-------- spec/lib/telephony/pinpoint/voice_sender_spec.rb | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/lib/telephony/pinpoint/sms_sender_spec.rb b/spec/lib/telephony/pinpoint/sms_sender_spec.rb index 5bba0ff5ff5..b849dd188b2 100644 --- a/spec/lib/telephony/pinpoint/sms_sender_spec.rb +++ b/spec/lib/telephony/pinpoint/sms_sender_spec.rb @@ -24,7 +24,7 @@ def ==(other) let(:status_message) { 'some status message' } before do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) Pinpoint::MockClient.message_response_result_status_code = status_code Pinpoint::MockClient.message_response_result_delivery_status = delivery_status @@ -175,7 +175,7 @@ def ==(other) let(:country_code) { 'PH' } it 'sends a message with a sender_id and no origination number' do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) response = subject.deliver( message: 'This is a test!', to: '+1 (604) 456-7890', @@ -207,7 +207,7 @@ def ==(other) context 'in the US' do it 'sends a message with a shortcode and no sender_id' do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) response = subject.deliver( message: 'This is a test!', to: '+1 (414) 456-7890', @@ -241,7 +241,7 @@ def ==(other) let(:country_code) { 'PR' } it 'sends a message with a longcode and no sender_id' do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) response = subject.deliver( message: 'This is a test!', to: '+1 (939) 456-7890', @@ -275,7 +275,7 @@ def ==(other) let(:country_code) { 'MX' } it 'sends a message with a longcode and no sender_id' do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) response = subject.deliver( message: 'This is a test!', to: '+525555555555', @@ -429,7 +429,7 @@ def ==(other) end before do - mock_build_clients(mock_client, nil) + mock_build_clients(client: mock_client, backup_client: nil) allow(mock_client).to receive(:send_messages).and_return(phone_numbers) allow(backup_mock_client).to receive(:send_messages).and_return(phone_numbers) @@ -447,7 +447,7 @@ def ==(other) end end - def mock_build_clients(client = mock_client, backup_client = backup_mock_client) + def mock_build_clients(client: mock_client, backup_client: backup_mock_client) clients = { sms_config => FakeConnectionPool.new { client }, } @@ -478,7 +478,7 @@ def mock_build_clients(client = mock_client, backup_client = backup_mock_client) sms.application_id = 'backup-sms-application-id' end - mock_build_clients(pinpoint_client, pinpoint_client) + mock_build_clients(client: pinpoint_client, backup_client: pinpoint_client) end context 'successful network requests' do diff --git a/spec/lib/telephony/pinpoint/voice_sender_spec.rb b/spec/lib/telephony/pinpoint/voice_sender_spec.rb index d3ea4adfa92..d0961f64296 100644 --- a/spec/lib/telephony/pinpoint/voice_sender_spec.rb +++ b/spec/lib/telephony/pinpoint/voice_sender_spec.rb @@ -11,7 +11,7 @@ let(:backup_pinpoint_client) { Aws::PinpointSMSVoice::Client.new(stub_responses: true) } let(:backup_voice_config) { Telephony.config.pinpoint.voice_configs.last } - def mock_build_clients(client = pinpoint_client, backup_client = backup_pinpoint_client) + def mock_build_clients(client: pinpoint_client, backup_client: backup_pinpoint_client) clients = { voice_config => FakeConnectionPool.new { client }, } @@ -51,7 +51,7 @@ def mock_build_clients(client = pinpoint_client, backup_client = backup_pinpoint # More deterministic sending phone Telephony.config.pinpoint.voice_configs.first.longcode_pool = [sending_phone] - mock_build_clients(pinpoint_client, nil) + mock_build_clients(client: pinpoint_client, backup_client: nil) end it 'initializes a pinpoint sms and voice client and uses that to send a message' do From 7829c9ae44244265e3c1ba65c15410c52402f7be Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 17:13:52 -0500 Subject: [PATCH 13/17] remove spec --- spec/config/initializers/ab_tests_spec.rb | 47 ----------------------- 1 file changed, 47 deletions(-) delete mode 100644 spec/config/initializers/ab_tests_spec.rb diff --git a/spec/config/initializers/ab_tests_spec.rb b/spec/config/initializers/ab_tests_spec.rb deleted file mode 100644 index 762a213f6c5..00000000000 --- a/spec/config/initializers/ab_tests_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'rails_helper' - -RSpec.describe AbTests do - def reload_ab_test_initializer! - # undefine the AB tests instances so we can re-initialize them with different config values - AbTests.constants.each do |const_name| - AbTests.class_eval { remove_const(const_name) } - end - load Rails.root.join('config', 'initializers', 'ab_tests.rb').to_s - end - - describe '::NATIVE_CAMERA' do - let(:percent) { 30 } - - before do - allow(IdentityConfig.store).to receive(:doc_auth_vendor_randomize). - and_return(true) - allow(IdentityConfig.store).to receive(:doc_auth_vendor_randomize_percent). - and_return(percent) - - reload_ab_test_initializer! - end - - after do - allow(IdentityConfig.store).to receive(:doc_auth_vendor_randomize). - and_call_original - allow(IdentityConfig.store).to receive(:doc_auth_vendor_randomize_percent). - and_call_original - - reload_ab_test_initializer! - end - - context 'configured with buckets adding up to less than 100 percent' do - let(:subject) { described_class::DOC_AUTH_VENDOR } - let(:a_uuid) { SecureRandom.uuid } - let(:b_uuid) { SecureRandom.uuid } - before do - allow(subject).to receive(:percent).with(a_uuid).and_return(percent) - allow(subject).to receive(:percent).with(b_uuid).and_return(percent + 1) - end - it 'sorts uuids into the buckets' do - expect(subject.bucket(a_uuid)).to eq(:alternate_vendor) - expect(subject.bucket(b_uuid)).to eq(:default) - end - end - end -end From 4400b355e6aee2f15a8b282964e618ccefdc496a Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 2 Apr 2024 17:14:02 -0500 Subject: [PATCH 14/17] remove stub --- spec/features/idv/analytics_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index c0a46501b95..f4367d1fcaf 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -934,8 +934,6 @@ def wait_for_event(event, wait) to receive(:biometric_comparison_required?). and_return(true) allow_any_instance_of(DocAuth::Response).to receive(:selfie_status).and_return(:success) - allow_any_instance_of(DocumentCaptureSessionResult). - to receive(:selfie_status).and_return(:success) perform_in_browser(:desktop) do sign_in_and_2fa_user(user) From e37a9053dd23f6bf623b187afa46807334e3e8b0 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 3 Apr 2024 12:23:08 -0500 Subject: [PATCH 15/17] turn max_sha into a constant --- lib/ab_test_bucket.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ab_test_bucket.rb b/lib/ab_test_bucket.rb index 046f95190a7..5819dd63f9b 100644 --- a/lib/ab_test_bucket.rb +++ b/lib/ab_test_bucket.rb @@ -3,6 +3,8 @@ class AbTestBucket attr_reader :buckets, :experiment_name, :default_bucket + MAX_SHA = (16 ** 64) - 1 + def initialize(experiment_name:, buckets: {}, default_bucket: :default) @buckets = buckets @experiment_name = experiment_name @@ -30,8 +32,7 @@ def bucket(discriminator = nil) private def percent(discriminator) - max_sha = (16 ** 64) - 1 - Digest::SHA256.hexdigest("#{discriminator}:#{experiment_name}").to_i(16).to_f / max_sha * 100 + Digest::SHA256.hexdigest("#{discriminator}:#{experiment_name}").to_i(16).to_f / MAX_SHA * 100 end def valid_bucket_data_structure? From f484bc018043b8530b4b49e047871b6c1de70a6f Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 3 Apr 2024 13:26:38 -0500 Subject: [PATCH 16/17] remove tests that are covered well by AbTestBucket spec --- spec/services/doc_auth_router_spec.rb | 40 +-------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/spec/services/doc_auth_router_spec.rb b/spec/services/doc_auth_router_spec.rb index 79938a61654..adf18dced02 100644 --- a/spec/services/doc_auth_router_spec.rb +++ b/spec/services/doc_auth_router_spec.rb @@ -35,7 +35,6 @@ def reload_ab_test_initializer! let(:doc_auth_vendor) { 'test1' } let(:doc_auth_vendor_randomize_alternate_vendor) { 'test2' } - let(:discriminator) { SecureRandom.uuid } let(:analytics) { FakeAnalytics.new } let(:doc_auth_vendor_randomize_percent) { 57 } let(:doc_auth_vendor_randomize) { true } @@ -63,51 +62,14 @@ def reload_ab_test_initializer! end context 'with a nil discriminator' do - let(:discriminator) { nil } - it 'is the default vendor, and logs analytics events' do expect(analytics).to receive(:idv_doc_auth_randomizer_defaulted) - result = DocAuthRouter.doc_auth_vendor(discriminator: discriminator, analytics: analytics) + result = DocAuthRouter.doc_auth_vendor(discriminator: nil, analytics: analytics) expect(result).to eq(doc_auth_vendor) end end - - context 'with a discriminator that hashes inside the test group' do - before do - allow(AbTests::DOC_AUTH_VENDOR). - to receive(:percent).with(discriminator). - and_return(doc_auth_vendor_randomize_percent - 1) - end - - it 'is the alternate vendor' do - expect(DocAuthRouter.doc_auth_vendor(discriminator: discriminator)). - to eq(doc_auth_vendor_randomize_alternate_vendor) - end - - context 'with randomize false' do - let(:doc_auth_vendor_randomize) { false } - - it 'is the original vendor' do - expect(DocAuthRouter.doc_auth_vendor(discriminator: discriminator)). - to eq(doc_auth_vendor) - end - end - end - - context 'with a discriminator that hashes outside the test group' do - before do - allow(AbTests::DOC_AUTH_VENDOR). - to receive(:percent).with(discriminator). - and_return(doc_auth_vendor_randomize_percent + 1) - end - - it 'is the original' do - expect(DocAuthRouter.doc_auth_vendor(discriminator: discriminator)). - to eq(doc_auth_vendor) - end - end end describe DocAuthRouter::DocAuthErrorTranslatorProxy do From 69f5bc6c165a25bdaf65c97254ffefbf780a0e18 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 3 Apr 2024 14:45:24 -0500 Subject: [PATCH 17/17] fix redis down spec --- spec/requests/redis_down_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/redis_down_spec.rb b/spec/requests/redis_down_spec.rb index 4a60038232d..f7ef4441eee 100644 --- a/spec/requests/redis_down_spec.rb +++ b/spec/requests/redis_down_spec.rb @@ -3,7 +3,7 @@ RSpec.describe 'redis down session error handling' do context 'with bad Redis connection' do it 'fails loudly' do - allow(REDIS_POOL).to receive(:with).and_raise(Redis::CannotConnectError) + allow_any_instance_of(Redis).to receive(:set).and_raise(Redis::CannotConnectError) expect do get forgot_password_path end.to raise_error(Redis::CannotConnectError)