discourse/lib/auth/result.rb
Andrei Prigorshnev 19d95c64af
DEV: simplify username suggester (#14531)
This PR doesn't change any behavior, but just removes code that wasn't in use. This is a pretty dangerous place to change, since it gets called during user's registration. At the same time the refactoring is very straightforward, it's clear that this code wasn't doing any work (it still needs to be double-checked during review though). Also, the test coverage of UserNameSuggester is good.
2021-10-27 14:41:24 +04:00

173 lines
3.9 KiB
Ruby

# frozen_string_literal: true
class Auth::Result
ATTRIBUTES = [
:user,
:name,
:username,
:email,
:email_valid,
:extra_data,
:awaiting_activation,
:awaiting_approval,
:authenticated,
:authenticator_name,
:requires_invite,
:not_allowed_from_ip_address,
:admin_not_allowed_from_ip_address,
:omit_username, # Used by plugins to prevent username edits
:skip_email_validation,
:destination_url,
:omniauth_disallow_totp,
:failed,
:failed_reason,
:failed_code
]
attr_accessor *ATTRIBUTES
# These are stored in the session during
# account creation. The user cannot read or modify them
SESSION_ATTRIBUTES = [
:email,
:username,
:email_valid,
:omit_username,
:name,
:authenticator_name,
:extra_data,
:skip_email_validation
]
def [](key)
key = key.to_sym
public_send(key) if ATTRIBUTES.include?(key)
end
def initialize
@failed = false
end
def email
@email&.downcase
end
def email_valid=(val)
if !val.in? [true, false, nil]
raise ArgumentError, "email_valid should be boolean or nil"
end
@email_valid = !!val
end
def failed?
!!@failed
end
def session_data
SESSION_ATTRIBUTES.map { |att| [att, public_send(att)] }.to_h
end
def self.from_session_data(data, user:)
result = new
data = data.symbolize_keys
SESSION_ATTRIBUTES.each { |att| result.public_send("#{att}=", data[att]) }
result.user = user
result
end
def apply_user_attributes!
change_made = false
if SiteSetting.auth_overrides_username? && username.present? && UserNameSuggester.fix_username(username) != user.username
user.username = UserNameSuggester.suggest(username)
change_made = true
end
if SiteSetting.auth_overrides_email && email_valid && email.present? && user.email != Email.downcase(email)
user.email = email
change_made = true
end
if SiteSetting.auth_overrides_name && name.present? && user.name != name
user.name = name
change_made = true
end
change_made
end
def can_edit_name
!SiteSetting.auth_overrides_name
end
def can_edit_username
!(SiteSetting.auth_overrides_username || omit_username)
end
def to_client_hash
if requires_invite
return { requires_invite: true }
end
if user&.suspended?
return {
suspended: true,
suspended_message: user.suspended_message
}
end
if omniauth_disallow_totp
return {
omniauth_disallow_totp: !!omniauth_disallow_totp,
email: email
}
end
if user
result = {
authenticated: !!authenticated,
awaiting_activation: !!awaiting_activation,
awaiting_approval: !!awaiting_approval,
not_allowed_from_ip_address: !!not_allowed_from_ip_address,
admin_not_allowed_from_ip_address: !!admin_not_allowed_from_ip_address
}
result[:destination_url] = destination_url if authenticated && destination_url.present?
return result
end
suggested_username = UserNameSuggester.suggest(username_suggester_attributes)
if email_valid && email.present?
if username.present? && User.username_available?(username, email)
suggested_username = username
elsif staged_user = User.where(staged: true).find_by_email(email)
suggested_username = staged_user.username
end
end
result = {
email: email,
username: suggested_username,
auth_provider: authenticator_name,
email_valid: !!email_valid,
can_edit_username: can_edit_username,
can_edit_name: can_edit_name
}
result[:destination_url] = destination_url if destination_url.present?
if SiteSetting.enable_names?
result[:name] = name.presence
result[:name] ||= User.suggest_name(username || email) if can_edit_name
end
result
end
private
def username_suggester_attributes
username || name || email
end
end