From 97a822ae15b0f12ede2fc9e54208332b85fa7030 Mon Sep 17 00:00:00 2001 From: dsainty Date: Tue, 11 Jun 2024 18:45:16 +1000 Subject: [PATCH] v0.5 -- change of approach given Discourse changes -- the Auth::DefaultCurrentUserProvider class has a current_user method which we want to try extending instead. --- plugin.rb | 80 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/plugin.rb b/plugin.rb index e7b1a2d..8e7e574 100644 --- a/plugin.rb +++ b/plugin.rb @@ -4,57 +4,57 @@ # name: discourse-md5_authentication # about: A plugin to authenticate users with MD5 passwords from legacy systems -# version: 0.4 +# version: 0.5 # authors: saint # 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 - # Reopening the Auth::DefaultAuthenticator class to add custom authentication logic. - class ::Auth::DefaultAuthenticator - # Define a module to encapsulate the MD5 authentication logic. - module LegacyMd5Authentication - # 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 + # Define a module to contain the MD5 authentication logic + module LegacyMd5Authentication + # Override the current_user method to include MD5 authentication + def current_user + # Attempt to find the current user using the standard Discourse method + user = super + return user if user - # Override the authenticate method to add custom MD5 password logic. - def authenticate(email_or_username, password) - # Log an attempt to authenticate. + # Check for MD5 authentication if no user is found by the standard method + email_or_username = @request.params[:login] + 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}") - # 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) - # Log if a user is found. - if user - Rails.logger.info("MD5 Auth: User found - #{user.username}") + # Log if a user with an MD5 password is found + if user && user.custom_fields['md5_password'] + 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 - - # 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 - # Prepend the module to the DefaultAuthenticator class. - prepend LegacyMd5Authentication + # Fallback to the original current_user method + nil + end end + + # Prepend our module to the DefaultCurrentUserProvider class + Auth::DefaultCurrentUserProvider.prepend LegacyMd5Authentication end