# plugins/discourse-md5_authentication/plugin.rb # frozen_string_literal: true # name: discourse-md5_authentication # about: A plugin to authenticate users with MD5 passwords from legacy systems # version: 0.6 # authors: saint # url: https://gitea.federated.computer/saint/discourse-md5_authentication.git # This block will run after Discourse has initialized after_initialize do # Define a module to contain the MD5 authentication logic module LegacyMd5Authentication # 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 # 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 # 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