Category not accepting "anonymous email" from known users

Reproduce:

  1. Have a “private” category that only has create/reply/see access for members of a specific group. No other permissions.
  2. Enable “anonymous email in” for that specific via a unique working alias to the incoming POP account.
  3. Have a non-staff user that is not a member of the group send an email report in to the category email address from the email address associated with their account.
  4. Send in an email from an account not associated with any known Discourse account.

Expected Behavior:

  • Both #3 and #4 result in new topics in the private category, and the group can begin discussion.

Actual Behavior:

  • The email in #4 works but email in #3 is rejected with the can_create? failed error.
8 إعجابات

@zogstrip can you review this?

Is this still a problem?

I’m no longer running a site with incoming email enabled so unfortunately can’t reproduce to say either way.

إعجابَين (2)

Pretty sure #3 still isn’t working.

When we receive an email, we first try to associate it to a user, and then we check for permissions. Since the user isn’t part of the group, they can’t post.

The email_in_allow_strangers field on the category only works for staged users.

3 إعجابات

Can confirm #3 still not working. Is the best workaround right now to have emails directed at a group rather than a category? Not my preferred arrangement but I can switch until a patch comes out.

إعجاب واحد (1)

I don’t think we can ever support #3 unless we add another setting that opens up any incoming emails?

This scenario seems to be replaced these days with the group functionality as a type of workaround, although I could see some use cases that it might still be just as valuable for categories/topics/discussions.

Sounds plausible. Is this a big thing to do?

Like you say, this is just a (bad) workaround. IMO this should be controllable on a per-category level. Clearly a bug that this works only for anonymous but not for known users.

إعجاب واحد (1)

I just ran into this issue while trying to set up a category for our organizations info list. This category only allows a certain group to access it, but we selected the option to allow emails from anonymous users. Email addresses that are not associated with any of our discourse users can send a message that will show up in the category, but registered users that are not in the group get rejected due to “Insufficient Trust Level”. I think I understand the technical reason why it works this way (only works for staged users) but is there a reason why this would be the desired or expected behavior? It seems to me if we are choosing to allow anonymous users we probably want to allow all registered users as well.

إعجاب واحد (1)

واجهنا هذه المشكلة في موقعنا الأسبوع الماضي أيضًا. بالنسبة لنا، تتمثل الحالة في التالي:

في حين أن معظم فئاتنا مخصصة للمستخدمين المسجلين فقط، أردنا توفير طريقة لغير الأعضاء في المجتمع للتواصل مع المطورين الأساسيين عبر البريد الإلكتروني لطرح سؤال سريع أو إثارة مخاوف، وما إلى ذلك.

قمنا بذلك عن طريق إعداد فئة لقبول رسائل البريد الإلكتروني من المستخدمين المجهولين باستخدام عنوان مخصص (مثل ourproject+contact@discoursemail.com). جعلنا صلاحيات الفئة قابلة للقراءة فقط من قبل أعضاء المشروع الأساسيين لتجنب توليد الكثير من الرسائل أو الضوضاء للمجتمع ككل (وهو ما يعني جعل المواضيع قابلة للإنشاء والرد عليها من قبل الأعضاء الأساسيين أيضًا، نظرًا لعدم وجود طريقة لتقييد الوصول للقراءة دون تقييد الوصول للإنشاء/الرد).

ومع ذلك، تعلمنا لاحقًا أنه إذا قام المستخدم المجهول بإنشاء حساب رسمي، فلن يتمكن بعد ذلك من إرسال رسائل إلى عنوان البريد الإلكتروني للتواصل. يبدو هذا غير بديهي، حيث أصبحوا الآن أكثر رسمية ومسجلين مما كانوا من قبل، لكنهم يستطيعون فعل أقل مما كانوا يستطيعونه سابقًا.

أدى ذلك إلى إرباكي الشديد قبل أن أصادف هذا الموضوع، ولا يزال يبدو موقفًا غير محظوظ.

-Brad

إعجابَين (2)

لا تزال هذه المشكلة موجودة في الإصدار 2.7.8. من المحير أن البريد المُرسل إلى عنوان البريد الإلكتروني المرتبط بفئة ما يُقبل عندما لا يكون للمرسل حساب مسجّل في المنتدى، ويُرفض إذا كان لديه حساب.

3 إعجابات

أعتقد أن التصحيح التالي (مقابل الفرع main الحالي) قد يحل هذه المشكلة بتجاوز عمليات التحقق عند تعيين email_in_allow_strangers للمجموعة، بنفس الطريقة التي يتم بها تجاوزها للمستخدمين المرحّلين. هل يبدو ذلك معقولاً؟

diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb
index 7c76c44d61..dd3bc3cfb0 100644
--- a/lib/email/receiver.rb
+++ b/lib/email/receiver.rb
@@ -762,7 +762,7 @@ module Email
                      elided: elided,
                      title: subject,
                      category: destination.id,
-                     skip_validations: user.staged?)
+                     skip_validations: (user.staged? || destination.email_in_allow_strangers))
 
       elsif destination.is_a?(PostReplyKey)
         # We don't stage new users for emails to reply addresses, exit if user is nil

لا يعمل ذلك لأن التحقق يتعلق بمحتوى المنشور، وليس بصلاحيات إنشاء منشور من عدمه…

لقد اختبرت البقعة أدناه لتعمل. إنها حيلة، لا تحاول ذلك في المنزل :scream: تكمن قيمتها في تحديد مكان التغييرات المطلوبة بشكل تقريبي. التحدي يكمن في معرفة كيفية القيام بذلك بالطريقة الصحيحة. أي نصيحة ستكون موضع ترحيب كبير :pray:

diff --git a/app/jobs/regular/notify_mailing_list_subscribers.rb b/app/jobs/regular/notify_mailing_list_subscribers.rb
index c535296105..1d3bf79637 100644
--- a/app/jobs/regular/notify_mailing_list_subscribers.rb
+++ b/app/jobs/regular/notify_mailing_list_subscribers.rb
@@ -74,7 +74,7 @@ module Jobs
 
       DiscourseEvent.trigger(:notify_mailing_list_subscribers, users, post)
       users.find_each do |user|
-        if Guardian.new(user).can_see?(post)
+        if Guardian.new(user).can_see?(post) && Guardian.new(user).can_see_category_staged?(post.topic.category)
           if EmailLog.reached_max_emails?(user)
             skip(user.email, user.id, post.id,
               SkippedEmailLog.reason_types[:exceeded_emails_limit]
diff --git a/app/models/category.rb b/app/models/category.rb
index 630a74c425..6c253650c6 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -201,7 +201,7 @@ class Category < ActiveRecord::Base
       end
     else
       permissions = permission_types.map { |p| CategoryGroup.permission_types[p] }
-      where("(:staged AND LENGTH(COALESCE(email_in, '')) > 0 AND email_in_allow_strangers)
+      where("(LENGTH(COALESCE(email_in, '')) > 0 AND email_in_allow_strangers)
           OR categories.id NOT IN (SELECT category_id FROM category_groups)
           OR categories.id IN (
                 SELECT category_id
@@ -209,7 +209,6 @@ class Category < ActiveRecord::Base
                  WHERE permission_type IN (:permissions)
                    AND (group_id = :everyone OR group_id IN (SELECT group_id FROM group_users WHERE user_id = :user_id))
              )",
-        staged: guardian.is_staged?,
         permissions: permissions,
         user_id: guardian.user.id,
         everyone: Group[:everyone].id)
diff --git a/lib/guardian/category_guardian.rb b/lib/guardian/category_guardian.rb
index 94a48466d6..2a4ba8015c 100644
--- a/lib/guardian/category_guardian.rb
+++ b/lib/guardian/category_guardian.rb
@@ -64,6 +64,14 @@ module CategoryGuardian
   end
 
   def can_see_category?(category)
+    return false unless category
+    return true if is_admin?
+    return true if !category.read_restricted
+    return true if category.email_in.present? && category.email_in_allow_strangers
+    secure_category_ids.include?(category.id)
+  end
+
+  def can_see_category_staged?(category)
     return false unless category
     return true if is_admin?
     return true if !category.read_restricted
إعجابَين (2)

ما رأيك في هذا الاقتراح @zogstrip؟

إعجاب واحد (1)

أعتقد أن السلوك هنا مقصود، وسيكون من الضروري أن يكون الإصلاح شاملاً إلى حد كبير.

المشكلة في السماح للأشخاص بربط موضوع بحساب موجود هي أن أي شخص يمكنه انتحال بريد أي شخص آخر.

أعتقد أن الطريقة لحل هذه المشكلة على المدى الطويل هي:

  1. يمتلك sam@somewhere.com حسابًا على Discourse.
  2. يرسل sam@somewhere.com بريدًا إلكترونيًا إلى فئة مع خيار “بريد إلكتروني مجهول”.
  3. يرسل Discourse بريدًا إلكترونيًا إلى sam@somewhere.com: "يبدو أنك نشرت: محتوى المنشور، إلى عنوان URL الخاص بـ Discourse. هل كنت أنت بالفعل؟
  4. انقر على نعم.
  5. يتم إنشاء الموضوع.

بدون هذه الحماية، ستكون هذه الميزة مفتوحة تمامًا للانتحال، وهو أمر محفوف بالمخاطر للغاية.

5 إعجابات

أليس هذا الأمر موجودًا بالفعل، بغض النظر عن المعلمة Accept emails from anonymous users with no accounts؟

أشارك هذا وجهة النظر: عندما يتم ربط بريد إلكتروني بحساب، ويتم تحديد المربع Accept emails from anonymous users with no accounts، فإن البريد الإلكتروني الوارد

  1. مرتبط بحساب Discourse
  2. غير مسموح له بقراءة الرسائل وفقًا لمعلمات Security للفئة

يجب قبوله.

إعجاب واحد (1)

هل استخدام SPF/DKIM/DMARC، وهو أكثر انتشارًا الآن مما كان عليه في عام 2016، لا يحمي من هذا بدرجة كافية؟

أي مزود بريد إلكتروني جيد (للمستخدم) لن يسمح للمستخدمين الآخرين بالإرسال من عناوين لا تخصهم، ويجب على أي مزود بريد إلكتروني جيد أو خدمة استقبال (لمثيل Discourse) رفض رسائل البريد الإلكتروني التي تفشل في التحقق من المصدر.

ستوجد مزودون لا يتحققون من عنوان المرسل و/أو لا يقومون بإعداد سجلات SPF/etc. ولكن إذا اختار المستخدم استخدام مزود بريد إلكتروني لا يفعل شيئًا للحماية من انتحال الشخصية، فيبدو من المعقول أن يتم انتحال شخصيته.

لم أتعمق في الأمر بشكل خاص ولكنه يبدو أن Email::AuthenticationResults يقوم بالفعل ببعض التحقق من المصدر. ربما على المدى (الأقصر)، يمكن جعل الحكم متاحًا (إذا لم يكن كذلك بالفعل) بحيث يمكن قبول هذه رسائل البريد الإلكتروني بحكم النجاح.

في حلك طويل الأجل، يمكن أيضًا تخطي التحقق “هل كنت أنت حقًا؟” في حالة وجود حكم نجاح.