diff --git a/plugin.rb b/plugin.rb index 8e7e574..912163b 100644 --- a/plugin.rb +++ b/plugin.rb @@ -4,7 +4,7 @@ # name: discourse-md5_authentication # about: A plugin to authenticate users with MD5 passwords from legacy systems -# version: 0.5 +# version: 0.6 # authors: saint # url: https://gitea.federated.computer/saint/discourse-md5_authentication.git @@ -12,49 +12,64 @@ after_initialize do # 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 - - # 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 username or email, ignoring case - user = User.find_by_username_or_email(email_or_username.downcase.strip) - - # 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 + # Override the log_on_user method to include MD5 authentication + def log_on_user(user, session, cookie_jar, opts = {}) + # If the user has an MD5 password and the MD5 password option is passed + if user.custom_fields['md5_password'] && opts[:md5_password] + # Check if the provided MD5 password matches the stored MD5 password + if user.custom_fields['md5_password'] == Digest::MD5.hexdigest(opts[:md5_password]) + # Update the user to use the new password and clear the MD5 password + user.update!(password: opts[:md5_password]) + user.custom_fields['md5_password'] = nil + user.save_custom_fields + else + # Return nil if the MD5 password does not match + return nil end end + # Call the original log_on_user method + super + end - # Fallback to the original current_user method - nil + # Define a method to authenticate a user with an MD5 password + def authenticate_with_md5(username, password) + # Find the user by username or email, ignoring case + user = User.find_by_username_or_email(username.downcase.strip) + # Check if the user exists and the provided MD5 password matches the stored MD5 password + if user && user.custom_fields['md5_password'] == Digest::MD5.hexdigest(password) + # 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 + user + else + nil + end end end - # Prepend our module to the DefaultCurrentUserProvider class - Auth::DefaultCurrentUserProvider.prepend LegacyMd5Authentication + # Extend the DefaultCurrentUserProvider class to include our MD5 authentication logic + class ::Auth::DefaultCurrentUserProvider + 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 + + user + end + end end