FIX: better error message when user without permissions replies via email

FIX: better error message when user without permissions replies via email

diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 38aa5fc..c785540 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -2867,6 +2867,14 @@ en:
 
         If you believe this is an error, [contact a staff member](%{base_url}/about).
 
+    email_reject_reply_not_allowed:
+      title: "Email Reject Reply Not Allowed"
+      subject_template: "[%{email_prefix}] Email issue -- Reply Not Allowed"
+      text_body_template: |
+        We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
+
+        You don't have permissions to reply to the topic. If you believe this is an error, [contact a staff member](%{base_url}/about).
+
     email_error_notification:
       title: "Email Error Notification"
       subject_template: "[%{email_prefix}] Email issue -- POP authentication error"
diff --git a/lib/email/processor.rb b/lib/email/processor.rb
index 6cb5d88..5b7cfaa 100644
--- a/lib/email/processor.rb
+++ b/lib/email/processor.rb
@@ -65,6 +65,7 @@ module Email
                          when Email::Receiver::InvalidPostAction           then :email_reject_invalid_post_action
                          when Discourse::InvalidAccess                     then :email_reject_invalid_access
                          when Email::Receiver::OldDestinationError         then :email_reject_old_destination
+                         when Email::Receiver::ReplyNotAllowedError        then :email_reject_reply_not_allowed
                          else                                                   :email_reject_unrecognized_error
       end
 
diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb
index 6013afd..24883d5 100644
--- a/lib/email/receiver.rb
+++ b/lib/email/receiver.rb
@@ -27,6 +27,7 @@ module Email
     class SilencedUserError            < ProcessingError; end
     class BadDestinationAddress        < ProcessingError; end
     class StrangersNotAllowedError     < ProcessingError; end
+    class ReplyNotAllowedError         < ProcessingError; end
     class InsufficientTrustLevelError  < ProcessingError; end
     class ReplyUserNotMatchingError    < ProcessingError; end
     class TopicNotFoundError           < ProcessingError; end
@@ -694,13 +695,13 @@ module Email
         raise BadDestinationAddress if user.blank?
 
         post_reply_key = destination[:obj]
+        post = Post.with_deleted.find(post_reply_key.post_id)
+        raise ReplyNotAllowedError if !Guardian.new(user).can_create_post?(post&.topic)
 
         if post_reply_key.user_id != user.id && !forwarded_reply_key?(post_reply_key, user)
           raise ReplyUserNotMatchingError, "post_reply_key.user_id => #{post_reply_key.user_id.inspect}, user.id => #{user.id.inspect}"
         end
 
-        post = Post.with_deleted.find(post_reply_key.post_id)
-
         create_reply(user: user,
                      raw: body,
                      elided: elided,
diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb
index c288a0e..9187677 100644
--- a/spec/components/email/receiver_spec.rb
+++ b/spec/components/email/receiver_spec.rb
@@ -298,6 +298,13 @@ describe Email::Receiver do
       expect(post.user).to eq(user)
     end
 
+    it "raises a ReplyNotAllowedError when user without permissions is replying" do
+      Fabricate(:user, email: "bob@bar.com")
+      category.set_permissions(admins: :full)
+      category.save
+      expect { process(:reply_user_not_matching_but_known) }.to raise_error(Email::Receiver::ReplyNotAllowedError)
+    end
+
     it "raises a TopicNotFoundError when the topic was deleted" do
       topic.update_columns(deleted_at: 1.day.ago)
       expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError)

GitHub sha: 87d3b864

1 Like

This commit has been mentioned on Discourse Meta. There might be relevant details there: