Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added app/assets/images/inherited_proofing/switch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion app/controllers/accounts/personal_keys_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def pii_locked?
# @return [FormResponse]
def send_new_personal_key_notifications
emails = current_user.confirmed_email_addresses.map do |email_address|
UserMailer.personal_key_regenerated(current_user, email_address.email).deliver_now_or_later
UserMailer.with(user: current_user, email_address: email_address).personal_key_regenerated.
deliver_now_or_later
end

telephony_responses = MfaContext.new(current_user).
Expand Down
20 changes: 16 additions & 4 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,22 @@ def sp_session
end

def sp_session_request_url_with_updated_params
# Login.gov redirects to the orginal request_url after a user authenticates
# replace prompt=login with prompt=select_account to prevent sign_out
# which should only every occur once when the user lands on Login.gov with prompt=login
url = sp_session[:request_url]&.gsub('prompt=login', 'prompt=select_account')
# Temporarily place SAML route update behind a feature flag
if IdentityConfig.store.saml_internal_post
return unless sp_session[:request_url].present?
request_url = URI(sp_session[:request_url])
url = if request_url.path.match?('saml')
complete_saml_url
else
# Login.gov redirects to the orginal request_url after a user authenticates
# replace prompt=login with prompt=select_account to prevent sign_out
# which should only ever occur once when the user
# lands on Login.gov with prompt=login
sp_session[:request_url]&.gsub('prompt=login', 'prompt=select_account')
end
else
url = sp_session[:request_url]&.gsub('prompt=login', 'prompt=select_account')
end

# If the user has changed the locale, we should preserve that as well
if url && locale_url_param && UriService.params(url)[:locale] != locale_url_param
Expand Down
37 changes: 37 additions & 0 deletions app/controllers/concerns/allowlisted_flow_step_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This Concern satisfies the brakeman gem "Dynamic Render Path" violation
# that is raised when rendering dynamic content in views and partials
# that come directly from params. In the below example, idv_inherited_proofing_cancel_path
# would render "/verify/inherited_proofing/cancel?step=<params[:step]>" where <params[:step]>
# == the value of params[:step], which could potentially be dangerous:
# <%= render ButtonComponent.new(action: ->(...) do
# button_to(idv_inherited_proofing_cancel_path(step: params[:step]), ...) ...
# end
# %>
module AllowlistedFlowStepConcern
extend ActiveSupport::Concern

included do
before_action :flow_step!
end

private

def flow_step!
flow_step = flow_step_param
unless flow_step_allowlist.include? flow_step
Rails.logger.warn "Flow step param \"#{flow_step})\" was not whitelisted!"
render_not_found and return
end

@flow_step = flow_step
end

# Override this method for flow step params other than params[:step]
def flow_step_param
params[:step]
end

def flow_step_allowlist
raise NotImplementedError, '#flow_step_allowlist must be overridden'
end
end
13 changes: 13 additions & 0 deletions app/controllers/concerns/inherited_proofing_404_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module InheritedProofing404Concern
extend ActiveSupport::Concern

included do
before_action :render_404_if_disabled
end

private

def render_404_if_disabled
render_not_found unless IdentityConfig.store.inherited_proofing_enabled
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ def phone_confirmed
def send_phone_added_email
event = create_user_event_with_disavowal(:phone_added, current_user)
current_user.confirmed_email_addresses.each do |email_address|
UserMailer.phone_added(current_user, email_address, disavowal_token: event.disavowal_token).
deliver_now_or_later
UserMailer.with(user: current_user, email_address: email_address).
phone_added(disavowal_token: event.disavowal_token).deliver_now_or_later
end
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/idv/gpo_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def confirmation_maker_perform

def send_reminder
current_user.confirmed_email_addresses.each do |email_address|
UserMailer.letter_reminder(current_user, email_address.email).deliver_now_or_later
UserMailer.with(user: current_user, email_address: email_address).
letter_reminder.deliver_now_or_later
end
end

Expand Down
86 changes: 86 additions & 0 deletions app/controllers/idv/inherited_proofing_cancellations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
module Idv
class InheritedProofingCancellationsController < ApplicationController
include IdvSession
include GoBackHelper
include InheritedProofing404Concern
include AllowlistedFlowStepConcern

before_action :confirm_idv_needed

def new
# NOTE: Uncomment this when analytics are implemented.
# properties = ParseControllerFromReferer.new(request.referer).call
# analytics.idv_inherited_proofing_cancellation_visited(step: params[:step], **properties)
self.session_go_back_path = go_back_path || idv_inherited_proofing_path
@presenter = CancellationsPresenter.new(
sp_name: decorated_session.sp_name,
url_options: url_options,
)
end

def update
# NOTE: Uncomment this when analytics are implemented.
# analytics.idv_inherited_proofing_cancellation_go_back(step: params[:step])
redirect_to session_go_back_path || idv_inherited_proofing_path
end

def destroy
# NOTE: Uncomment this when analytics are implemented.
# analytics.idv_inherited_proofing_cancellation_confirmed(step: params[:step])
cancel_session
render json: { redirect_url: cancelled_redirect_path }
end

private

def cancel_session
cancel_idv_session
cancel_user_session
end

def cancel_idv_session
idv_session = user_session[:idv]
idv_session&.clear
end

def cancel_user_session
user_session['idv'] = {}
end

def cancelled_redirect_path
return return_to_sp_failure_to_proof_path(location_params) if decorated_session.sp_name

account_path
end

def location_params
params.permit(:step, :location).to_h.symbolize_keys
end

def session_go_back_path=(path)
idv_session.go_back_path = path
end

def session_go_back_path
idv_session.go_back_path
end

# AllowlistedFlowStepConcern Concern overrides

def flow_step_allowlist
@flow_step_allowlist ||= Idv::Flows::InheritedProofingFlow::STEPS.keys.map(&:to_s)
end

# NOTE: Override and use Inherited Proofing (IP)-specific :throttle_type
# if current IDV-specific :idv_resolution type is unacceptable!
# def idv_attempter_throttled?
# ...
# end

# IdvSession Concern > EffectiveUser Concern overrides

def effective_user_id
current_user&.id
end
end
end
9 changes: 1 addition & 8 deletions app/controllers/idv/inherited_proofing_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ module Idv
class InheritedProofingController < ApplicationController
include Flow::FlowStateMachine
include IdvSession
include InheritedProofing404Concern
include InheritedProofingConcern

before_action :render_404_if_disabled

FLOW_STATE_MACHINE_SETTINGS = {
step_url: :idv_inherited_proofing_step_url,
final_url: :idv_phone_url,
Expand All @@ -16,11 +15,5 @@ class InheritedProofingController < ApplicationController
def return_to_sp
redirect_to return_to_sp_failure_to_proof_url(step: next_step, location: params[:location])
end

private

def render_404_if_disabled
render_not_found unless IdentityConfig.store.inherited_proofing_enabled
end
end
end
27 changes: 27 additions & 0 deletions app/controllers/saml_completion_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Handles the INTERNAL redirect which happens when a service provider authentication request
# is passed through the IDP's authentication flow (sign-in, MFA, etc.)
# The original request was saved to the sp_session object, so we retrieve it to pass on the
# original request url in the form of a POST request to the SamlIdpController#auth method
class SamlCompletionController < ApplicationController
# Pass the original service provider request to the main SamlIdpController#auth method
# via a POST with form parameters replacing the url query parameters
def index
if sp_session.present?
request_url = URI(sp_session[:request_url])
path_year = request_url.path[-4..-1]
path_method = "api_saml_finalauthpost#{path_year}_url"
action_url = Rails.application.routes.url_helpers.send(path_method)

# Takes the query params which were set internally in the
# sp_session (so they should always be valid).
# A bad request that originated outside of the IDP would have
# already responded with a 400 status before reaching this point.
form_params = UriService.params(request_url)

render 'shared/saml_post_form', locals: { action_url: action_url, form_params: form_params },
layout: false
else
render_not_found
end
end
end
3 changes: 2 additions & 1 deletion app/controllers/saml_post_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def auth

form_params = params.permit(:SAMLRequest, :RelayState, :SigAlg, :Signature)

render locals: { action_url: action_url, form_params: form_params }, layout: false
render 'shared/saml_post_form', locals: { action_url: action_url, form_params: form_params },
layout: false
end
end
4 changes: 2 additions & 2 deletions app/controllers/users/email_confirmations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def process_successful_confirmation(email_address)
def confirm_and_notify(email_address)
email_address.update!(confirmed_at: Time.zone.now)
email_address.user.confirmed_email_addresses.each do |confirmed_email_address|
UserMailer.email_added(email_address.user, confirmed_email_address.email).
deliver_now_or_later
UserMailer.with(user: email_address.user, email_address: confirmed_email_address).
email_added.deliver_now_or_later
end
notify_subscribers(email_address)
end
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/users/emails_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ def check_max_emails_per_account
end

def retain_confirmed_emails
@current_confirmed_emails = current_user.confirmed_email_addresses.map(&:email)
@current_confirmed_emails = current_user.confirmed_email_addresses.to_a
end

def send_delete_email_notification
@current_confirmed_emails.each do |confirmed_email|
UserMailer.email_deleted(current_user, confirmed_email).deliver_now_or_later
UserMailer.with(user: current_user, email_address: confirmed_email).
email_deleted.deliver_now_or_later
end
end
end
Expand Down
11 changes: 9 additions & 2 deletions app/forms/register_user_email_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,23 @@ def send_sign_up_confirmed_email
email: email, email_already_registered: true,
)
else
UserMailer.signup_with_your_email(existing_user, email).deliver_now_or_later
UserMailer.with(user: existing_user, email_address: email_address_record).
signup_with_your_email.deliver_now_or_later
end
end

def user_unconfirmed?
existing_user.email_addresses.none?(&:confirmed?)
end

def email_address_record
return @email_address_record if defined?(@email_address_record)
@email_address_record = EmailAddress.find_with_email(email)
@email_address_record
end

def existing_user
@existing_user ||= User.find_with_email(email) || AnonymousUser.new
@existing_user ||= email_address_record&.user || AnonymousUser.new
end

def email_request_id(request_id)
Expand Down
12 changes: 3 additions & 9 deletions app/jobs/get_usps_proofing_results_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,7 @@ def process_enrollment_response(enrollment, response)
def send_verified_email(user, enrollment)
user.confirmed_email_addresses.each do |email_address|
# rubocop:disable IdentityIdp/MailLaterLinter
UserMailer.in_person_verified(
user,
email_address,
UserMailer.with(user: user, email_address: email_address).in_person_verified(
enrollment: enrollment,
).deliver_later(**mail_delivery_params)
# rubocop:enable IdentityIdp/MailLaterLinter
Expand All @@ -275,9 +273,7 @@ def send_verified_email(user, enrollment)
def send_failed_email(user, enrollment)
user.confirmed_email_addresses.each do |email_address|
# rubocop:disable IdentityIdp/MailLaterLinter
UserMailer.in_person_failed(
user,
email_address,
UserMailer.with(user: user, email_address: email_address).in_person_failed(
enrollment: enrollment,
).deliver_later(**mail_delivery_params)
# rubocop:enable IdentityIdp/MailLaterLinter
Expand All @@ -287,9 +283,7 @@ def send_failed_email(user, enrollment)
def send_failed_fraud_email(user, enrollment)
user.confirmed_email_addresses.each do |email_address|
# rubocop:disable IdentityIdp/MailLaterLinter
UserMailer.in_person_failed_fraud(
user,
email_address,
UserMailer.with(user: user, email_address: email_address).in_person_failed_fraud(
enrollment: enrollment,
).deliver_later(**mail_delivery_params)
# rubocop:enable IdentityIdp/MailLaterLinter
Expand Down
Loading