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
13 changes: 11 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
AWS_ACCESS_KEY_ID=YOUR-AWS-ACCESS-KEY-ID
AWS_SECRET_ACCESS_KEY=YOUR-AWS-SECRET-ACCESS-KEY
AWS_REGION=

LOGIN_GOV_CLIENT_ID='urn:gov:gsa:openidconnect:sp:myapp'
LOGIN_GOV_IDP_BASE_URL='http://localhost:3000/'
LOGIN_GOV_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----............."
LOGIN_GOV_REDIRECT_URI='http://localhost:3002/users/auth/login_dot_gov/callback'

NEW_RELIC_KEY=YOUR-NEW-RELIC-KEY-HERE

S3_AWS_ACCESS_KEY_ID=
S3_AWS_SECRET_ACCESS_KEY=
S3_AWS_BUCKET_NAME=
S3_AWS_REGION=
S3_AWS_HOST=
S3_AWS_BUCKET_NAME=
[email protected]

TOUCHPOINTS_GTM_CONTAINER_ID=GTM-your-number
[email protected]
5 changes: 5 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=

LOGIN_GOV_CLIENT_ID=
LOGIN_GOV_IDP_BASE_URL=
LOGIN_GOV_PRIVATE_KEY=
LOGIN_GOV_REDIRECT_URI=

NEW_RELIC_KEY=

S3_AWS_ACCESS_KEY_ID=
Expand Down
33 changes: 33 additions & 0 deletions app/controllers/users/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def login_dot_gov
if (auth_hash && auth_hash["info"]["email_verified"])
@email = auth_hash["info"]["email"]
end

login
end


private

def auth_hash
request.env["omniauth.auth"]
end

def login
if @email.present?
@user = User.from_omniauth(auth_hash)
end

# If user exists
# Else, if valid email and no user, we create an account.
if [email protected]?
sign_in_and_redirect(:user, @user)
set_flash_message(:notice, :success, kind: "Login.gov")
elsif @user.errors.present?
redirect_to root_path, alert: @user.errors.full_messages.join(",")
else
redirect_to root_path, notice: "Error: During oAuth Login"
end
end
end
24 changes: 22 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ class User < ApplicationRecord
# :lockable, and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:trackable, :confirmable,
:trackable,
# :confirmable,
:timeoutable

devise :omniauthable, omniauth_providers: [:login_dot_gov]

belongs_to :organization, optional: true
has_many :user_services
has_many :services, through: :user_services
Expand All @@ -15,6 +18,23 @@ class User < ApplicationRecord

validates :email, presence: true, if: :tld_check

def self.from_omniauth(auth)
# Set login_dot_gov as Provider for legacy TP Devise accounts
# TODO: Remove once all accounts are migrated/have `provider` and `uid` set
@existing_user = User.find_by_email(auth.info.email)
if @existing_user && !@existing_user.provider.present?
@existing_user.provider = auth.provider
@existing_user.uid = auth.uid
@existing_user.save
end

# For login.gov native accounts
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end

def tld_check
unless APPROVED_DOMAINS.any? { |word| email.end_with?(word) }
errors.add(:email, "is not from a valid TLD - .gov and .mil domains only")
Expand Down Expand Up @@ -44,7 +64,7 @@ def ensure_organization
if org = Organization.find_by_domain(address.domain)
self.organization_id = org.id
else
errors.add(:organization, "#{address.domain} is not a valid organization - Please contact Feedback Analytics Team for assistance")
errors.add(:organization, "'#{address.domain}' has not yet been configured for Touchpoints - Please contact the Feedback Analytics Team for assistance.")
end
end

Expand Down
11 changes: 3 additions & 8 deletions app/views/components/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,9 @@
<ul class="usa-unstyled-list usa-nav-secondary-links">
<% unless current_user %>
<li>
<a href="/users/sign_up">
Sign up
</a>
</li>
<li>
<a href="/users/sign_in">
Sign in
</a>
<%= link_to user_login_dot_gov_omniauth_authorize_path do %>
Sign in with Login.gov
<% end %>
</li>
<% else %>
<li>
Expand Down
11 changes: 2 additions & 9 deletions app/views/devise/sessions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Misuse is subject to criminal and civil penalties.
<%= link_to "Read more details", "#", id: "read-more-details" %>.
<br>
<%= link_to "Agree and continue to Sign In", "#", id: "agree-button", class: "usa-button" %>
<%= link_to "Agree and continue to Sign In", user_login_dot_gov_omniauth_authorize_path, id: "agree-button", class: "usa-button" %>
</div>
<br>
<%= link_to "Learn about getting access to Touchpoints.", "https://feedback.usa.gov", target: "_blank", rel: "noopener" %>
Expand All @@ -30,7 +30,7 @@
Misuse is subject to criminal and civil penalties.
<%= link_to "Read more details", "#", id: "read-more-details" %>.
<br>
<%= link_to "Agree and continue to Sign In", "#", id: "agree-button", class: "usa-button" %>
<%= link_to "Agree and continue to Sign In", user_login_dot_gov_omniauth_authorize_path, id: "agree-button", class: "usa-button" %>
</div>
<br>
<%= link_to "Learn about getting access to Touchpoints.", "https://feedback.usa.gov", target: "_blank", rel: "noopener" %>
Expand Down Expand Up @@ -97,17 +97,10 @@
</div>
</div>



<script type="text/javascript">
$(function() {
// Hide the form by default
$(".login-form-body").hide();
// Show the login form after agreeing to the TOS
$("#agree-button").on("click", function() {
$(".disclaimer").hide();
$(".login-form-body").show();
});

// Manage the modal
function hideModal() {
Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/shared/_links.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", user_login_dot_gov_omniauth_authorize_path %><br />
<% end %>
<% end %>
2 changes: 1 addition & 1 deletion config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this
# time the user will be asked for credentials again. Default is 30 minutes.
config.timeout_in = 24.hours
config.timeout_in = 15.minutes

# ==> Configuration for :lockable
# Defines which strategy will be used to lock an account.
Expand Down
21 changes: 21 additions & 0 deletions config/initializers/omniauth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# LOGIN_GOV_PRIVATE_KEY expects the .pem in a certain format
# For the .pem (private key):
#
# pem_string = File.open("your-filepath.pem", "r").read
# use the value `pem_string`

# eg:
# export LOGIN_GOV_PRIVATE_KEY="#{pem_string}"
# Of note: .gsub() is used for the `private_key`
# below, to decode the line breaks properly

Rails.application.config.middleware.use OmniAuth::Builder do
provider :login_dot_gov, {
name: :login_dot_gov,
client_id: ENV.fetch("LOGIN_GOV_CLIENT_ID"),
idp_base_url: ENV.fetch("LOGIN_GOV_IDP_BASE_URL"),
ial: 1,
private_key: OpenSSL::PKey::RSA.new(ENV.fetch("LOGIN_GOV_PRIVATE_KEY").gsub("\\n", "\n")),
redirect_uri: ENV.fetch("LOGIN_GOV_REDIRECT_URI")
}
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Rails.application.routes.draw do
devise_for :users
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }

resources :touchpoints, only: [:show] do
member do
Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20190710222800_add_omniauth_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddOmniauthToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :provider, :string
add_column :users, :uid, :string
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_06_19_162610) do
ActiveRecord::Schema.define(version: 2019_07_10_222800) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -184,6 +184,8 @@
t.datetime "updated_at", null: false
t.boolean "admin", default: false
t.boolean "organization_manager", default: false
t.string "provider"
t.string "uid"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
Expand Down
6 changes: 0 additions & 6 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ def production_suitable_seeds
password: "password",
admin: true
})
admin_user.skip_confirmation!
admin_user.save!
puts "Created Admin User: #{admin_user.email}"

Expand Down Expand Up @@ -72,7 +71,6 @@ def production_suitable_seeds
password: "password",
organization: example_gov
})
webmaster.skip_confirmation!
webmaster.save!
puts "Created #{webmaster.email}"

Expand All @@ -82,7 +80,6 @@ def production_suitable_seeds
organization: example_gov,
organization_manager: true
})
organization_manager.skip_confirmation!
organization_manager.save!
puts "Created #{organization_manager.email}"

Expand All @@ -91,7 +88,6 @@ def production_suitable_seeds
password: "password",
organization: example_gov
})
service_manager.skip_confirmation!
service_manager.save!
puts "Created #{service_manager.email}"

Expand All @@ -100,7 +96,6 @@ def production_suitable_seeds
password: "password",
organization: example_gov
})
submission_viewer.skip_confirmation!
submission_viewer.save!
puts "Created #{submission_viewer.email}"

Expand Down Expand Up @@ -300,7 +295,6 @@ def production_suitable_seeds
email: "[email protected]",
password: "password"
})
digital_gov_user.skip_confirmation!
digital_gov_user.save!
puts "Created Test User in Secondary Organization: #{digital_gov_user.email}"

Expand Down
4 changes: 2 additions & 2 deletions spec/features/login_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
it "redirect to /users with a error flash message" do
expect(page.current_path).to eq("/users")
expect(page).to have_content("1 error prohibited this user from being saved:")
expect(page).to have_content("Organization new.gov is not a valid organization - Please contact Feedback Analytics Team for assistance")
expect(page).to have_content("Organization 'new.gov' has not yet been configured for Touchpoints - Please contact the Feedback Analytics Team for assistance.")
end
# try a non .gov address
# try a non-exi
Expand Down Expand Up @@ -73,7 +73,7 @@
end
end

describe "Sign In" do
xdescribe "Sign In" do
let(:user) { FactoryBot.create(:user) }

before "user completes Sign Up form" do
Expand Down