Skip to content

Commit

Permalink
Merge branch 'master' into pension-77412-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
TaiWilkin authored Mar 26, 2024
2 parents 30dd537 + 0a3f02a commit 6bde7f4
Show file tree
Hide file tree
Showing 128 changed files with 3,326 additions and 525 deletions.
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ end

group :test do
gem 'apivore', git: 'https://github.com/department-of-veterans-affairs/apivore', tag: 'v2.0.0.vsp'
gem 'fakeredis'
gem 'mock_redis'
gem 'pdf-inspector'
gem 'rspec_junit_formatter'
gem 'rspec-retry'
Expand Down Expand Up @@ -215,7 +215,7 @@ group :development, :test do
gem 'rubocop-rails'
gem 'rubocop-rspec'
gem 'rubocop-thread_safety'
gem 'sidekiq', '>= 6.4.0'
gem 'sidekiq', '~> 7.2.0'
gem 'timecop'
gem 'webmock'
gem 'yard'
Expand Down
44 changes: 24 additions & 20 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,13 @@ PATH
GEM
remote: https://enterprise.contribsys.com/
specs:
sidekiq-ent (2.5.3)
einhorn (>= 0.7.4)
sidekiq (>= 6.5.0, < 7)
sidekiq-pro (>= 5.5.0, < 6)
sidekiq-pro (5.5.8)
sidekiq (~> 6.0, >= 6.5.6)
sidekiq-ent (7.2.2)
einhorn (~> 1.0)
gserver
sidekiq (>= 7.2.0, < 8)
sidekiq-pro (>= 7.2.0, < 8)
sidekiq-pro (7.2.0)
sidekiq (>= 7.2.0, < 8)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -282,7 +283,7 @@ GEM
bundler (>= 1.2.0, < 3)
thor (~> 1.0)
byebug (11.1.3)
carrierwave (3.0.6)
carrierwave (3.0.7)
activemodel (>= 6.0.0)
activesupport (>= 6.0.0)
addressable (~> 2.6)
Expand Down Expand Up @@ -415,10 +416,8 @@ GEM
factory_bot_rails (6.4.3)
factory_bot (~> 6.4)
railties (>= 5.0.0)
faker (3.2.3)
faker (3.3.0)
i18n (>= 1.8.11, < 2)
fakeredis (0.9.2)
redis (~> 4.8)
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
faraday-follow_redirects (0.3.0)
Expand Down Expand Up @@ -634,6 +633,7 @@ GEM
mini_mime (1.1.5)
mini_portile2 (2.8.5)
minitest (5.22.3)
mock_redis (0.44.0)
msgpack (1.7.2)
msgpack (1.7.2-java)
multi_json (1.15.0)
Expand Down Expand Up @@ -691,7 +691,7 @@ GEM
os (1.1.4)
ox (2.14.18)
parallel (1.24.0)
parallel_tests (4.5.2)
parallel_tests (4.6.0)
parallel
parser (3.3.0.5)
ast (~> 2.4.1)
Expand Down Expand Up @@ -810,9 +810,12 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
rchardet (1.8.0)
rdoc (6.6.2)
rdoc (6.6.3.1)
psych (>= 4.0.0)
redis (4.8.1)
redis (5.1.0)
redis-client (>= 0.17.0)
redis-client (0.20.0)
connection_pool
redis-namespace (1.11.0)
redis (>= 4)
regexp_parser (2.9.0)
Expand Down Expand Up @@ -904,7 +907,7 @@ GEM
rubocop-factory_bot (2.25.1)
rubocop (~> 1.41)
rubocop-junit-formatter (0.1.4)
rubocop-rails (2.24.0)
rubocop-rails (2.24.1)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
Expand Down Expand Up @@ -954,10 +957,11 @@ GEM
shrine (3.5.0)
content_disposition (~> 1.0)
down (~> 5.1)
sidekiq (6.5.12)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
sidekiq (7.2.2)
concurrent-ruby (< 2)
connection_pool (>= 2.3.0)
rack (>= 2.2.4)
redis-client (>= 0.19.0)
sidekiq_alive (2.4.0)
gserver (~> 0.0.1)
sidekiq (>= 5, < 8)
Expand Down Expand Up @@ -1122,7 +1126,6 @@ DEPENDENCIES
facilities_api!
factory_bot_rails
faker
fakeredis
faraday (~> 2.9)
faraday-follow_redirects
faraday-httpclient
Expand Down Expand Up @@ -1170,6 +1173,7 @@ DEPENDENCIES
mimemagic
mini_magick
mobile!
mock_redis
mocked_authentication!
my_health!
net-sftp
Expand Down Expand Up @@ -1234,7 +1238,7 @@ DEPENDENCIES
sentry-ruby
shoulda-matchers
shrine
sidekiq (>= 6.4.0)
sidekiq (~> 7.2.0)
sidekiq-ent!
sidekiq-pro!
sidekiq_alive
Expand Down
12 changes: 9 additions & 3 deletions app/controllers/v0/burial_claims_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ class BurialClaimsController < ClaimsBaseController

def create
PensionBurial::TagSentry.tag_sentry
claim = claim_class.new(form: filtered_params[:form])

claim = if Flipper.enabled?(:va_burial_v2)
# cannot parse a nil form, to pass unit tests do a check for form presence
form = filtered_params[:form]
claim_class.new(form:, formV2: form.present? ? JSON.parse(form)['formV2'] : nil)
else
claim_class.new(form: filtered_params[:form])
end

unless claim.save
StatsD.increment("#{stats_key}.failure")
Sentry.set_tags(team: 'benefits-memorial-1') # tag sentry logs with team name
raise Common::Exceptions::ValidationErrors, claim
end

# this method also calls claim.process_attachments!
claim.submit_to_structured_data_services!

Rails.logger.info "ClaimID=#{claim.confirmation_number} Form=#{claim.class::FORM}"
Rails.logger.info "ClaimID=#{claim.confirmation_number} Form=#{claim.form_id}"
clear_saved_form(claim.form_id)
render(json: claim)
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/v0/claim_documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def create

def klass
case form_id
when '21P-527EZ', '21P-530'
when '21P-527EZ', '21P-530', '21P-530V2'
PensionBurial::TagSentry.tag_sentry
PersistentAttachments::PensionBurial
when '21-686C', '686C-674'
Expand Down
73 changes: 73 additions & 0 deletions app/controllers/v1/pension_ipf_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

require 'decision_review_v1/utilities/logging_utils'

module V1
class PensionIpfCallbacksController < ApplicationController
include ActionController::HttpAuthentication::Token::ControllerMethods
include DecisionReviewV1::Appeals::LoggingUtils

service_tag 'pension-ipf-callbacks'

skip_before_action :verify_authenticity_token, only: [:create]
skip_before_action :authenticate, only: [:create]
skip_after_action :set_csrf_header, only: [:create]
before_action :authenticate_header, only: [:create]

STATUSES_TO_IGNORE = %w[sent delivered temporary-failure].freeze

def create
return render json: nil, status: :not_found unless Flipper.enabled? :pension_ipf_callbacks_endpoint

payload = JSON.parse(request.body.string)

# save encrypted request body in database table for non-successful notifications
payload_status = payload['status']&.downcase
if STATUSES_TO_IGNORE.exclude? payload_status
begin
PensionIpfNotification.create!(payload:)
rescue ActiveRecord::RecordInvalid => e
log_formatted(**log_params(payload).merge(is_success: false), params: { exception_message: e.message })
return render json: { message: 'failed' }
end
end

log_formatted(**log_params(payload).merge(is_success: true))
render json: { message: 'success' }
end

private

def authenticate_header
authenticate_user_with_token || authenticity_error
end

def authenticate_user_with_token
Rails.logger.info('pension-ipf-callbacks-69766 - Received request, authenticating')
authenticate_with_http_token do |token|
return false if bearer_token_secret.nil?

token == bearer_token_secret
end
end

def authenticity_error
Rails.logger.info('pension-ipf-callbacks-69766 - Failed to authenticate request')
render json: { message: 'Invalid credentials' }, status: :unauthorized
end

def bearer_token_secret
Settings.dig(:pension_ipf_vanotify_status_callback, :bearer_token)
end

def log_params(payload)
{
key: :callbacks,
form_id: '21P-527EZ',
user_uuid: nil,
upstream_system: 'VANotify',
body: payload.merge('to' => '<FILTERED>') # scrub PII from logs
}
end
end
end
3 changes: 2 additions & 1 deletion app/models/form_profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class FormProfile
22-5495 22-0993 22-0994 FEEDBACK-TOOL 22-10203 22-1990S 22-1990EZ],
evss: ['21-526EZ'],
hca: %w[1010ez 10-10EZR],
pension_burial: %w[21P-530 21P-527EZ],
pension_burial: %w[21P-530 21P-527EZ 21P-530V2],
dependents: ['686C-674'],
decision_review: %w[20-0995 20-0996 10182],
mdot: ['MDOT'],
Expand Down Expand Up @@ -121,6 +121,7 @@ class FormProfile
'22-5490E' => ::FormProfiles::VA5490e,
'22-5495' => ::FormProfiles::VA5495,
'21P-530' => ::FormProfiles::VA21p530,
'21P-530V2' => ::FormProfiles::VA21p530v2,
'21-686C' => ::FormProfiles::VA21686c,
'686C-674' => ::FormProfiles::VA686c674,
'40-10007' => ::FormProfiles::VA4010007,
Expand Down
33 changes: 33 additions & 0 deletions app/models/form_profiles/va_21p530v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require 'iso_country_codes'

class FormProfiles::VA21p530v2 < FormProfile
def metadata
{
version: 0,
prefill: true,
returnUrl: '/claimant-information'
}
end

def prefill
@identity_information = initialize_identity_information
@contact_information = initialize_contact_information
if @contact_information&.address&.country.present?
@contact_information.address.country = convert_to_iso2(@contact_information.address.country)
end
mappings = self.class.mappings_for_form(form_id)

form_data = generate_prefill(mappings) if FormProfile.prefill_enabled_forms.include?(form_id)

{ form_data:, metadata: }
end

private

def convert_to_iso2(country_code)
code = IsoCountryCodes.find(country_code)
code.alpha2
end
end
20 changes: 20 additions & 0 deletions app/models/pension_ipf_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'json_marshal/marshaller'

class PensionIpfNotification < ApplicationRecord
serialize :payload, JsonMarshal::Marshaller

has_kms_key
has_encrypted :payload, key: :kms_key, **lockbox_options

validates(:payload, presence: true)

before_save :serialize_payload

private

def serialize_payload
self.payload = payload.to_json unless payload.is_a?(String)
end
end
8 changes: 6 additions & 2 deletions app/models/saved_claim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SavedClaim < ApplicationRecord
# create a uuid for this second (used in the confirmation number) and store
# the form type based on the constant found in the subclass.
after_initialize do
self.form_id = self.class::FORM.upcase
self.form_id = self.class::FORM.upcase unless instance_of?(SavedClaim::Burial)
end

def self.add_form_and_validation(form_id)
Expand All @@ -51,7 +51,7 @@ def process_attachments!

def submit_to_structured_data_services!
# Only 21P-530 burial forms are supported at this time
if form_id != '21P-530'
unless %w[21P-530 21P-530V2].include?(form_id)
err_message = "Unsupported form id: #{form_id}"
raise Common::Exceptions::UnprocessableEntity.new(detail: err_message), err_message
end
Expand Down Expand Up @@ -102,6 +102,10 @@ def update_form(key, value)
self.form = JSON.generate(application)
end

def business_line
''
end

private

def attachment_keys
Expand Down
23 changes: 23 additions & 0 deletions app/models/saved_claim/burial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
class SavedClaim::Burial < CentralMailClaim
FORM = '21P-530'

# attribute name is passed from the FE as a flag, maintaining camel case
attr_accessor :formV2 # rubocop:disable Naming/MethodName

after_initialize do
self.form_id = if Flipper.enabled?(:va_burial_v2)
formV2 || form_id == '21P-530V2' ? '21P-530V2' : self.class::FORM.upcase
else
self.class::FORM.upcase
end
end

def process_attachments!
refs = attachment_keys.map { |key| Array(open_struct_form.send(key)) }.flatten
files = PersistentAttachment.where(guid: refs.map(&:confirmationCode))
Expand All @@ -24,4 +35,16 @@ def attachment_keys
def email
parsed_form['claimantEmail']
end

def form_matches_schema
return unless form_is_string

JSON::Validator.fully_validate(VetsJsonSchema::SCHEMAS[form_id], parsed_form).each do |v|
errors.add(:form, v.to_s)
end
end

def business_line
'NCA'
end
end
4 changes: 4 additions & 0 deletions app/models/saved_claim/education_career_counseling_claim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ def process_attachments!

CentralMail::SubmitSavedClaimJob.new.perform(id)
end

def business_line
'EDU'
end
end
Loading

0 comments on commit 6bde7f4

Please sign in to comment.