diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb
index 3ae5e28c..84395d70 100644
--- a/app/controllers/admins_controller.rb
+++ b/app/controllers/admins_controller.rb
@@ -175,6 +175,13 @@ class AdminsController < ApplicationController
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
def clear_cache
Rails.cache.delete("#{@user_domain}/getUser")
diff --git a/app/controllers/concerns/authenticator.rb b/app/controllers/concerns/authenticator.rb
index f4dc3799..f935d6b4 100644
--- a/app/controllers/concerns/authenticator.rb
+++ b/app/controllers/concerns/authenticator.rb
@@ -68,6 +68,18 @@ module Authenticator
session.delete(:user_id) if current_user
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
# Migrates all of the twitter users rooms to the new account
diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb
index 3c22a43e..1164e5b8 100644
--- a/app/controllers/password_resets_controller.rb
+++ b/app/controllers/password_resets_controller.rb
@@ -56,6 +56,8 @@ class PasswordResetsController < ApplicationController
# Password does not match password confirmation
flash.now[:alert] = I18n.t("password_different_notice")
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
return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
end
@@ -66,7 +68,7 @@ class PasswordResetsController < ApplicationController
private
def find_user
- @user = User.find_by(email: params[:email])
+ @user = User.find_by(email: params[:email], provider: @user_domain)
end
def user_params
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 11e7d0fe..90272c46 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -74,6 +74,10 @@ class SessionsController < ApplicationController
# Check user with that email exists
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
return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user.try(:authenticate,
session_params[:password])
@@ -199,6 +203,9 @@ class SessionsController < ApplicationController
# 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
+ # 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)
logger.info "Support: Auth user #{user.email} is attempting to login."
@@ -225,4 +232,28 @@ class SessionsController < ApplicationController
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
diff --git a/app/views/admins/components/_settings.html.erb b/app/views/admins/components/_settings.html.erb
index 0b2fd482..fa36afe1 100644
--- a/app/views/admins/components/_settings.html.erb
+++ b/app/views/admins/components/_settings.html.erb
@@ -155,6 +155,7 @@
<% if current_user.has_role? :super_admin%>
+