# 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.7 # authors: saint # url: https://gitea.federated.computer/saint/discourse-md5_authentication.git after_initialize do class ::SessionController < ApplicationController def create params.require(:login) params.require(:password) return invalid_credentials if params[:password].length > User.max_password_length user = User.find_by_username_or_email(normalized_login_param) raise Discourse::ReadOnly if staff_writes_only_mode? && !user&.staff? rate_limit_second_factor!(user) if user.present? password = params[:password] custom_password_md5 = user.custom_fields['custom_password_md5'] # Check for MD5 password in custom field if custom_password_md5.present? # MD5 password is present if Digest::MD5.hexdigest(password) == custom_password_md5 # MD5 matches, so update the user's password to the new one and remove the custom field user.password = password user.custom_fields['custom_password_md5'] = nil user.save! Rails.logger.debug "Updated MD5 password for user: #{user.id}" else # MD5 doesn't match, so we have a failed login attempt. Rails.logger.debug "Password incorrect for user: #{user.id}" invalid_credentials return end # If their password is incorrect elsif !user.confirm_password?(password) # There is no MD5 password and the password was incorrect. Rails.logger.debug "Password incorrect for user: #{user.id}" invalid_credentials return end # If the site requires user approval and the user is not approved yet if login_not_approved_for?(user) render json: login_not_approved return end # User signed on with username and password, so let's prevent the invite link # from being used to log in (if one exists). Invite.invalidate_for_email(user.email) # User's password has expired so they need to reset it if user.password_expired?(password) render json: { error: "expired", reason: "expired" } return end else invalid_credentials return end if payload = login_error_check(user) return render json: payload end second_factor_auth_result = authenticate_second_factor(user) return render(json: @second_factor_failure_payload) unless second_factor_auth_result.ok if user.active && user.email_confirmed? login(user, second_factor_auth_result) else not_activated(user) end end end end