From f7432d8ec91c3e0e2cf1fa2172a3139aa3840bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Wed, 24 Feb 2016 19:47:58 +0100 Subject: [PATCH] FEATURE: add support for multiple incoming emails for groups & categories --- app/models/category.rb | 15 +++++++++++++-- app/models/group.rb | 8 +++++--- config/locales/server.en.yml | 1 + lib/email/receiver.rb | 4 ++-- spec/components/email/receiver_spec.rb | 4 ++-- spec/fixtures/emails/encoded_display_name.eml | 2 +- spec/fixtures/emails/new_user.eml | 2 +- spec/fixtures/emails/no_subject.eml | 2 +- 8 files changed, 26 insertions(+), 12 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 1b968ef8d..f23dfa06e 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -33,6 +33,8 @@ class Category < ActiveRecord::Base length: { in: 1..50 } validate :parent_category_validator + validate :email_in_validator + validate :ensure_slug before_save :apply_permissions before_save :downcase_email @@ -308,7 +310,16 @@ SQL end def downcase_email - self.email_in = email_in.downcase if self.email_in + self.email_in = (email_in || "").strip.downcase.presence + end + + def email_in_validator + return if self.email_in.blank? + email_in.split("|").each do |email| + unless Email.is_valid?(email) + self.errors.add(:base, I18n.t('category.errors.invalid_email_in', email_in: email)) + end + end end def downcase_name @@ -380,7 +391,7 @@ SQL end def self.find_by_email(email) - self.find_by(email_in: Email.downcase(email)) + self.where("email_in LIKE ?", "%#{Email.downcase(email)}%").first end def has_children? diff --git a/app/models/group.rb b/app/models/group.rb index 413d17b44..dfb21f2f0 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -81,8 +81,10 @@ class Group < ActiveRecord::Base def incoming_email_validator return if self.automatic || self.incoming_email.blank? - unless Email.is_valid?(incoming_email) - self.errors.add(:base, I18n.t('groups.errors.invalid_incoming_email', incoming_email: incoming_email)) + incoming_email.split("|").each do |email| + unless Email.is_valid?(email) + self.errors.add(:base, I18n.t('groups.errors.invalid_incoming_email', incoming_email: email)) + end end end @@ -332,7 +334,7 @@ class Group < ActiveRecord::Base end def self.find_by_email(email) - self.find_by(incoming_email: Email.downcase(email)) + self.where("incoming_email LIKE ?", "%#{Email.downcase(email)}%").first end def bulk_add(user_ids) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index bfa7d6385..431b7d7f6 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -374,6 +374,7 @@ en: self_parent: "A subcategory's parent cannot be itself" depth: "You can't nest a subcategory under another" email_in_already_exist: "Incoming email address '%{email_in}' is already in use for '%{category_name}' category." + invalid_email_in: "'%{email_in}' is not a valid email address." cannot_delete: uncategorized: "Can't delete Uncategorized" has_subcategories: "Can't delete this category because it has sub-categories." diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 1a65c0863..f094631da 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -214,11 +214,11 @@ module Email end def group_incoming_emails_regex - @group_incoming_emails_regex ||= Regexp.union Group.pluck(:incoming_email).select(&:present?).uniq + @group_incoming_emails_regex ||= Regexp.union Group.pluck(:incoming_email).select(&:present?).map { |e| e.split("|") }.flatten.uniq end def category_email_in_regex - @category_email_in_regex ||= Regexp.union Category.pluck(:email_in).select(&:present?).uniq + @category_email_in_regex ||= Regexp.union Category.pluck(:email_in).select(&:present?).map { |e| e.split("|") }.flatten.uniq end def find_related_post diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index 1690784e6..bdb42a0a2 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -223,7 +223,7 @@ describe Email::Receiver do context "new message to a group" do - let!(:group) { Fabricate(:group, incoming_email: "team@bar.com") } + let!(:group) { Fabricate(:group, incoming_email: "team@bar.com|meat@bar.com") } it "handles encoded display names" do expect { process(:encoded_display_name) }.to change(Topic, :count) @@ -275,7 +275,7 @@ describe Email::Receiver do context "new topic in a category" do - let!(:category) { Fabricate(:category, email_in: "category@bar.com", email_in_allow_strangers: false) } + let!(:category) { Fabricate(:category, email_in: "category@bar.com|category@foo.com", email_in_allow_strangers: false) } it "raises a StrangersNotAllowedError when 'email_in_allow_strangers' is disabled" do expect { process(:new_user) }.to raise_error(Email::Receiver::StrangersNotAllowedError) diff --git a/spec/fixtures/emails/encoded_display_name.eml b/spec/fixtures/emails/encoded_display_name.eml index cf31f703e..1b5d6bb3a 100644 --- a/spec/fixtures/emails/encoded_display_name.eml +++ b/spec/fixtures/emails/encoded_display_name.eml @@ -1,6 +1,6 @@ Return-Path: From: =?UTF-8?B?0KHQu9GD0YfQsNC50L3QsNGP?= =?UTF-8?B?INCY0LzRjw==?= -To: team@bar.com +To: meat@bar.com Subject: I need help Date: Fri, 15 Jan 2016 00:12:43 +0100 Message-ID: <29@foo.bar.mail> diff --git a/spec/fixtures/emails/new_user.eml b/spec/fixtures/emails/new_user.eml index 1464e8ddd..fdae501ab 100644 --- a/spec/fixtures/emails/new_user.eml +++ b/spec/fixtures/emails/new_user.eml @@ -1,6 +1,6 @@ Return-Path: From: Foo Bar -To: category@bar.com +To: category@foo.com Subject: This is a topic from a complete stranger Date: Fri, 15 Jan 2016 00:12:43 +0100 Message-ID: <31@foo.bar.mail> diff --git a/spec/fixtures/emails/no_subject.eml b/spec/fixtures/emails/no_subject.eml index 580410964..ccfd9ea59 100644 --- a/spec/fixtures/emails/no_subject.eml +++ b/spec/fixtures/emails/no_subject.eml @@ -1,5 +1,5 @@ From: Some One -To: team@bar.com +To: meat@bar.com Date: Mon, 1 Feb 2016 00:12:43 +0100 Message-ID: <40@foo.bar.mail> Mime-Version: 1.0