diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5f3c1446369..2ef9b9f7772 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -609,6 +609,7 @@ app/uploaders/uploader_virus_scan.rb @department-of-veterans-affairs/va-api-engi app/uploaders/validate_pdf.rb @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group app/uploaders/vets_shrine.rb @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group app/validators/token_util.rb @department-of-veterans-affairs/backend-review-group +app/uploaders/veteran_facing_forms_remediation_uploader.rb @department-of-veterans-affairs/platform-va-product-forms @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group app/sidekiq/account_login_statistics_job.rb @department-of-veterans-affairs/octo-identity app/sidekiq/benefits_intake_remediation_status_job.rb @department-of-veterans-affairs/platform-va-product-forms @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group app/sidekiq/benefits_intake_status_job.rb @department-of-veterans-affairs/platform-va-product-forms @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group @@ -2104,6 +2105,7 @@ spec/uploaders/form1010cg/poa_uploader_spec.rb @department-of-veterans-affairs/v spec/uploaders/supporting_evidence_attachment_uploader_spec.rb @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/uploaders/uploader_virus_scan_spec.rb @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/uploaders/validate_pdf_spec.rb @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group +spec/uploaders/veteran_facing_forms_remediation_uploader_spec.rb @department-of-veterans-affairs/platform-va-product-forms @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group app/models/prescription_details.rb @department-of-veterans-affairs/vfs-mhv-medications @department-of-veterans-affairs/backend-review-group modules/my_health/app/controllers/my_health/v1/prescriptions_controller.rb @department-of-veterans-affairs/vfs-mhv-medications @department-of-veterans-affairs/backend-review-group modules/my_health/spec/request/v1/prescriptions_request_spec.rb @department-of-veterans-affairs/vfs-mhv-medications @department-of-veterans-affairs/backend-review-group diff --git a/app/uploaders/veteran_facing_forms_remediation_uploader.rb b/app/uploaders/veteran_facing_forms_remediation_uploader.rb new file mode 100644 index 00000000000..c3cf2bc7ce0 --- /dev/null +++ b/app/uploaders/veteran_facing_forms_remediation_uploader.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class VeteranFacingFormsRemediationUploader < CarrierWave::Uploader::Base + include SetAWSConfig + include UploaderVirusScan + + def size_range + (1.byte)...(100_000_000.bytes) + end + + # All the same files allowed by benefits intake, with the + # addition of json for metadata and csv for manifest + def extension_allowlist + %w[bmp csv gif jpeg jpg json pdf png tif tiff txt] + end + + def initialize(benefits_intake_uuid, directory) + raise 'The benefits_intake_uuid is missing.' if benefits_intake_uuid.blank? + + super + @benefits_intake_uuid = benefits_intake_uuid + @directory = directory + + set_storage_options! + end + + def store_dir + raise 'The s3 directory is missing.' if @directory.blank? + + @directory + end + + def set_storage_options! + # TODO: update this to vff specific S3 bucket once it has been created + s3_settings = Settings.reports.aws + # defaults to CarrierWave::Storage::File if not AWS unless a real aws_access_key_id is set + if s3_settings.aws_access_key_id.present? + set_aws_config( + s3_settings.aws_access_key_id, + s3_settings.aws_secret_access_key, + s3_settings.region, + s3_settings.bucket + ) + end + end +end diff --git a/modules/simple_forms_api/app/services/simple_forms_api/s3/submission_archiver.rb b/modules/simple_forms_api/app/services/simple_forms_api/s3/submission_archiver.rb index 5483fab907f..363b3111758 100644 --- a/modules/simple_forms_api/app/services/simple_forms_api/s3/submission_archiver.rb +++ b/modules/simple_forms_api/app/services/simple_forms_api/s3/submission_archiver.rb @@ -36,7 +36,7 @@ def initialize(parent_dir: 'vff-simple-forms', **options) # rubocop:disable Lint def upload log_info("Uploading archive: #{benefits_intake_uuid} to S3 bucket") - upload_temp_folder_to_s3 + upload_directory_to_s3(temp_directory_path) cleanup generate_presigned_url rescue => e @@ -72,11 +72,16 @@ def build_submission_archive(**) SubmissionArchiveBuilder.new(**).run end - def upload_temp_folder_to_s3 - Dir.glob("#{temp_directory_path}/**/*").each do |path| + def upload_directory_to_s3(directory_path) + raise "Directory #{directory_path} does not exist" unless Dir.exist?(directory_path) + + Dir.glob(File.join(directory_path, '**', '*')).each do |path| next if File.directory?(path) - File.open(path, 'rb') { |file| save_file_to_s3(file.read) } + File.open(path) do |file_obj| + sanitized_file = CarrierWave::SanitizedFile.new(file_obj) + s3_uploader.store!(sanitized_file) + end end end @@ -102,10 +107,6 @@ def generate_presigned_url submission_object.presigned_url(:get, expires_in: 30.minutes.to_i) end - def save_file_to_s3(content) - submission_object.tap { |obj| obj.put(body: content) } - end - def submission_object s3_resource.bucket(target_bucket).object(s3_submission_file_path) end @@ -131,6 +132,10 @@ def s3_directory_path @s3_directory_path ||= "#{parent_dir}/#{unique_file_name}" end + def s3_uploader + @s3_uploader ||= VeteranFacingFormsRemediationUploader.new(benefits_intake_uuid, s3_submission_file_path) + end + def local_submission_file_path @local_submission_file_path ||= build_local_file_path(s3_submission_file_path) end diff --git a/spec/uploaders/veteran_facing_forms_remediation_uploader_spec.rb b/spec/uploaders/veteran_facing_forms_remediation_uploader_spec.rb new file mode 100644 index 00000000000..4ef25eb8f01 --- /dev/null +++ b/spec/uploaders/veteran_facing_forms_remediation_uploader_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe VeteranFacingFormsRemediationUploader do + subject { described_class.new(benefits_intake_uuid, directory) } + + let(:benefits_intake_uuid) { SecureRandom.uuid } + let(:directory) { '/some/path' } + + it 'allows image, pdf, json, csv, and text files' do + expect(subject.extension_allowlist).to match_array %w[bmp csv gif jpeg jpg json pdf png tif tiff txt] + end + + it 'returns a store directory containing benefits_intake_uuid' do + expect(subject.store_dir).to eq(directory) + end + + it 'throws an error if no benefits_intake_uuid is given' do + expect { described_class.new(nil, directory) }.to raise_error(RuntimeError, 'The benefits_intake_uuid is missing.') + end + + it 'throws an error if no directory is given' do + malformed_uploader = described_class.new(benefits_intake_uuid, nil) + expect { malformed_uploader.store_dir }.to raise_error(RuntimeError, 'The s3 directory is missing.') + end +end