Skip to content

Commit

Permalink
DPC-4204 AO fails email check (#2264)
Browse files Browse the repository at this point in the history
## 🎫 Ticket

https://jira.cms.gov/browse/DPC_4204

## 🛠 Changes

- Logout button added to BadInvitationComponent
- IDP environment variables moved to ApplicationController as used in
multiple controllers
- logout and logged_out routes added to LoginDotGovController to handle
logout and return from IdP
- Failed PII match text updated

## ℹ️ Context

Matches designs

## 🧪 Validation

Manual and automated testing
  • Loading branch information
jdettmannnava authored Sep 9, 2024
1 parent 8199a33 commit 13afb2c
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@
<%= render Core::Button::ButtonComponent.new(label: "Go to DPC home",
destination: 'https://dpc.cms.gov/',
method: :get) %>
<% when :pii_mismatch %>
<%= render Core::Button::ButtonComponent.new(label: "Sign out of Login.gov",
destination: login_dot_gov_logout_path(invitation_id: @invitation.id),
method: :delete) %>
<% end %>
</div>
11 changes: 11 additions & 0 deletions dpc-portal/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ def tos_accepted
end
end

# Documentation at https://developers.login.gov/oidc/logout/
def url_for_login_dot_gov_logout
state = SecureRandom.hex(16)
session['omniauth.state'] = state
URI::HTTPS.build(host: IDP_HOST,
path: '/openid_connect/logout',
query: { client_id: IDP_CLIENT_ID,
post_logout_redirect_uri: "#{root_url}users/auth/logged_out",
state: }.to_query)
end

def block_prod_sbx
redirect_to root_url if ENV.fetch('ENV', nil) == 'prod-sbx'
end
Expand Down
10 changes: 10 additions & 0 deletions dpc-portal/app/controllers/login_dot_gov_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ def failure
end
end

def logout
if params[:invitation_id].present?
invitation = Invitation.find(params[:invitation_id])
session[:user_return_to] = organization_invitation_url(invitation.provider_organization.id, invitation.id)
end

redirect_to url_for_login_dot_gov_logout, allow_other_host: true
end

# Return from login.gov
def logged_out
redirect_to session.delete(:user_return_to) || new_user_session_path
end
Expand Down
8 changes: 1 addition & 7 deletions dpc-portal/app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@ def destroy
Rails.logger.info(['User logged out',
{ actionContext: LoggingConstants::ActionContext::Authentication,
actionType: LoggingConstants::ActionType::UserLoggedOut }])
session['omniauth.state'] = @state = SecureRandom.hex(16)
sign_out(current_user)
url = URI::HTTPS.build(host: IDP_HOST,
path: '/openid_connect/logout',
query: { client_id: IDP_CLIENT_ID,
post_logout_redirect_uri: "#{root_url}users/auth/logged_out",
state: @state }.to_query)
redirect_to url, allow_other_host: true
redirect_to url_for_login_dot_gov_logout, allow_other_host: true
end
end
end
4 changes: 2 additions & 2 deletions dpc-portal/config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
en:
verification:
pii_mismatch_status: Invitation denied
pii_mismatch_text: Sorry, this invitation is for someone else.
pii_mismatch_status: The email you used to sign in doesn't match your invite.
pii_mismatch_text: <p>Please <b>sign out</b> of Login.gov and either:<ul><li>Create an account</li><li>Add an alternate email to your current Login.gov account</li></ul></p>
accepted_status: Organization already registered.
accepted_text: If you meant to register a different organization, check your inbox for the correct request. Sign in to access details for this organization.
ao_expired_status: Your registration link has expired.
Expand Down
3 changes: 2 additions & 1 deletion dpc-portal/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
devise_for :users, controllers: { sessions: 'users/sessions', omniauth_callbacks: 'login_dot_gov' }
devise_scope :user do
get '/users/auth/failure', to: 'login_dot_gov#failure', as: 'login_dot_gov_failure'
get '/users/auth/logged_out', to: 'login_dot_gov#logged_out', as: 'login_dot_gov_logged_out'
get '/users/auth/logged_out', to: 'login_dot_gov#logged_out'
delete '/logout', to: 'login_dot_gov#logout', as: 'login_dot_gov_logout'
get 'active', to: 'users/sessions#active'
get 'timeout', to: 'users/sessions#timeout'
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@
let(:component) { described_class.new(invitation, 'pii_mismatch') }
it 'should match header' do
header = <<~HTML
<h1>#{I18n.t('verification.pii_mismatch_status')}</h1>
<h1>#{CGI.escapeHTML(I18n.t('verification.pii_mismatch_status'))}</h1>
HTML
is_expected.to include(normalize_space(header))
end
it 'should have logout button' do
button_url = "/logout?invitation_id=#{invitation.id}"
is_expected.to include(button_url)
end
end

context 'Already accepted' do
Expand Down
4 changes: 2 additions & 2 deletions dpc-portal/spec/requests/invitations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
stub_user_info(overrides: { 'email' => '[email protected]' })
get "/organizations/#{org.id}/invitations/#{invitation.id}/accept"
expect(response).to be_forbidden
expect(response.body).to include(I18n.t('verification.pii_mismatch_status'))
expect(response.body).to include(CGI.escapeHTML(I18n.t('verification.pii_mismatch_status')))
end
context :server_error do
it 'should show server error page' do
Expand Down Expand Up @@ -517,7 +517,7 @@
stub_user_info(overrides: { 'email' => '[email protected]' })
get "/organizations/#{org.id}/invitations/#{cd_invite.id}/confirm_cd"
expect(response).to be_forbidden
expect(response.body).to include(I18n.t('verification.pii_mismatch_status'))
expect(response.body).to include(CGI.escapeHTML(I18n.t('verification.pii_mismatch_status')))
expect(response.body).to_not include(confirm_organization_invitation_path(org, cd_invite))
end
it 'should render error page if given_name not match' do
Expand Down
27 changes: 21 additions & 6 deletions dpc-portal/spec/requests/login_dot_gov_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,31 @@
end
end

describe 'GET /users/auth/logged_out' do
it 'should go to sign in page' do
get '/users/auth/logged_out'
expect(response).to redirect_to(new_user_session_path)
expect(flash).to be_empty
describe 'Delete /logout' do
it 'should redirect to login.gov' do
delete '/logout'
expect(response.location).to include(ENV.fetch('IDP_HOST'))
expect(request.session[:user_return_to]).to be_nil
end
it 'should set return to invitation flow if invitation sent' do
invitation = create(:invitation, :ao)
delete "/logout?invitation_id=#{invitation.id}"
expect(request.session[:user_return_to]).to eq organization_invitation_url(invitation.provider_organization.id,
invitation.id)
end
it 'should go to bespoke page if set' do
end

describe 'Get /users/auth/logged_out' do
it 'should redirect to user_return_to' do
get '/organizations'
expect(request.session[:user_return_to]).to eq organizations_path
get '/users/auth/logged_out'
expect(response).to redirect_to(organizations_path)
end

it 'should redirect to new session if no user_return_to set' do
get '/users/auth/logged_out'
expect(response).to redirect_to(new_user_session_path)
end
end
end

0 comments on commit 13afb2c

Please sign in to comment.