Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conflict #16389

Merged
merged 8 commits into from
Apr 17, 2024
2 changes: 1 addition & 1 deletion app/controllers/v0/profile/direct_deposits_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def control_info_params
end

def send_confirmation_email
VANotifyDdEmailJob.send_to_emails(current_user.all_emails, 'comp_and_pen')
VANotifyDdEmailJob.send_to_emails(current_user.all_emails)
end
end
end
Expand Down
13 changes: 10 additions & 3 deletions app/sidekiq/va_notify_dd_email_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class VANotifyDdEmailJob
STATSD_ERROR_NAME = 'worker.direct_deposit_confirmation_email.error'
STATSD_SUCCESS_NAME = 'worker.direct_deposit_confirmation_email.success'

def self.send_to_emails(user_emails, dd_type)
def self.send_to_emails(user_emails, dd_type = nil)
if user_emails.present?
user_emails.each do |email|
perform_async(email, dd_type)
Expand All @@ -25,9 +25,9 @@ def self.send_to_emails(user_emails, dd_type)
end
end

def perform(email, dd_type)
def perform(email, dd_type = nil)
notify_client = VaNotify::Service.new(Settings.vanotify.services.va_gov.api_key)
template_type = "direct_deposit_#{dd_type.to_sym == :ch33 ? 'edu' : 'comp_pen'}"
template_type = template_type(dd_type)
template_id = Settings.vanotify.services.va_gov.template_id.public_send(template_type)

notify_client.send_email(
Expand All @@ -39,6 +39,13 @@ def perform(email, dd_type)
handle_errors(e)
end

def template_type(dd_type)
return 'direct_deposit_edu' if dd_type&.to_sym == :ch33
return 'direct_deposit_comp_pen' if dd_type&.to_sym == :comp_pen

'direct_deposit'
end

def handle_errors(ex)
VANotifyDdEmailJob.log_exception_to_sentry(ex)
StatsD.increment(STATSD_ERROR_NAME)
Expand Down
1 change: 1 addition & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ vanotify:
in_progress_reminder_email_generic: fake_template_id
covid_vaccine_registration: fake_template_id
covid_vaccine_expanded_registration: fake_template_id
direct_deposit: direct_deposit_template_id
direct_deposit_edu: edu_template_id
direct_deposit_comp_pen: comp_pen_template_id
login_reactivation_email: reactivation_email_test_b
Expand Down
29 changes: 27 additions & 2 deletions lib/saml/post_url_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ def tou_declined_logout_redirect_url
end

def terms_of_use_redirect_url
application = @tracker&.payload_attr(:application) || 'vaweb'
if enabled_tou_clients.include?(application)
if terms_of_use_enabled_application
Rails.logger.info('Redirecting to /terms-of-use', type: :ssoe)
add_query(terms_of_use_url, { redirect_url: login_redirect_url })
else
Expand All @@ -79,6 +78,32 @@ def ssoe_slo_url

private

def terms_of_use_enabled_application
cache_key = "terms_of_use_redirect_user_#{user.uuid}"
cached_application = retrieve_and_delete_terms_of_use_redirect_user(cache_key)
current_application = @tracker&.payload_attr(:application)
write_terms_of_use_redirect_user(cache_key, current_application) if should_cache_application?(current_application)
terms_of_use_redirect_enabled?(cached_application, current_application)
end

def terms_of_use_redirect_enabled?(cached_application, current_application)
enabled_tou_clients.include?(cached_application || current_application || 'vaweb')
end

def should_cache_application?(application)
enabled_tou_clients.include?(application)
end

def retrieve_and_delete_terms_of_use_redirect_user(cache_key)
application = Rails.cache.read(cache_key)
Rails.cache.delete(cache_key)
application
end

def write_terms_of_use_redirect_user(cache_key, application)
Rails.cache.write(cache_key, application, expires_in: 5.minutes)
end

def terms_of_use_url
if Settings.review_instance_slug.present?
"http://#{Settings.review_instance_slug}.review.vetsgov-internal/terms-of-use"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ class ClaimsController < ApplicationController

def index
veis_token = client.request_veis_token
# Non-intuitive Ruby behavior: #split splits a string on space by default
vagov_token = request.headers['Authorization'].split[1]
btsss_token = client.request_btsss_token(veis_token, vagov_token)

sts_token = client.request_sts_token(@current_user)
btsss_token = client.request_btsss_token(veis_token, sts_token)

begin
claims = client.get_claims(veis_token, btsss_token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ def ping
end

def authorized_ping
vagov_token = request.headers['Authorization'].split[1]
sts_token = client.request_sts_token(@current_user)
veis_token = client.request_veis_token
btsss_token = client.request_btsss_token(veis_token, vagov_token)
btsss_token = client.request_btsss_token(veis_token, sts_token)

btsss_authorized_ping_response = client.authorized_ping(veis_token, btsss_token)
render json: {
Expand Down
57 changes: 55 additions & 2 deletions modules/travel_pay/app/services/travel_pay/client.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'securerandom'

module TravelPay
class Client
##
Expand All @@ -24,7 +26,7 @@ def request_veis_token
#
# @return [Faraday::Response]
#
def request_btsss_token(veis_token, vagov_token)
def request_btsss_token(veis_token, sts_token)
btsss_url = Settings.travel_pay.base_url
api_key = Settings.travel_pay.subscription_key
client_number = Settings.travel_pay.client_number
Expand All @@ -33,7 +35,7 @@ def request_btsss_token(veis_token, vagov_token)
req.headers['Authorization'] = "Bearer #{veis_token}"
req.headers['Ocp-Apim-Subscription-Key'] = api_key
req.headers['BTSSS-API-Client-Number'] = client_number.to_s
req.body = { authJwt: vagov_token }
req.body = { authJwt: sts_token }
end
response.body['access_token']
end
Expand Down Expand Up @@ -90,8 +92,59 @@ def get_claims(veis_token, btsss_token)
symbolized_body[:data].sort_by(&parse_claim_date).reverse!
end

def request_sts_token(user)
host_baseurl = build_host_baseurl({ ip_form: false })
private_key_file = Settings.sign_in.sts_client.key_path
private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file))

assertion = build_sts_assertion(user)
jwt = JWT.encode(assertion, private_key, 'RS256')

# send to sis
response = connection(server_url: host_baseurl).post('/v0/sign_in/token') do |req|
req.params['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
req.params['assertion'] = jwt
end

response.body['data']['access_token']
end

private

def build_sts_assertion(user)
service_account_id = Settings.travel_pay.sts.service_account_id
host_baseurl = build_host_baseurl({ ip_form: false })
audience_baseurl = build_host_baseurl({ ip_form: true })

current_time = Time.now.to_i
jti = SecureRandom.uuid

{
'iss' => host_baseurl,
'sub' => user.email,
'aud' => "#{audience_baseurl}/v0/sign_in/token",
'iat' => current_time,
'exp' => current_time + 300,
'scopes' => [],
'service_account_id' => service_account_id,
'jti' => jti,
'user_attributes' => { 'icn' => user.icn }
}
end

def build_host_baseurl(config)
env = Settings.vsp_environment
host = Settings.hostname

if env == 'localhost'
return 'http://127.0.0.1:3000' if config[:ip_form]

'http://localhost:3000'
end

"https://#{host}"
end

def veis_params
{
client_id: Settings.travel_pay.veis.client_id,
Expand Down
12 changes: 10 additions & 2 deletions modules/travel_pay/spec/controllers/claims_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
.to receive(:request_veis_token)
.and_return('veis_token')

allow_any_instance_of(TravelPay::Client)
.to receive(:request_sts_token)
.and_return('sts_token')

allow_any_instance_of(TravelPay::Client)
.to receive(:request_btsss_token)
.with('veis_token', 'vagov_token')
.with('veis_token', 'sts_token')
.and_return('btsss_token')

allow_any_instance_of(TravelPay::Client)
Expand All @@ -34,9 +38,13 @@
.to receive(:request_veis_token)
.and_return('veis_token')

allow_any_instance_of(TravelPay::Client)
.to receive(:request_sts_token)
.and_return('sts_token')

allow_any_instance_of(TravelPay::Client)
.to receive(:request_btsss_token)
.with('veis_token', 'vagov_token')
.with('veis_token', 'sts_token')
.and_return('btsss_token')

allow_any_instance_of(TravelPay::Client)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
before do
btsss_authorized_ping_response = double
allow(btsss_authorized_ping_response).to receive(:status).and_return(200)
allow(client)
.to receive(:request_sts_token)
.and_return('sample_sts_token')
allow(client)
.to receive(:request_btsss_token)
.and_return('sample_btsss_token')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
context 'when the user does have an associated email address' do
it 'sends an email through va notify' do
expect(VANotifyDdEmailJob).to receive(:send_to_emails).with(
user.all_emails, 'comp_and_pen'
user.all_emails
)

VCR.use_cassette('lighthouse/direct_deposit/update/200_valid') do
Expand Down
Loading
Loading