2024-06-11 05:28:46 +00:00
|
|
|
# plugins/discourse-md5_authentication/plugin.rb
|
2024-06-11 04:26:59 +00:00
|
|
|
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2024-06-11 05:28:46 +00:00
|
|
|
# name: discourse-md5_authentication
|
2024-06-11 04:26:59 +00:00
|
|
|
# about: A plugin to authenticate users with MD5 passwords from legacy systems
|
2024-06-11 06:35:22 +00:00
|
|
|
# version: 0.4
|
2024-06-11 04:26:59 +00:00
|
|
|
# authors: saint
|
|
|
|
# url: https://gitea.federated.computer/saint/discourse-md5_authentication.git
|
|
|
|
|
2024-06-11 06:35:22 +00:00
|
|
|
# This block of code is executed after the Discourse application is initialized.
|
2024-06-11 04:26:59 +00:00
|
|
|
after_initialize do
|
2024-06-11 06:35:22 +00:00
|
|
|
# Reopening the Auth::DefaultAuthenticator class to add custom authentication logic.
|
|
|
|
class ::Auth::DefaultAuthenticator
|
|
|
|
# Define a module to encapsulate the MD5 authentication logic.
|
2024-06-11 04:26:59 +00:00
|
|
|
module LegacyMd5Authentication
|
2024-06-11 06:35:22 +00:00
|
|
|
# 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
|
2024-06-11 04:26:59 +00:00
|
|
|
end
|
|
|
|
|
2024-06-11 06:35:22 +00:00
|
|
|
# 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}")
|
|
|
|
|
|
|
|
# Find the user by their username or email.
|
|
|
|
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}")
|
|
|
|
end
|
2024-06-11 04:26:59 +00:00
|
|
|
|
2024-06-11 06:35:22 +00:00
|
|
|
# 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}")
|
2024-06-11 04:26:59 +00:00
|
|
|
|
2024-06-11 06:35:22 +00:00
|
|
|
# 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)
|
2024-06-11 04:26:59 +00:00
|
|
|
end
|
2024-06-11 06:35:22 +00:00
|
|
|
|
|
|
|
# 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)
|
2024-06-11 04:26:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-11 06:35:22 +00:00
|
|
|
# Prepend the module to the DefaultAuthenticator class.
|
|
|
|
prepend LegacyMd5Authentication
|
2024-06-11 04:26:59 +00:00
|
|
|
end
|
|
|
|
end
|