From 21d1546b4211119f6aa634e4f2270a4bc90c2b1a Mon Sep 17 00:00:00 2001 From: Trevor Bosaw Date: Wed, 17 Apr 2024 13:14:09 -0700 Subject: [PATCH] [80904] Creating a terms of use application check that occurs during secondary authentications with custom (#16371) --- lib/saml/post_url_service.rb | 29 +++++- spec/lib/saml/post_url_service_spec.rb | 129 ++++++++++++++++++------- 2 files changed, 121 insertions(+), 37 deletions(-) diff --git a/lib/saml/post_url_service.rb b/lib/saml/post_url_service.rb index d16313784d4..b91b651d8e0 100644 --- a/lib/saml/post_url_service.rb +++ b/lib/saml/post_url_service.rb @@ -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 @@ -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" diff --git a/spec/lib/saml/post_url_service_spec.rb b/spec/lib/saml/post_url_service_spec.rb index 692020efd7a..fb2c9df8172 100644 --- a/spec/lib/saml/post_url_service_spec.rb +++ b/spec/lib/saml/post_url_service_spec.rb @@ -613,29 +613,102 @@ let(:expected_log_message) { 'Redirecting to /terms-of-use' } let(:expected_log_payload) { { type: :ssoe } } - context 'when tracker application is within Settings.terms_of_use.enabled_clients' do + context 'when associated terms of use redirect user cache object exists' do + let(:cache_key) { "terms_of_use_redirect_user_#{user.uuid}" } + let(:enabled_clients) { application } + let(:cache_expiration) { 5.minutes } + before do - allow(Settings.terms_of_use).to receive(:enabled_clients).and_return(application) + allow(Settings.terms_of_use).to receive(:enabled_clients).and_return(enabled_clients) + allow(Rails.cache).to receive(:read).with(cache_key).and_return(application) end - context 'and authentication is occuring on a review instance' do - let(:review_instance_slug) { 'some-review-instance-slug' } - let(:review_instance_url) { "#{review_instance_slug}.review.vetsgov-internal" } + context 'and application is within Settings.terms_of_use.enabled_clients' do + let(:enabled_clients) { application } - before { allow(Settings).to receive(:review_instance_slug).and_return(review_instance_slug) } + context 'and authentication is occuring on a review instance' do + let(:review_instance_slug) { 'some-review-instance-slug' } + let(:review_instance_url) { "#{review_instance_slug}.review.vetsgov-internal" } - it 'has a login redirect url as a parameter embedded in review instance terms of use page' do - expect(subject.terms_of_use_redirect_url) - .to eq("http://#{review_instance_url}/terms-of-use?#{expected_redirect_url_param}") + before { allow(Settings).to receive(:review_instance_slug).and_return(review_instance_slug) } + + it 'has a login redirect url as a parameter embedded in review instance terms of use page' do + expect(subject.terms_of_use_redirect_url) + .to eq("http://#{review_instance_url}/terms-of-use?#{expected_redirect_url_param}") + end + + it 'logs expected message and payload' do + expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) + subject.terms_of_use_redirect_url + end end - it 'logs expected message and payload' do - expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) - subject.terms_of_use_redirect_url + context 'and authentication is not occurring on a review instance' do + it 'has a login redirect url as a parameter embedded in terms of use page with success' do + expect(subject.terms_of_use_redirect_url) + .to eq("#{values[:base_redirect]}/terms-of-use?#{expected_redirect_url_param}") + end + + it 'logs expected message and payload' do + expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) + subject.terms_of_use_redirect_url + end end end - context 'and authentication is not occurring on a review instance' do + context 'and stored application is not within Settings.terms_of_use.enabled_clients' do + let(:enabled_clients) { '' } + + it 'has a login redirect url with success not embedded in a terms of use page' do + expect(subject.terms_of_use_redirect_url).to eq(expected_login_redirect_url) + end + end + + it 'deletes the cached terms of use redirect user object' do + expect(Rails.cache).to receive(:delete).with(cache_key) + subject.terms_of_use_redirect_url + end + end + + context 'when associated terms of use redirect user cache object does not exist' do + context 'when tracker application is within Settings.terms_of_use.enabled_clients' do + before do + allow(Settings.terms_of_use).to receive(:enabled_clients).and_return(application) + end + + context 'and authentication is occuring on a review instance' do + let(:review_instance_slug) { 'some-review-instance-slug' } + let(:review_instance_url) { "#{review_instance_slug}.review.vetsgov-internal" } + + before { allow(Settings).to receive(:review_instance_slug).and_return(review_instance_slug) } + + it 'has a login redirect url as a parameter embedded in review instance terms of use page' do + expect(subject.terms_of_use_redirect_url) + .to eq("http://#{review_instance_url}/terms-of-use?#{expected_redirect_url_param}") + end + + it 'logs expected message and payload' do + expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) + subject.terms_of_use_redirect_url + end + end + + context 'and authentication is not occurring on a review instance' do + it 'has a login redirect url as a parameter embedded in terms of use page with success' do + expect(subject.terms_of_use_redirect_url) + .to eq("#{values[:base_redirect]}/terms-of-use?#{expected_redirect_url_param}") + end + + it 'logs expected message and payload' do + expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) + subject.terms_of_use_redirect_url + end + end + end + + context 'when tracker application is nil' do + let(:application) { nil } + it 'has a login redirect url as a parameter embedded in terms of use page with success' do expect(subject.terms_of_use_redirect_url) .to eq("#{values[:base_redirect]}/terms-of-use?#{expected_redirect_url_param}") @@ -646,30 +719,16 @@ subject.terms_of_use_redirect_url end end - end - - context 'when tracker application is nil' do - let(:application) { nil } - - it 'has a login redirect url as a parameter embedded in terms of use page with success' do - expect(subject.terms_of_use_redirect_url) - .to eq("#{values[:base_redirect]}/terms-of-use?#{expected_redirect_url_param}") - end - - it 'logs expected message and payload' do - expect(Rails.logger).to receive(:info).with(expected_log_message, expected_log_payload) - subject.terms_of_use_redirect_url - end - end - context 'when tracker application is not within Settings.terms_of_use.enabled_clients' do - before do - allow(Settings.terms_of_use).to receive(:enabled_clients).and_return('') - end + context 'when tracker application is not within Settings.terms_of_use.enabled_clients' do + before do + allow(Settings.terms_of_use).to receive(:enabled_clients).and_return('') + end - it 'has a login redirect url with success not embedded in a terms of use page' do - expect(subject.terms_of_use_redirect_url) - .to eq(expected_login_redirect_url) + it 'has a login redirect url with success not embedded in a terms of use page' do + expect(subject.terms_of_use_redirect_url) + .to eq(expected_login_redirect_url) + end end end end