FIX: Limit new and existent staged users for email topics (#17970)
The maximum_staged_users_per_email site setting controls how many staged users will be invited to the topic created from an incoming email. Previously, it counted only the new staged users.
This commit is contained in:
parent
b082f459c9
commit
707034bc75
|
@ -55,6 +55,7 @@ module Email
|
|||
def initialize(mail_string, opts = {})
|
||||
raise EmptyEmailError if mail_string.blank?
|
||||
@staged_users = []
|
||||
@created_staged_users = []
|
||||
@raw_email = mail_string
|
||||
|
||||
COMMON_ENCODINGS.each do |encoding|
|
||||
|
@ -92,7 +93,7 @@ module Email
|
|||
post
|
||||
rescue Exception => e
|
||||
@incoming_email.update_columns(error: e.class.name) if @incoming_email
|
||||
delete_staged_users
|
||||
delete_created_staged_users
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
@ -698,11 +699,9 @@ module Email
|
|||
end
|
||||
end
|
||||
|
||||
def find_or_create_user(email, display_name, raise_on_failed_create: false)
|
||||
user = nil
|
||||
|
||||
def find_or_create_user(email, display_name, raise_on_failed_create: false, user: nil)
|
||||
User.transaction do
|
||||
user = User.find_by_email(email)
|
||||
user ||= User.find_by_email(email)
|
||||
|
||||
if user.nil? && SiteSetting.enable_staged_users
|
||||
raise EmailNotAllowed unless EmailValidator.allowed?(email)
|
||||
|
@ -715,12 +714,14 @@ module Email
|
|||
name: display_name.presence || User.suggest_name(email),
|
||||
staged: true
|
||||
)
|
||||
@staged_users << user
|
||||
@created_staged_users << user
|
||||
rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
|
||||
raise if raise_on_failed_create
|
||||
user = nil
|
||||
end
|
||||
end
|
||||
|
||||
@staged_users << user if user&.staged?
|
||||
end
|
||||
|
||||
user
|
||||
|
@ -1358,6 +1359,8 @@ module Email
|
|||
end
|
||||
|
||||
def add_other_addresses(post, sender, mail_object)
|
||||
max_staged_users_post = nil
|
||||
|
||||
%i(to cc bcc).each do |d|
|
||||
next if mail_object[d].blank?
|
||||
|
||||
|
@ -1367,18 +1370,22 @@ module Email
|
|||
email = address_field.address.downcase
|
||||
display_name = address_field.display_name.try(:to_s)
|
||||
next unless email["@"]
|
||||
|
||||
if should_invite?(email)
|
||||
user = find_or_create_user(email, display_name)
|
||||
user = User.find_by_email(email)
|
||||
|
||||
# cap number of staged users created per email
|
||||
if (!user || user.staged) && @staged_users.count >= SiteSetting.maximum_staged_users_per_email
|
||||
max_staged_users_post ||= post.topic.add_moderator_post(sender, I18n.t("emails.incoming.maximum_staged_user_per_email_reached"), import_mode: @opts[:import_mode])
|
||||
next
|
||||
end
|
||||
|
||||
user = find_or_create_user(email, display_name, user: user)
|
||||
if user && can_invite?(post.topic, user)
|
||||
post.topic.topic_allowed_users.create!(user_id: user.id)
|
||||
TopicUser.auto_notification_for_staging(user.id, post.topic_id, TopicUser.notification_reasons[:auto_watch])
|
||||
post.topic.add_small_action(sender, "invited_user", user.username, import_mode: @opts[:import_mode])
|
||||
end
|
||||
# cap number of staged users created per email
|
||||
if @staged_users.count > SiteSetting.maximum_staged_users_per_email
|
||||
post.topic.add_moderator_post(sender, I18n.t("emails.incoming.maximum_staged_user_per_email_reached"), import_mode: @opts[:import_mode])
|
||||
return
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid, EmailNotAllowed
|
||||
# don't care if user already allowed or the user's email address is not allowed
|
||||
|
@ -1413,8 +1420,8 @@ module Email
|
|||
end
|
||||
end
|
||||
|
||||
def delete_staged_users
|
||||
@staged_users.each do |user|
|
||||
def delete_created_staged_users
|
||||
@created_staged_users.each do |user|
|
||||
if @incoming_email.user&.id == user.id
|
||||
@incoming_email.update_columns(user_id: nil)
|
||||
end
|
||||
|
|
|
@ -879,7 +879,17 @@ RSpec.describe Email::Receiver do
|
|||
|
||||
it "cap the number of staged users created per email" do
|
||||
SiteSetting.maximum_staged_users_per_email = 1
|
||||
expect { process(:cc) }.to change(Topic, :count)
|
||||
expect { process(:cc) }.to change(Topic, :count).by(1)
|
||||
.and change(User, :count).by(1)
|
||||
expect(Topic.last.ordered_posts[-1].post_type).to eq(Post.types[:moderator_action])
|
||||
end
|
||||
|
||||
it "cap the number of staged users existing per email" do
|
||||
Fabricate(:user, email: "discourse@bar.com", staged: true) # from
|
||||
Fabricate(:user, email: "someone@else.com", staged: true) # to
|
||||
|
||||
SiteSetting.maximum_staged_users_per_email = 1
|
||||
expect { process(:cc) }.to change(Topic, :count).and not_change(User, :count)
|
||||
expect(Topic.last.ordered_posts[-1].post_type).to eq(Post.types[:moderator_action])
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue