From d87edce6c35d3e833c0653f5d3d5e68849f1b075 Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 09:56:15 -0700 Subject: [PATCH 1/6] Pass rejection message along in rejection mail if present --- app/jobs/scheduled/poll_mailbox.rb | 15 ++++++++++++--- app/mailers/rejection_mailer.rb | 27 +++++++++++++++++++++------ config/locales/server.en.yml | 13 ++++++++++++- lib/email/message_builder.rb | 2 +- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/app/jobs/scheduled/poll_mailbox.rb b/app/jobs/scheduled/poll_mailbox.rb index 82bdc679559..36cd759f981 100644 --- a/app/jobs/scheduled/poll_mailbox.rb +++ b/app/jobs/scheduled/poll_mailbox.rb @@ -25,6 +25,7 @@ module Jobs Email::Receiver.new(mail_string).process rescue => e message_template = nil + template_args = {} case e when Email::Receiver::UserNotSufficientTrustLevelError message_template = :email_reject_trust_level @@ -39,8 +40,13 @@ module Jobs when ActiveRecord::Rollback message_template = :email_reject_post_error when Email::Receiver::InvalidPost - # TODO there is a message in this exception, place it in email - message_template = :email_reject_post_error + if e.message.length < 6 + message_template = :email_reject_post_error + else + message_template = :email_reject_post_error_specified + template_args[:post_error] = e.message + end + else message_template = nil end @@ -48,7 +54,10 @@ module Jobs if message_template # inform the user about the rejection message = Mail::Message.new(mail_string) - client_message = RejectionMailer.send_rejection(message.from, message.body, message.subject, message.to, message_template) + template_args[:former_title] = message.subject + template_args[:destination] = message.to + + client_message = RejectionMailer.send_rejection(message_template, message.from, template_args) Email::Sender.new(client_message, message_template).send else Discourse.handle_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string)) diff --git a/app/mailers/rejection_mailer.rb b/app/mailers/rejection_mailer.rb index 20727b459de..6eaf4b915e8 100644 --- a/app/mailers/rejection_mailer.rb +++ b/app/mailers/rejection_mailer.rb @@ -3,12 +3,27 @@ require_dependency 'email/message_builder' class RejectionMailer < ActionMailer::Base include Email::BuildEmailHelper - def send_rejection(message_from, message_body, message_subject, forum_address, template) - build_email(message_from, - template: "system_messages.#{template}", - source: message_body, - former_title: message_subject, - destination: forum_address) + DISALLOWED_TEMPLATE_ARGS = [:to, :from, :site_name, :base_url, + :user_preferences_url, + :include_respond_instructions, :html_override, + :add_unsubscribe_link, :respond_instructions, + :style, :body, :post_id, :topic_id, :subject, + :template, :allow_reply_by_email, + :private_reply, :from_alias] + + # Send an email rejection message. + # + # template - i18n key under system_messages + # message_from - Who to send the rejection messsage to + # template_args - arguments to pass to i18n for interpolation into the message + # Certain keys are disallowed in template_args to avoid confusing the + # BuildEmailHelper. You can see the list in DISALLOWED_TEMPLATE_ARGS. + def send_rejection(template, message_from, template_args) + if template_args.keys.any? { |k| DISALLOWED_TEMPLATE_ARGS.include? k } + raise ArgumentError.new('Reserved key in template arguments') + end + + build_email(message_from, template_args.merge(template: "system_messages.#{template}")) end end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index e97675c5821..f3e1c694165 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1419,7 +1419,18 @@ en: text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - Some possible causes are: complex formatting, message too large, message too small. Please try again. + Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues. + + email_reject_post_error_specified: + subject_template: "Email issue -- Posting error" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Rejection message: + + %{post_error} + + Please attempt to fix the errors and try again. email_reject_reply_key: subject_template: "Email issue -- Bad Reply Key" diff --git a/lib/email/message_builder.rb b/lib/email/message_builder.rb index 310f97f9ea5..20482788606 100644 --- a/lib/email/message_builder.rb +++ b/lib/email/message_builder.rb @@ -49,7 +49,7 @@ module Email return unless html_override = @opts[:html_override] if @opts[:add_unsubscribe_link] - if response_instructions = @template_args[:respond_instructions] + if response_instructions = @opts[:respond_instructions] respond_instructions = PrettyText.cook(response_instructions).html_safe html_override.gsub!("%{respond_instructions}", respond_instructions) end From d7df4e597995bdf0ceff7fee56fda3e36427a58b Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 11:03:03 -0700 Subject: [PATCH 2/6] Start making better-written tests for the email job --- spec/fixtures/emails/valid_incoming.cooked | 5 ++ spec/fixtures/emails/valid_incoming.eml | 4 +- spec/fixtures/emails/valid_reply.cooked | 3 + spec/fixtures/emails/valid_reply.eml | 4 +- spec/jobs/poll_mailbox_spec.rb | 87 ++++++++++++++++++++++ 5 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 spec/fixtures/emails/valid_incoming.cooked create mode 100644 spec/fixtures/emails/valid_reply.cooked diff --git a/spec/fixtures/emails/valid_incoming.cooked b/spec/fixtures/emails/valid_incoming.cooked new file mode 100644 index 00000000000..2bf35825373 --- /dev/null +++ b/spec/fixtures/emails/valid_incoming.cooked @@ -0,0 +1,5 @@ +

Hey folks,

+ +

I was thinking. Wouldn't it be great if we could post topics via email? Yes it would!

+ +

Jakie

diff --git a/spec/fixtures/emails/valid_incoming.eml b/spec/fixtures/emails/valid_incoming.eml index 5e8db53319e..5e03d1dc223 100644 --- a/spec/fixtures/emails/valid_incoming.eml +++ b/spec/fixtures/emails/valid_incoming.eml @@ -4,8 +4,8 @@ Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: +From: Jake the Dog +To: Foo Discourse Message-ID: Subject: We should have a post-by-email-feature. Mime-Version: 1.0 diff --git a/spec/fixtures/emails/valid_reply.cooked b/spec/fixtures/emails/valid_reply.cooked new file mode 100644 index 00000000000..d622863da83 --- /dev/null +++ b/spec/fixtures/emails/valid_reply.cooked @@ -0,0 +1,3 @@ +

I could not disagree more. I am obviously biased but adventure time is the greatest show ever created. Everyone should watch it.

+ +

- Jake out

diff --git a/spec/fixtures/emails/valid_reply.eml b/spec/fixtures/emails/valid_reply.eml index 1e696389954..ec387c8d535 100644 --- a/spec/fixtures/emails/valid_reply.eml +++ b/spec/fixtures/emails/valid_reply.eml @@ -4,8 +4,8 @@ Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo +From: Jake the Dog +To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com Message-ID: Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 diff --git a/spec/jobs/poll_mailbox_spec.rb b/spec/jobs/poll_mailbox_spec.rb index 3adcb78c735..90c8ec9bea9 100644 --- a/spec/jobs/poll_mailbox_spec.rb +++ b/spec/jobs/poll_mailbox_spec.rb @@ -41,6 +41,93 @@ describe Jobs::PollMailbox do end + # Testing mock for the email objects that you get + # from Net::POP3.start { |pop| pop.mails } + class MockPop3EmailObject + def initialize(mail_string) + @message = mail_string + @delete_called = 0 + end + + def pop + @message + end + + def delete + @delete_called += 1 + end + + # call 'assert email.deleted?' at the end of the test + def deleted? + @delete_called == 1 + end + end + + describe "processing email B" do + let(:category) { Fabricate(:category) } + let(:user) { Fabricate(:user) } + + before do + SiteSetting.email_in = true + SiteSetting.reply_by_email_address = 'reply+%{reply_key}@discourse.example.com' + category.email_in = 'incoming+amazing@discourse.example.com' + category.save + user.change_trust_level! :regular + user.username = 'Jake' + user.email = 'jake@email.example.com' + user.save + end + + describe "valid incoming email" do + let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_incoming.eml')} + let(:expected_post) { fixture_file('emails/valid_incoming.cooked') } + + it "posts a new topic with the correct content" do + + poller.handle_mail(email) + + topic = Topic.where(category: category).where.not(id: category.topic_id).first + assert topic.present? + post = topic.posts.first + assert_equal expected_post.strip, post.cooked.strip + + assert email.deleted? + end + end + + describe "valid reply" do + let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} + let(:expected_post) { fixture_file('emails/valid_reply.cooked')} + let(:topic) { Fabricate(:topic) } + let(:first_post) { Fabricate(:post, topic: topic, post_number: 1)} + + before do + first_post.save + EmailLog.create(to_address: 'jake@email.example.com', + email_type: 'user_posted', + reply_key: '59d8df8370b7e95c5a49fbf86aeb2c93', + post: first_post, + topic: topic) + end + + pending "creates a new post with the correct content" do + RejectionMailer.expects(:send_rejection).never + Discourse.expects(:handle_exception).never + + poller.handle_mail(email) + + new_post = Post.where(topic: topic, post_number: 2) + assert new_post.present? + + assert_equal expected_post.strip, new_post.cooked.strip + + assert email.deleted? + end + end + + + end + describe "processing email" do let!(:receiver) { mock } From c0b2b9b341254d0e98b2f2b3a86488812fd6e42a Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 11:03:55 -0700 Subject: [PATCH 3/6] Refactor out handle_failure method in PollMailbox --- app/jobs/scheduled/poll_mailbox.rb | 79 ++++++++++++++++-------------- spec/jobs/poll_mailbox_spec.rb | 8 ++- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/app/jobs/scheduled/poll_mailbox.rb b/app/jobs/scheduled/poll_mailbox.rb index 36cd759f981..749dd67748e 100644 --- a/app/jobs/scheduled/poll_mailbox.rb +++ b/app/jobs/scheduled/poll_mailbox.rb @@ -24,49 +24,52 @@ module Jobs mail_string = mail.pop Email::Receiver.new(mail_string).process rescue => e - message_template = nil - template_args = {} - case e - when Email::Receiver::UserNotSufficientTrustLevelError - message_template = :email_reject_trust_level - when Email::Receiver::UserNotFoundError - message_template = :email_reject_no_account - when Email::Receiver::EmptyEmailError - message_template = :email_reject_empty - when Email::Receiver::EmailUnparsableError - message_template = :email_reject_parsing - when Email::Receiver::EmailLogNotFound - message_template = :email_reject_reply_key - when ActiveRecord::Rollback - message_template = :email_reject_post_error - when Email::Receiver::InvalidPost - if e.message.length < 6 - message_template = :email_reject_post_error - else - message_template = :email_reject_post_error_specified - template_args[:post_error] = e.message - end - - else - message_template = nil - end - - if message_template - # inform the user about the rejection - message = Mail::Message.new(mail_string) - template_args[:former_title] = message.subject - template_args[:destination] = message.to - - client_message = RejectionMailer.send_rejection(message_template, message.from, template_args) - Email::Sender.new(client_message, message_template).send - else - Discourse.handle_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string)) - end + handle_failure(mail_string, e) ensure mail.delete end end + def handle_failure(mail_string, e) + template_args = {} + case e + when Email::Receiver::UserNotSufficientTrustLevelError + message_template = :email_reject_trust_level + when Email::Receiver::UserNotFoundError + message_template = :email_reject_no_account + when Email::Receiver::EmptyEmailError + message_template = :email_reject_empty + when Email::Receiver::EmailUnparsableError + message_template = :email_reject_parsing + when Email::Receiver::EmailLogNotFound + message_template = :email_reject_reply_key + when ActiveRecord::Rollback + message_template = :email_reject_post_error + when Email::Receiver::InvalidPost + if e.message.length < 6 + message_template = :email_reject_post_error + else + message_template = :email_reject_post_error_specified + template_args[:post_error] = e.message + end + + else + message_template = nil + end + + if message_template + # inform the user about the rejection + message = Mail::Message.new(mail_string) + template_args[:former_title] = message.subject + template_args[:destination] = message.to + + client_message = RejectionMailer.send_rejection(message_template, message.from, template_args) + Email::Sender.new(client_message, message_template).send + else + Discourse.handle_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string)) + end + end + def poll_pop3s if !SiteSetting.pop3s_polling_insecure Net::POP3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) diff --git a/spec/jobs/poll_mailbox_spec.rb b/spec/jobs/poll_mailbox_spec.rb index 90c8ec9bea9..4875ead98f0 100644 --- a/spec/jobs/poll_mailbox_spec.rb +++ b/spec/jobs/poll_mailbox_spec.rb @@ -63,6 +63,10 @@ describe Jobs::PollMailbox do end end + def expect_success + Jobs::PollMailbox.expects(:handle_failure).never + end + describe "processing email B" do let(:category) { Fabricate(:category) } let(:user) { Fabricate(:user) } @@ -83,6 +87,7 @@ describe Jobs::PollMailbox do let(:expected_post) { fixture_file('emails/valid_incoming.cooked') } it "posts a new topic with the correct content" do + expect_success poller.handle_mail(email) @@ -111,8 +116,7 @@ describe Jobs::PollMailbox do end pending "creates a new post with the correct content" do - RejectionMailer.expects(:send_rejection).never - Discourse.expects(:handle_exception).never + expect_success poller.handle_mail(email) From 0faea8ee0b4d9f1435411ccd40b58b9e2aefa5cb Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 11:38:44 -0700 Subject: [PATCH 4/6] Attempt at checking throws.... --- spec/fixtures/emails/valid_reply.cooked | 5 +++-- spec/jobs/poll_mailbox_spec.rb | 25 +++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spec/fixtures/emails/valid_reply.cooked b/spec/fixtures/emails/valid_reply.cooked index d622863da83..4bce79ad12a 100644 --- a/spec/fixtures/emails/valid_reply.cooked +++ b/spec/fixtures/emails/valid_reply.cooked @@ -1,3 +1,4 @@ -

I could not disagree more. I am obviously biased but adventure time is the greatest show ever created. Everyone should watch it.

+

I could not disagree more. I am obviously biased but adventure time is the +greatest show ever created. Everyone should watch it.

-

- Jake out

+
  • Jake out
diff --git a/spec/jobs/poll_mailbox_spec.rb b/spec/jobs/poll_mailbox_spec.rb index 4875ead98f0..a96e30916c3 100644 --- a/spec/jobs/poll_mailbox_spec.rb +++ b/spec/jobs/poll_mailbox_spec.rb @@ -67,7 +67,7 @@ describe Jobs::PollMailbox do Jobs::PollMailbox.expects(:handle_failure).never end - describe "processing email B" do + describe "processing emails" do let(:category) { Fabricate(:category) } let(:user) { Fabricate(:user) } @@ -82,11 +82,11 @@ describe Jobs::PollMailbox do user.save end - describe "valid incoming email" do + describe "a valid incoming email" do let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_incoming.eml')} let(:expected_post) { fixture_file('emails/valid_incoming.cooked') } - it "posts a new topic with the correct content" do + it "posts a new topic" do expect_success poller.handle_mail(email) @@ -100,7 +100,7 @@ describe Jobs::PollMailbox do end end - describe "valid reply" do + describe "a valid reply" do let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} let(:expected_post) { fixture_file('emails/valid_reply.cooked')} let(:topic) { Fabricate(:topic) } @@ -111,28 +111,37 @@ describe Jobs::PollMailbox do EmailLog.create(to_address: 'jake@email.example.com', email_type: 'user_posted', reply_key: '59d8df8370b7e95c5a49fbf86aeb2c93', + user: user, post: first_post, topic: topic) end - pending "creates a new post with the correct content" do + it "creates a new post" do expect_success poller.handle_mail(email) - new_post = Post.where(topic: topic, post_number: 2) + new_post = Post.find_by(topic: topic, post_number: 2) assert new_post.present? - assert_equal expected_post.strip, new_post.cooked.strip assert email.deleted? end end + describe "without an email log" do + let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} + it "handles an EmailLogNotFound error" do + poller.expects(:handle_failure).with { |mail_string, ex| ex.is_a? Email::Receiver::EmailLogNotFound } + + poller.handle_mail(email) + assert email.deleted? + end + end end - describe "processing email" do + describe "processing email A" do let!(:receiver) { mock } let!(:email_string) { fixture_file("emails/valid_incoming.eml") } From 63cdde3d965e9f32c4bd14436aa01a2a881b690a Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 12:40:28 -0700 Subject: [PATCH 5/6] Add more tests, undo some changes to fixture files Was causing Email::Reciever tests to fail --- lib/email/receiver.rb | 26 ++-- spec/fixtures/emails/bottom_reply.eml | 160 +++++++++++++++++++++ spec/fixtures/emails/empty.eml | 21 +++ spec/fixtures/emails/valid_incoming.eml | 4 +- spec/fixtures/emails/valid_reply.eml | 4 +- spec/fixtures/emails/wrong_reply_key.eml | 40 ++++++ spec/jobs/poll_mailbox_spec.rb | 168 +++++++++++------------ 7 files changed, 322 insertions(+), 101 deletions(-) create mode 100644 spec/fixtures/emails/bottom_reply.eml create mode 100644 spec/fixtures/emails/empty.eml create mode 100644 spec/fixtures/emails/wrong_reply_key.eml diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 13a36939263..94201f5f93f 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -67,6 +67,19 @@ module Email end end + def is_in_email? + @allow_strangers = false + return false unless SiteSetting.email_in + + category = Category.find_by_email(@message.to.first) + return false unless category + + @category_id = category.id + @allow_strangers = category.email_in_allow_strangers + + true + end + private def parse_body @@ -135,19 +148,6 @@ module Email @body.strip! end - def is_in_email? - @allow_strangers = false - return false unless SiteSetting.email_in - - category = Category.find_by_email(@message.to.first) - return false unless category - - @category_id = category.id - @allow_strangers = category.email_in_allow_strangers - - true - end - def wrap_body_in_quote @body = "[quote=\"#{@message.from.first}\"] #{@body} diff --git a/spec/fixtures/emails/bottom_reply.eml b/spec/fixtures/emails/bottom_reply.eml new file mode 100644 index 00000000000..5fc992971fc --- /dev/null +++ b/spec/fixtures/emails/bottom_reply.eml @@ -0,0 +1,160 @@ +Received: by 10.107.19.29 with SMTP id b29csp111716ioj; + Wed, 30 Jul 2014 17:52:05 -0700 (PDT) +X-Received: by 10.194.238.6 with SMTP id vg6mr11340975wjc.24.1406767925330; + Wed, 30 Jul 2014 17:52:05 -0700 (PDT) +Received: from localhost (localhost [127.0.0.1]) + by bendel.debian.org (Postfix) with QMQP + id 18F5C417; Thu, 31 Jul 2014 00:52:04 +0000 (UTC) +Old-Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on bendel.debian.org +X-Spam-Level: +X-Spam-Status: No, score=-25.9 required=4.0 tests=FOURLA,LDOSUBSCRIBER, + LDO_WHITELIST,MURPHY_DEBIAN_MESSAGE,PGPSIGNATURE autolearn=unavailable + version=3.3.2 +X-Original-To: lists-debian-ctte@bendel.debian.org +Delivered-To: lists-debian-ctte@bendel.debian.org +Received: from localhost (localhost [127.0.0.1]) + by bendel.debian.org (Postfix) with ESMTP id CE6CDEE + for ; Thu, 31 Jul 2014 00:51:52 +0000 (UTC) +X-Virus-Scanned: at lists.debian.org with policy bank en-lt +X-Amavis-Spam-Status: No, score=-11.9 tagged_above=-10000 required=5.3 + tests=[BAYES_00=-2, FOURLA=0.1, LDO_WHITELIST=-5, PGPSIGNATURE=-5] + autolearn=ham +Received: from bendel.debian.org ([127.0.0.1]) + by localhost (lists.debian.org [127.0.0.1]) (amavisd-new, port 2525) + with ESMTP id SB451DwGZCOe for ; + Thu, 31 Jul 2014 00:51:47 +0000 (UTC) +X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .debian. - helo: .becquer.dodds. - helo-domain: .dodds.) FROM/MX_MATCHES_NOT_HELO(DOMAIN)=0; rate: -5 +Received: from becquer.dodds.net (becquer.dodds.net [207.224.24.209]) + by bendel.debian.org (Postfix) with ESMTP id 8E89A2B4 + for ; Thu, 31 Jul 2014 00:51:47 +0000 (UTC) +Received: from virgil.dodds.net (unknown [192.168.15.59]) + by becquer.dodds.net (Postfix) with ESMTPA id 9B0A9256EB + for ; Wed, 30 Jul 2014 17:51:19 -0700 (PDT) +Received: by virgil.dodds.net (Postfix, from userid 1000) + id 942FB60199; Wed, 30 Jul 2014 17:51:15 -0700 (PDT) +Date: Wed, 30 Jul 2014 17:51:15 -0700 +From: Jake +To: incoming+amazing@appmail.adventuretime.ooo +Subject: Re: Next Debian CTTE IRC Meeting at date -d'Thu Jul 31 17:00:00 UTC + 2014' +Message-ID: <20140731005115.GA19044@virgil.dodds.net> +Mail-Followup-To: debian-ctte@lists.debian.org +References: <20140730213924.GA12356@teltox.donarmstrong.com> +MIME-Version: 1.0 +Content-Type: multipart/signed; micalg=pgp-sha256; + protocol="application/pgp-signature"; boundary="qMm9M+Fa2AknHoGS" +Content-Disposition: inline +In-Reply-To: <20140730213924.GA12356@teltox.donarmstrong.com> +User-Agent: Mutt/1.5.23 (2014-03-12) +X-Debian-Message: Signature check passed for Debian member +X-Rc-Virus: 2007-09-13_01 +X-Rc-Spam: 2008-11-04_01 +Resent-Message-ID: +Resent-From: debian-ctte@lists.debian.org +X-Mailing-List: archive/latest/4791 +X-Loop: debian-ctte@lists.debian.org +List-Id: +List-Post: +List-Help: +List-Subscribe: +List-Unsubscribe: +Precedence: list +Resent-Sender: debian-ctte-request@lists.debian.org +Resent-Date: Thu, 31 Jul 2014 00:52:04 +0000 (UTC) + + +--qMm9M+Fa2AknHoGS +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +Content-Transfer-Encoding: quoted-printable + +On Wed, Jul 30, 2014 at 02:39:24PM -0700, Don Armstrong wrote: +> The next Debian CTTE IRC meeting is at=20 + +> date -d 'Thu Jul 31 17:00:00 UTC 2014' on irc.debian.org in +> #debian-ctte. + +> The current meeting agenda is here, and more up-to-date ones may be +> found in the git repository. + +> #startmeeting + +> #topic Who is here? + +> #topic Next Meeting? + +> #topic #717076 Decide between libjpeg-turbo and libjpeg8 et al. + +This has been voted on; should probably be removed from the agenda, someone +just needs to confirm the vote results and get it on the website. (AIUI the +archive has already begun moving on accordingly.) + +> #topic #636783 constitution: super-majority bug + +> #topic #636783 constitution: casting vote + +> #topic #636783 constitution: minimum discussion period + +> #topic #636783 constitution: TC member retirement/rollover + +> #topic #636783 constitution: TC chair retirement/rollover + +> #topic #681419 Depends: foo | foo-nonfree + +> #topic #741573 menu systems and mime-support + +> #topic #746715 init system fallout + +Also voted and just needs to be confirmed. + +> #topic #750135 Maintainer of aptitude package +>=20 +> #topic #752400 Advice on util-linux + +This has been closed by mutual agreement of the people involved and doesn't +require any action from the TC. Removed from the agenda. + +There's also bug #744246, which was assigned to the TC at my request but +without any preamble so it may have escaped notice. However, that situation +has been evolving constructively among the related parties (apparently, an +informal comment from a member of the release team was mistaken for a +release team position, so that's now being revisited), so I don't believe +this is anything we need to put on the agenda for tomorrow despite being on +the open bug list. + +--=20 +Steve Langasek Give me a lever long enough and a Free OS +Debian Developer to set it on, and I can move the world. +Ubuntu Developer http://www.debian.org/ +slangasek@ubuntu.com vorlon@debian.org + +--qMm9M+Fa2AknHoGS +Content-Type: application/pgp-signature; name="signature.asc" +Content-Description: Digital signature + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQIcBAEBCAAGBQJT2ZMDAAoJEFaNMPMhshM9GLsP/244S3wtYZEeVgJWIdB5PE0A +sZVezEA692y++/0oVZVecwV67yBOyfSjPPetdAph2UDMRtfurwxfj2BkbOFA2+Y6 +++MErbmC3V7IGpd/L/fFGdXgvMQT2MNBpw0fnMA7bLpNjCvoj+Hr1HXRUcWoJSlj +WmHWwWSTVRcHg8a3iWYJzY6XfLyEEgHlahrlKvJExsTx/9mc1qg7g8KGdnhzHFBl +ttdH2fxpAk/624dReCcw5RKmOLfZ1HsEl9XcVe1cb4K+MDaQiXmoEK5v3xaNz1tS +NK5v2D5gDs229zoxKzQnnzOPLHxqI5E0L9PpI/mu4T9z7H2bHR3U5BvhnT99t5uw +ydf2cZNGY0uFCV3Rvn07BfAIW5WSXhOfN/5IymRKmdhjsTiwZ/wFjFrK8tVjtERu +yeyA7RIYiblGCEKYIYLWSxhoXeEdmAdfp6EA2/IA1CpgMB+ZdSfaeMgFY7xosgmG +ax3NTnaKyhr1QEUJ2gjAwHnKjuGbRVDAinYrSvP0o8Bh9sAs2BN2negWBCZVwwkN +S9hWTjVqsBmpaPOt5SEDwDo9O9dfzkmaamDsxOuUEz9F7v5jYg0mxA/WbogGty9R +vOMKxdxRkzflL/CferVbkzL/EkZRDfWDp9SleZggrpz7miiNDbS7jdRzJ4EttmJ8 +gHBAVrOzcnbIPOIkk9pw +=KXIu +-----END PGP SIGNATURE----- + +--qMm9M+Fa2AknHoGS-- + + +-- +To UNSUBSCRIBE, email to debian-ctte-REQUEST@lists.debian.org +with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org +Archive: https://lists.debian.org/20140731005115.GA19044@virgil.dodds.net diff --git a/spec/fixtures/emails/empty.eml b/spec/fixtures/emails/empty.eml new file mode 100644 index 00000000000..33f21b4f690 --- /dev/null +++ b/spec/fixtures/emails/empty.eml @@ -0,0 +1,21 @@ +Return-Path: +Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 +Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 +Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 +Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 +Date: Thu, 13 Jun 2013 17:03:48 -0400 +From: Jake the Dog +To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com +Message-ID: +Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' +Mime-Version: 1.0 +Content-Type: text/plain; + charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit +X-Sieve: CMU Sieve 2.2 +X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, + 13 Jun 2013 14:03:48 -0700 (PDT) +X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 + + + diff --git a/spec/fixtures/emails/valid_incoming.eml b/spec/fixtures/emails/valid_incoming.eml index 5e03d1dc223..5e8db53319e 100644 --- a/spec/fixtures/emails/valid_incoming.eml +++ b/spec/fixtures/emails/valid_incoming.eml @@ -4,8 +4,8 @@ Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: Foo Discourse +From: Jake the Dog +To: Message-ID: Subject: We should have a post-by-email-feature. Mime-Version: 1.0 diff --git a/spec/fixtures/emails/valid_reply.eml b/spec/fixtures/emails/valid_reply.eml index ec387c8d535..1e696389954 100644 --- a/spec/fixtures/emails/valid_reply.eml +++ b/spec/fixtures/emails/valid_reply.eml @@ -4,8 +4,8 @@ Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com +From: Jake the Dog +To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo Message-ID: Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 diff --git a/spec/fixtures/emails/wrong_reply_key.eml b/spec/fixtures/emails/wrong_reply_key.eml new file mode 100644 index 00000000000..74963826f7f --- /dev/null +++ b/spec/fixtures/emails/wrong_reply_key.eml @@ -0,0 +1,40 @@ +Return-Path: +Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 +Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 +Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 +Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 +Date: Thu, 13 Jun 2013 17:03:48 -0400 +From: Jake the Dog +To: reply+QQd8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com +Message-ID: +Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' +Mime-Version: 1.0 +Content-Type: text/plain; + charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit +X-Sieve: CMU Sieve 2.2 +X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, + 13 Jun 2013 14:03:48 -0700 (PDT) +X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 + +I could not disagree more. I am obviously biased but adventure time is the +greatest show ever created. Everyone should watch it. + +- Jake out + + +On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta + wrote: +> +> +> +> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: +> +> --- +> hey guys everyone knows adventure time sucks! +> +> --- +> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 +> +> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). +> \ No newline at end of file diff --git a/spec/jobs/poll_mailbox_spec.rb b/spec/jobs/poll_mailbox_spec.rb index a96e30916c3..d9f9dbd104e 100644 --- a/spec/jobs/poll_mailbox_spec.rb +++ b/spec/jobs/poll_mailbox_spec.rb @@ -64,7 +64,11 @@ describe Jobs::PollMailbox do end def expect_success - Jobs::PollMailbox.expects(:handle_failure).never + poller.expects(:handle_failure).never + end + + def expect_exception(clazz) + poller.expects(:handle_failure).with(anything, instance_of(clazz)) end describe "processing emails" do @@ -73,30 +77,65 @@ describe Jobs::PollMailbox do before do SiteSetting.email_in = true - SiteSetting.reply_by_email_address = 'reply+%{reply_key}@discourse.example.com' - category.email_in = 'incoming+amazing@discourse.example.com' + SiteSetting.reply_by_email_address = "reply+%{reply_key}@appmail.adventuretime.ooo" + category.email_in = 'incoming+amazing@appmail.adventuretime.ooo' category.save user.change_trust_level! :regular user.username = 'Jake' - user.email = 'jake@email.example.com' + user.email = 'jake@adventuretime.ooo' user.save end describe "a valid incoming email" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_incoming.eml')} + let(:email) { + # this string replacing is kinda dumb + str = fixture_file('emails/valid_incoming.eml') + str = str.gsub("FROM", 'jake@adventuretime.ooo').gsub("TO", 'incoming+amazing@appmail.adventuretime.ooo') + MockPop3EmailObject.new str + } let(:expected_post) { fixture_file('emails/valid_incoming.cooked') } - it "posts a new topic" do + it "posts a new topic with the correct content" do expect_success poller.handle_mail(email) - topic = Topic.where(category: category).where.not(id: category.topic_id).first - assert topic.present? - post = topic.posts.first - assert_equal expected_post.strip, post.cooked.strip + topic = Topic.where(category: category).where.not(id: category.topic_id).last + topic.should be_present + topic.title.should == "We should have a post-by-email-feature" - assert email.deleted? + post = topic.posts.first + post.cooked.strip.should == expected_post.strip + + email.should be_deleted + end + + describe "with insufficient trust" do + before do + user.change_trust_level! :newuser + end + + it "raises a UserNotSufficientTrustLevelError" do + expect_exception Email::Receiver::UserNotSufficientTrustLevelError + + poller.handle_mail(email) + end + + it "posts the topic if allow_strangers is true" do + begin + category.email_in_allow_strangers = true + category.save + + expect_success + poller.handle_mail(email) + topic = Topic.where(category: category).where.not(id: category.topic_id).last + topic.should be_present + topic.title.should == "We should have a post-by-email-feature" + ensure + category.email_in_allow_strangers = false + category.save + end + end end end @@ -125,86 +164,47 @@ describe Jobs::PollMailbox do assert new_post.present? assert_equal expected_post.strip, new_post.cooked.strip - assert email.deleted? + email.should be_deleted end - end - describe "without an email log" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} + describe "with the wrong reply key" do + let(:email) { MockPop3EmailObject.new fixture_file('emails/wrong_reply_key.eml')} - it "handles an EmailLogNotFound error" do - poller.expects(:handle_failure).with { |mail_string, ex| ex.is_a? Email::Receiver::EmailLogNotFound } - - poller.handle_mail(email) - assert email.deleted? - end - end - end - - describe "processing email A" do - - let!(:receiver) { mock } - let!(:email_string) { fixture_file("emails/valid_incoming.eml") } - let!(:email) { mock } - - before do - email.stubs(:pop).returns(email_string) - Email::Receiver.expects(:new).with(email_string).returns(receiver) - end - - describe "all goes fine" do - - it "email gets deleted" do - receiver.expects(:process) - email.expects(:delete) - - poller.handle_mail(email) - end - end - - describe "raises Untrusted error" do - - it "sends a reply and deletes the email" do - receiver.expects(:process).raises(Email::Receiver::UserNotSufficientTrustLevelError) - email.expects(:delete) - - message = Mail::Message.new(email_string) - Mail::Message.expects(:new).with(email_string).returns(message) - - client_message = mock - sender_object = mock - - RejectionMailer.expects(:send_rejection).with( - message.from, message.body, message.subject, message.to, :email_reject_trust_level - ).returns(client_message) - Email::Sender.expects(:new).with(client_message, :email_reject_trust_level).returns(sender_object) - sender_object.expects(:send) - - poller.handle_mail(email) - end - end - - describe "raises error" do - - [ Email::Receiver::ProcessingError, - Email::Receiver::EmailUnparsableError, - Email::Receiver::EmptyEmailError, - Email::Receiver::UserNotFoundError, - Email::Receiver::EmailLogNotFound, - ActiveRecord::Rollback, - TypeError - ].each do |exception| - - it "deletes email on #{exception}" do - receiver.expects(:process).raises(exception) - email.expects(:delete) - - Discourse.stubs(:handle_exception) + it "raises an EmailLogNotFound error" do + expect_exception Email::Receiver::EmailLogNotFound poller.handle_mail(email) + email.should be_deleted end - end + end + + describe "in failure conditions" do + + it "a valid reply without an email log raises an EmailLogNotFound error" do + email = MockPop3EmailObject.new fixture_file('emails/valid_reply.eml') + expect_exception Email::Receiver::EmailLogNotFound + + poller.handle_mail(email) + email.should be_deleted + end + + it "a no content reply raises an EmailUnparsableError" do + email = MockPop3EmailObject.new fixture_file('emails/no_content_reply.eml') + expect_exception Email::Receiver::EmailUnparsableError + + poller.handle_mail(email) + email.should be_deleted + end + + it "a fully empty email raises an EmptyEmailError" do + email = MockPop3EmailObject.new fixture_file('emails/empty.eml') + expect_exception Email::Receiver::EmptyEmailError + + poller.handle_mail(email) + email.should be_deleted + end + end end From de27c6b4b99c120f478abaabdea55ea13c520000 Mon Sep 17 00:00:00 2001 From: riking Date: Fri, 1 Aug 2014 12:47:08 -0700 Subject: [PATCH 6/6] Revert bad diff --- lib/email/message_builder.rb | 2 +- lib/email/receiver.rb | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/email/message_builder.rb b/lib/email/message_builder.rb index 20482788606..310f97f9ea5 100644 --- a/lib/email/message_builder.rb +++ b/lib/email/message_builder.rb @@ -49,7 +49,7 @@ module Email return unless html_override = @opts[:html_override] if @opts[:add_unsubscribe_link] - if response_instructions = @opts[:respond_instructions] + if response_instructions = @template_args[:respond_instructions] respond_instructions = PrettyText.cook(response_instructions).html_safe html_override.gsub!("%{respond_instructions}", respond_instructions) end diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 94201f5f93f..13a36939263 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -67,19 +67,6 @@ module Email end end - def is_in_email? - @allow_strangers = false - return false unless SiteSetting.email_in - - category = Category.find_by_email(@message.to.first) - return false unless category - - @category_id = category.id - @allow_strangers = category.email_in_allow_strangers - - true - end - private def parse_body @@ -148,6 +135,19 @@ module Email @body.strip! end + def is_in_email? + @allow_strangers = false + return false unless SiteSetting.email_in + + category = Category.find_by_email(@message.to.first) + return false unless category + + @category_id = category.id + @allow_strangers = category.email_in_allow_strangers + + true + end + def wrap_body_in_quote @body = "[quote=\"#{@message.from.first}\"] #{@body}