diff --git a/app/controllers/admin/email_templates_controller.rb b/app/controllers/admin/email_templates_controller.rb index b32f0b919..e7d632580 100644 --- a/app/controllers/admin/email_templates_controller.rb +++ b/app/controllers/admin/email_templates_controller.rb @@ -11,7 +11,7 @@ class Admin::EmailTemplatesController < Admin::AdminController "system_messages.email_reject_destination", "system_messages.email_reject_empty", "system_messages.email_reject_invalid_access", "system_messages.email_reject_no_account", "system_messages.email_reject_parsing", "system_messages.email_reject_post_error", - "system_messages.email_reject_post_error_specified", + "system_messages.email_reject_post_error_specified", "system_messages.email_reject_user_not_found", "system_messages.email_reject_reply_key", "system_messages.email_reject_topic_closed", "system_messages.email_reject_topic_not_found", "system_messages.email_reject_trust_level", "system_messages.pending_users_reminder", "system_messages.post_hidden", diff --git a/app/jobs/scheduled/poll_mailbox.rb b/app/jobs/scheduled/poll_mailbox.rb index c01da2d2d..03193837f 100644 --- a/app/jobs/scheduled/poll_mailbox.rb +++ b/app/jobs/scheduled/poll_mailbox.rb @@ -40,6 +40,7 @@ module Jobs message_template = case e when Email::Receiver::EmptyEmailError then :email_reject_empty when Email::Receiver::NoBodyDetectedError then :email_reject_empty + when Email::Receiver::UserNotFoundError then :email_reject_user_not_found when Email::Receiver::AutoGeneratedEmailError then :email_reject_auto_generated when Email::Receiver::InactiveUserError then :email_reject_inactive_user when Email::Receiver::BlockedUserError then :email_reject_blocked_user diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index c293a5b58..04bd73c1c 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1162,6 +1162,7 @@ en: delete_email_logs_after_days: "Delete email logs after (N) days. 0 to keep indefinitely" max_emails_per_day_per_user: "Maximum number of emails to send users per day. 0 to disable the limit" + enable_staged_users: "Automatically create staged users when processing incoming emails." manual_polling_enabled: "Push emails using the API for email replies." pop3_polling_enabled: "Poll via POP3 for email replies." @@ -1828,6 +1829,13 @@ en: Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member. + email_reject_user_not_found: + subject_template: "[%{site_name}] Email issue -- User Not Found" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Your reply was sent from an unknown email address. Try sending from another email address, or contact a staff member. + email_reject_inactive_user: subject_template: "[%{site_name}] Email issue -- Inactive User" text_body_template: | diff --git a/config/site_settings.yml b/config/site_settings.yml index 096b4eab5..4d516bc1e 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -560,6 +560,7 @@ email: default: 365 min: 0 max_emails_per_day_per_user: 100 + enable_staged_users: true files: max_image_size_kb: 3072 diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 5c16c7e09..2211541e1 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -10,6 +10,7 @@ module Email class ProcessingError < StandardError; end class EmptyEmailError < ProcessingError; end + class UserNotFoundError < ProcessingError; end class AutoGeneratedEmailError < ProcessingError; end class NoBodyDetectedError < ProcessingError; end class InactiveUserError < ProcessingError; end @@ -53,6 +54,9 @@ module Email def process_internal user = find_or_create_user(@from_email, @from_display_name) + + raise UserNotFoundError if user.nil? + @incoming_email.update_columns(user_id: user.id) body, @elided = select_body @@ -195,13 +199,23 @@ module Email end def find_or_create_user(email, display_name) - username = UserNameSuggester.sanitize_username(display_name) if display_name.present? + user = nil - User.find_or_create_by(email: email) do |user| - user.username = UserNameSuggester.suggest(username.presence || email) - user.name = display_name.presence || User.suggest_name(email) - user.staged = true + User.transaction do + user = User.find_by_email(email) + + if user.nil? && SiteSetting.enable_staged_users + username = UserNameSuggester.sanitize_username(display_name) if display_name.present? + user = User.create( + email: email, + username: UserNameSuggester.suggest(username.presence || email), + name: display_name.presence || User.suggest_name(email), + staged: true + ) + end end + + user end def destinations @@ -382,7 +396,7 @@ module Email display_name = address_field.display_name.try(:to_s) if should_invite?(email) user = find_or_create_user(email, display_name) - if can_invite?(topic, user) + if user && can_invite?(topic, user) topic.topic_allowed_users.create!(user_id: user.id) topic.add_small_action(sender, "invited_user", user.username) end diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index 0dce786dc..01afbb6f8 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -21,6 +21,11 @@ describe Email::Receiver do expect { Email::Receiver.new("") }.to raise_error(Email::Receiver::EmptyEmailError) end + it "raises and UserNotFoundError when staged users are disabled" do + SiteSetting.enable_staged_users = false + expect { process(:user_not_found) }.to raise_error(Email::Receiver::UserNotFoundError) + end + it "raises an AutoGeneratedEmailError when the mail is auto generated" do expect { process(:auto_generated_precedence) }.to raise_error(Email::Receiver::AutoGeneratedEmailError) expect { process(:auto_generated_header) }.to raise_error(Email::Receiver::AutoGeneratedEmailError) diff --git a/spec/fixtures/emails/user_not_found.eml b/spec/fixtures/emails/user_not_found.eml new file mode 100644 index 000000000..b2863e5d0 --- /dev/null +++ b/spec/fixtures/emails/user_not_found.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Not Found +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <50@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Email from an unknown user.