0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-07 13:19:19 +08:00
discourse/spec/serializers/concerns/user_status_mixin_spec.rb
Régis Hanol 20e4134a09
FEATURE: Prevent silenced users from liking and using reactions (#37040)
Silenced users can now no longer like posts or use reactions, which
closes a potential griefing vector that was difficult for moderators
to monitor.

The implementation adds a silenced check to the guardian's post_can_act?
method for likes, and introduces a new can_use_reactions? guardian method
in the discourse-reactions plugin that delegates to the same logic. This
ensures both features share the same authorization path.

Additionally, silenced users' custom status is now shadow-banned: visible
to themselves and staff, but hidden from other users.

A new `can_see_user_status?` guardian method centralizes the visibility
logic, used by serializers and MessageBus publishing. Status updates
from silenced users are now only broadcast to themselves and staff.

Also includes minor CSS fixes for user status spacing and alignment.

Chat reactions already had proper silenced user checks in place via the
can_react? guardian method, so no changes were needed there.

Ref - t/140084
2026-01-13 13:59:57 +01:00

49 lines
1.3 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe UserStatusMixin do
fab!(:user_status)
fab!(:user) { Fabricate(:user, user_status:) }
class DummySerializer < ApplicationSerializer
include UserStatusMixin
end
def serialize_status(scope: Guardian.new(user), include_status: true)
DummySerializer.new(user, scope:, root: false, include_status:).as_json[:status]
end
context "when user status is disabled" do
before { SiteSetting.enable_user_status = false }
it "doesn't include status" do
expect(serialize_status).to be_nil
end
end
context "when user status is enabled" do
before { SiteSetting.enable_user_status = true }
it "doesn't include status by default" do
expect(serialize_status(include_status: false)).to be_nil
end
it "includes status when include_status option is passed" do
expect(serialize_status).to be_present
end
it "doesn't include status if user hid profile" do
user.user_option.hide_profile = true
expect(serialize_status).to be_nil
end
it "respects guardian's can_see_user_status?" do
user.update!(silenced_till: 1.year.from_now)
# own status is visible
expect(serialize_status).to be_present
# other user's status is not visible
expect(serialize_status(scope: Guardian.new(Fabricate(:user)))).to be_nil
end
end
end