From dffe50a2e6cccb31a54bffae55ad94f6fb71f293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 10 Jun 2016 16:14:42 +0200 Subject: [PATCH] new alternative reply by email addresses --- config/locales/server.en.yml | 2 ++ config/site_settings.yml | 4 +++- lib/email/receiver.rb | 21 ++++++++++++++----- ...tive_reply_by_email_addresses_validator.rb | 16 ++++++++++++++ .../reply_by_email_address_validator.rb | 6 +++--- spec/components/email/receiver_spec.rb | 1 + spec/fixtures/emails/html_reply.eml | 2 +- 7 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 lib/validators/alternative_reply_by_email_addresses_validator.rb diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index b85c82744..2ab37f4dc 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1171,6 +1171,7 @@ en: reply_by_email_enabled: "Enable replying to topics via email." reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com" + alternative_reply_by_email_addresses: "List of alternative templates for reply by email incoming email addresses." incoming_email_prefer_html: "Use the HTML instead of the text for incoming email. May cause unexcpeted formatting issues!" disable_emails: "Prevent Discourse from sending any kind of emails" @@ -1363,6 +1364,7 @@ en: invalid_string_min: "Must be at least %{min} characters." invalid_string_max: "Must be no more than %{max} characters." invalid_reply_by_email_address: "Value must contain '%{reply_key}' and be different from the notification email." + invalid_alternative_reply_by_email_addresses: "All values must contain '%{reply_key}' and be different from the notification email." pop3_polling_host_is_empty: "You must set a 'pop3 polling host' before enabling POP3 polling." pop3_polling_username_is_empty: "You must set a 'pop3 polling username' before enabling POP3 polling." pop3_polling_password_is_empty: "You must set a 'pop3 polling password' before enabling POP3 polling." diff --git a/config/site_settings.yml b/config/site_settings.yml index 1f9fddf2b..2d5b7f45c 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -534,7 +534,9 @@ email: validator: "ReplyByEmailEnabledValidator" reply_by_email_address: default: '' - validator: "ReplyByEmailAddressValidator" + validator: "AlternativeReplyByEmailAddressesValidator" + alternative_reply_by_email_addresses: + default: '' manual_polling_enabled: default: false pop3_polling_enabled: diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 5d9b5d162..36b0dc484 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -327,15 +327,26 @@ module Email # reply match = reply_by_email_address_regex.match(address) - if match && match[1].present? - email_log = EmailLog.for(match[1]) - return { type: :reply, obj: email_log } if email_log + if match && match.captures + match.captures.each do |c| + next if c.blank? + email_log = EmailLog.for(c) + return { type: :reply, obj: email_log } if email_log + end end end def reply_by_email_address_regex - @reply_by_email_address_regex ||= Regexp.new Regexp.escape(SiteSetting.reply_by_email_address) - .gsub(Regexp.escape("%{reply_key}"), "([[:xdigit:]]{32})") + @reply_by_email_address_regex ||= begin + reply_addresses = [ + SiteSetting.reply_by_email_address, + *SiteSetting.alternative_reply_by_email_addresses.split("|") + ] + escaped_reply_addresses = reply_addresses.select { |a| a.present? } + .map { |a| Regexp.escape(a) } + .map { |a| a.gsub(Regexp.escape("%{reply_key}"), "([[:xdigit:]]{32})") } + Regexp.new(escaped_reply_addresses.join("|")) + end end def group_incoming_emails_regex diff --git a/lib/validators/alternative_reply_by_email_addresses_validator.rb b/lib/validators/alternative_reply_by_email_addresses_validator.rb new file mode 100644 index 000000000..d35dedf7c --- /dev/null +++ b/lib/validators/alternative_reply_by_email_addresses_validator.rb @@ -0,0 +1,16 @@ +class AlternativeReplyByEmailAddressesValidator + def initialize(opts={}) + @opts = opts + end + + def valid_value?(val) + return true if val.blank? + + validator = ReplyByEmailAddressValidator.new(@opts) + val.split("|").all? { |v| validator.valid_value?(v) } + end + + def error_message + I18n.t('site_settings.errors.invalid_alternative_reply_by_email_addresses') + end +end diff --git a/lib/validators/reply_by_email_address_validator.rb b/lib/validators/reply_by_email_address_validator.rb index f5c19d2bd..024a1aab7 100644 --- a/lib/validators/reply_by_email_address_validator.rb +++ b/lib/validators/reply_by_email_address_validator.rb @@ -6,9 +6,9 @@ class ReplyByEmailAddressValidator def valid_value?(val) return true if val.blank? - !!(val =~ /@/i) && - !!(val =~ /%{reply_key}/i) && - val.gsub(/\+?%{reply_key}/i, "") != SiteSetting.notification_email + !!val["@"] && + !!val["%{reply_key}"] && + val.gsub(/\+?%{reply_key}/, "") != SiteSetting.notification_email end def error_message diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index 7a802acd1..533eea27e 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -6,6 +6,7 @@ describe Email::Receiver do before do SiteSetting.email_in = true SiteSetting.reply_by_email_address = "reply+%{reply_key}@bar.com" + SiteSetting.alternative_reply_by_email_addresses = "alt+%{reply_key}@bar.com" end def process(email_name) diff --git a/spec/fixtures/emails/html_reply.eml b/spec/fixtures/emails/html_reply.eml index 28e5feff8..2f4ac8f34 100644 --- a/spec/fixtures/emails/html_reply.eml +++ b/spec/fixtures/emails/html_reply.eml @@ -1,6 +1,6 @@ Return-Path: From: Foo Bar -To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +To: alt+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com Date: Fri, 15 Jan 2016 00:12:43 +0100 Message-ID: <18@foo.bar.mail> Mime-Version: 1.0