From fa22e04e65ffa79c6527170bb68369fb20ee026d Mon Sep 17 00:00:00 2001 From: dsainty Date: Tue, 11 Jun 2024 16:35:22 +1000 Subject: [PATCH] v0.4 -- change to attempt use of Auth::DefaultAuthenticator Instead of User, code comments --- plugin.rb | 75 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/plugin.rb b/plugin.rb index f562a4a..e7b1a2d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -4,54 +4,57 @@ # name: discourse-md5_authentication # about: A plugin to authenticate users with MD5 passwords from legacy systems -# version: 0.3 +# version: 0.4 # authors: saint # url: https://gitea.federated.computer/saint/discourse-md5_authentication.git +# This block of code is executed after the Discourse application is initialized. after_initialize do - Rails.logger.error("MD5 Authentication Plugin: Initialized") - class ::User + # Reopening the Auth::DefaultAuthenticator class to add custom authentication logic. + class ::Auth::DefaultAuthenticator + # Define a module to encapsulate the MD5 authentication logic. module LegacyMd5Authentication - def self.included(base) - base.singleton_class.prepend(ClassMethods) + # This method is called when the module is prepended to the class. + # It creates an alias for the existing authenticate method to preserve it. + def self.prepended(base) + base.singleton_class.class_eval do + alias_method :old_authenticate, :authenticate + end end - module ClassMethods - def authenticate(login, password) - Rails.logger.error("LegacyMd5Authentication: Trying to authenticate user with login #{login}") + # Override the authenticate method to add custom MD5 password logic. + def authenticate(email_or_username, password) + # Log an attempt to authenticate. + Rails.logger.info("MD5 Auth: Attempting to authenticate #{email_or_username}") - user = nil - - if login.include?('@') - # Assume it's an email address - user_email = UserEmail.find_by(email: login.downcase.strip) - user = user_email ? User.find(user_email.user_id) : nil - else - # Assume it's a username - user = User.find_by(username: login.downcase.strip) - end + # Find the user by their username or email. + user = User.find_by_username_or_email(email_or_username.downcase.strip) - if user - Rails.logger.error("LegacyMd5Authentication: User found: #{user.username}") - if user.custom_fields['md5_password'] && user.custom_fields['md5_password'] == Digest::MD5.hexdigest(password) - Rails.logger.error("LegacyMd5Authentication: MD5 password match for user: #{user.username}") - user.update!(password: password) - user.custom_fields['md5_password'] = nil - user.save_custom_fields - return user - else - Rails.logger.error("LegacyMd5Authentication: MD5 password did not match for user: #{user.username}") - end - else - Rails.logger.error("LegacyMd5Authentication: No user found with login #{login}") - end - - super(login, password) + # Log if a user is found. + if user + Rails.logger.info("MD5 Auth: User found - #{user.username}") 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 - include LegacyMd5Authentication + # Prepend the module to the DefaultAuthenticator class. + prepend LegacyMd5Authentication end end -