v0.5 -- change of approach given Discourse changes -- the Auth::DefaultCurrentUserProvider class has a current_user method which we want to try extending instead.

This commit is contained in:
dsainty 2024-06-11 18:45:16 +10:00
parent fa22e04e65
commit 97a822ae15

View File

@ -4,57 +4,57 @@
# 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.4 # version: 0.5
# 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 of code is executed after the Discourse application is initialized. # This block will run after Discourse has initialized
after_initialize do after_initialize do
# Reopening the Auth::DefaultAuthenticator class to add custom authentication logic. # Define a module to contain the MD5 authentication logic
class ::Auth::DefaultAuthenticator module LegacyMd5Authentication
# Define a module to encapsulate the MD5 authentication logic. # Override the current_user method to include MD5 authentication
module LegacyMd5Authentication def current_user
# This method is called when the module is prepended to the class. # Attempt to find the current user using the standard Discourse method
# It creates an alias for the existing authenticate method to preserve it. user = super
def self.prepended(base) return user if user
base.singleton_class.class_eval do
alias_method :old_authenticate, :authenticate
end
end
# Override the authenticate method to add custom MD5 password logic. # Check for MD5 authentication if no user is found by the standard method
def authenticate(email_or_username, password) email_or_username = @request.params[:login]
# Log an attempt to authenticate. password = @request.params[:password]
if email_or_username && password
# Log the start of the MD5 authentication attempt
Rails.logger.info("MD5 Auth: Attempting to authenticate #{email_or_username}") Rails.logger.info("MD5 Auth: Attempting to authenticate #{email_or_username}")
# Find the user by their username or email. # Find the user by username or email, ignoring case
user = User.find_by_username_or_email(email_or_username.downcase.strip) user = User.find_by_username_or_email(email_or_username.downcase.strip)
# Log if a user is found. # Log if a user with an MD5 password is found
if user if user && user.custom_fields['md5_password']
Rails.logger.info("MD5 Auth: User found - #{user.username}") Rails.logger.info("MD5 Auth: User found with MD5 password - #{user.username}")
# Check if the provided password matches the stored MD5 password
if user.custom_fields['md5_password'] == Digest::MD5.hexdigest(password)
# Log the successful MD5 password match
Rails.logger.info("MD5 Auth: MD5 password match for user #{user.username}")
# Update the user to use the new password and clear the MD5 password
user.update!(password: password)
user.custom_fields['md5_password'] = nil
user.save_custom_fields
# Set the current user in the environment
@env[CURRENT_USER_KEY] = user
return user
end
end end
# Check if the user's custom field contains an MD5 password and if it matches the provided password.
if user && user.custom_fields['md5_password'] && user.custom_fields['md5_password'] == Digest::MD5.hexdigest(password)
Rails.logger.info("MD5 Auth: MD5 password match for user #{user.username}")
# Update the user's password to the new format and clear the MD5 password field.
user.update!(password: password)
user.custom_fields['md5_password'] = nil
user.save_custom_fields
# Return an authentication result indicating success.
return Auth::Result.new(user)
end
# If MD5 authentication fails, fall back to the original authentication method.
Rails.logger.info("MD5 Auth: Falling back to default authentication for #{email_or_username}")
old_authenticate(email_or_username, password)
end end
end
# Prepend the module to the DefaultAuthenticator class. # Fallback to the original current_user method
prepend LegacyMd5Authentication nil
end
end end
# Prepend our module to the DefaultCurrentUserProvider class
Auth::DefaultCurrentUserProvider.prepend LegacyMd5Authentication
end end