diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb old mode 100644 new mode 100755 index 6b7e518..27bd97e --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -33,8 +33,16 @@ class SettingsController < ApplicationController def edit @notifiables = Redmine::Notifiable.all + valid = true if request.post? - if Setting.set_all_from_params(params[:settings]) + if params[:settings][:mail_handler_enable_regex_delimiters] == '1' + invalid_delimiters = Setting.validate_regex_delimiters params[:settings][:mail_handler_body_delimiters] + if invalid_delimiters.count > 0 + valid = false + flash[:error] = invalid_delimiters.join('\n') + end + end + if valid && Setting.set_all_from_params(params[:settings]) flash[:notice] = l(:notice_successful_update) end redirect_to settings_path(:tab => params[:tab]) diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb old mode 100644 new mode 100755 index 2884131..0052a5a --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -561,7 +561,9 @@ class MailHandler < ActionMailer::Base # Removes the email body of text after the truncation configurations. def cleanup_body(body) - delimiters = Setting.mail_handler_body_delimiters.to_s.split(/[\r\n]+/).reject(&:blank?).map {|s| Regexp.escape(s)} + delimiters = Setting.mail_handler_body_delimiters.to_s.split(/[\r\n]+/).reject(&:blank?) + delimiters = delimiters.map {|s| Regexp.escape(s)} unless Setting.mail_handler_enable_regex_delimiters? + unless delimiters.empty? regex = Regexp.new("^[> ]*(#{ delimiters.join('|') })\s*[\r\n].*", Regexp::MULTILINE) body = body.gsub(regex, '') diff --git a/app/models/setting.rb b/app/models/setting.rb old mode 100644 new mode 100755 index 934e6bf..c9377f7 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -259,6 +259,17 @@ END_SRC load_available_settings load_plugin_settings + def self.validate_regex_delimiters(delimiters) + invalid_delimiters = [] + delimiters.to_s.split(/[\r\n]+/).reject(&:blank?).each do |regex| + begin + Regexp.new(regex) + rescue => exception + invalid_delimiters << l(:error_invalid_regex_delimiter, :delimiter => regex) + end + end + invalid_delimiters + end private def force_utf8_strings(arg) diff --git a/app/views/settings/_mail_handler.html.erb b/app/views/settings/_mail_handler.html.erb old mode 100644 new mode 100755 index f255b4a..6ce890f --- a/app/views/settings/_mail_handler.html.erb +++ b/app/views/settings/_mail_handler.html.erb @@ -6,6 +6,9 @@ <%= l(:text_line_separated) %>

+ <%= setting_check_box :mail_handler_enable_regex_delimiters %> +

+

<%= setting_text_field :mail_handler_excluded_filenames, :size => 60 %> <%= l(:text_comma_separated) %> <%= l(:label_example) %>: smime.p7s, *.vcf diff --git a/config/locales/en.yml b/config/locales/en.yml old mode 100644 new mode 100755 index e0ebe3b..1c30776 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -215,6 +215,7 @@ en: error_ldap_bind_credentials: "Invalid LDAP Account/Password" error_no_tracker_allowed_for_new_issue_in_project: "The project doesn't have any trackers for which you can create an issue" error_no_projects_with_tracker_allowed_for_new_issue: "There are no projects with trackers for which you can create an issue" + error_invalid_regex_delimiter: "Delimiter \"%{delimiter}\" is not a valid regex" mail_subject_lost_password: "Your %{value} password" mail_body_lost_password: 'To change your password, click on the following link:' @@ -448,6 +449,7 @@ en: setting_attachment_extensions_allowed: Allowed extensions setting_attachment_extensions_denied: Disallowed extensions setting_new_item_menu_tab: Project menu tab for creating new objects + setting_mail_handler_enable_regex_delimiters: Enable regex delimiters permission_add_project: Create project permission_add_subprojects: Create subprojects diff --git a/config/settings.yml b/config/settings.yml old mode 100644 new mode 100755 index b9a8258..f042955 --- a/config/settings.yml +++ b/config/settings.yml @@ -182,6 +182,8 @@ notified_events: - issue_updated mail_handler_body_delimiters: default: '' +mail_handler_enable_regex_delimiters: + default: 0 mail_handler_excluded_filenames: default: '' mail_handler_api_enabled: diff --git a/test/fixtures/mail_handler/ticket_reply_from_mail.eml b/test/fixtures/mail_handler/ticket_reply_from_mail.eml new file mode 100644 index 0000000..016b189 --- /dev/null +++ b/test/fixtures/mail_handler/ticket_reply_from_mail.eml @@ -0,0 +1,35 @@ +Return-Path: +Received: from osiris ([127.0.0.1]) + by OSIRIS + with hMailServer; Wed, 12 Oct 2016 03:05:50 -0700 +Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> +From: "John Smith" +To: +Subject: New ticket on a given project +Date: Wed, 12 Oct 2016 13:05:38 +0300 +MIME-Version: 1.0 +Content-Type: text/plain; + format=flowed; + charset="iso-8859-1"; + reply-type=original +Content-Transfer-Encoding: 7bit +X-Priority: 3 +X-MSMail-Priority: Normal +X-Mailer: Microsoft Outlook Express 6.00.2900.2869 +X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 + +Project: onlinestore +Status: Resolved +due date: 2010-12-31 +Start Date:2010-01-01 +Assigned to: John Smith +fixed version: alpha +estimated hours: 2.5 +remaining hours: 1 +done ratio: 30 + +This paragraph is before delimiter + +On Wed, 11 Oct at 1:05 PM, Jon Smith > wrote: + +This paragraph is after the delimiter diff --git a/test/functional/mail_handler_controller_test.rb b/test/functional/mail_handler_controller_test.rb old mode 100644 new mode 100755 diff --git a/test/functional/settings_controller_test.rb b/test/functional/settings_controller_test.rb old mode 100644 new mode 100755 index 38e5695..ebfc8c3 --- a/test/functional/settings_controller_test.rb +++ b/test/functional/settings_controller_test.rb @@ -254,4 +254,32 @@ class SettingsControllerTest < Redmine::ControllerTest ensure Redmine::Plugin.unregister(:foo) end + + def test_post_mail_handler_delimiters_should_not_save_invalid_regex_delimiters + post :edit, :params => { + :settings => { + :mail_handler_enable_regex_delimiters => '1', + :mail_handler_body_delimiters => 'Abc[', + } + } + + assert_redirected_to '/settings' + assert_equal '0', Setting.mail_handler_enable_regex_delimiters + assert_equal '', Setting.mail_handler_body_delimiters + + end + + def test_post_mail_handler_delimiters_should_save_valid_regex_delimiters + post :edit, :params => { + :settings => { + :mail_handler_enable_regex_delimiters => '1', + :mail_handler_body_delimiters => 'On .*, .* at .*, .* <.*> wrote:', + } + } + + assert_redirected_to '/settings' + assert_equal '1', Setting.mail_handler_enable_regex_delimiters + assert_equal 'On .*, .* at .*, .* <.*> wrote:', Setting.mail_handler_body_delimiters + + end end diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb old mode 100644 new mode 100755 index c1afdae..898ccc9 --- a/test/unit/mail_handler_test.rb +++ b/test/unit/mail_handler_test.rb @@ -977,6 +977,25 @@ class MailHandlerTest < ActiveSupport::TestCase end end + test "truncate emails using a regex delimiter" do + delimiter = "On .*, .* at .*, .* <.*> wrote:" + with_settings :mail_handler_enable_regex_delimiters => '1', :mail_handler_body_delimiters => delimiter do + issue = submit_email('ticket_reply_from_mail.eml') + assert_issue_created(issue) + assert issue.description.include?('This paragraph is before delimiter') + assert !issue.description.include?('On Wed, 11 Oct at 1:05 PM, Jon Smith > wrote:') + assert !issue.description.include?('This paragraph is after the delimiter') + end + + with_settings :mail_handler_enable_regex_delimiters => '0', :mail_handler_body_delimiters => delimiter do + issue = submit_email('ticket_reply_from_mail.eml') + assert_issue_created(issue) + assert issue.description.include?('This paragraph is before delimiter') + assert issue.description.include?('On Wed, 11 Oct at 1:05 PM, Jon Smith > wrote:') + assert issue.description.include?('This paragraph is after the delimiter') + end + end + def test_attachments_that_match_mail_handler_excluded_filenames_should_be_ignored with_settings :mail_handler_excluded_filenames => '*.vcf, *.jpg' do issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'}) diff --git a/test/unit/setting_test.rb b/test/unit/setting_test.rb old mode 100644 new mode 100755 index 58ea2fb..d2bdf5e --- a/test/unit/setting_test.rb +++ b/test/unit/setting_test.rb @@ -110,7 +110,7 @@ class SettingTest < ActiveSupport::TestCase def test_setting_serialied_as_binary_should_be_loaded_as_utf8_encoded_strings yaml = <<-YAML ---- +--- - keywords: !binary | Zml4ZXMsY2xvc2VzLNC40YHQv9GA0LDQstC70LXQvdC+LNCz0L7RgtC+0LLQ vizRgdC00LXQu9Cw0L3QvixmaXhlZA==