Skip to content

Commit

Permalink
Merge branch 'master' into sjc-clamav-container
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenjcumming authored Apr 24, 2024
2 parents 236af02 + 6af92d9 commit f85a6ba
Show file tree
Hide file tree
Showing 123 changed files with 11,092 additions and 1,070 deletions.
8 changes: 8 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ app/mailers/views/veteran_readiness_employment_cmp.html.erb @department-of-veter
app/mailers/views/veteran_readiness_employment.html.erb @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
app/models/account_login_stat.rb @department-of-veterans-affairs/octo-identity
app/models/account.rb @department-of-veterans-affairs/octo-identity
app/models/accredited_individual.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
app/models/accredited_organization.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
app/models/adapters/payment_history_adapter.rb @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/va-api-engineers
app/models/appeal_submission.rb @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
app/models/appeal_submission_upload.rb @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down Expand Up @@ -667,6 +669,7 @@ config/form_profile_mappings/0873.yml @department-of-veterans-affairs/vfs-virtua
config/form_profile_mappings/1010ez.yml @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/10-10EZR.yml @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/10182.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/10-7959F-1.yml @department-of-veterans-affairs/champva-engineering @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/20-0995.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/20-0996.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
config/form_profile_mappings/21-526EZ.yml @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down Expand Up @@ -791,6 +794,7 @@ docs/setup/codespaces.md @department-of-veterans-affairs/backend-review-group @d
docs/setup/va_forms.md @department-of-veterans-affairs/platform-va-product-forms @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/va-api-engineers
docs/setup/virtual_machine_access.md @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/va-api-engineers
.github @department-of-veterans-affairs/backend-review-group
lib/accredited_representation/constants.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
lib/aes_256_cbc_encryptor.rb @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
lib/apps @department-of-veterans-affairs/vfs-facilities-frontend @department-of-veterans-affairs/lighthouse-pivot
lib/bb @department-of-veterans-affairs/vfs-vaos @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down Expand Up @@ -1076,6 +1080,8 @@ spec/factories/686c/form_686c_674.rb @department-of-veterans-affairs/benefits-de
spec/factories/686c/spouse.rb @department-of-veterans-affairs/benefits-dependents-management @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/factories/686c/step_child_lives_with_veteran.rb @department-of-veterans-affairs/benefits-dependents-management @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/factories/accounts.rb @department-of-veterans-affairs/octo-identity
spec/factories/accredited_individuals.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
spec/factories/accredited_organizations.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
spec/factories/appeal_submissions.rb @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/factories/appeal_submission_uploads.rb @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/factories/ask.rb @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down Expand Up @@ -1439,6 +1445,8 @@ spec/mailers/transactional_email_mailer_spec.rb @department-of-veterans-affairs/
spec/mailers/veteran_readiness_employment_mailer_spec.rb @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/middleware @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/models/account_spec.rb @department-of-veterans-affairs/octo-identity
spec/models/accredited_individual_spec.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
spec/models/accredited_organization_spec.rb @department-of-veterans-affairs/accredited-representation-management @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-accredited-rep-facing
spec/models/async_transaction/base_spec.rb @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/models/async_transaction/va_profile @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/models/async_transaction/vet360 @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
FROM ruby:3.2.3-slim-bullseye AS rubyimg
FROM ruby:3.2.3-slim-bookworm as rubyimg

# XXX: using stretch here for pdftk dep, which is not availible after
# stretch (or in alpine) and is switched automatically to pdftk-java in buster
# https://github.com/department-of-veterans-affairs/va.gov-team/issues/3032

FROM rubyimg AS modules

WORKDIR /tmp
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ gem 'carrierwave-aws'
gem 'clamav-client', require: 'clamav/client'
gem 'combine_pdf'
gem 'config'
gem 'connect_vbms', git: 'https://github.com/department-of-veterans-affairs/connect_vbms.git', branch: 'master', require: 'vbms'
gem 'connect_vbms', git: 'https://github.com/adhocteam/connect_vbms', tag: 'v2.0.0.rc', require: 'vbms'
gem 'date_validator'
gem 'ddtrace'
gem 'dogstatsd-ruby', '5.6.1'
Expand Down
37 changes: 19 additions & 18 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
GIT
remote: https://github.com/adhocteam/connect_vbms
revision: 6e5dc751afaf0da9c7cbc10c94b909f114f3a156
tag: v2.0.0.rc
specs:
connect_vbms (2.0.0.rc)
httpclient (~> 2.8.0)
httpi (~> 2.4)
mail
nokogiri (>= 1.8.4)
nori
xmldsig (~> 0.3.1)
xmlenc

GIT
remote: https://github.com/department-of-veterans-affairs/apivore
revision: f8ccd476f6c5301f5ebe4e2dd5b30ff0e567ffc1
Expand Down Expand Up @@ -30,20 +44,6 @@ GIT
nokogiri (>= 1.13.6)
savon (= 2.12)

GIT
remote: https://github.com/department-of-veterans-affairs/connect_vbms.git
revision: 1834cf61310001c82e2e96d665518407c3bce947
branch: master
specs:
connect_vbms (1.4.0)
httpclient (~> 2.8.0)
httpi (~> 2.4)
mail
nokogiri (>= 1.8.4)
nori
xmldsig (~> 0.3.1)
xmlenc

GIT
remote: https://github.com/department-of-veterans-affairs/fhir_client.git
revision: 52e0197dcb1f940a1f0b28bfa983699f0c199696
Expand Down Expand Up @@ -317,7 +317,7 @@ GEM
content_disposition (1.0.0)
cork (0.3.0)
colored2 (~> 3.1)
coverband (6.1.0)
coverband (6.1.1)
redis (>= 3.0)
crack (1.0.0)
bigdecimal
Expand Down Expand Up @@ -666,7 +666,8 @@ GEM
nokogiri (1.16.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nori (2.6.0)
nori (2.7.0)
bigdecimal
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
Expand Down Expand Up @@ -695,7 +696,7 @@ GEM
os (1.1.4)
ox (2.14.18)
parallel (1.24.0)
parallel_tests (4.6.1)
parallel_tests (4.7.0)
parallel
parser (3.3.0.5)
ast (~> 2.4.1)
Expand Down Expand Up @@ -893,7 +894,7 @@ GEM
rswag-ui (2.13.0)
actionpack (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
rubocop (1.63.2)
rubocop (1.63.3)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
Expand Down
118 changes: 86 additions & 32 deletions app/controllers/v0/terms_of_use_agreements_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,79 @@ class TermsOfUseAgreementsController < ApplicationController
before_action :terms_authenticate

def latest
terms_of_use_agreement = get_terms_of_use_agreements_for_version(params[:version]).last
render_success(terms_of_use_agreement, :ok)
terms_of_use_agreement = find_latest_agreement_by_version(params[:version])
render_success(action: 'latest', body: { terms_of_use_agreement: })
end

def accept
terms_of_use_agreement = TermsOfUse::Acceptor.new(user_account: current_user.user_account,
common_name: current_user.common_name,
version: params[:version]).perform!
recache_user
render_success(terms_of_use_agreement, :created)
terms_of_use_agreement = acceptor.perform!
recache_user unless terms_code_temporary_auth?
render_success(action: 'accept', body: { terms_of_use_agreement: }, status: :created)
rescue TermsOfUse::Errors::AcceptorError => e
render_error(e.message)
render_error(action: 'accept', message: e.message)
end

def accept_and_provision
terms_of_use_agreement = acceptor(async: false).perform!
if terms_of_use_agreement.accepted? && provisioner.perform
create_cerner_cookie
recache_user unless terms_code_temporary_auth?
render_success(action: 'accept_and_provision', body: { terms_of_use_agreement:, provisioned: true },
status: :created)
else
render_error(action: 'accept_and_provision', message: 'Failed to accept and provision')
end
rescue TermsOfUse::Errors::AcceptorError => e
render_error(action: 'accept_and_provision', message: e.message)
end

def decline
terms_of_use_agreement = TermsOfUse::Decliner.new(user_account: current_user.user_account,
common_name: current_user.common_name,
version: params[:version]).perform!
recache_user
render_success(terms_of_use_agreement, :created)
terms_of_use_agreement = decliner.perform!
recache_user unless terms_code_temporary_auth?
render_success(action: 'decline', body: { terms_of_use_agreement: }, status: :created)
rescue TermsOfUse::Errors::DeclinerError => e
render_error(e.message)
render_error(action: 'decline', message: e.message)
end

def update_provisioning
provisioner = TermsOfUse::Provisioner.new(icn: current_user.icn,
first_name: current_user.first_name,
last_name: current_user.last_name,
mpi_gcids: current_user.mpi_gcids)
if provisioner.perform
create_cerner_cookie
Rails.logger.info('[TermsOfUseAgreementsController] update_provisioning success', { icn: current_user.icn })
render json: { provisioned: true }, status: :ok
render_success(action: 'update_provisioning', body: { provisioned: true }, status: :ok)
else
Rails.logger.error('[TermsOfUseAgreementsController] update_provisioning error', { icn: current_user.icn })
render_error('Failed to provision')
render_error(action: 'update_provisioning', message: 'Failed to provision')
end
rescue TermsOfUse::Errors::ProvisionerError => e
render_error(e.message)
render_error(action: 'update_provisioning', message: e.message)
end

private

def acceptor(async: true)
TermsOfUse::Acceptor.new(
user_account: @user_account,
common_name:,
version: params[:version],
async:
)
end

def decliner
TermsOfUse::Decliner.new(
user_account: @user_account,
common_name:,
version: params[:version]
)
end

def provisioner
TermsOfUse::Provisioner.new(
icn: @user_account.icn,
first_name: mpi_profile.given_names.first,
last_name: mpi_profile.family_name,
mpi_gcids: mpi_profile.full_mvi_ids
)
end

def recache_user
current_user.needs_accepted_terms_of_use = current_user.user_account&.needs_accepted_terms_of_use?
current_user.save
Expand All @@ -68,29 +98,53 @@ def create_cerner_cookie
}
end

def get_terms_of_use_agreements_for_version(version)
current_user.user_account.terms_of_use_agreements.where(agreement_version: version)
def find_latest_agreement_by_version(version)
@user_account.terms_of_use_agreements.where(agreement_version: version).last
end

def authenticate_one_time_terms_code
terms_code_container = SignIn::TermsCodeContainer.find(params[:terms_code])
@current_user = User.find(terms_code_container.user_uuid)
return unless terms_code_container

@user_account = UserAccount.find(terms_code_container.user_account_uuid)
ensure
terms_code_container&.destroy
end

def authenticate_current_user
load_user(skip_terms_check: true)
return unless current_user

@user_account = current_user.user_account
end

def terms_code_temporary_auth?
params[:terms_code].present?
end

def terms_authenticate
params[:terms_code].present? ? authenticate_one_time_terms_code : load_user(skip_terms_check: true)
terms_code_temporary_auth? ? authenticate_one_time_terms_code : authenticate_current_user

raise Common::Exceptions::Unauthorized unless @user_account
end

def mpi_profile
@mpi_profile ||= MPI::Service.new.find_profile_by_identifier(identifier: @user_account.icn,
identifier_type: MPI::Constants::ICN)&.profile
end

raise Common::Exceptions::Unauthorized unless @current_user
def common_name
"#{mpi_profile.given_names.first} #{mpi_profile.family_name}"
end

def render_success(terms_of_use_agreement, status)
render json: { terms_of_use_agreement: }, status:
def render_success(action:, body:, status: :ok)
Rails.logger.info("[TermsOfUseAgreementsController] #{action} success", { icn: @user_account.icn })
render json: body, status:
end

def render_error(message)
render json: { error: message }, status: :unprocessable_entity
def render_error(action:, message:, status: :unprocessable_entity)
Rails.logger.error("[TermsOfUseAgreementsController] #{action} error: #{message}", { icn: @user_account.icn })
render json: { error: message }, status:
end
end
end
43 changes: 43 additions & 0 deletions app/models/accredited_individual.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require 'accredited_representation/constants'

class AccreditedIndividual < ApplicationRecord
# rubocop:disable Rails/HasAndBelongsToMany
has_and_belongs_to_many :accredited_organizations,
class: 'AccreditedOrganization',
join_table: 'accredited_individuals_accredited_organizations'

# rubocop:enable Rails/HasAndBelongsToMany

validates :ogc_id, :registration_number, :individual_type, presence: true
validates :poa_code, length: { is: 3 }, allow_blank: true
validates :individual_type, uniqueness: { scope: :registration_number }

enum individual_type: {
'attorney' => 'attorney',
'claims_agent' => 'claims_agent',
'representative' => 'representative'
}

# Find all [AccreditedIndividuals] that are located within a distance of a specific location
# @param long [Float] longitude of the location of interest
# @param lat [Float] latitude of the location of interest
# @param max_distance [Float] the maximum search distance in meters
#
# @return [AccreditedIndividual::ActiveRecord_Relation] an ActiveRecord_Relation of
# all individuals matching the search criteria
def self.find_within_max_distance(long, lat, max_distance = AccreditedRepresentation::Constants::DEFAULT_MAX_DISTANCE)
query = 'ST_DWithin(ST_SetSRID(ST_MakePoint(:long, :lat), 4326)::geography, location, :max_distance)'
params = { long:, lat:, max_distance: }

where(query, params)
end

# return all poa_codes associated with the individual
#
# @return [Array<String>]
def poa_codes
([poa_code] + accredited_organizations.pluck(:poa_code)).compact
end
end
37 changes: 37 additions & 0 deletions app/models/accredited_organization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require 'accredited_representation/constants'

class AccreditedOrganization < ApplicationRecord
# rubocop:disable Rails/HasAndBelongsToMany
has_and_belongs_to_many :accredited_individuals,
class: 'AccreditedIndividual',
join_table: 'accredited_individuals_accredited_organizations'
# rubocop:enable Rails/HasAndBelongsToMany

validates :ogc_id, :poa_code, presence: true
validates :poa_code, length: { is: 3 }
validates :poa_code, uniqueness: true

#
# Find all [AccreditedOrganizations] that are located within a distance of a specific location
# @param long [Float] longitude of the location of interest
# @param lat [Float] latitude of the location of interest
# @param max_distance [Float] the maximum search distance in meters
#
# @return [AccreditedOrganization::ActiveRecord_Relation] an ActiveRecord_Relation of
# all organizations matching the search criteria
def self.find_within_max_distance(long, lat, max_distance = AccreditedRepresentation::Constants::DEFAULT_MAX_DISTANCE)
query = 'ST_DWithin(ST_SetSRID(ST_MakePoint(:long, :lat), 4326)::geography, location, :max_distance)'
params = { long:, lat:, max_distance: }

where(query, params)
end

# return all registration_numbers associated with the individual
#
# @return [Array<String>]
def registration_numbers
accredited_individuals.pluck(:registration_number)
end
end
Loading

0 comments on commit f85a6ba

Please sign in to comment.