v0.7 -- complete rework... override SessionController::create
This commit is contained in:
parent
7445bd8f06
commit
4dc121eb76
125
plugin.rb
125
plugin.rb
@ -4,72 +4,89 @@
|
|||||||
|
|
||||||
# name: discourse-md5_authentication
|
# name: discourse-md5_authentication
|
||||||
# about: A plugin to authenticate users with MD5 passwords from legacy systems
|
# about: A plugin to authenticate users with MD5 passwords from legacy systems
|
||||||
# version: 0.6
|
# version: 0.7
|
||||||
# authors: saint
|
# authors: saint
|
||||||
# url: https://gitea.federated.computer/saint/discourse-md5_authentication.git
|
# url: https://gitea.federated.computer/saint/discourse-md5_authentication.git
|
||||||
|
|
||||||
# This block will run after Discourse has initialized
|
|
||||||
after_initialize do
|
after_initialize do
|
||||||
# Define a module to contain the MD5 authentication logic
|
class ::SessionController < ApplicationController
|
||||||
module LegacyMd5Authentication
|
def create
|
||||||
# Override the log_on_user method to include MD5 authentication
|
params.require(:login)
|
||||||
def log_on_user(user, session, cookie_jar, opts = {})
|
params.require(:password)
|
||||||
# If the user has an MD5 password and the MD5 password option is passed
|
|
||||||
if user.custom_fields['md5_password'] && opts[:md5_password]
|
return invalid_credentials if params[:password].length > User.max_password_length
|
||||||
# Check if the provided MD5 password matches the stored MD5 password
|
|
||||||
if user.custom_fields['md5_password'] == Digest::MD5.hexdigest(opts[:md5_password])
|
user = User.find_by_username_or_email(normalized_login_param)
|
||||||
# Update the user to use the new password and clear the MD5 password
|
|
||||||
user.update!(password: opts[:md5_password])
|
raise Discourse::ReadOnly if staff_writes_only_mode? && !user&.staff?
|
||||||
user.custom_fields['md5_password'] = nil
|
|
||||||
user.save_custom_fields
|
rate_limit_second_factor!(user)
|
||||||
|
|
||||||
|
if user.present?
|
||||||
|
password = params[:password]
|
||||||
|
custom_password_md5 = user.custom_fields['custom_password_md5']
|
||||||
|
|
||||||
|
# Check for MD5 password in custom field
|
||||||
|
if custom_password_md5.present?
|
||||||
|
|
||||||
|
# MD5 password is present
|
||||||
|
if Digest::MD5.hexdigest(password) == custom_password_md5
|
||||||
|
|
||||||
|
# MD5 matches, so update the user's password to the new one and remove the custom field
|
||||||
|
user.password = password
|
||||||
|
user.custom_fields['custom_password_md5'] = nil
|
||||||
|
user.save!
|
||||||
|
Rails.logger.debug "Updated MD5 password for user: #{user.id}"
|
||||||
|
|
||||||
else
|
else
|
||||||
# Return nil if the MD5 password does not match
|
|
||||||
return nil
|
# MD5 doesn't match, so we have a failed login attempt.
|
||||||
end
|
Rails.logger.debug "Password incorrect for user: #{user.id}"
|
||||||
end
|
invalid_credentials
|
||||||
# Call the original log_on_user method
|
return
|
||||||
super
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Define a method to authenticate a user with an MD5 password
|
# If their password is incorrect
|
||||||
def authenticate_with_md5(username, password)
|
elsif !user.confirm_password?(password)
|
||||||
# Find the user by username or email, ignoring case
|
|
||||||
user = User.find_by_username_or_email(username.downcase.strip)
|
# There is no MD5 password and the password was incorrect.
|
||||||
# Check if the user exists and the provided MD5 password matches the stored MD5 password
|
Rails.logger.debug "Password incorrect for user: #{user.id}"
|
||||||
if user && user.custom_fields['md5_password'] == Digest::MD5.hexdigest(password)
|
invalid_credentials
|
||||||
# Update the user to use the new password and clear the MD5 password
|
return
|
||||||
user.update!(password: password)
|
end
|
||||||
user.custom_fields['md5_password'] = nil
|
|
||||||
user.save_custom_fields
|
# If the site requires user approval and the user is not approved yet
|
||||||
user
|
if login_not_approved_for?(user)
|
||||||
|
render json: login_not_approved
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# User signed on with username and password, so let's prevent the invite link
|
||||||
|
# from being used to log in (if one exists).
|
||||||
|
Invite.invalidate_for_email(user.email)
|
||||||
|
|
||||||
|
# User's password has expired so they need to reset it
|
||||||
|
if user.password_expired?(password)
|
||||||
|
render json: { error: "expired", reason: "expired" }
|
||||||
|
return
|
||||||
|
end
|
||||||
else
|
else
|
||||||
nil
|
invalid_credentials
|
||||||
end
|
return
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Extend the DefaultCurrentUserProvider class to include our MD5 authentication logic
|
if payload = login_error_check(user)
|
||||||
class ::Auth::DefaultCurrentUserProvider
|
return render json: payload
|
||||||
prepend LegacyMd5Authentication
|
|
||||||
|
|
||||||
# Alias the original current_user method
|
|
||||||
alias_method :original_current_user, :current_user
|
|
||||||
def current_user
|
|
||||||
# Attempt to find the current user using the standard Discourse method
|
|
||||||
user = original_current_user
|
|
||||||
return user if user
|
|
||||||
|
|
||||||
# Check for MD5 authentication if no user is found by the standard method
|
|
||||||
username = @request.params[:login]
|
|
||||||
password = @request.params[:password]
|
|
||||||
|
|
||||||
if username && password
|
|
||||||
# Authenticate the user with MD5
|
|
||||||
user = authenticate_with_md5(username, password)
|
|
||||||
@env[CURRENT_USER_KEY] = user if user
|
|
||||||
end
|
end
|
||||||
|
|
||||||
user
|
second_factor_auth_result = authenticate_second_factor(user)
|
||||||
|
return render(json: @second_factor_failure_payload) unless second_factor_auth_result.ok
|
||||||
|
|
||||||
|
if user.active && user.email_confirmed?
|
||||||
|
login(user, second_factor_auth_result)
|
||||||
|
else
|
||||||
|
not_activated(user)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user