Rename "Blocked" to "Silenced"

This commit is contained in:
Robin Ward 2017-11-10 12:18:08 -05:00
parent ec3d800492
commit 1f14350220
51 changed files with 366 additions and 332 deletions

View File

@ -7,7 +7,7 @@ import computed from 'ember-addons/ember-computed-decorators';
const PROBLEMS_CHECK_MINUTES = 1; const PROBLEMS_CHECK_MINUTES = 1;
const ATTRIBUTES = [ 'disk_space','admins', 'moderators', 'blocked', 'suspended', 'top_traffic_sources', const ATTRIBUTES = [ 'disk_space','admins', 'moderators', 'silenced', 'suspended', 'top_traffic_sources',
'top_referred_topics', 'updated_at']; 'top_referred_topics', 'updated_at'];
const REPORTS = [ 'global_reports', 'page_view_reports', 'private_message_reports', 'http_reports', const REPORTS = [ 'global_reports', 'page_view_reports', 'private_message_reports', 'http_reports',

View File

@ -58,8 +58,8 @@ export default Ember.Controller.extend(CanCheckEmails, {
saveTrustLevel() { return this.get("model").saveTrustLevel(); }, saveTrustLevel() { return this.get("model").saveTrustLevel(); },
restoreTrustLevel() { return this.get("model").restoreTrustLevel(); }, restoreTrustLevel() { return this.get("model").restoreTrustLevel(); },
lockTrustLevel(locked) { return this.get("model").lockTrustLevel(locked); }, lockTrustLevel(locked) { return this.get("model").lockTrustLevel(locked); },
unblock() { return this.get("model").unblock(); }, unsilence() { return this.get("model").unsilence(); },
block() { return this.get("model").block(); }, silence() { return this.get("model").silence(); },
deleteAllPosts() { return this.get("model").deleteAllPosts(); }, deleteAllPosts() { return this.get("model").deleteAllPosts(); },
anonymize() { return this.get('model').anonymize(); }, anonymize() { return this.get('model').anonymize(); },
destroy() { return this.get('model').destroy(); }, destroy() { return this.get('model').destroy(); },

View File

@ -299,32 +299,32 @@ const AdminUser = Discourse.User.extend({
}); });
}, },
unblock() { unsilence() {
this.set('blockingUser', true); this.set('silencingUser', true);
return ajax('/admin/users/' + this.id + '/unblock', { return ajax('/admin/users/' + this.id + '/unsilence', {
type: 'PUT' type: 'PUT'
}).then(function() { }).then(function() {
window.location.reload(); window.location.reload();
}).catch(function(e) { }).catch(function(e) {
var error = I18n.t('admin.user.unblock_failed', { error: "http: " + e.status + " - " + e.body }); var error = I18n.t('admin.user.unsilence_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error); bootbox.alert(error);
}); });
}, },
block() { silence() {
const user = this, const user = this,
message = I18n.t("admin.user.block_confirm"); message = I18n.t("admin.user.silence_confirm");
const performBlock = function() { const performSilence = function() {
user.set('blockingUser', true); user.set('silencingUser', true);
return ajax('/admin/users/' + user.id + '/block', { return ajax('/admin/users/' + user.id + '/silence', {
type: 'PUT' type: 'PUT'
}).then(function() { }).then(function() {
window.location.reload(); window.location.reload();
}).catch(function(e) { }).catch(function(e) {
var error = I18n.t('admin.user.block_failed', { error: "http: " + e.status + " - " + e.body }); var error = I18n.t('admin.user.silence_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error); bootbox.alert(error);
user.set('blockingUser', false); user.set('silencingUser', false);
}); });
}; };
@ -333,9 +333,9 @@ const AdminUser = Discourse.User.extend({
"class": "cancel", "class": "cancel",
"link": true "link": true
}, { }, {
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t('admin.user.block_accept'), "label": `${iconHTML('exclamation-triangle')} ` + I18n.t('admin.user.silence_accept'),
"class": "btn btn-danger", "class": "btn btn-danger",
"callback": function() { performBlock(); } "callback": function() { performSilence(); }
}]; }];
bootbox.dialog(message, buttons, { "classes": "delete-user-modal" }); bootbox.dialog(message, buttons, { "classes": "delete-user-modal" });

View File

@ -37,8 +37,8 @@
<tr> <tr>
<td class="title">{{d-icon "shield"}} {{i18n 'admin.dashboard.moderators'}}</td> <td class="title">{{d-icon "shield"}} {{i18n 'admin.dashboard.moderators'}}</td>
<td class="value">{{#link-to 'adminUsersList.show' 'moderators'}}{{moderators}}{{/link-to}}</td> <td class="value">{{#link-to 'adminUsersList.show' 'moderators'}}{{moderators}}{{/link-to}}</td>
<td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.blocked'}}</td> <td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.silenced'}}</td>
<td class="value">{{#link-to 'adminUsersList.show' 'blocked'}}{{blocked}}{{/link-to}}</td> <td class="value">{{#link-to 'adminUsersList.show' 'silenced'}}{{silenced}}{{/link-to}}</td>
</tr> </tr>
</table> </table>
</div> </div>

View File

@ -347,17 +347,17 @@
</div> </div>
{{/if}} {{/if}}
<div class="display-row {{if model.blocked 'highlight-danger'}}"> <div class="display-row {{if model.silenced 'highlight-danger'}}">
<div class='field'>{{i18n 'admin.user.blocked'}}</div> <div class='field'>{{i18n 'admin.user.silenced'}}</div>
<div class='value'>{{i18n-yes-no model.blocked}}</div> <div class='value'>{{i18n-yes-no model.silenced}}</div>
<div class='controls'> <div class='controls'>
{{#conditional-loading-spinner size="small" condition=model.blockingUser}} {{#conditional-loading-spinner size="small" condition=model.silencingUser}}
{{#if model.blocked}} {{#if model.silenced}}
{{d-button action="unblock" icon="thumbs-o-up" label="admin.user.unblock"}} {{d-button action="unsilence" icon="thumbs-o-up" label="admin.user.unsilence"}}
{{i18n 'admin.user.block_explanation'}} {{i18n 'admin.user.silence_explanation'}}
{{else}} {{else}}
{{d-button action="block" icon="ban" label="admin.user.block"}} {{d-button action="silence" icon="ban" label="admin.user.silence"}}
{{i18n 'admin.user.block_explanation'}} {{i18n 'admin.user.silence_explanation'}}
{{/if}} {{/if}}
{{/conditional-loading-spinner}} {{/conditional-loading-spinner}}
</div> </div>

View File

@ -8,7 +8,7 @@
{{/if}} {{/if}}
{{nav-item route='adminUsersList.show' routeParam='staff' label='admin.users.nav.staff'}} {{nav-item route='adminUsersList.show' routeParam='staff' label='admin.users.nav.staff'}}
{{nav-item route='adminUsersList.show' routeParam='suspended' label='admin.users.nav.suspended'}} {{nav-item route='adminUsersList.show' routeParam='suspended' label='admin.users.nav.suspended'}}
{{nav-item route='adminUsersList.show' routeParam='blocked' label='admin.users.nav.blocked'}} {{nav-item route='adminUsersList.show' routeParam='silenced' label='admin.users.nav.silenced'}}
{{nav-item route='adminUsersList.show' routeParam='suspect' label='admin.users.nav.suspect'}} {{nav-item route='adminUsersList.show' routeParam='suspect' label='admin.users.nav.suspect'}}
</ul> </ul>
</div> </div>

View File

@ -10,8 +10,8 @@
{{#user-link user=post.user}} {{#user-link user=post.user}}
{{post.user.username}} {{post.user.username}}
{{/user-link}} {{/user-link}}
{{#if post.user.blocked}} {{#if post.user.silenced}}
{{d-icon "ban" title="user.blocked_tooltip"}} {{d-icon "ban" title="user.silenced_tooltip"}}
{{/if}} {{/if}}
</span> </span>
</div> </div>

View File

@ -5,7 +5,7 @@ class Admin::EmailTemplatesController < Admin::AdminController
"custom_invite_mailer", "custom_invite_forum_mailer", "custom_invite_mailer", "custom_invite_forum_mailer",
"new_version_mailer", "new_version_mailer_with_notes", "queued_posts_reminder", "new_version_mailer", "new_version_mailer_with_notes", "queued_posts_reminder",
"system_messages.backup_failed", "system_messages.backup_succeeded", "system_messages.backup_failed", "system_messages.backup_succeeded",
"system_messages.blocked_by_staff", "system_messages.bulk_invite_failed", "system_messages.silenced_by_staff", "system_messages.bulk_invite_failed",
"system_messages.bulk_invite_succeeded", "system_messages.csv_export_failed", "system_messages.bulk_invite_succeeded", "system_messages.csv_export_failed",
"system_messages.csv_export_succeeded", "system_messages.download_remote_images_disabled", "system_messages.csv_export_succeeded", "system_messages.download_remote_images_disabled",
"system_messages.email_error_notification", "system_messages.email_reject_auto_generated", "system_messages.email_error_notification", "system_messages.email_reject_auto_generated",
@ -19,7 +19,7 @@ class Admin::EmailTemplatesController < Admin::AdminController
"system_messages.pending_users_reminder", "system_messages.post_hidden", "system_messages.pending_users_reminder", "system_messages.post_hidden",
"system_messages.restore_failed", "system_messages.restore_succeeded", "system_messages.restore_failed", "system_messages.restore_succeeded",
"system_messages.spam_post_blocked", "system_messages.too_many_spam_flags", "system_messages.spam_post_blocked", "system_messages.too_many_spam_flags",
"system_messages.unblocked", "system_messages.user_automatically_blocked", "system_messages.unsilenced", "system_messages.user_automatically_silenced",
"system_messages.welcome_invite", "system_messages.welcome_user", "test_mailer", "system_messages.welcome_invite", "system_messages.welcome_user", "test_mailer",
"user_notifications.account_created", "user_notifications.admin_login", "user_notifications.account_created", "user_notifications.admin_login",
"user_notifications.confirm_new_email", "user_notifications.confirm_old_email", "user_notifications.confirm_new_email", "user_notifications.confirm_old_email",

View File

@ -15,8 +15,8 @@ class Admin::UsersController < Admin::AdminController
:approve, :approve,
:activate, :activate,
:deactivate, :deactivate,
:block, :silence,
:unblock, :unsilence,
:trust_level, :trust_level,
:trust_level_lock, :trust_level_lock,
:add_group, :add_group,
@ -272,15 +272,15 @@ class Admin::UsersController < Admin::AdminController
render body: nil render body: nil
end end
def block def silence
guardian.ensure_can_block_user! @user guardian.ensure_can_silence_user! @user
UserBlocker.block(@user, current_user, keep_posts: true) UserSilencer.silence(@user, current_user, keep_posts: true)
render body: nil render body: nil
end end
def unblock def unsilence
guardian.ensure_can_unblock_user! @user guardian.ensure_can_unsilence_user! @user
UserBlocker.unblock(@user, current_user) UserSilencer.unsilence(@user, current_user)
render body: nil render body: nil
end end

View File

@ -10,7 +10,7 @@ module Jobs
HEADER_ATTRS_FOR ||= HashWithIndifferentAccess.new( HEADER_ATTRS_FOR ||= HashWithIndifferentAccess.new(
user_archive: ['topic_title', 'category', 'sub_category', 'is_pm', 'post', 'like_count', 'reply_count', 'url', 'created_at'], user_archive: ['topic_title', 'category', 'sub_category', 'is_pm', 'post', 'like_count', 'reply_count', 'url', 'created_at'],
user_list: ['id', 'name', 'username', 'email', 'title', 'created_at', 'last_seen_at', 'last_posted_at', 'last_emailed_at', 'trust_level', 'approved', 'suspended_at', 'suspended_till', 'blocked', 'active', 'admin', 'moderator', 'ip_address', 'staged'], user_list: ['id', 'name', 'username', 'email', 'title', 'created_at', 'last_seen_at', 'last_posted_at', 'last_emailed_at', 'trust_level', 'approved', 'suspended_at', 'suspended_till', 'silenced', 'active', 'admin', 'moderator', 'ip_address', 'staged'],
user_stats: ['topics_entered', 'posts_read_count', 'time_read', 'topic_count', 'post_count', 'likes_given', 'likes_received'], user_stats: ['topics_entered', 'posts_read_count', 'time_read', 'topic_count', 'post_count', 'likes_given', 'likes_received'],
user_profile: ['location', 'website', 'views'], user_profile: ['location', 'website', 'views'],
user_sso: ['external_id', 'external_email', 'external_username', 'external_name', 'external_avatar_url'], user_sso: ['external_id', 'external_email', 'external_username', 'external_name', 'external_avatar_url'],
@ -181,7 +181,7 @@ module Jobs
def get_base_user_array(user) def get_base_user_array(user)
user_array = [] user_array = []
user_array.push(user.id, escape_comma(user.name), user.username, user.email, escape_comma(user.title), user.created_at, user.last_seen_at, user.last_posted_at, user.last_emailed_at, user.trust_level, user.approved, user.suspended_at, user.suspended_till, user.blocked, user.active, user.admin, user.moderator, user.ip_address, user.staged, user.user_stat.topics_entered, user.user_stat.posts_read_count, user.user_stat.time_read, user.user_stat.topic_count, user.user_stat.post_count, user.user_stat.likes_given, user.user_stat.likes_received, escape_comma(user.user_profile.location), user.user_profile.website, user.user_profile.views) user_array.push(user.id, escape_comma(user.name), user.username, user.email, escape_comma(user.title), user.created_at, user.last_seen_at, user.last_posted_at, user.last_emailed_at, user.trust_level, user.approved, user.suspended_at, user.suspended_till, user.silenced, user.active, user.admin, user.moderator, user.ip_address, user.staged, user.user_stat.topics_entered, user.user_stat.posts_read_count, user.user_stat.time_read, user.user_stat.topic_count, user.user_stat.post_count, user.user_stat.likes_given, user.user_stat.likes_received, escape_comma(user.user_profile.location), user.user_profile.website, user.user_profile.views)
end end
def add_single_sign_on(user, user_info_array) def add_single_sign_on(user, user_info_array)

View File

@ -15,7 +15,7 @@ module Jobs
return if !post || post.trashed? || post.user_deleted? || !post.topic return if !post || post.trashed? || post.user_deleted? || !post.topic
users = users =
User.activated.not_blocked.not_suspended.real User.activated.not_silenced.not_suspended.real
.joins(:user_option) .joins(:user_option)
.where('user_options.mailing_list_mode AND user_options.mailing_list_mode_frequency > 0') .where('user_options.mailing_list_mode AND user_options.mailing_list_mode_frequency > 0')
.where('NOT EXISTS ( .where('NOT EXISTS (

View File

@ -22,7 +22,7 @@ module Jobs
ub.badge_id = #{Badge::Anniversary} AND ub.badge_id = #{Badge::Anniversary} AND
ub.granted_at BETWEEN '#{fmt_start_date}' AND '#{fmt_end_date}' ub.granted_at BETWEEN '#{fmt_start_date}' AND '#{fmt_end_date}'
WHERE u.active AND WHERE u.active AND
NOT u.blocked AND NOT u.silenced AND
NOT p.hidden AND NOT p.hidden AND
p.deleted_at IS NULL AND p.deleted_at IS NULL AND
t.visible AND t.visible AND

View File

@ -147,7 +147,7 @@ class AdminDashboardData
admins: User.admins.count, admins: User.admins.count,
moderators: User.moderators.count, moderators: User.moderators.count,
suspended: User.suspended.count, suspended: User.suspended.count,
blocked: User.blocked.count, silenced: User.silenced.count,
top_referrers: IncomingLinksReport.find('top_referrers').as_json, top_referrers: IncomingLinksReport.find('top_referrers').as_json,
top_traffic_sources: IncomingLinksReport.find('top_traffic_sources').as_json, top_traffic_sources: IncomingLinksReport.find('top_traffic_sources').as_json,
top_referred_topics: IncomingLinksReport.find('top_referred_topics').as_json, top_referred_topics: IncomingLinksReport.find('top_referred_topics').as_json,

View File

@ -82,7 +82,7 @@ class DirectoryItem < ActiveRecord::Base
LEFT OUTER JOIN posts AS p ON ua.target_post_id = p.id LEFT OUTER JOIN posts AS p ON ua.target_post_id = p.id
LEFT OUTER JOIN categories AS c ON t.category_id = c.id LEFT OUTER JOIN categories AS c ON t.category_id = c.id
WHERE u.active WHERE u.active
AND NOT u.blocked AND NOT u.silenced
AND t.deleted_at IS NULL AND t.deleted_at IS NULL
AND COALESCE(t.visible, true) AND COALESCE(t.visible, true)
AND p.deleted_at IS NULL AND p.deleted_at IS NULL

View File

@ -66,7 +66,7 @@ class QueuedPost < ActiveRecord::Base
QueuedPost.transaction do QueuedPost.transaction do
change_to!(:approved, approved_by) change_to!(:approved, approved_by)
UserBlocker.unblock(user, approved_by) if user.blocked? UserSilencer.unsilence(user, approved_by) if user.silenced?
created_post = creator.create created_post = creator.create

View File

@ -146,9 +146,9 @@ class User < ActiveRecord::Base
# TODO-PERF: There is no indexes on any of these # TODO-PERF: There is no indexes on any of these
# and NotifyMailingListSubscribers does a select-all-and-loop # and NotifyMailingListSubscribers does a select-all-and-loop
# may want to create an index on (active, blocked, suspended_till)? # may want to create an index on (active, silence, suspended_till)?
scope :blocked, -> { where(blocked: true) } scope :silenced, -> { where(silenced: true) }
scope :not_blocked, -> { where(blocked: false) } scope :not_silenced, -> { where(silenced: false) }
scope :suspended, -> { where('suspended_till IS NOT NULL AND suspended_till > ?', Time.zone.now) } scope :suspended, -> { where('suspended_till IS NOT NULL AND suspended_till > ?', Time.zone.now) }
scope :not_suspended, -> { where('suspended_till IS NULL OR suspended_till <= ?', Time.zone.now) } scope :not_suspended, -> { where('suspended_till IS NULL OR suspended_till <= ?', Time.zone.now) }
scope :activated, -> { where(active: true) } scope :activated, -> { where(active: true) }
@ -1141,7 +1141,7 @@ end
# flag_level :integer default(0), not null # flag_level :integer default(0), not null
# ip_address :inet # ip_address :inet
# moderator :boolean default(FALSE) # moderator :boolean default(FALSE)
# blocked :boolean default(FALSE) # silenced :boolean default(FALSE)
# title :string # title :string
# uploaded_avatar_id :integer # uploaded_avatar_id :integer
# locale :string(10) # locale :string(10)

View File

@ -45,8 +45,8 @@ class UserHistory < ActiveRecord::Base
delete_category: 27, delete_category: 27,
create_category: 28, create_category: 28,
change_site_text: 29, change_site_text: 29,
block_user: 30, silence_user: 30,
unblock_user: 31, unsilence_user: 31,
grant_admin: 32, grant_admin: 32,
revoke_admin: 33, revoke_admin: 33,
grant_moderation: 34, grant_moderation: 34,
@ -90,8 +90,8 @@ class UserHistory < ActiveRecord::Base
:change_category_settings, :change_category_settings,
:delete_category, :delete_category,
:create_category, :create_category,
:block_user, :silence_user,
:unblock_user, :unsilence_user,
:grant_admin, :grant_admin,
:revoke_admin, :revoke_admin,
:grant_moderation, :grant_moderation,

View File

@ -22,7 +22,7 @@ class AdminUserListSerializer < BasicUserSerializer
:suspended_at, :suspended_at,
:suspended_till, :suspended_till,
:suspended, :suspended,
:blocked, :silenced,
:time_read, :time_read,
:staged :staged

View File

@ -1,37 +1,37 @@
class SpamRule::AutoBlock class SpamRule::AutoSilence
def initialize(user) def initialize(user)
@user = user @user = user
end end
def self.block?(user) def self.silence?(user)
self.new(user).block? self.new(user).silence?
end end
def self.punish!(user) def self.punish!(user)
self.new(user).block_user self.new(user).silence_user
end end
def perform def perform
block_user if block? silence_user if silence?
end end
def block? def silence?
return true if @user.blocked? return true if @user.silenced?
return false if @user.staged? return false if @user.staged?
return false if @user.has_trust_level?(TrustLevel[1]) return false if @user.has_trust_level?(TrustLevel[1])
if SiteSetting.num_spam_flags_to_block_new_user > (0) && if SiteSetting.num_spam_flags_to_silence_new_user > (0) &&
SiteSetting.num_users_to_block_new_user > (0) && SiteSetting.num_users_to_silence_new_user > (0) &&
num_spam_flags_against_user >= (SiteSetting.num_spam_flags_to_block_new_user) && num_spam_flags_against_user >= (SiteSetting.num_spam_flags_to_silence_new_user) &&
num_users_who_flagged_spam_against_user >= (SiteSetting.num_users_to_block_new_user) num_users_who_flagged_spam_against_user >= (SiteSetting.num_users_to_silence_new_user)
return true return true
end end
if SiteSetting.num_tl3_flags_to_block_new_user > (0) && if SiteSetting.num_tl3_flags_to_silence_new_user > (0) &&
SiteSetting.num_tl3_users_to_block_new_user > (0) && SiteSetting.num_tl3_users_to_silence_new_user > (0) &&
num_tl3_flags_against_user >= (SiteSetting.num_tl3_flags_to_block_new_user) && num_tl3_flags_against_user >= (SiteSetting.num_tl3_flags_to_silence_new_user) &&
num_tl3_users_who_flagged >= (SiteSetting.num_tl3_users_to_block_new_user) num_tl3_users_who_flagged >= (SiteSetting.num_tl3_users_to_silence_new_user)
return true return true
end end
@ -70,10 +70,10 @@ class SpamRule::AutoBlock
.pluck(:id) .pluck(:id)
end end
def block_user def silence_user
Post.transaction do Post.transaction do
if UserBlocker.block(@user, Discourse.system_user, message: :too_many_spam_flags) && SiteSetting.notify_mods_when_user_blocked if UserSilencer.silence(@user, Discourse.system_user, message: :too_many_spam_flags) && SiteSetting.notify_mods_when_user_silenced
GroupMessage.create(Group[:moderators].name, :user_automatically_blocked, user: @user, limit_once_per: false) GroupMessage.create(Group[:moderators].name, :user_automatically_silenced, user: @user, limit_once_per: false)
end end
end end
end end

View File

@ -12,7 +12,7 @@ class SpamRulesEnforcer
end end
def enforce! def enforce!
SpamRule::AutoBlock.new(@user).perform if @user SpamRule::AutoSilence.new(@user).perform if @user
SpamRule::FlagSockpuppets.new(@post).perform if @post SpamRule::FlagSockpuppets.new(@post).perform if @post
true true
end end

View File

@ -273,15 +273,15 @@ class StaffActionLogger
context: category.url)) context: category.url))
end end
def log_block_user(user, opts = {}) def log_silence_user(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:block_user], UserHistory.create(params(opts).merge(action: UserHistory.actions[:silence_user],
target_user_id: user.id)) target_user_id: user.id))
end end
def log_unblock_user(user, opts = {}) def log_unsilence_user(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:unblock_user], UserHistory.create(params(opts).merge(action: UserHistory.actions[:unsilence_user],
target_user_id: user.id)) target_user_id: user.id))
end end

View File

@ -1,26 +1,26 @@
class UserBlocker class UserSilencer
def initialize(user, by_user = nil, opts = {}) def initialize(user, by_user = nil, opts = {})
@user, @by_user, @opts = user, by_user, opts @user, @by_user, @opts = user, by_user, opts
end end
def self.block(user, by_user = nil, opts = {}) def self.silence(user, by_user = nil, opts = {})
UserBlocker.new(user, by_user, opts).block UserSilencer.new(user, by_user, opts).silence
end end
def self.unblock(user, by_user = nil, opts = {}) def self.unsilence(user, by_user = nil, opts = {})
UserBlocker.new(user, by_user, opts).unblock UserSilencer.new(user, by_user, opts).unsilence
end end
def block def silence
hide_posts unless @opts[:keep_posts] hide_posts unless @opts[:keep_posts]
unless @user.blocked? unless @user.silenced?
@user.blocked = true @user.silenced = true
if @user.save if @user.save
message_type = @opts[:message] || :blocked_by_staff message_type = @opts[:message] || :silenced_by_staff
post = SystemMessage.create(@user, message_type) post = SystemMessage.create(@user, message_type)
if post && @by_user if post && @by_user
StaffActionLogger.new(@by_user).log_block_user(@user, context: "#{message_type}: '#{post.topic&.title rescue ''}' #{@opts[:reason]}") StaffActionLogger.new(@by_user).log_silence_user(@user, context: "#{message_type}: '#{post.topic&.title rescue ''}' #{@opts[:reason]}")
end end
end end
else else
@ -36,11 +36,11 @@ class UserBlocker
Topic.where(id: topic_ids).update_all(visible: false) unless topic_ids.empty? Topic.where(id: topic_ids).update_all(visible: false) unless topic_ids.empty?
end end
def unblock def unsilence
@user.blocked = false @user.silenced = false
if @user.save if @user.save
SystemMessage.create(@user, :unblocked) SystemMessage.create(@user, :unsilenced)
StaffActionLogger.new(@by_user).log_unblock_user(@user) if @by_user StaffActionLogger.new(@by_user).log_unsilence_user(@user) if @by_user
end end
end end

View File

@ -605,7 +605,7 @@ en:
admin: "{{user}} is an admin" admin: "{{user}} is an admin"
moderator_tooltip: "This user is a moderator" moderator_tooltip: "This user is a moderator"
admin_tooltip: "This user is an admin" admin_tooltip: "This user is an admin"
blocked_tooltip: "This user is blocked" silenced_tooltip: "This user is silenced"
suspended_notice: "This user is suspended until {{date}}." suspended_notice: "This user is suspended until {{date}}."
suspended_permanently: "This user is suspended." suspended_permanently: "This user is suspended."
suspended_reason: "Reason: " suspended_reason: "Reason: "
@ -2575,7 +2575,7 @@ en:
no_problems: "No problems were found." no_problems: "No problems were found."
moderators: 'Moderators:' moderators: 'Moderators:'
admins: 'Admins:' admins: 'Admins:'
blocked: 'Blocked:' silenced: 'Silenced:'
suspended: 'Suspended:' suspended: 'Suspended:'
private_messages_short: "Msgs" private_messages_short: "Msgs"
private_messages_title: "Messages" private_messages_title: "Messages"
@ -3136,8 +3136,8 @@ en:
change_category_settings: "change category settings" change_category_settings: "change category settings"
delete_category: "delete category" delete_category: "delete category"
create_category: "create category" create_category: "create category"
block_user: "block user" silence_user: "silence user"
unblock_user: "unblock user" unsilence_user: "unsilence user"
grant_admin: "grant admin" grant_admin: "grant admin"
revoke_admin: "revoke admin" revoke_admin: "revoke admin"
grant_moderation: "grant moderation" grant_moderation: "grant moderation"
@ -3235,7 +3235,7 @@ en:
pending: "Pending" pending: "Pending"
staff: 'Staff' staff: 'Staff'
suspended: 'Suspended' suspended: 'Suspended'
blocked: 'Blocked' silenced: 'Silenced'
suspect: 'Suspect' suspect: 'Suspect'
approved: "Approved?" approved: "Approved?"
approved_selected: approved_selected:
@ -3256,7 +3256,7 @@ en:
staff: "Staff" staff: "Staff"
admins: 'Admin Users' admins: 'Admin Users'
moderators: 'Moderators' moderators: 'Moderators'
blocked: 'Blocked Users' silenced: 'Silenced Users'
suspended: 'Suspended Users' suspended: 'Suspended Users'
suspect: 'Suspect Users' suspect: 'Suspect Users'
reject_successful: reject_successful:
@ -3287,12 +3287,12 @@ en:
# keys ending with _MF use message format, see https://meta.discourse.org/t/message-format-support-for-localization/7035 for details # keys ending with _MF use message format, see https://meta.discourse.org/t/message-format-support-for-localization/7035 for details
delete_all_posts_confirm_MF: "You are about to delete {POSTS, plural, one {1 post} other {# posts}} and {TOPICS, plural, one {1 topic} other {# topics}}. Are you sure?" delete_all_posts_confirm_MF: "You are about to delete {POSTS, plural, one {1 post} other {# posts}} and {TOPICS, plural, one {1 topic} other {# topics}}. Are you sure?"
suspend: "Suspend" silence: "Silence"
unsuspend: "Unsuspend" unsilence: "Unsilence"
suspended: "Suspended?" silenced: "Silenced?"
moderator: "Moderator?" moderator: "Moderator?"
admin: "Admin?" admin: "Admin?"
blocked: "Blocked?" suspended: "Suspended?"
staged: "Staged?" staged: "Staged?"
show_admin_profile: "Admin" show_admin_profile: "Admin"
refresh_browsers: "Force browser refresh" refresh_browsers: "Force browser refresh"
@ -3308,8 +3308,8 @@ en:
grant_admin_confirm: "We've sent you an email to verify the new administrator. Please open it and follow the instructions." grant_admin_confirm: "We've sent you an email to verify the new administrator. Please open it and follow the instructions."
revoke_moderation: 'Revoke Moderation' revoke_moderation: 'Revoke Moderation'
grant_moderation: 'Grant Moderation' grant_moderation: 'Grant Moderation'
unblock: 'Unblock' unsuspend: 'Unsuspend'
block: 'Block' suspend: 'Suspend'
reputation: Reputation reputation: Reputation
permissions: Permissions permissions: Permissions
activity: Activity activity: Activity
@ -3356,10 +3356,10 @@ en:
activate_failed: "There was a problem activating the user." activate_failed: "There was a problem activating the user."
deactivate_account: "Deactivate Account" deactivate_account: "Deactivate Account"
deactivate_failed: "There was a problem deactivating the user." deactivate_failed: "There was a problem deactivating the user."
unblock_failed: 'There was a problem unblocking the user.' unsilence_failed: 'There was a problem unsilencing the user.'
block_failed: 'There was a problem blocking the user.' silence_failed: 'There was a problem unsilencing the user.'
block_confirm: 'Are you sure you want to block this user? They will not be able to create any new topics or posts.' silence_confirm: 'Are you sure you want to silence this user? They will not be able to create any new topics or posts.'
block_accept: 'Yes, block this user' silence_accept: 'Yes, silence this user'
bounce_score: "Bounce Score" bounce_score: "Bounce Score"
reset_bounce_score: reset_bounce_score:
label: "Reset" label: "Reset"
@ -3368,7 +3368,7 @@ en:
deactivate_explanation: "A deactivated user must re-validate their email." deactivate_explanation: "A deactivated user must re-validate their email."
suspended_explanation: "A suspended user can't log in." suspended_explanation: "A suspended user can't log in."
block_explanation: "A blocked user can't post or start topics." silence_explanation: "A silenced user can't post or start topics."
staged_explanation: "A staged user can only post via email in specific topics." staged_explanation: "A staged user can only post via email in specific topics."
bounce_score_explanation: bounce_score_explanation:
none: "No bounces were received recently from that email." none: "No bounces were received recently from that email."

View File

@ -70,7 +70,7 @@ en:
no_body_detected_error: "Happens when we couldn't extract a body and there were no attachments." no_body_detected_error: "Happens when we couldn't extract a body and there were no attachments."
no_sender_detected_error: "Happens when we couldn't find a valid email address in the From header." no_sender_detected_error: "Happens when we couldn't find a valid email address in the From header."
inactive_user_error: "Happens when the sender is not active." inactive_user_error: "Happens when the sender is not active."
blocked_user_error: "Happens when the sender has been blocked." silenced_user_error: "Happens when the sender has been silenced."
bad_destination_address: "Happens when none of the email addresses in To/Cc/Bcc fields matched a configured incoming email address." bad_destination_address: "Happens when none of the email addresses in To/Cc/Bcc fields matched a configured incoming email address."
strangers_not_allowed_error: "Happens when a user tried to create a new topic in a category they're not a member of." strangers_not_allowed_error: "Happens when a user tried to create a new topic in a category they're not a member of."
insufficient_trust_level_error: "Happens when a user tried to create a new topic in a category they don't have the required trust level for." insufficient_trust_level_error: "Happens when a user tried to create a new topic in a category they don't have the required trust level for."
@ -1046,11 +1046,11 @@ en:
tl3_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl3 (regular) by multiplying with this number" tl3_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl3 (regular) by multiplying with this number"
tl4_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl4 (leader) by multiplying with this number" tl4_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl4 (leader) by multiplying with this number"
num_spam_flags_to_block_new_user: "If a new user's posts get this many spam flags from num_users_to_block_new_user different users, hide all their posts and prevent future posting. 0 to disable." num_spam_flags_to_silence_new_user: "If a new user's posts get this many spam flags from num_users_to_silence_new_user different users, hide all their posts and prevent future posting. 0 to disable."
num_users_to_block_new_user: "If a new user's posts get num_spam_flags_to_block_new_user spam flags from this many different users, hide all their posts and prevent future posting. 0 to disable." num_users_to_silence_new_user: "If a new user's posts get num_spam_flags_to_silence_new_user spam flags from this many different users, hide all their posts and prevent future posting. 0 to disable."
num_tl3_flags_to_block_new_user: "If a new user's posts get this many flags from num_tl3_users_to_block_new_user different trust level 3 users, hide all their posts and prevent future posting. 0 to disable." num_tl3_flags_to_silence_new_user: "If a new user's posts get this many flags from num_tl3_users_to_silence_new_user different trust level 3 users, hide all their posts and prevent future posting. 0 to disable."
num_tl3_users_to_block_new_user: "If a new user's posts get num_tl3_flags_to_block_new_user flags from this many different trust level 3 users, hide all their posts and prevent future posting. 0 to disable." num_tl3_users_to_silence_new_user: "If a new user's posts get num_tl3_flags_to_silence_new_user flags from this many different trust level 3 users, hide all their posts and prevent future posting. 0 to disable."
notify_mods_when_user_blocked: "If a user is automatically blocked, send a message to all moderators." notify_mods_when_user_silenced: "If a user is automatically silenced, send a message to all moderators."
flag_sockpuppets: "If a new user replies to a topic from the same IP address as the new user who started the topic, flag both of their posts as potential spam." flag_sockpuppets: "If a new user replies to a topic from the same IP address as the new user who started the topic, flag both of their posts as potential spam."
traditional_markdown_linebreaks: "Use traditional linebreaks in Markdown, which require two trailing spaces for a linebreak." traditional_markdown_linebreaks: "Use traditional linebreaks in Markdown, which require two trailing spaces for a linebreak."
@ -1354,9 +1354,9 @@ en:
auto_respond_to_flag_actions: "Enable automatic reply when disposing a flag." auto_respond_to_flag_actions: "Enable automatic reply when disposing a flag."
min_first_post_typing_time: "Minimum amount of time in milliseconds a user must type during first post, if threshold is not met post will automatically enter the needs approval queue. Set to 0 to disable (not recommended)" min_first_post_typing_time: "Minimum amount of time in milliseconds a user must type during first post, if threshold is not met post will automatically enter the needs approval queue. Set to 0 to disable (not recommended)"
auto_block_fast_typers_on_first_post: "Automatically block users that do not meet min_first_post_typing_time" auto_silence_fast_typers_on_first_post: "Automatically silence users that do not meet min_first_post_typing_time"
auto_block_fast_typers_max_trust_level: "Maximum trust level to auto block fast typers" auto_silence_fast_typers_max_trust_level: "Maximum trust level to auto silence fast typers"
auto_block_first_post_regex: "Case insensitive regex that if passed will cause first post by user to be blocked and sent to approval queue. Example: raging|a[bc]a , will cause all posts containing raging or aba or aca to be blocked on first. Only applies to first post." auto_silence_first_post_regex: "Case insensitive regex that if passed will cause first post by user to be silenced and sent to approval queue. Example: raging|a[bc]a , will cause all posts containing raging or aba or aca to be silenced on first. Only applies to first post."
flags_default_topics: "Show flagged topics by default in the admin section" flags_default_topics: "Show flagged topics by default in the admin section"
reply_by_email_enabled: "Enable replying to topics via email." reply_by_email_enabled: "Enable replying to topics via email."
@ -2172,13 +2172,13 @@ en:
Your account associated with this email address is not activated. Please activate your account before sending emails in. Your account associated with this email address is not activated. Please activate your account before sending emails in.
email_reject_blocked_user: email_reject_silenced_user:
title: "Email Reject Blocked User" title: "Email Reject Silenced User"
subject_template: "[%{email_prefix}] Email issue -- Blocked User" subject_template: "[%{email_prefix}] Email issue -- Silenced User"
text_body_template: | text_body_template: |
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
Your account associated with this email address has been blocked. Your account associated with this email address has been silenced.
email_reject_reply_user_not_matching: email_reject_reply_user_not_matching:
title: "Email Reject User Not Matching" title: "Email Reject User Not Matching"
@ -2324,7 +2324,7 @@ en:
This is an automated message from %{site_name} to let you know that your posts have been temporarily hidden because they were flagged by the community. This is an automated message from %{site_name} to let you know that your posts have been temporarily hidden because they were flagged by the community.
As a precautionary measure, your new account has been blocked from creating new replies or topics until a staff member can review your account. We apologize for the inconvenience. As a precautionary measure, your new account has been silenced from creating new replies or topics until a staff member can review your account. We apologize for the inconvenience.
For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines).
too_many_tl3_flags: too_many_tl3_flags:
@ -2335,11 +2335,11 @@ en:
This is an automated message from %{site_name} to let you know you that your account has been placed on hold due to a large number of community flags. This is an automated message from %{site_name} to let you know you that your account has been placed on hold due to a large number of community flags.
As a precautionary measure, your new account has been blocked from creating new replies or topics until a staff member can review your account. We apologize for the inconvenience. As a precautionary measure, your new account has been silenced from creating new replies or topics until a staff member can review your account. We apologize for the inconvenience.
For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines).
blocked_by_staff: silenced_by_staff:
title: "Blocked by Staff" title: "Silenced by Staff"
subject_template: "Account temporarily on hold" subject_template: "Account temporarily on hold"
text_body_template: | text_body_template: |
Hello, Hello,
@ -2350,32 +2350,32 @@ en:
For additional guidance, refer to our [community guidelines](%{base_url}/guidelines). For additional guidance, refer to our [community guidelines](%{base_url}/guidelines).
user_automatically_blocked: user_automatically_silenced:
title: "User Automatically Blocked" title: "User Automatically Silenced"
subject_template: "New user %{username} blocked by community flags" subject_template: "New user %{username} silenced by community flags"
text_body_template: | text_body_template: |
This is an automated message. This is an automated message.
The new user [%{username}](%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). The new user [%{username}](%{user_url}) was automatically silenced because multiple users flagged %{username}'s post(s).
Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{user_url}). Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly silenced from posting, click the unsilence button on [the admin page for this user](%{user_url}).
This threshold can be changed via the `block_new_user` site settings. This threshold can be changed via the `block_new_user` site settings.
spam_post_blocked: spam_post_silenced:
title: "Spam Post Blocked" title: "Spam Post Silenced"
subject_template: "New user %{username} posts blocked due to repeated links" subject_template: "New user %{username} posts silenced due to repeated links"
text_body_template: | text_body_template: |
This is an automated message. This is an automated message.
The new user [%{username}](%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}. The new user [%{username}](%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were silenced to avoid spam. The user is still able to create new posts that do not link to %{domains}.
Please [review the user](%{user_url}). Please [review the user](%{user_url}).
This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings.
unblocked: unsilenced:
title: "Unblocked" title: "Unsilenced"
subject_template: "Account no longer on hold" subject_template: "Account no longer on hold"
text_body_template: | text_body_template: |
Hello, Hello,

View File

@ -117,8 +117,8 @@ Discourse::Application.routes.draw do
post "log_out", constraints: AdminConstraint.new post "log_out", constraints: AdminConstraint.new
put "activate" put "activate"
put "deactivate" put "deactivate"
put "block" put "silence"
put "unblock" put "unsilence"
put "trust_level" put "trust_level"
put "trust_level_lock" put "trust_level_lock"
put "primary_group" put "primary_group"

View File

@ -968,11 +968,11 @@ spam:
add_rel_nofollow_to_user_content: true add_rel_nofollow_to_user_content: true
flags_required_to_hide_post: 3 flags_required_to_hide_post: 3
cooldown_minutes_after_hiding_posts: 10 cooldown_minutes_after_hiding_posts: 10
num_spam_flags_to_block_new_user: 3 num_spam_flags_to_silence_new_user: 3
num_users_to_block_new_user: 3 num_users_to_silence_new_user: 3
num_tl3_flags_to_block_new_user: 4 num_tl3_flags_to_silence_new_user: 4
num_tl3_users_to_block_new_user: 2 num_tl3_users_to_silence_new_user: 2
notify_mods_when_user_blocked: false notify_mods_when_user_silenced: false
flag_sockpuppets: false flag_sockpuppets: false
newuser_spam_host_threshold: 3 newuser_spam_host_threshold: 3
white_listed_spam_host_domains: white_listed_spam_host_domains:
@ -992,9 +992,9 @@ spam:
min: 1 min: 1
auto_respond_to_flag_actions: true auto_respond_to_flag_actions: true
min_first_post_typing_time: 3000 min_first_post_typing_time: 3000
auto_block_fast_typers_on_first_post: true auto_silence_fast_typers_on_first_post: true
auto_block_fast_typers_max_trust_level: 0 auto_silence_fast_typers_max_trust_level: 0
auto_block_first_post_regex: "" auto_silence_first_post_regex: ""
flags_default_topics: flags_default_topics:
default: false default: false
client: true client: true

View File

@ -61,6 +61,17 @@ ColumnDropper.drop(
} }
) )
ColumnDropper.drop(
table: 'users',
after_migration: 'RenameBlockedSilence',
columns: %w[
blocked
],
on_drop: ->() {
STDERR.puts 'Removing user blocked column!'
}
)
# User for the smoke tests # User for the smoke tests
if ENV["SMOKE"] == "1" if ENV["SMOKE"] == "1"
UserEmail.seed do |ue| UserEmail.seed do |ue|

View File

@ -0,0 +1,32 @@
class RenameBlockedSilence < ActiveRecord::Migration[5.1]
def setting(old, new)
execute "UPDATE site_settings SET name='#{new}' where name='#{old}'"
end
def up
add_column :users, :silenced, :boolean, default: false, null: false
execute "UPDATE users set silenced = blocked"
setting :notify_mods_when_user_blocked, :notify_mods_when_user_silenced
setting :auto_block_fast_typers_on_first_post, :auto_silence_fast_typers_on_first_post
setting :auto_block_fast_typers_max_trust_level, :auto_silence_fast_typers_max_trust_level
setting :auto_block_first_post_regex, :auto_silence_first_post_regex
setting :num_spam_flags_to_block_new_user, :num_spam_flags_to_silence_new_user
setting :num_users_to_block_new_user, :num_users_to_silence_new_user
setting :num_tl3_flags_to_block_new_user, :num_tl3_flags_to_silence_new_user
setting :num_tl3_users_to_block_new_user, :num_tl3_users_to_silence_new_user
end
def down
remove_column :users, :silenced
setting :notify_mods_when_user_silenced, :notify_mods_when_user_blocked
setting :auto_silence_fast_typers_on_first_post, :auto_block_fast_typers_on_first_post
setting :auto_silence_fast_typers_max_trust_level, :auto_block_fast_typers_max_trust_level
setting :auto_silence_first_post_regex, :auto_block_first_post_regex
setting :num_spam_flags_to_silence_new_user, :num_spam_flags_to_block_new_user
setting :num_users_to_silence_new_user, :num_users_to_block_new_user
setting :num_tl3_flags_to_silence_new_user, :num_tl3_flags_to_block_new_user
setting :num_tl3_users_to_silence_new_user, :num_tl3_users_to_block_new_user
end
end

View File

@ -94,7 +94,7 @@ class AdminUserIndexQuery
when 'staff' then @query.where("admin or moderator") when 'staff' then @query.where("admin or moderator")
when 'admins' then @query.where(admin: true) when 'admins' then @query.where(admin: true)
when 'moderators' then @query.where(moderator: true) when 'moderators' then @query.where(moderator: true)
when 'blocked' then @query.blocked when 'silenced' then @query.silenced
when 'suspended' then @query.suspended when 'suspended' then @query.suspended
when 'pending' then @query.not_suspended.where(approved: false, active: true) when 'pending' then @query.not_suspended.where(approved: false, active: true)
when 'suspect' then suspect_users when 'suspect' then suspect_users

View File

@ -141,10 +141,10 @@ SQL
SELECT invited_by_id SELECT invited_by_id
FROM invites i FROM invites i
JOIN users u2 ON u2.id = i.user_id JOIN users u2 ON u2.id = i.user_id
WHERE i.deleted_at IS NULL AND u2.active AND u2.trust_level >= #{trust_level.to_i} AND not u2.blocked WHERE i.deleted_at IS NULL AND u2.active AND u2.trust_level >= #{trust_level.to_i} AND not u2.silenced
GROUP BY invited_by_id GROUP BY invited_by_id
HAVING COUNT(*) >= #{count.to_i} HAVING COUNT(*) >= #{count.to_i}
) AND u.active AND NOT u.blocked AND u.id > 0 AND ) AND u.active AND NOT u.silenced AND u.id > 0 AND
(:backfill OR u.id IN (:user_ids) ) (:backfill OR u.id IN (:user_ids) )
" "
end end

View File

@ -43,7 +43,7 @@ module Email
when Email::Receiver::EmailNotAllowed then :email_reject_not_allowed_email when Email::Receiver::EmailNotAllowed then :email_reject_not_allowed_email
when Email::Receiver::AutoGeneratedEmailError then :email_reject_auto_generated when Email::Receiver::AutoGeneratedEmailError then :email_reject_auto_generated
when Email::Receiver::InactiveUserError then :email_reject_inactive_user when Email::Receiver::InactiveUserError then :email_reject_inactive_user
when Email::Receiver::BlockedUserError then :email_reject_blocked_user when Email::Receiver::SilencedUserError then :email_reject_silenced_user
when Email::Receiver::BadDestinationAddress then :email_reject_bad_destination_address when Email::Receiver::BadDestinationAddress then :email_reject_bad_destination_address
when Email::Receiver::StrangersNotAllowedError then :email_reject_strangers_not_allowed when Email::Receiver::StrangersNotAllowedError then :email_reject_strangers_not_allowed
when Email::Receiver::InsufficientTrustLevelError then :email_reject_insufficient_trust_level when Email::Receiver::InsufficientTrustLevelError then :email_reject_insufficient_trust_level

View File

@ -21,7 +21,7 @@ module Email
class NoBodyDetectedError < ProcessingError; end class NoBodyDetectedError < ProcessingError; end
class NoSenderDetectedError < ProcessingError; end class NoSenderDetectedError < ProcessingError; end
class InactiveUserError < ProcessingError; end class InactiveUserError < ProcessingError; end
class BlockedUserError < ProcessingError; end class SilencedUserError < ProcessingError; end
class BadDestinationAddress < ProcessingError; end class BadDestinationAddress < ProcessingError; end
class StrangersNotAllowedError < ProcessingError; end class StrangersNotAllowedError < ProcessingError; end
class InsufficientTrustLevelError < ProcessingError; end class InsufficientTrustLevelError < ProcessingError; end
@ -144,7 +144,7 @@ module Email
@incoming_email.update_columns(user_id: user.id) @incoming_email.update_columns(user_id: user.id)
raise InactiveUserError if !user.active && !user.staged raise InactiveUserError if !user.active && !user.staged
raise BlockedUserError if user.blocked raise SilencedUserError if user.silenced?
end end
def is_bounce? def is_bounce?

View File

@ -25,7 +25,7 @@ class Guardian
def moderator?; false; end def moderator?; false; end
def approved?; false; end def approved?; false; end
def staged?; false; end def staged?; false; end
def blocked?; false; end def silenced?; false; end
def secure_category_ids; []; end def secure_category_ids; []; end
def topic_create_allowed_category_ids; []; end def topic_create_allowed_category_ids; []; end
def has_trust_level?(level); false; end def has_trust_level?(level); false; end
@ -63,8 +63,8 @@ class Guardian
@user.moderator? @user.moderator?
end end
def is_blocked? def is_silenced?
@user.blocked? @user.silenced?
end end
def is_developer? def is_developer?
@ -122,7 +122,7 @@ class Guardian
end end
def can_moderate?(obj) def can_moderate?(obj)
obj && authenticated? && !is_blocked? && (is_staff? || (obj.is_a?(Topic) && @user.has_trust_level?(TrustLevel[4]))) obj && authenticated? && !is_silenced? && (is_staff? || (obj.is_a?(Topic) && @user.has_trust_level?(TrustLevel[4])))
end end
alias :can_move_posts? :can_moderate? alias :can_move_posts? :can_moderate?
alias :can_see_flags? :can_moderate? alias :can_see_flags? :can_moderate?
@ -300,8 +300,8 @@ class Guardian
(is_staff? || SiteSetting.enable_private_messages) && (is_staff? || SiteSetting.enable_private_messages) &&
# Can't send PMs to suspended users # Can't send PMs to suspended users
(is_staff? || is_group || !target.suspended?) && (is_staff? || is_group || !target.suspended?) &&
# Blocked users can only send PM to staff # Silenced users can only send PM to staff
(!is_blocked? || target.staff?) (!is_silenced? || target.staff?)
end end
def cand_send_private_messages_to_email? def cand_send_private_messages_to_email?

View File

@ -80,7 +80,7 @@ module PostGuardian
# Creating Method # Creating Method
def can_create_post?(parent) def can_create_post?(parent)
(!SpamRule::AutoBlock.block?(@user) || (!!parent.try(:private_message?) && parent.allowed_users.include?(@user))) && ( (!SpamRule::AutoSilence.silence?(@user) || (!!parent.try(:private_message?) && parent.allowed_users.include?(@user))) && (
!parent || !parent ||
!parent.category || !parent.category ||
Category.post_create_allowed(self).where(id: parent.category.id).count == 1 Category.post_create_allowed(self).where(id: parent.category.id).count == 1

View File

@ -30,11 +30,11 @@ module UserGuardian
is_me?(user) || is_admin? is_me?(user) || is_admin?
end end
def can_block_user?(user) def can_silence_user?(user)
user && is_staff? && not(user.staff?) user && is_staff? && not(user.staff?)
end end
def can_unblock_user?(user) def can_unsilence_user?(user)
user && is_staff? user && is_staff?
end end

View File

@ -44,14 +44,14 @@ class NewPostManager
is_first_post?(manager) && is_first_post?(manager) &&
args[:typing_duration_msecs].to_i < SiteSetting.min_first_post_typing_time && args[:typing_duration_msecs].to_i < SiteSetting.min_first_post_typing_time &&
SiteSetting.auto_block_fast_typers_on_first_post && SiteSetting.auto_silence_fast_typers_on_first_post &&
manager.user.trust_level <= SiteSetting.auto_block_fast_typers_max_trust_level manager.user.trust_level <= SiteSetting.auto_silence_fast_typers_max_trust_level
end end
def self.matches_auto_block_regex?(manager) def self.matches_auto_silence_regex?(manager)
args = manager.args args = manager.args
pattern = SiteSetting.auto_block_first_post_regex pattern = SiteSetting.auto_silence_first_post_regex
return false unless pattern.present? return false unless pattern.present?
return false unless is_first_post?(manager) return false unless is_first_post?(manager)
@ -59,7 +59,7 @@ class NewPostManager
begin begin
regex = Regexp.new(pattern, Regexp::IGNORECASE) regex = Regexp.new(pattern, Regexp::IGNORECASE)
rescue => e rescue => e
Rails.logger.warn "Invalid regex in auto_block_first_post_regex #{e}" Rails.logger.warn "Invalid regex in auto_silence_first_post_regex #{e}"
return false return false
end end
@ -80,7 +80,7 @@ class NewPostManager
(user.trust_level < SiteSetting.approve_unless_trust_level.to_i) || (user.trust_level < SiteSetting.approve_unless_trust_level.to_i) ||
(manager.args[:title].present? && user.trust_level < SiteSetting.approve_new_topics_unless_trust_level.to_i) || (manager.args[:title].present? && user.trust_level < SiteSetting.approve_new_topics_unless_trust_level.to_i) ||
is_fast_typer?(manager) || is_fast_typer?(manager) ||
matches_auto_block_regex?(manager) || matches_auto_silence_regex?(manager) ||
WordWatcher.new("#{manager.args[:title]} #{manager.args[:raw]}").requires_approval? WordWatcher.new("#{manager.args[:title]} #{manager.args[:raw]}").requires_approval?
end end
@ -110,9 +110,9 @@ class NewPostManager
result = manager.enqueue('default') result = manager.enqueue('default')
if is_fast_typer?(manager) if is_fast_typer?(manager)
UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.new_user_typed_too_fast")) UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.new_user_typed_too_fast"))
elsif matches_auto_block_regex?(manager) elsif matches_auto_silence_regex?(manager)
UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.content_matches_auto_block_regex")) UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.content_matches_auto_silence_regex"))
end end
result result

View File

@ -165,12 +165,12 @@ describe AdminUserIndexQuery do
end end
describe "with a blocked user" do describe "with a silenced user" do
let!(:user) { Fabricate(:user, blocked: true) } let!(:user) { Fabricate(:user, silenced: true) }
it "finds the blocked user" do it "finds the silenced user" do
query = ::AdminUserIndexQuery.new(query: 'blocked') query = ::AdminUserIndexQuery.new(query: 'silenced')
expect(query.find_users.count).to eq(1) expect(query.find_users.count).to eq(1)
end end

View File

@ -56,9 +56,9 @@ describe Email::Receiver do
expect { process(:inactive_sender) }.to raise_error(Email::Receiver::InactiveUserError) expect { process(:inactive_sender) }.to raise_error(Email::Receiver::InactiveUserError)
end end
it "raises a BlockedUserError when the sender has been blocked" do it "raises a SilencedUserError when the sender has been silenced" do
Fabricate(:user, email: "blocked@bar.com", blocked: true) Fabricate(:user, email: "silenced@bar.com", silenced: true)
expect { process(:blocked_sender) }.to raise_error(Email::Receiver::BlockedUserError) expect { process(:silenced_sender) }.to raise_error(Email::Receiver::SilencedUserError)
end end
it "doesn't raise an InactiveUserError when the sender is staged" do it "doesn't raise an InactiveUserError when the sender is staged" do

View File

@ -193,9 +193,9 @@ describe Guardian do
end end
end end
context "author is blocked" do context "author is silenced" do
before do before do
user.blocked = true user.silenced = true
user.save user.save
end end
@ -852,14 +852,14 @@ describe Guardian do
expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey
end end
it "allows new posts from blocked users included in the pm" do it "allows new posts from silenced users included in the pm" do
user.update_attribute(:blocked, true) user.update_attribute(:silenced, true)
private_message.topic_allowed_users.create!(user_id: user.id) private_message.topic_allowed_users.create!(user_id: user.id)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy
end end
it "doesn't allow new posts from blocked users not invited to the pm" do it "doesn't allow new posts from silenced users not invited to the pm" do
user.update_attribute(:blocked, true) user.update_attribute(:silenced, true)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey
end end
end end
@ -1374,9 +1374,9 @@ describe Guardian do
expect(Guardian.new(user).can_moderate?(nil)).to be_falsey expect(Guardian.new(user).can_moderate?(nil)).to be_falsey
end end
context 'when user is blocked' do context 'when user is silenced' do
it 'returns false' do it 'returns false' do
user.toggle!(:blocked) user.toggle!(:silenced)
expect(Guardian.new(user).can_moderate?(post)).to be(false) expect(Guardian.new(user).can_moderate?(post)).to be(false)
expect(Guardian.new(user).can_moderate?(topic)).to be(false) expect(Guardian.new(user).can_moderate?(topic)).to be(false)
end end

View File

@ -583,48 +583,48 @@ describe Admin::UsersController do
end end
end end
context 'block' do context 'silence' do
before do before do
@reg_user = Fabricate(:user) @reg_user = Fabricate(:user)
end end
it "raises an error when the user doesn't have permission" do it "raises an error when the user doesn't have permission" do
Guardian.any_instance.expects(:can_block_user?).with(@reg_user).returns(false) Guardian.any_instance.expects(:can_silence_user?).with(@reg_user).returns(false)
UserBlocker.expects(:block).never UserSilencer.expects(:silence).never
put :block, params: { user_id: @reg_user.id }, format: :json put :silence, params: { user_id: @reg_user.id }, format: :json
expect(response).to be_forbidden expect(response).to be_forbidden
end end
it "returns a 403 if the user doesn't exist" do it "returns a 403 if the user doesn't exist" do
put :block, params: { user_id: 123123 }, format: :json put :silence, params: { user_id: 123123 }, format: :json
expect(response).to be_forbidden expect(response).to be_forbidden
end end
it "punishes the user for spamming" do it "punishes the user for spamming" do
UserBlocker.expects(:block).with(@reg_user, @user, anything) UserSilencer.expects(:silence).with(@reg_user, @user, anything)
put :block, params: { user_id: @reg_user.id }, format: :json put :silence, params: { user_id: @reg_user.id }, format: :json
end end
end end
context 'unblock' do context 'unsilence' do
before do before do
@reg_user = Fabricate(:user) @reg_user = Fabricate(:user)
end end
it "raises an error when the user doesn't have permission" do it "raises an error when the user doesn't have permission" do
Guardian.any_instance.expects(:can_unblock_user?).with(@reg_user).returns(false) Guardian.any_instance.expects(:can_unsilence_user?).with(@reg_user).returns(false)
put :unblock, params: { user_id: @reg_user.id }, format: :json put :unsilence, params: { user_id: @reg_user.id }, format: :json
expect(response).to be_forbidden expect(response).to be_forbidden
end end
it "returns a 403 if the user doesn't exist" do it "returns a 403 if the user doesn't exist" do
put :unblock, params: { user_id: 123123 }, format: :json put :unsilence, params: { user_id: 123123 }, format: :json
expect(response).to be_forbidden expect(response).to be_forbidden
end end
it "punishes the user for spamming" do it "punishes the user for spamming" do
UserBlocker.expects(:unblock).with(@reg_user, @user, anything) UserSilencer.expects(:unsilence).with(@reg_user, @user, anything)
put :unblock, params: { user_id: @reg_user.id }, format: :json put :unsilence, params: { user_id: @reg_user.id }, format: :json
end end
end end

View File

@ -695,7 +695,7 @@ describe PostsController do
context "fast typing" do context "fast typing" do
before do before do
SiteSetting.min_first_post_typing_time = 3000 SiteSetting.min_first_post_typing_time = 3000
SiteSetting.auto_block_fast_typers_max_trust_level = 1 SiteSetting.auto_silence_fast_typers_max_trust_level = 1
end end
it 'queues the post if min_first_post_typing_time is not met' do it 'queues the post if min_first_post_typing_time is not met' do
@ -710,7 +710,7 @@ describe PostsController do
expect(parsed["action"]).to eq("enqueued") expect(parsed["action"]).to eq("enqueued")
user.reload user.reload
expect(user.blocked).to eq(true) expect(user.silenced).to eq(true)
qp = QueuedPost.first qp = QueuedPost.first
@ -718,7 +718,7 @@ describe PostsController do
qp.approve!(mod) qp.approve!(mod)
user.reload user.reload
expect(user.blocked).to eq(false) expect(user.silenced).to eq(false)
end end
it "doesn't enqueue replies when the topic is closed" do it "doesn't enqueue replies when the topic is closed" do
@ -749,8 +749,8 @@ describe PostsController do
end end
end end
it 'blocks correctly based on auto_block_first_post_regex' do it 'silences correctly based on auto_silence_first_post_regex' do
SiteSetting.auto_block_first_post_regex = "I love candy|i eat s[1-5]" SiteSetting.auto_silence_first_post_regex = "I love candy|i eat s[1-5]"
post :create, params: { post :create, params: {
raw: 'this is the test content', raw: 'this is the test content',
@ -763,7 +763,7 @@ describe PostsController do
expect(parsed["action"]).to eq("enqueued") expect(parsed["action"]).to eq("enqueued")
user.reload user.reload
expect(user.blocked).to eq(true) expect(user.silenced).to eq(true)
end end
it "can send a message to a group" do it "can send a message to a group" do

View File

@ -1,9 +0,0 @@
Return-Path: <blocked@bar.com>
From: Foo Bar <blocked@bar.com>
Date: Fri, 15 Jan 2016 00:12:43 +0100
Message-ID: <8@foo.bar.mail>
Mime-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Lorem ipsum dolor sit amet, consectetur adipiscing elit.

View File

@ -4,7 +4,7 @@ require 'rails_helper'
describe SpamRulesEnforcer do describe SpamRulesEnforcer do
describe 'auto-blocking users based on flagging' do describe 'auto-silenceing users based on flagging' do
let!(:admin) { Fabricate(:admin) } # needed to send a system message let!(:admin) { Fabricate(:admin) } # needed to send a system message
let!(:moderator) { Fabricate(:moderator) } let!(:moderator) { Fabricate(:moderator) }
let(:user1) { Fabricate(:user) } let(:user1) { Fabricate(:user) }
@ -12,8 +12,8 @@ describe SpamRulesEnforcer do
before do before do
SiteSetting.flags_required_to_hide_post = 0 SiteSetting.flags_required_to_hide_post = 0
SiteSetting.num_spam_flags_to_block_new_user = 2 SiteSetting.num_spam_flags_to_silence_new_user = 2
SiteSetting.num_users_to_block_new_user = 2 SiteSetting.num_users_to_silence_new_user = 2
end end
context 'spammer is a new user' do context 'spammer is a new user' do
@ -37,7 +37,7 @@ describe SpamRulesEnforcer do
expect(spam_post.reload).to_not be_hidden expect(spam_post.reload).to_not be_hidden
expect(spam_post2.reload).to_not be_hidden expect(spam_post2.reload).to_not be_hidden
expect(spammer.reload).to_not be_blocked expect(spammer.reload).to_not be_silenced
end end
end end
@ -55,7 +55,7 @@ describe SpamRulesEnforcer do
end end
it 'should hide the posts' do it 'should hide the posts' do
expect(spammer.reload).to be_blocked expect(spammer.reload).to be_silenced
expect(spam_post.reload).to be_hidden expect(spam_post.reload).to be_hidden
expect(spam_post2.reload).to be_hidden expect(spam_post2.reload).to be_hidden
expect(spammer.reload.private_topics_count).to eq(private_messages_count + 1) expect(spammer.reload.private_topics_count).to eq(private_messages_count + 1)
@ -63,35 +63,35 @@ describe SpamRulesEnforcer do
# The following cases describe when a staff user takes some action, but the user # The following cases describe when a staff user takes some action, but the user
# still won't be able to make posts. # still won't be able to make posts.
# A staff user needs to clear the blocked flag from the user record. # A staff user needs to clear the silenced flag from the user record.
context "a post's flags are cleared" do context "a post's flags are cleared" do
it 'should block the spammer' do it 'should silence the spammer' do
PostAction.clear_flags!(spam_post, admin); spammer.reload PostAction.clear_flags!(spam_post, admin); spammer.reload
expect(spammer.reload).to be_blocked expect(spammer.reload).to be_silenced
end end
end end
context "a post is deleted" do context "a post is deleted" do
it 'should block the spammer' do it 'should silence the spammer' do
spam_post.trash!(moderator); spammer.reload spam_post.trash!(moderator); spammer.reload
expect(spammer.reload).to be_blocked expect(spammer.reload).to be_silenced
end end
end end
context "spammer becomes trust level 1" do context "spammer becomes trust level 1" do
it 'should block the spammer' do it 'should silence the spammer' do
spammer.change_trust_level!(TrustLevel[1]); spammer.reload spammer.change_trust_level!(TrustLevel[1]); spammer.reload
expect(spammer.reload).to be_blocked expect(spammer.reload).to be_silenced
end end
end end
end end
context 'flags_required_to_hide_post takes effect too' do context 'flags_required_to_hide_post takes effect too' do
it 'should block the spammer' do it 'should silence the spammer' do
SiteSetting.flags_required_to_hide_post = 2 SiteSetting.flags_required_to_hide_post = 2
PostAction.act(user2, spam_post, PostActionType.types[:spam]) PostAction.act(user2, spam_post, PostActionType.types[:spam])
expect(spammer.reload).to be_blocked expect(spammer.reload).to be_silenced
expect(Guardian.new(spammer).can_create_topic?(nil)).to be false expect(Guardian.new(spammer).can_create_topic?(nil)).to be false
end end
end end

View File

@ -23,8 +23,8 @@ describe Jobs::GrantAnniversaryBadges do
expect(badge).to be_blank expect(badge).to be_blank
end end
it "doesn't award to a blocked user" do it "doesn't award to a silenced user" do
user = Fabricate(:user, created_at: 400.days.ago, blocked: true) user = Fabricate(:user, created_at: 400.days.ago, silenced: true)
Fabricate(:post, user: user, created_at: 1.week.ago) Fabricate(:post, user: user, created_at: 1.week.ago)
granter.execute({}) granter.execute({})

View File

@ -65,8 +65,8 @@ describe Jobs::NotifyMailingListSubscribers do
include_examples "no emails" include_examples "no emails"
end end
context "to a blocked user" do context "to a silenced user" do
before { mailing_list_user.update(blocked: true) } before { mailing_list_user.update(silenced: true) }
include_examples "no emails" include_examples "no emails"
end end

View File

@ -677,7 +677,7 @@ describe Topic do
context "when moderator post fails to be created" do context "when moderator post fails to be created" do
before do before do
user.toggle!(:blocked) user.toggle!(:silenced)
end end
it "should not increment moderator_posts_count" do it "should not increment moderator_posts_count" do

View File

@ -1,32 +1,32 @@
require 'rails_helper' require 'rails_helper'
describe SpamRule::AutoBlock do describe SpamRule::AutoSilence do
before do before do
SiteSetting.flags_required_to_hide_post = 0 # never SiteSetting.flags_required_to_hide_post = 0 # never
SiteSetting.num_spam_flags_to_block_new_user = 2 SiteSetting.num_spam_flags_to_silence_new_user = 2
SiteSetting.num_users_to_block_new_user = 2 SiteSetting.num_users_to_silence_new_user = 2
end end
describe 'perform' do describe 'perform' do
let(:post) { Fabricate.build(:post, user: Fabricate.build(:user, trust_level: TrustLevel[0])) } let(:post) { Fabricate.build(:post, user: Fabricate.build(:user, trust_level: TrustLevel[0])) }
subject { described_class.new(post.user) } subject { described_class.new(post.user) }
it 'takes no action if user should not be blocked' do it 'takes no action if user should not be silenced' do
subject.stubs(:block?).returns(false) subject.stubs(:silence?).returns(false)
subject.expects(:block_user).never subject.expects(:silence_user).never
subject.perform subject.perform
end end
it 'delivers punishment when user should be blocked' do it 'delivers punishment when user should be silenced' do
subject.stubs(:block?).returns(true) subject.stubs(:silence?).returns(true)
subject.expects(:block_user) subject.expects(:silence_user)
subject.perform subject.perform
end end
end end
describe 'num_spam_flags_against_user' do describe 'num_spam_flags_against_user' do
before { described_class.any_instance.stubs(:block_user) } before { described_class.any_instance.stubs(:silence_user) }
let(:post) { Fabricate(:post) } let(:post) { Fabricate(:post) }
let(:enforcer) { described_class.new(post.user) } let(:enforcer) { described_class.new(post.user) }
subject { enforcer.num_spam_flags_against_user } subject { enforcer.num_spam_flags_against_user }
@ -53,7 +53,7 @@ describe SpamRule::AutoBlock do
end end
describe 'num_users_who_flagged_spam_against_user' do describe 'num_users_who_flagged_spam_against_user' do
before { described_class.any_instance.stubs(:block_user) } before { described_class.any_instance.stubs(:silence_user) }
let(:post) { Fabricate(:post) } let(:post) { Fabricate(:post) }
let(:enforcer) { described_class.new(post.user) } let(:enforcer) { described_class.new(post.user) }
subject { enforcer.num_users_who_flagged_spam_against_user } subject { enforcer.num_users_who_flagged_spam_against_user }
@ -124,85 +124,85 @@ describe SpamRule::AutoBlock do
end end
end end
describe 'block_user' do describe 'silence_user' do
let!(:admin) { Fabricate(:admin) } # needed for SystemMessage let!(:admin) { Fabricate(:admin) } # needed for SystemMessage
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
let!(:post) { Fabricate(:post, user: user) } let!(:post) { Fabricate(:post, user: user) }
subject { described_class.new(user) } subject { described_class.new(user) }
before do before do
described_class.stubs(:block?).with { |u| u.id != user.id }.returns(false) described_class.stubs(:silence?).with { |u| u.id != user.id }.returns(false)
described_class.stubs(:block?).with { |u| u.id == user.id }.returns(true) described_class.stubs(:silence?).with { |u| u.id == user.id }.returns(true)
subject.stubs(:block?).returns(true) subject.stubs(:silence?).returns(true)
end end
context 'user is not blocked' do context 'user is not silenced' do
before do before do
UserBlocker.expects(:block).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(true) UserSilencer.expects(:silence).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(true)
end end
it 'prevents the user from making new posts' do it 'prevents the user from making new posts' do
subject.block_user subject.silence_user
expect(Guardian.new(user).can_create_post?(nil)).to be_falsey expect(Guardian.new(user).can_create_post?(nil)).to be_falsey
end end
it 'sends private message to moderators' do it 'sends private message to moderators' do
SiteSetting.notify_mods_when_user_blocked = true SiteSetting.notify_mods_when_user_silenced = true
moderator = Fabricate(:moderator) moderator = Fabricate(:moderator)
GroupMessage.expects(:create).with do |group, msg_type, params| GroupMessage.expects(:create).with do |group, msg_type, params|
group == (Group[:moderators].name) && msg_type == (:user_automatically_blocked) && params[:user].id == (user.id) group == (Group[:moderators].name) && msg_type == (:user_automatically_silenced) && params[:user].id == (user.id)
end end
subject.block_user subject.silence_user
end end
it "doesn't send a pm to moderators if notify_mods_when_user_blocked is false" do it "doesn't send a pm to moderators if notify_mods_when_user_silenced is false" do
SiteSetting.notify_mods_when_user_blocked = false SiteSetting.notify_mods_when_user_silenced = false
GroupMessage.expects(:create).never GroupMessage.expects(:create).never
subject.block_user subject.silence_user
end end
end end
context 'user is already blocked' do context 'user is already silenced' do
before do before do
UserBlocker.expects(:block).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(false) UserSilencer.expects(:silence).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(false)
end end
it "doesn't send a pm to moderators if the user is already blocked" do it "doesn't send a pm to moderators if the user is already silenced" do
GroupMessage.expects(:create).never GroupMessage.expects(:create).never
subject.block_user subject.silence_user
end end
end end
end end
describe 'block?' do describe 'silence?' do
context 'never been blocked' do context 'never been silenced' do
shared_examples "can't be blocked" do shared_examples "can't be silenced" do
it "returns false" do it "returns false" do
enforcer = described_class.new(user) enforcer = described_class.new(user)
enforcer.expects(:num_spam_flags_against_user).never enforcer.expects(:num_spam_flags_against_user).never
enforcer.expects(:num_users_who_flagged_spam_against_user).never enforcer.expects(:num_users_who_flagged_spam_against_user).never
enforcer.expects(:num_flags_against_user).never enforcer.expects(:num_flags_against_user).never
enforcer.expects(:num_users_who_flagged).never enforcer.expects(:num_users_who_flagged).never
expect(enforcer.block?).to eq(false) expect(enforcer.silence?).to eq(false)
end end
end end
(1..4).each do |trust_level| (1..4).each do |trust_level|
context "user has trust level #{trust_level}" do context "user has trust level #{trust_level}" do
let(:user) { Fabricate(:user, trust_level: trust_level) } let(:user) { Fabricate(:user, trust_level: trust_level) }
include_examples "can't be blocked" include_examples "can't be silenced"
end end
end end
context "user is an admin" do context "user is an admin" do
let(:user) { Fabricate(:admin) } let(:user) { Fabricate(:admin) }
include_examples "can't be blocked" include_examples "can't be silenced"
end end
context "user is a moderator" do context "user is a moderator" do
let(:user) { Fabricate(:moderator) } let(:user) { Fabricate(:moderator) }
include_examples "can't be blocked" include_examples "can't be silenced"
end end
end end
@ -213,73 +213,73 @@ describe SpamRule::AutoBlock do
it 'returns false if there are no spam flags' do it 'returns false if there are no spam flags' do
subject.stubs(:num_spam_flags_against_user).returns(0) subject.stubs(:num_spam_flags_against_user).returns(0)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(0) subject.stubs(:num_users_who_flagged_spam_against_user).returns(0)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns false if there are not received enough flags' do it 'returns false if there are not received enough flags' do
subject.stubs(:num_spam_flags_against_user).returns(1) subject.stubs(:num_spam_flags_against_user).returns(1)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(2) subject.stubs(:num_users_who_flagged_spam_against_user).returns(2)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns false if there have not been enough users' do it 'returns false if there have not been enough users' do
subject.stubs(:num_spam_flags_against_user).returns(2) subject.stubs(:num_spam_flags_against_user).returns(2)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(1) subject.stubs(:num_users_who_flagged_spam_against_user).returns(1)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns false if num_spam_flags_to_block_new_user is 0' do it 'returns false if num_spam_flags_to_silence_new_user is 0' do
SiteSetting.num_spam_flags_to_block_new_user = 0 SiteSetting.num_spam_flags_to_silence_new_user = 0
subject.stubs(:num_spam_flags_against_user).returns(100) subject.stubs(:num_spam_flags_against_user).returns(100)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(100) subject.stubs(:num_users_who_flagged_spam_against_user).returns(100)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns false if num_users_to_block_new_user is 0' do it 'returns false if num_users_to_silence_new_user is 0' do
SiteSetting.num_users_to_block_new_user = 0 SiteSetting.num_users_to_silence_new_user = 0
subject.stubs(:num_spam_flags_against_user).returns(100) subject.stubs(:num_spam_flags_against_user).returns(100)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(100) subject.stubs(:num_users_who_flagged_spam_against_user).returns(100)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns true when there are enough flags from enough users' do it 'returns true when there are enough flags from enough users' do
subject.stubs(:num_spam_flags_against_user).returns(2) subject.stubs(:num_spam_flags_against_user).returns(2)
subject.stubs(:num_users_who_flagged_spam_against_user).returns(2) subject.stubs(:num_users_who_flagged_spam_against_user).returns(2)
expect(subject.block?).to be_truthy expect(subject.silence?).to be_truthy
end end
context "all types of flags" do context "all types of flags" do
before do before do
SiteSetting.num_tl3_flags_to_block_new_user = 3 SiteSetting.num_tl3_flags_to_silence_new_user = 3
SiteSetting.num_tl3_users_to_block_new_user = 2 SiteSetting.num_tl3_users_to_silence_new_user = 2
end end
it 'returns false if there are not enough flags' do it 'returns false if there are not enough flags' do
subject.stubs(:num_tl3_flags_against_user).returns(1) subject.stubs(:num_tl3_flags_against_user).returns(1)
subject.stubs(:num_tl3_users_who_flagged).returns(1) subject.stubs(:num_tl3_users_who_flagged).returns(1)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns false if enough flags but not enough users' do it 'returns false if enough flags but not enough users' do
subject.stubs(:num_tl3_flags_against_user).returns(3) subject.stubs(:num_tl3_flags_against_user).returns(3)
subject.stubs(:num_tl3_users_who_flagged).returns(1) subject.stubs(:num_tl3_users_who_flagged).returns(1)
expect(subject.block?).to be_falsey expect(subject.silence?).to be_falsey
end end
it 'returns true if enough flags and users' do it 'returns true if enough flags and users' do
subject.stubs(:num_tl3_flags_against_user).returns(3) subject.stubs(:num_tl3_flags_against_user).returns(3)
subject.stubs(:num_tl3_users_who_flagged).returns(2) subject.stubs(:num_tl3_users_who_flagged).returns(2)
expect(subject.block?).to eq(true) expect(subject.silence?).to eq(true)
end end
end end
end end
context "blocked, but has higher trust level now" do context "silenced, but has higher trust level now" do
let(:user) { Fabricate(:user, blocked: true, trust_level: TrustLevel[1]) } let(:user) { Fabricate(:user, silenced: true, trust_level: TrustLevel[1]) }
subject { described_class.new(user) } subject { described_class.new(user) }
it 'returns false' do it 'returns false' do
expect(subject.block?).to be_truthy expect(subject.silence?).to be_truthy
end end
end end
end end

View File

@ -11,7 +11,7 @@ describe GroupMessage do
Discourse.stubs(:system_user).returns(admin) Discourse.stubs(:system_user).returns(admin)
end end
subject(:send_group_message) { GroupMessage.create(moderators_group, :user_automatically_blocked, user: user) } subject(:send_group_message) { GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) }
describe 'not sent recently' do describe 'not sent recently' do
before { GroupMessage.any_instance.stubs(:sent_recently?).returns(false) } before { GroupMessage.any_instance.stubs(:sent_recently?).returns(false) }
@ -42,7 +42,7 @@ describe GroupMessage do
describe 'sent recently' do describe 'sent recently' do
before { GroupMessage.any_instance.stubs(:sent_recently?).returns(true) } before { GroupMessage.any_instance.stubs(:sent_recently?).returns(true) }
subject { GroupMessage.create(moderators_group, :user_automatically_blocked, user: user) } subject { GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) }
it { is_expected.to eq(false) } it { is_expected.to eq(false) }
@ -61,8 +61,8 @@ describe GroupMessage do
end end
end end
context 'user_automatically_blocked' do context 'user_automatically_silenced' do
subject { GroupMessage.new(moderators_group, :user_automatically_blocked, user: user).message_params } subject { GroupMessage.new(moderators_group, :user_automatically_silenced, user: user).message_params }
include_examples 'common message params for group messages' include_examples 'common message params for group messages'
end end
@ -74,7 +74,7 @@ describe GroupMessage do
describe 'methods that use redis' do describe 'methods that use redis' do
let(:user) { Fabricate.build(:user, id: 123123) } let(:user) { Fabricate.build(:user, id: 123123) }
subject(:group_message) { GroupMessage.new(moderators_group, :user_automatically_blocked, user: user) } subject(:group_message) { GroupMessage.new(moderators_group, :user_automatically_silenced, user: user) }
before do before do
PostCreator.stubs(:create).returns(stub_everything) PostCreator.stubs(:create).returns(stub_everything)
group_message.stubs(:sent_recently_key).returns('the_key') group_message.stubs(:sent_recently_key).returns('the_key')
@ -92,7 +92,7 @@ describe GroupMessage do
end end
it 'always returns false if limit_once_per is false' do it 'always returns false if limit_once_per is false' do
gm = GroupMessage.new(moderators_group, :user_automatically_blocked, user: user, limit_once_per: false) gm = GroupMessage.new(moderators_group, :user_automatically_silenced, user: user, limit_once_per: false)
gm.stubs(:sent_recently_key).returns('the_key') gm.stubs(:sent_recently_key).returns('the_key')
$redis.stubs(:get).with(gm.sent_recently_key).returns('1') $redis.stubs(:get).with(gm.sent_recently_key).returns('1')
expect(gm.sent_recently?).to be_falsey expect(gm.sent_recently?).to be_falsey
@ -107,12 +107,12 @@ describe GroupMessage do
it 'can use a given expiry time' do it 'can use a given expiry time' do
$redis.expects(:setex).with(anything, 30 * 60, anything).returns('OK') $redis.expects(:setex).with(anything, 30 * 60, anything).returns('OK')
GroupMessage.new(moderators_group, :user_automatically_blocked, user: user, limit_once_per: 30.minutes).remember_message_sent GroupMessage.new(moderators_group, :user_automatically_silenced, user: user, limit_once_per: 30.minutes).remember_message_sent
end end
it 'can be disabled' do it 'can be disabled' do
$redis.expects(:setex).never $redis.expects(:setex).never
GroupMessage.new(moderators_group, :user_automatically_blocked, user: user, limit_once_per: false).remember_message_sent GroupMessage.new(moderators_group, :user_automatically_silenced, user: user, limit_once_per: false).remember_message_sent
end end
end end
end end

View File

@ -19,8 +19,8 @@ describe SpamRulesEnforcer do
context 'user argument' do context 'user argument' do
subject(:enforce) { described_class.enforce!(Fabricate.build(:user)) } subject(:enforce) { described_class.enforce!(Fabricate.build(:user)) }
it 'performs the AutoBlock' do it 'performs the AutoSilence' do
SpamRule::AutoBlock.any_instance.expects(:perform).once SpamRule::AutoSilence.any_instance.expects(:perform).once
enforce enforce
end end
end end

View File

@ -1,39 +1,39 @@
require 'rails_helper' require 'rails_helper'
describe UserBlocker do describe UserSilencer do
before do before do
SystemMessage.stubs(:create) SystemMessage.stubs(:create)
end end
describe 'block' do describe 'silence' do
let(:user) { stub_everything(save: true) } let(:user) { stub_everything(save: true) }
let(:blocker) { UserBlocker.new(user) } let(:silencer) { UserSilencer.new(user) }
subject(:block_user) { blocker.block } subject(:silence_user) { silencer.silence }
it 'blocks the user' do it 'silences the user' do
u = Fabricate(:user) u = Fabricate(:user)
expect { UserBlocker.block(u) }.to change { u.reload.blocked? } expect { UserSilencer.silence(u) }.to change { u.reload.silenced? }
end end
it 'hides posts' do it 'hides posts' do
blocker.expects(:hide_posts) silencer.expects(:hide_posts)
block_user silence_user
end end
context 'given a staff user argument' do context 'given a staff user argument' do
it 'sends the correct message to the blocked user' do it 'sends the correct message to the silenced user' do
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).with(user, :blocked_by_staff).returns(true) SystemMessage.expects(:create).with(user, :silenced_by_staff).returns(true)
UserBlocker.block(user, Fabricate.build(:admin)) UserSilencer.silence(user, Fabricate.build(:admin))
end end
end end
context 'not given a staff user argument' do context 'not given a staff user argument' do
it 'sends a default message to the user' do it 'sends a default message to the user' do
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).with(user, :blocked_by_staff).returns(true) SystemMessage.expects(:create).with(user, :silenced_by_staff).returns(true)
UserBlocker.block(user, Fabricate.build(:admin)) UserSilencer.silence(user, Fabricate.build(:admin))
end end
end end
@ -41,7 +41,7 @@ describe UserBlocker do
it 'sends that message to the user' do it 'sends that message to the user' do
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).with(user, :the_custom_message).returns(true) SystemMessage.expects(:create).with(user, :the_custom_message).returns(true)
UserBlocker.block(user, Fabricate.build(:admin), message: :the_custom_message) UserSilencer.silence(user, Fabricate.build(:admin), message: :the_custom_message)
end end
end end
@ -49,50 +49,50 @@ describe UserBlocker do
user.stubs(:save).returns(false) user.stubs(:save).returns(false)
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).never SystemMessage.expects(:create).never
block_user silence_user
end end
it "doesn't send a pm if the user is already blocked" do it "doesn't send a pm if the user is already silenced" do
user.stubs(:blocked?).returns(true) user.stubs(:silenced?).returns(true)
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).never SystemMessage.expects(:create).never
expect(block_user).to eq(false) expect(silence_user).to eq(false)
end end
it "logs it with context" do it "logs it with context" do
SystemMessage.stubs(:create).returns(Fabricate.build(:post)) SystemMessage.stubs(:create).returns(Fabricate.build(:post))
expect { expect {
UserBlocker.block(user, Fabricate(:admin)) UserSilencer.silence(user, Fabricate(:admin))
}.to change { UserHistory.count }.by(1) }.to change { UserHistory.count }.by(1)
expect(UserHistory.last.context).to be_present expect(UserHistory.last.context).to be_present
end end
end end
describe 'unblock' do describe 'unsilence' do
let(:user) { stub_everything(save: true) } let(:user) { stub_everything(save: true) }
subject(:unblock_user) { UserBlocker.unblock(user, Fabricate.build(:admin)) } subject(:unsilence_user) { UserSilencer.unsilence(user, Fabricate.build(:admin)) }
it 'unblocks the user' do it 'unsilences the user' do
u = Fabricate(:user, blocked: true) u = Fabricate(:user, silenced: true)
expect { UserBlocker.unblock(u) }.to change { u.reload.blocked? } expect { UserSilencer.unsilence(u) }.to change { u.reload.silenced? }
end end
it 'sends a message to the user' do it 'sends a message to the user' do
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).with(user, :unblocked).returns(true) SystemMessage.expects(:create).with(user, :unsilenced).returns(true)
unblock_user unsilence_user
end end
it "doesn't send a pm if save fails" do it "doesn't send a pm if save fails" do
user.stubs(:save).returns(false) user.stubs(:save).returns(false)
SystemMessage.unstub(:create) SystemMessage.unstub(:create)
SystemMessage.expects(:create).never SystemMessage.expects(:create).never
unblock_user unsilence_user
end end
it "logs it" do it "logs it" do
expect { expect {
unblock_user unsilence_user
}.to change { UserHistory.count }.by(1) }.to change { UserHistory.count }.by(1)
end end
end end
@ -100,28 +100,28 @@ describe UserBlocker do
describe 'hide_posts' do describe 'hide_posts' do
let(:user) { Fabricate(:user, trust_level: 0) } let(:user) { Fabricate(:user, trust_level: 0) }
let!(:post) { Fabricate(:post, user: user) } let!(:post) { Fabricate(:post, user: user) }
subject { UserBlocker.new(user) } subject { UserSilencer.new(user) }
it "hides all the user's posts" do it "hides all the user's posts" do
subject.block subject.silence
expect(post.reload).to be_hidden expect(post.reload).to be_hidden
end end
it "hides the topic if the post was the first post" do it "hides the topic if the post was the first post" do
subject.block subject.silence
expect(post.topic.reload).to_not be_visible expect(post.topic.reload).to_not be_visible
end end
it "doesn't hide posts if user is TL1" do it "doesn't hide posts if user is TL1" do
user.trust_level = 1 user.trust_level = 1
subject.block subject.silence
expect(post.reload).to_not be_hidden expect(post.reload).to_not be_hidden
expect(post.topic.reload).to be_visible expect(post.topic.reload).to be_visible
end end
it "only hides posts from the past 24 hours" do it "only hides posts from the past 24 hours" do
old_post = Fabricate(:post, user: user, created_at: 2.days.ago) old_post = Fabricate(:post, user: user, created_at: 2.days.ago)
subject.block subject.silence
expect(post.reload).to be_hidden expect(post.reload).to be_hidden
expect(post.topic.reload).to_not be_visible expect(post.topic.reload).to_not be_visible
old_post.reload old_post.reload

View File

@ -10,7 +10,7 @@ QUnit.test("For topics: body of post, title, category and tags are all editbale"
return [ return [
200, 200,
{"Content-Type": "application/json"}, {"Content-Type": "application/json"},
{"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"blocked":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"queued_posts":[{"id":22,"queue":"default","user_id":3,"state":1,"topic_id":null,"approved_by_id":null,"rejected_by_id":null,"raw":"some content","post_options":{"archetype":"regular","category":"1","typing_duration_msecs":"3200","composer_open_duration_msecs":"19007","visible":true,"is_warning":false,"title":"a new topic that needs to be reviewed","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-11T20:43:41.115Z","category_id":1,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"} {"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"silenced":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"queued_posts":[{"id":22,"queue":"default","user_id":3,"state":1,"topic_id":null,"approved_by_id":null,"rejected_by_id":null,"raw":"some content","post_options":{"archetype":"regular","category":"1","typing_duration_msecs":"3200","composer_open_duration_msecs":"19007","visible":true,"is_warning":false,"title":"a new topic that needs to be reviewed","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-11T20:43:41.115Z","category_id":1,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"}
]; ];
}); });
@ -31,7 +31,7 @@ QUnit.test("For replies: only the body of post is editbale", assert => {
return [ return [
200, 200,
{"Content-Type": "application/json"}, {"Content-Type": "application/json"},
{"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"blocked":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"topics":[{"id":11,"title":"This is a topic","fancy_title":"This is a topic","slug":"this-is-a-topic","posts_count":2}],"queued_posts":[{"id":4,"queue":"default","user_id":3,"state":1,"topic_id":11,"approved_by_id":null,"rejected_by_id":null,"raw":"edited haahaasdfasdfasdfasdf","post_options":{"archetype":"regular","category":"3","reply_to_post_number":"2","typing_duration_msecs":"1900","composer_open_duration_msecs":"12096","visible":true,"is_warning":false,"featured_link":"","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-07T19:11:52.018Z","category_id":3,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"} {"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"silenced":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"topics":[{"id":11,"title":"This is a topic","fancy_title":"This is a topic","slug":"this-is-a-topic","posts_count":2}],"queued_posts":[{"id":4,"queue":"default","user_id":3,"state":1,"topic_id":11,"approved_by_id":null,"rejected_by_id":null,"raw":"edited haahaasdfasdfasdfasdf","post_options":{"archetype":"regular","category":"3","reply_to_post_number":"2","typing_duration_msecs":"1900","composer_open_duration_msecs":"12096","visible":true,"is_warning":false,"featured_link":"","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-07T19:11:52.018Z","category_id":3,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"}
]; ];
}); });