diff --git app/controllers/mail_handler_controller.rb app/controllers/mail_handler_controller.rb index 1942ab1..9258cc2 100644 --- app/controllers/mail_handler_controller.rb +++ app/controllers/mail_handler_controller.rb @@ -26,10 +26,11 @@ class MailHandlerController < ActionController::Base def index options = params.dup email = options.delete(:email) - if MailHandler.safe_receive(email, options) + error = [] + if MailHandler.safe_receive(email, options, error) head :created else - head :unprocessable_entity + render :plain => error.join('\n'), :status => :unprocessable_entity end end diff --git app/models/mail_handler.rb app/models/mail_handler.rb index d11b6f4..eb49731 100755 --- app/models/mail_handler.rb +++ app/models/mail_handler.rb @@ -24,7 +24,7 @@ class MailHandler < ActionMailer::Base attr_reader :email, :user, :handler_options - def self.receive(raw_mail, options={}) + def self.receive(raw_mail, options={}, error=[]) options = options.deep_dup options[:issue] ||= {} @@ -46,7 +46,7 @@ class MailHandler < ActionMailer::Base ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload| mail = Mail.new(raw_mail) set_payload_for_mail(payload, mail) - new.receive(mail, options) + new.receive(mail, options, error) end end @@ -86,13 +86,14 @@ class MailHandler < ActionMailer::Base # Processes incoming emails # Returns the created object (eg. an issue, a message) or false - def receive(email, options={}) + def receive(email, options={}, error=[]) @email = email @handler_options = options sender_email = email.from.to_a.first.to_s.strip # Ignore emails received from the application emission address to avoid hell cycles emission_address = Setting.mail_from.to_s.gsub(/(?:.*<|>.*|\(.*\))/, '').strip if sender_email.casecmp(emission_address) == 0 + error << "Ignoring email from Redmine emission address [#{sender_email}]." if logger logger.info "MailHandler: ignoring email from Redmine emission address [#{sender_email}]" end @@ -104,6 +105,7 @@ class MailHandler < ActionMailer::Base if value value = value.to_s.downcase if (ignored_value.is_a?(Regexp) && value.match(ignored_value)) || value == ignored_value + error << "Ignoring email with #{key}:#{value} header." if logger logger.info "MailHandler: ignoring email with #{key}:#{value} header" end @@ -113,6 +115,7 @@ class MailHandler < ActionMailer::Base end @user = User.find_by_mail(sender_email) if sender_email.present? if @user && !@user.active? + error << "Ignoring email from non-active user [#{@user.login}]." if logger logger.info "MailHandler: ignoring email from non-active user [#{@user.login}]" end @@ -134,6 +137,7 @@ class MailHandler < ActionMailer::Base ::Mailer.deliver_account_information(@user, @user.password) end else + error << "Could not create account for [#{sender_email}]." if logger logger.error "MailHandler: could not create account for [#{sender_email}]" end @@ -141,6 +145,7 @@ class MailHandler < ActionMailer::Base end else # Default behaviour, emails from unknown users are ignored + error << "Ignoring email from unknown user [#{sender_email}]." if logger logger.info "MailHandler: ignoring email from unknown user [#{sender_email}]" end @@ -148,7 +153,7 @@ class MailHandler < ActionMailer::Base end end User.current = @user - dispatch + dispatch(error) end private @@ -157,7 +162,7 @@ class MailHandler < ActionMailer::Base ISSUE_REPLY_SUBJECT_RE = %r{\[(?:[^\]]*\s+)?#(\d+)\]} MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]} - def dispatch + def dispatch(error) headers = [email.in_reply_to, email.references].flatten.compact subject = email.subject.to_s if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE} @@ -177,12 +182,15 @@ class MailHandler < ActionMailer::Base end rescue ActiveRecord::RecordInvalid => e # TODO: send a email to the user + error << "#{e.message}." logger.error "MailHandler: #{e.message}" if logger false rescue MissingInformation => e + error << "Missing information from #{user}: #{e.message}." logger.error "MailHandler: missing information from #{user}: #{e.message}" if logger false rescue UnauthorizedAction => e + error << "Unauthorized attempt from #{user}." logger.error "MailHandler: unauthorized attempt from #{user}" if logger false end diff --git extra/mail_handler/rdm-mailhandler.rb extra/mail_handler/rdm-mailhandler.rb index 901f7bf..1e7777e 100644 --- extra/mail_handler/rdm-mailhandler.rb +++ extra/mail_handler/rdm-mailhandler.rb @@ -176,8 +176,8 @@ END_DESC "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key." return 77 when 422 - warn "Request was denied by your Redmine server. " + - "Possible reasons: email is sent from an invalid email address or is missing some information." + warn response.body + warn "Request was denied by your Redmine server." return 77 when 400..499 warn "Request was denied by your Redmine server (#{response.code})."