mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-07 02:22:49 +08:00
Don't require password to create users with previous authentication in
the session, regardless of email/email verification during user creation
Before my changes we were calling `user.password_required!` in
`UserAuthenticator.authenticated?` based on whether authentication
session data contained a matching email address and email verified
externally. I believe `authenticated?` is intended for our own email
validation during the activation process, but shouldn't be a gate for
password requirement.
Even when we were setting `user.password_required`, then during user
creation we were creating random passwords to get around the blank
password restriction when creating accounts with external auth.
After my change we can remove the random password creation because we no
longer require a password when the session has previous authentication
info at all.
Looks like this extra password requirement may have been introduced as a
side effect during a previous refactor of `UserController` here:
51eff92170
Before that change, password requirement was simply based on whether
session[:authentication] existed, but after that change it was based on
the email/email_valid fields as well.
70 lines
1.6 KiB
Ruby
70 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class UserAuthenticator
|
|
def initialize(
|
|
user,
|
|
session,
|
|
authenticator_finder: Users::OmniauthCallbacksController,
|
|
require_password: true
|
|
)
|
|
@user = user
|
|
@session = session
|
|
if session&.dig(:authentication) && session[:authentication].is_a?(Hash)
|
|
@auth_result = Auth::Result.from_session_data(session[:authentication], user: user)
|
|
end
|
|
@authenticator_finder = authenticator_finder
|
|
@require_password = require_password
|
|
end
|
|
|
|
def start
|
|
if authenticated?
|
|
@user.active = true
|
|
@auth_result.apply_user_attributes!
|
|
end
|
|
|
|
@user.password_required! if !@auth_result && @require_password
|
|
@user.skip_email_validation = true if @auth_result && @auth_result.skip_email_validation
|
|
end
|
|
|
|
def has_authenticator?
|
|
!!authenticator
|
|
end
|
|
|
|
def finish
|
|
if authenticator
|
|
authenticator.after_create_account(@user, @auth_result)
|
|
confirm_email
|
|
end
|
|
if @session&.dig(:authentication)
|
|
@session[:authentication] = @auth_result = nil
|
|
@session[:authenticated_with_oauth] = true
|
|
end
|
|
end
|
|
|
|
def email_valid?
|
|
@auth_result&.email_valid
|
|
end
|
|
|
|
def authenticated?
|
|
return false if !@auth_result
|
|
return false if @auth_result&.email&.downcase != @user.email.downcase
|
|
return false if !@auth_result.email_valid
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def confirm_email
|
|
@user.activate if authenticated?
|
|
end
|
|
|
|
def authenticator
|
|
if authenticator_name
|
|
@authenticator ||= @authenticator_finder.find_authenticator(authenticator_name)
|
|
end
|
|
end
|
|
|
|
def authenticator_name
|
|
@auth_result&.authenticator_name
|
|
end
|
|
end
|