forked from External/greenlight
GRN2-252: Change to how sign ins are processed (#869)
* Social to local * Social/Local to Social * Rubocop fixes * Added test cases * Added the ability to clear social uids * Update admins_controller.rb * Update admins_controller.rb
This commit is contained in:
parent
42e6e4f235
commit
005ec84c73
|
@ -175,6 +175,13 @@ class AdminsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# POST /admins/clear_auth
|
||||||
|
def clear_auth
|
||||||
|
User.include_deleted.where(provider: @user_domain).update_all(social_uid: nil)
|
||||||
|
|
||||||
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
|
end
|
||||||
|
|
||||||
# POST /admins/clear_cache
|
# POST /admins/clear_cache
|
||||||
def clear_cache
|
def clear_cache
|
||||||
Rails.cache.delete("#{@user_domain}/getUser")
|
Rails.cache.delete("#{@user_domain}/getUser")
|
||||||
|
|
|
@ -68,6 +68,18 @@ module Authenticator
|
||||||
session.delete(:user_id) if current_user
|
session.delete(:user_id) if current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Check if the user is using local accounts
|
||||||
|
def auth_changed_to_local?(user)
|
||||||
|
Rails.configuration.loadbalanced_configuration && user.social_uid.present? && allow_greenlight_accounts?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if the user exists under the same email with no social uid and that social accounts are allowed
|
||||||
|
def auth_changed_to_social?(email)
|
||||||
|
Rails.configuration.loadbalanced_configuration &&
|
||||||
|
User.exists?(email: email, provider: @user_domain, social_uid: nil) &&
|
||||||
|
!allow_greenlight_accounts?
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Migrates all of the twitter users rooms to the new account
|
# Migrates all of the twitter users rooms to the new account
|
||||||
|
|
|
@ -56,6 +56,8 @@ class PasswordResetsController < ApplicationController
|
||||||
# Password does not match password confirmation
|
# Password does not match password confirmation
|
||||||
flash.now[:alert] = I18n.t("password_different_notice")
|
flash.now[:alert] = I18n.t("password_different_notice")
|
||||||
elsif @user.update_attributes(user_params)
|
elsif @user.update_attributes(user_params)
|
||||||
|
# Clear the user's social uid if they are switching from a social to a local account
|
||||||
|
@user.update_attribute(:social_uid, nil) if @user.social_uid.present?
|
||||||
# Successfully reset password
|
# Successfully reset password
|
||||||
return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
|
return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
|
||||||
end
|
end
|
||||||
|
@ -66,7 +68,7 @@ class PasswordResetsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_user
|
def find_user
|
||||||
@user = User.find_by(email: params[:email])
|
@user = User.find_by(email: params[:email], provider: @user_domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
|
|
|
@ -74,6 +74,10 @@ class SessionsController < ApplicationController
|
||||||
|
|
||||||
# Check user with that email exists
|
# Check user with that email exists
|
||||||
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user
|
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user
|
||||||
|
|
||||||
|
# Check if authenticators have switched
|
||||||
|
return switch_account_to_local(user) if !is_super_admin && auth_changed_to_local?(user)
|
||||||
|
|
||||||
# Check correct password was entered
|
# Check correct password was entered
|
||||||
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user.try(:authenticate,
|
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user.try(:authenticate,
|
||||||
session_params[:password])
|
session_params[:password])
|
||||||
|
@ -199,6 +203,9 @@ class SessionsController < ApplicationController
|
||||||
# If using invitation registration method, make sure user is invited
|
# If using invitation registration method, make sure user is invited
|
||||||
return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
|
return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
|
||||||
|
|
||||||
|
# Switch the user to a social account if they exist under the same email with no social uid
|
||||||
|
switch_account_to_social if !@user_exists && auth_changed_to_social?(@auth['info']['email'])
|
||||||
|
|
||||||
user = User.from_omniauth(@auth)
|
user = User.from_omniauth(@auth)
|
||||||
|
|
||||||
logger.info "Support: Auth user #{user.email} is attempting to login."
|
logger.info "Support: Auth user #{user.email} is attempting to login."
|
||||||
|
@ -225,4 +232,28 @@ class SessionsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Send the user a password reset email to allow them to set their password
|
||||||
|
def switch_account_to_local(user)
|
||||||
|
logger.info "Switching social account to local account for #{user.uid}"
|
||||||
|
|
||||||
|
# Send the user a reset password email
|
||||||
|
user.create_reset_digest
|
||||||
|
send_password_reset_email(user)
|
||||||
|
|
||||||
|
# Overwrite the flash with a more descriptive message if successful
|
||||||
|
flash[:success] = I18n.t("reset_password.auth_change") if flash[:success].present?
|
||||||
|
|
||||||
|
redirect_to signin_path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set the user's social id to the new id being passed
|
||||||
|
def switch_account_to_social
|
||||||
|
user = User.find_by(email: @auth['info']['email'], provider: @user_domain, social_uid: nil)
|
||||||
|
|
||||||
|
logger.info "Switching account to social account for #{user.uid}"
|
||||||
|
|
||||||
|
# Set the user's social id to the one being returned from auth
|
||||||
|
user.update_attribute(:social_uid, @auth['uid'])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -155,6 +155,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% if current_user.has_role? :super_admin%>
|
<% if current_user.has_role? :super_admin%>
|
||||||
|
<hr>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="mb-6 form-group">
|
<div class="mb-6 form-group">
|
||||||
|
@ -164,4 +165,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-4 row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%= t("administrator.site_settings.clear_auth.title") %></label>
|
||||||
|
<label class="form-label text-muted"><%= t("administrator.site_settings.clear_auth.info") %></label>
|
||||||
|
<%= button_to t("administrator.site_settings.clear_auth.button"), admin_clear_auth_path, class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -46,6 +46,10 @@ en:
|
||||||
info: Clears the stored provider cache which forces a new request for the updated info
|
info: Clears the stored provider cache which forces a new request for the updated info
|
||||||
title: Clear Provider Cache
|
title: Clear Provider Cache
|
||||||
button: Clear Cache
|
button: Clear Cache
|
||||||
|
clear_auth:
|
||||||
|
info: Clears the current authenticator for users allowing them to sign back in using a different authentication method
|
||||||
|
title: Clear Current Authenticator
|
||||||
|
button: Clear Auth
|
||||||
color:
|
color:
|
||||||
info: Changing the Regular Color will change both Lighten and Darken. Lighten and Darken can then be changed individually
|
info: Changing the Regular Color will change both Lighten and Darken. Lighten and Darken can then be changed individually
|
||||||
title: Primary Color
|
title: Primary Color
|
||||||
|
@ -415,6 +419,7 @@ en:
|
||||||
password: New Password
|
password: New Password
|
||||||
confirm: New Password Confirmation
|
confirm: New Password Confirmation
|
||||||
update: Update Password
|
update: Update Password
|
||||||
|
auth_change: The authentication method has changed. Please check your email to set your password.
|
||||||
roles:
|
roles:
|
||||||
active: Active
|
active: Active
|
||||||
admin: Admin
|
admin: Admin
|
||||||
|
|
|
@ -55,6 +55,7 @@ Rails.application.routes.draw do
|
||||||
post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration
|
post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration
|
||||||
post '/coloring', to: 'admins#coloring', as: :admin_coloring
|
post '/coloring', to: 'admins#coloring', as: :admin_coloring
|
||||||
post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache
|
post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache
|
||||||
|
post '/clear_auth', to: 'admins#clear_auth', as: :admin_clear_auth
|
||||||
# Roles
|
# Roles
|
||||||
post '/role', to: 'admins#new_role', as: :admin_new_role
|
post '/role', to: 'admins#new_role', as: :admin_new_role
|
||||||
patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order
|
patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order
|
||||||
|
|
|
@ -344,6 +344,36 @@ describe AdminsController, type: :controller do
|
||||||
expect(response).to redirect_to(admin_site_settings_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "clears all users social uids if clear auth button is clicked" do
|
||||||
|
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
|
||||||
|
controller.instance_variable_set(:@user_domain, "provider1")
|
||||||
|
|
||||||
|
@request.session[:user_id] = @admin.id
|
||||||
|
|
||||||
|
@admin.add_role :super_admin
|
||||||
|
@admin.update_attribute(:provider, "greenlight")
|
||||||
|
@user2 = create(:user, provider: "provider1")
|
||||||
|
@user3 = create(:user, provider: "provider1")
|
||||||
|
|
||||||
|
@user.update_attribute(:social_uid, Faker::Internet.password)
|
||||||
|
@user2.update_attribute(:social_uid, Faker::Internet.password)
|
||||||
|
@user3.update_attribute(:social_uid, Faker::Internet.password)
|
||||||
|
|
||||||
|
expect(@user.social_uid).not_to be(nil)
|
||||||
|
expect(@user2.social_uid).not_to be(nil)
|
||||||
|
expect(@user3.social_uid).not_to be(nil)
|
||||||
|
|
||||||
|
post :clear_auth
|
||||||
|
|
||||||
|
@user.reload
|
||||||
|
@user2.reload
|
||||||
|
@user3.reload
|
||||||
|
|
||||||
|
expect(@user.social_uid).to be(nil)
|
||||||
|
expect(@user2.social_uid).to be(nil)
|
||||||
|
expect(@user3.social_uid).to be(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Roles" do
|
describe "Roles" do
|
||||||
|
|
|
@ -115,7 +115,7 @@ describe PasswordResetsController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates attributes if the password update is a success" do
|
it "updates attributes if the password update is a success" do
|
||||||
user = create(:user)
|
user = create(:user, provider: "greenlight")
|
||||||
token = "reset_token"
|
token = "reset_token"
|
||||||
|
|
||||||
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||||
|
|
|
@ -88,7 +88,11 @@ describe SessionsController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST #create" do
|
describe "POST #create" do
|
||||||
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
|
before do
|
||||||
|
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
|
||||||
|
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_local?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@user1 = create(:user, provider: 'greenlight', password: 'example', password_confirmation: 'example')
|
@user1 = create(:user, provider: 'greenlight', password: 'example', password_confirmation: 'example')
|
||||||
@user2 = create(:user, password: 'example', password_confirmation: "example")
|
@user2 = create(:user, password: 'example', password_confirmation: "example")
|
||||||
|
@ -251,6 +255,22 @@ describe SessionsController, type: :controller do
|
||||||
expect(@user1.rooms.find { |r| r.name == "Old Home Room" }).to_not be_nil
|
expect(@user1.rooms.find { |r| r.name == "Old Home Room" }).to_not be_nil
|
||||||
expect(@user1.rooms.find { |r| r.name == "Test" }).to_not be_nil
|
expect(@user1.rooms.find { |r| r.name == "Test" }).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "sends the user a reset password email if the authentication method is changing to local" do
|
||||||
|
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_local?).and_return(true)
|
||||||
|
email = Faker::Internet.email
|
||||||
|
|
||||||
|
create(:user, email: email, provider: "greenlight", social_uid: "google-user")
|
||||||
|
|
||||||
|
expect {
|
||||||
|
post :create, params: {
|
||||||
|
session: {
|
||||||
|
email: email,
|
||||||
|
password: 'example',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET/POST #omniauth" do
|
describe "GET/POST #omniauth" do
|
||||||
|
@ -428,6 +448,66 @@ describe SessionsController, type: :controller do
|
||||||
|
|
||||||
expect(response).to redirect_to(root_path)
|
expect(response).to redirect_to(root_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "switches a social account to a different social account if the authentication method changed" do
|
||||||
|
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:bn_launcher]
|
||||||
|
get :omniauth, params: { provider: 'bn_launcher' }
|
||||||
|
|
||||||
|
u = User.find_by(social_uid: "bn-launcher-user")
|
||||||
|
u.social_uid = nil
|
||||||
|
users_old_uid = u.uid
|
||||||
|
u.save!
|
||||||
|
|
||||||
|
new_user = OmniAuth::AuthHash.new(
|
||||||
|
provider: "bn_launcher",
|
||||||
|
uid: "bn-launcher-user-new",
|
||||||
|
info: {
|
||||||
|
email: "user@google.com",
|
||||||
|
name: "Office User",
|
||||||
|
nickname: "googleuser",
|
||||||
|
image: "touch.png",
|
||||||
|
customer: 'customer1',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_social?).and_return(true)
|
||||||
|
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("customer1")
|
||||||
|
controller.instance_variable_set(:@user_domain, "customer1")
|
||||||
|
|
||||||
|
request.env["omniauth.auth"] = new_user
|
||||||
|
get :omniauth, params: { provider: 'bn_launcher' }
|
||||||
|
|
||||||
|
new_u = User.find_by(social_uid: "bn-launcher-user-new")
|
||||||
|
expect(users_old_uid).to eq(new_u.uid)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "switches a local account to a different social account if the authentication method changed" do
|
||||||
|
email = Faker::Internet.email
|
||||||
|
user = create(:user, email: email, provider: "customer1")
|
||||||
|
users_old_uid = user.uid
|
||||||
|
|
||||||
|
new_user = OmniAuth::AuthHash.new(
|
||||||
|
provider: "bn_launcher",
|
||||||
|
uid: "bn-launcher-user-new",
|
||||||
|
info: {
|
||||||
|
email: email,
|
||||||
|
name: "Office User",
|
||||||
|
nickname: "googleuser",
|
||||||
|
image: "touch.png",
|
||||||
|
customer: 'customer1',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
allow_any_instance_of(SessionsController).to receive(:auth_changed_to_social?).and_return(true)
|
||||||
|
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("customer1")
|
||||||
|
controller.instance_variable_set(:@user_domain, "customer1")
|
||||||
|
|
||||||
|
request.env["omniauth.auth"] = new_user
|
||||||
|
get :omniauth, params: { provider: 'bn_launcher' }
|
||||||
|
|
||||||
|
new_u = User.find_by(social_uid: "bn-launcher-user-new")
|
||||||
|
expect(users_old_uid).to eq(new_u.uid)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST #ldap" do
|
describe "POST #ldap" do
|
||||||
|
|
Loading…
Reference in New Issue