Skip to content

Commit

Permalink
SRCH-947 (#669)
Browse files Browse the repository at this point in the history
SRCH-947 - Redirect to correct page after login in all cases

Redirect to the correct landing page in all cases (user not approved,
user pending approval, explicit destination, super-admin). Also changed
the flash text when login is not allowed.
  • Loading branch information
jmax-fearless authored Apr 6, 2021
1 parent 1950da2 commit 32cfd65
Show file tree
Hide file tree
Showing 25 changed files with 563 additions and 121 deletions.
37 changes: 26 additions & 11 deletions app/controllers/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
# frozen_string_literal: true

class OmniauthCallbacksController < ApplicationController
class LoginError < StandardError
class OmniauthError < StandardError
end

def login_dot_gov
try_to_login
rescue LandingPageFinder::Error => e
flash[:error] = e.message
redirect_to('/login')
rescue OmniauthError => e
Rails.logger.error e.message
flash[:error] = 'Error logging in. Please reach out to' \
' [email protected] if the problem persists'
redirect_to('/login')
end

private

def try_to_login
@return_to = session[:return_to]
reset_session
set_id_token
set_user_session
redirect_to(admin_home_page_path)
rescue LoginError => e
flash[:error] = "login internal error: #{e.message}"
redirect_to('/login')
redirect_to(destination)
end

def user
@user ||= User.from_omniauth(omniauth_data)
def destination
LandingPageFinder.new(user, @return_to).landing_page
end

raise LoginError, "can't find user #{omniauth_data.info.email}" unless @user
def user
return @user if @user

raise LoginError, "login not allowed for #{@user.email}" unless @user.login_allowed?
@user = User.from_omniauth(omniauth_data)
raise OmniauthError, 'db error creating user' unless @user.persisted?

@user
end

def omniauth_data
raise LoginError, 'no omniauth data' unless request.env['omniauth.auth']
raise OmniauthError, 'no omniauth data' unless request.env['omniauth.auth']

request.env['omniauth.auth']
end

def credentials
raise LoginError, 'no user credentials' unless omniauth_data['credentials']
raise OmniauthError, 'no user credentials' unless omniauth_data['credentials']

omniauth_data['credentials']
end
Expand Down
20 changes: 5 additions & 15 deletions app/controllers/user_sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,20 @@ class UserSessionsController < ApplicationController
before_action :require_user, only: :destroy

def security_notification
redirect_to(account_path) if current_user && current_user&.complete?
return unless current_user

landing_page = LandingPageFinder.new(current_user, params[:return_to]).landing_page
redirect_to(landing_page)
end

def destroy
id_token = session[:id_token]
reset_session
current_user_session.destroy
redirect_to(logout_redirect_uri(id_token))
redirect_to(LoginDotGovSettings.logout_redirect_uri(id_token, login_uri))
end

def login_uri
"#{request.protocol}#{request.host_with_port}/login"
end

def logout_redirect_uri(id_token)
base_uri = URI(Rails.application.secrets.login_dot_gov[:idp_base_url])
URI::HTTPS.build(
host: base_uri.host,
path: '/openid_connect/logout',
query: {
id_token_hint: id_token,
post_logout_redirect_uri: login_uri,
state: '1234567890123456789012'
}.to_query
).to_s
end
end
47 changes: 27 additions & 20 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# frozen_string_literal: true

class UsersController < ApplicationController
layout 'sites'
before_action :require_user, :only => [:show, :edit, :update]
before_action :require_user, only: [:show, :edit, :update]
before_action :set_user, except: :create
before_action :complain_if_non_gov_email, only: [:show, :edit]

NON_GOV_EMAIL_MESSAGE = <<~MESSAGE
Because you don't have a .gov or .mil email address, we need additional information.
If you are a contractor on an active contract, please use your .gov or .mil email
address on this account, or have your federal POC email [email protected]
to confirm your status.
MESSAGE

def create
@user = User.new(user_params)
if verify_recaptcha(:model => @user, :message => 'Word verification is incorrect') && @user.save
if verify_recaptcha(model: @user, message: 'Word verification is incorrect') && @user.save
if @user.has_government_affiliated_email?
flash[:success] = "Thank you for signing up. To continue the signup process, check your inbox, so we may verify your email address."
flash[:success] = 'Thank you for signing up. To continue the signup process, check your inbox, so we may verify your email address.'
else
flash[:success] = "Sorry! You don't have a .gov or .mil email address so we need some more information from you before approving your account."
end
Expand All @@ -18,20 +28,6 @@ def create
end
end

def show
message = <<~MESSAGE
Because you don't have a .gov or .mil email address, we need additional information.
If you are a contractor on an active contract, please use your .gov or .mil email
address on this account, or have your federal POC email [email protected]
to confirm your status.
MESSAGE

flash[:notice] = message unless @user.has_government_affiliated_email? ||
@user.approval_status == 'approved'
end

def edit; end

def update_account
@user.attributes = user_params
if @user.save(context: :update_account)
Expand All @@ -42,9 +38,13 @@ def update_account
end
end

def show; end

def edit; end

def update
if @user.update_attributes(user_params)
flash[:success] = "Account updated!"
if @user.update(user_params)
flash[:success] = 'Account updated!'
redirect_to account_url
else
render :edit
Expand All @@ -55,8 +55,15 @@ def developer_redirect; end

private

def complain_if_non_gov_email
return if @user.has_government_affiliated_email? ||
@user.approval_status == 'approved'

flash[:notice] = NON_GOV_EMAIL_MESSAGE
end

def require_user
redirect_to developer_redirect_url if super.nil? and current_user.is_developer?
redirect_to developer_redirect_url if super.nil? && current_user.is_developer?
end

def set_user
Expand Down
50 changes: 50 additions & 0 deletions app/poros/landing_page_finder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

class LandingPageFinder
include Rails.application.routes.url_helpers

ACCESS_DENIED_TEXT =
'Access Denied: These credentials are not recognized as valid' \
' for accessing Search.gov. Please reach out to' \
' [email protected] if you believe this is in error.'

class Error < StandardError
end

def initialize(user, return_to)
@user = user
@return_to = return_to
end

def landing_page
raise(Error, ACCESS_DENIED_TEXT) unless @user.login_allowed?

destination_edit_account ||
destination_original ||
destination_affiliate_admin ||
destination_site_page ||
new_site_path
end

private

def destination_edit_account
edit_account_path if @user.approval_status == 'pending_approval' || !@user.complete?
end

def destination_original
@return_to
end

def destination_affiliate_admin
admin_home_page_path if @user.is_affiliate_admin?
end

def destination_site_page
if @user.default_affiliate
site_path(@user.default_affiliate)
elsif !@user.affiliates.empty?
site_path(@user.affiliates.first)
end
end
end
6 changes: 0 additions & 6 deletions features/admin.feature
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ Feature: Administration
When I follow "Super Admin" in the main navigation bar
Then I should be on the admin home page

# SRCH-1552
# Commented out until we figure out how to get login.gov out of
# the loop during testing.
# When I follow "Sign Out"
# Then I should be on the login page

Scenario: Visiting the admin home page as an admin who is also an affiliate
Given "[email protected]" is an affiliate
When I go to the admin home page
Expand Down
19 changes: 3 additions & 16 deletions features/step_definitions/user_steps.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
Given /^I am logged in with email "([^"]*)"$/ do |email|
OmniAuth.config.test_mode = true

omniauth_hash = {
uid: 'test_123',
info: {
email: email
},
credentials: {
id_token: 'fake_id_token',
},
}

OmniAuth.config.add_mock('logindotgov', omniauth_hash)
visit '/auth/logindotgov'
Given /^I (?:log in|am logged in) with email "([^"]*)"$/ do |email|
mock_user_auth(email)
visit '/auth/logindotgov/callback'
end


When /^I sign out$/ do
email = find '#nav-auth-menu a[data-toggle=dropdown]'
click_link email.text
Expand Down
5 changes: 5 additions & 0 deletions features/support/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class << self
end

require_relative '../../spec/test_services.rb'
require_relative '../../spec/support/omniauth_helpers.rb'

World OmniauthHelpers

After { OmniAuth.config.mock_auth[:default] = OmniAuth::AuthHash.new({}) }

EmailTemplate.load_default_templates
OutboundRateLimit.load_defaults
Expand Down
2 changes: 2 additions & 0 deletions features/support/paths.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def path_to(page_name)
signup_path
when /the user account page/
account_path
when /the user edit account page/
edit_account_path
when /the reports homepage/
monthly_reports_path
when /the affiliate analytics query search results page/
Expand Down
32 changes: 8 additions & 24 deletions features/user_sessions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,21 @@ Feature: User sessions
Scenario: Already logged-in user visits login page
Given I am logged in with email "[email protected]"
And I go to the login page
Then I should see "Contact Information"
Then I should be on the admin home page

# to be updated in SRCH-947 for login.gov
@wip
Scenario: Affiliate admin should be on the site home page upon successful login
Given I am on the login page
Then I should see the browser page titled "Search.gov Login"
And I log in with email "[email protected]" and password "test1234!"
Then I should be on the new site page

# to be updated in SRCH-947 for login.gov
@wip
Scenario: Affiliate manager should be on the site home page upon successful login
When I am logged in with email "[email protected]"
When I log in with email "[email protected]"
Then I should be on the gobiernousa's Dashboard page

# to be updated in SRCH-946 for login.gov
@wip
Scenario: Affiliate manager with not approved status should not be able to login
When I log in with email "[email protected]" and password "test1234!"
Then I should not see "Admin Center"
Scenario: Affiliate admin should be on the admin home page upon successful login
When I log in with email "[email protected]"
Then I should be on the admin home page

# to be updated in SRCH-946 for login.gov
@wip
Scenario: User is not approved
Given I am logged in with email "[email protected]"
Then I should be on the user session page
And I should see "These credentials are not recognized as valid for accessing Search.gov. Please contact [email protected] if you believe this is in error."
When I log in with email "[email protected]"
Then I should see "Security Notification"
And I should see "These credentials are not recognized as valid for accessing Search.gov. Please reach out to [email protected] if you believe this is in error."

# to be updated in SRCH-945 for login.gov
@wip
Scenario: User's session expires after 1 hour
Given the following Users exist:
| first_name | last_name | email | approval_status |
Expand Down
10 changes: 3 additions & 7 deletions features/users.feature
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Feature: Users

@javascript
Scenario: Logged-in, approved non-developer user visits account page
Given I am logged in with email "[email protected]"
When I go to the user account page
Expand All @@ -11,7 +10,6 @@ Feature: Users
And I should see "Agency"
And I should see "Email"

@javascript
Scenario: User goes to login page and is directed to the security notification first
Given I go to the login page
Then I should see "Security Notification"
Expand Down Expand Up @@ -41,23 +39,21 @@ Feature: Users
When I open the email
Then I should see "Welcome to Search.gov" in the email subject

@javascript
Scenario: Registering as a new affiliate user without government affiliated email address
Given the following Users exist:
| first_name | last_name | email |
| Joe | Schno | jschmo@random.com |
And I am logged in with email "[email protected]"
Then I should be on the user account page
Then I should be on the user edit account page
And I should see "Because you don't have a .gov or .mil email address, we need additional information."

@javascript
Scenario: Logging in as a new approved affiliate user without government affiliated email address
Given the following Users exist:
| first_name | last_name | email | approval_status |
| Joe | Schmo | jschmo@random.com | approved |

And I am logged in with email "[email protected]"
Then I should be on the user account page
Then I should be on the new site page
And I should not see "Because you don't have a .gov or .mil email address, we need additional information."

@javascript
Expand Down Expand Up @@ -101,7 +97,7 @@ Feature: Users
And I should see "Because you don't have a .gov or .mil email address, your account is pending approval."
And I should be on the user account page

Scenario: Logging in as a developer user
Scenario: Logging in as a developer user
Given I am logged in with email "[email protected]"
When I go to the user account page
Then I should see "Our Recalls API Has Moved"
Loading

0 comments on commit 32cfd65

Please sign in to comment.