discourse/spec/lib/guardian_spec.rb
Martin Brennan 7ce76143ac
FIX: Always trust admin and moderators with post edits (#25602)
Removes duplication from LimitedEdit to see who can edit
posts, and also removes the old trust level setting check
since it's no longer necessary.

Also make it so staff can always edit since can_edit_post?
already has a staff escape hatch.
2024-02-08 13:10:26 +10:00

4451 lines
157 KiB
Ruby

# frozen_string_literal: true
RSpec.describe Guardian do
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:another_user) { Fabricate(:user) }
fab!(:member) { Fabricate(:user) }
fab!(:owner) { Fabricate(:user) }
fab!(:moderator) { Fabricate(:moderator, refresh_auto_groups: true) }
fab!(:admin) { Fabricate(:admin, refresh_auto_groups: true) }
fab!(:anonymous_user) { Fabricate(:anonymous) }
fab!(:staff_post) { Fabricate(:post, user: moderator) }
fab!(:group)
fab!(:another_group) { Fabricate(:group) }
fab!(:automatic_group) { Fabricate(:group, automatic: true) }
fab!(:plain_category) { Fabricate(:category) }
fab!(:trust_level_0)
fab!(:trust_level_1)
fab!(:trust_level_2)
fab!(:trust_level_3)
fab!(:trust_level_4)
fab!(:another_admin) { Fabricate(:admin) }
fab!(:coding_horror) { Fabricate(:coding_horror, refresh_auto_groups: true) }
fab!(:topic) { Fabricate(:topic, user: user) }
fab!(:post) { Fabricate(:post, topic: topic, user: topic.user) }
before { Guardian.enable_topic_can_see_consistency_check }
after { Guardian.disable_topic_can_see_consistency_check }
it "can be created without a user (not logged in)" do
expect { Guardian.new }.not_to raise_error
end
it "can be instantiated with a user instance" do
expect { Guardian.new(user) }.not_to raise_error
end
describe "link_posting_access" do
it "is none for anonymous users" do
expect(Guardian.new.link_posting_access).to eq("none")
end
it "is full for regular users" do
expect(Guardian.new(user).link_posting_access).to eq("full")
end
it "is full for staff users regardless of TL" do
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
admin_user = Fabricate(:admin)
admin_user.change_trust_level!(TrustLevel[1])
expect(Guardian.new(admin_user).link_posting_access).to eq("full")
end
it "is none for a user of a low trust level" do
user.change_trust_level!(TrustLevel[0])
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(user).link_posting_access).to eq("none")
end
it "is limited for a user of a low trust level with a allowlist" do
SiteSetting.allowed_link_domains = "example.com"
user.change_trust_level!(TrustLevel[0])
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(user).link_posting_access).to eq("limited")
end
end
describe "can_post_link?" do
let(:host) { "discourse.org" }
it "returns false for anonymous users" do
expect(Guardian.new.can_post_link?(host: host)).to eq(false)
end
it "returns true for a regular user" do
expect(Guardian.new(user).can_post_link?(host: host)).to eq(true)
end
it "supports customization by site setting" do
user.change_trust_level!(TrustLevel[0])
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
expect(Guardian.new(user).can_post_link?(host: host)).to eq(true)
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(user).can_post_link?(host: host)).to eq(false)
end
describe "allowlisted host" do
before { SiteSetting.allowed_link_domains = host }
it "allows a new user to post the link to the host" do
user.change_trust_level!(TrustLevel[0])
SiteSetting.post_links_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(user).can_post_link?(host: host)).to eq(true)
expect(Guardian.new(user).can_post_link?(host: "another-host.com")).to eq(false)
end
end
end
describe "#post_can_act?" do
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:post)
describe "an anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
context "when allow_anonymous_likes is enabled" do
before { SiteSetting.allow_anonymous_likes = true }
it "returns true when liking" do
expect(Guardian.new(anonymous_user).post_can_act?(post, :like)).to be_truthy
end
it "cannot perform any other action" do
expect(Guardian.new(anonymous_user).post_can_act?(post, :flag)).to be_falsey
expect(Guardian.new(anonymous_user).post_can_act?(post, :bookmark)).to be_falsey
expect(Guardian.new(anonymous_user).post_can_act?(post, :notify_user)).to be_falsey
end
end
context "when allow_anonymous_likes is disabled" do
before { SiteSetting.allow_anonymous_likes = false }
it "returns false when liking" do
expect(Guardian.new(anonymous_user).post_can_act?(post, :like)).to be_falsey
end
it "cannot perform any other action" do
expect(Guardian.new(anonymous_user).post_can_act?(post, :flag)).to be_falsey
expect(Guardian.new(anonymous_user).post_can_act?(post, :bookmark)).to be_falsey
expect(Guardian.new(anonymous_user).post_can_act?(post, :notify_user)).to be_falsey
end
end
end
it "returns false when the user is nil" do
expect(Guardian.new(nil).post_can_act?(post, :like)).to be_falsey
end
it "returns false when the post is nil" do
expect(Guardian.new(user).post_can_act?(nil, :like)).to be_falsey
end
it "returns false when the topic is archived" do
post.topic.archived = true
expect(Guardian.new(user).post_can_act?(post, :like)).to be_falsey
end
it "returns false when the post is deleted" do
post.deleted_at = Time.now
expect(Guardian.new(user).post_can_act?(post, :like)).to be_falsey
expect(Guardian.new(admin).post_can_act?(post, :spam)).to be_truthy
expect(Guardian.new(admin).post_can_act?(post, :notify_user)).to be_truthy
end
it "works as expected for silenced users" do
UserSilencer.silence(user, admin)
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_falsey
expect(Guardian.new(user).post_can_act?(post, :like)).to be_truthy
expect(Guardian.new(user).post_can_act?(post, :bookmark)).to be_truthy
end
it "allows flagging archived posts" do
post.topic.archived = true
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_truthy
end
it "does not allow flagging of hidden posts" do
post.hidden = true
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_falsey
end
it "allows flagging of staff posts when allow_flagging_staff is true" do
SiteSetting.allow_flagging_staff = true
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to be_truthy
end
describe "when allow_flagging_staff is false" do
before { SiteSetting.allow_flagging_staff = false }
it "doesn't allow flagging of staff posts" do
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to eq(false)
end
it "allows flagging of staff posts when staff has been deleted" do
staff_post.user.destroy!
staff_post.reload
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to eq(true)
end
it "allows liking of staff" do
expect(Guardian.new(user).post_can_act?(staff_post, :like)).to eq(true)
end
end
it "returns false when liking yourself" do
expect(Guardian.new(post.user).post_can_act?(post, :like)).to be_falsey
end
it "returns false when you've already done it" do
expect(
Guardian.new(user).post_can_act?(
post,
:like,
opts: {
taken_actions: {
PostActionType.types[:like] => 1,
},
},
),
).to be_falsey
end
it "returns false when you already flagged a post" do
PostActionType.notify_flag_types.each do |type, _id|
expect(
Guardian.new(user).post_can_act?(
post,
:off_topic,
opts: {
taken_actions: {
PostActionType.types[type] => 1,
},
},
),
).to be_falsey
end
end
it "returns false for notify_user if user is not in any group that can send personal messages" do
user = Fabricate(:user)
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:staff]
user.change_trust_level!(1)
expect(Guardian.new(user).post_can_act?(post, :notify_user)).to be_falsey
end
describe "trust levels" do
before { user.change_trust_level!(TrustLevel[0]) }
it "returns true for a new user liking something" do
expect(Guardian.new(user).post_can_act?(post, :like)).to be_truthy
end
it "returns false for a new user flagging as spam" do
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_falsey
end
it "returns true for a new user flagging as spam if enabled" do
SiteSetting.flag_post_allowed_groups = 0
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_truthy
end
it "returns true for a new user flagging a private message as spam" do
post = Fabricate(:private_message_post, user: admin)
user.trust_level = TrustLevel[0]
post.topic.allowed_users << user
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_truthy
end
it "returns false for a new user flagging something as off topic" do
user.trust_level = TrustLevel[0]
expect(Guardian.new(user).post_can_act?(post, :off_topic)).to be_falsey
end
it "returns false for a new user flagging with notify_user" do
user.trust_level = TrustLevel[0]
expect(Guardian.new(user).post_can_act?(post, :notify_user)).to be_falsey # because new users can't send private messages
end
end
end
describe "can_enable_safe_mode" do
fab!(:user)
fab!(:moderator)
context "when enabled" do
before { SiteSetting.enable_safe_mode = true }
it "can be performed" do
expect(Guardian.new.can_enable_safe_mode?).to eq(true)
expect(Guardian.new(user).can_enable_safe_mode?).to eq(true)
expect(Guardian.new(moderator).can_enable_safe_mode?).to eq(true)
end
end
context "when disabled" do
before { SiteSetting.enable_safe_mode = false }
it "can be performed" do
expect(Guardian.new.can_enable_safe_mode?).to eq(false)
expect(Guardian.new(user).can_enable_safe_mode?).to eq(false)
expect(Guardian.new(moderator).can_enable_safe_mode?).to eq(true)
end
end
end
describe "can_send_private_message" do
fab!(:suspended_user) do
Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago)
end
it "returns false when the user is nil" do
expect(Guardian.new(nil).can_send_private_message?(user)).to be_falsey
end
it "returns false when the target user is nil" do
expect(Guardian.new(user).can_send_private_message?(nil)).to be_falsey
end
it "returns true when the target is the same as the user" do
# this is now allowed so yay
expect(Guardian.new(user).can_send_private_message?(user)).to be_truthy
end
it "returns false when you are untrusted" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: TrustLevel[0])
Group.user_trust_level_change!(user.id, TrustLevel[0])
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey
end
it "returns true to another user" do
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_truthy
end
it "disallows pms to other users if trust level is not met" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: TrustLevel[1])
Group.user_trust_level_change!(user.id, TrustLevel[1])
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey
end
context "when personal_message_enabled_groups does not contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns false if user is not staff member" do
expect(Guardian.new(trust_level_4).can_send_private_message?(another_user)).to be_falsey
GroupUser.create(user: trust_level_4, group: group)
trust_level_4.reload
expect(Guardian.new(trust_level_4).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for staff member" do
expect(Guardian.new(moderator).can_send_private_message?(another_user)).to be_truthy
expect(Guardian.new(admin).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for bot user" do
expect(Guardian.new(Fabricate(:bot)).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for system user" do
expect(
Guardian.new(Discourse.system_user).can_send_private_message?(another_user),
).to be_truthy
end
end
context "when target user is suspended" do
it "returns true for staff" do
expect(Guardian.new(admin).can_send_private_message?(suspended_user)).to be_truthy
expect(Guardian.new(moderator).can_send_private_message?(suspended_user)).to be_truthy
end
it "returns false for regular users" do
expect(Guardian.new(user).can_send_private_message?(suspended_user)).to be_falsey
end
end
context "when author is silenced" do
before do
user.silenced_till = 1.year.from_now
user.save
end
it "returns true if target is staff" do
expect(Guardian.new(user).can_send_private_message?(admin)).to be_truthy
expect(Guardian.new(user).can_send_private_message?(moderator)).to be_truthy
end
it "returns false if target is not staff" do
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey
end
it "returns true if target is a staff group" do
Group::STAFF_GROUPS.each do |name|
g = Group[name]
g.update!(messageable_level: Group::ALIAS_LEVELS[:everyone])
expect(Guardian.new(user).can_send_private_message?(g)).to be_truthy
end
end
end
it "respects the group's messageable_level" do
Group::ALIAS_LEVELS.each do |level, _|
group.update!(messageable_level: Group::ALIAS_LEVELS[level])
user_output = level == :everyone ? true : false
admin_output = level != :nobody
mod_output = %i[nobody only_admins].exclude?(level)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(user_output)
expect(Guardian.new(admin).can_send_private_message?(group)).to eq(admin_output)
expect(Guardian.new(moderator).can_send_private_message?(group)).to eq(mod_output)
end
end
it "allows TL0 to message group with messageable_level = everyone regardless of personal_message_enabled_groups" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:everyone])
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(true)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
end
it "respects the group members messageable_level" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:members_mods_and_admins])
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_0]
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(false)
# user must have both a group from personal_message_enabled_groups to send messages in general,
# and be a member of this group to send the message to this group for this messageable_level
group.add(trust_level_0)
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(true)
end
it "respects the group owners messageable_level" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:owners_mods_and_admins])
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add_owner(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
end
context "when target user has private message disabled" do
before { another_user.user_option.update!(allow_private_messages: false) }
context "for a normal user" do
it "should return false" do
expect(Guardian.new(user).can_send_private_message?(another_user)).to eq(false)
end
end
context "for a staff user" do
it "should return true" do
[admin, moderator].each do |staff_user|
expect(Guardian.new(staff_user).can_send_private_message?(another_user)).to eq(true)
end
end
end
end
end
describe "can_send_private_messages" do
fab!(:suspended_user) do
Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago)
end
it "returns false when the user is nil" do
expect(Guardian.new(nil).can_send_private_messages?).to be_falsey
end
it "disallows pms to other users if the user is not in the automated trust level used for personal_message_enabled_groups" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: TrustLevel[1])
Group.user_trust_level_change!(user.id, TrustLevel[1])
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_falsey
user.update!(trust_level: TrustLevel[2])
Group.user_trust_level_change!(user.id, TrustLevel[2])
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
context "when personal_message_enabled_groups does contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns true" do
expect(Guardian.new(user).can_send_private_messages?).to be_falsey
GroupUser.create(user: user, group: group)
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
end
context "when personal_message_enabled_groups does not contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns false if user is not staff member" do
expect(Guardian.new(trust_level_4).can_send_private_messages?).to be_falsey
GroupUser.create(user: trust_level_4, group: group)
trust_level_4.reload
expect(Guardian.new(trust_level_4).can_send_private_messages?).to be_truthy
end
it "returns true for staff member" do
expect(Guardian.new(moderator).can_send_private_messages?).to be_truthy
expect(Guardian.new(admin).can_send_private_messages?).to be_truthy
end
it "returns true for bot user" do
expect(Guardian.new(Fabricate(:bot)).can_send_private_messages?).to be_truthy
end
it "returns true for system user" do
expect(Guardian.new(Discourse.system_user).can_send_private_messages?).to be_truthy
end
end
context "when author is silenced" do
before do
user.silenced_till = 1.year.from_now
user.save
end
it "returns true, since there is no target user, we do that check separately" do
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
end
end
describe "can_reply_as_new_topic" do
fab!(:topic)
fab!(:private_message) { Fabricate(:private_message_topic) }
it "returns false for a non logged in user" do
expect(Guardian.new(nil).can_reply_as_new_topic?(topic)).to be_falsey
end
it "returns false for a nil topic" do
expect(Guardian.new(user).can_reply_as_new_topic?(nil)).to be_falsey
end
it "returns false for an untrusted user" do
user.trust_level = TrustLevel[0]
expect(Guardian.new(user).can_reply_as_new_topic?(topic)).to be_falsey
end
it "returns true for a trusted user" do
expect(Guardian.new(user).can_reply_as_new_topic?(topic)).to be_truthy
end
it "returns true for a private message" do
expect(Guardian.new(user).can_reply_as_new_topic?(private_message)).to be_truthy
end
end
describe "can_see_post_actors?" do
let(:topic) { Fabricate(:topic, user: coding_horror) }
it "displays visibility correctly" do
guardian = Guardian.new(user)
expect(guardian.can_see_post_actors?(nil, PostActionType.types[:like])).to be_falsey
expect(guardian.can_see_post_actors?(topic, PostActionType.types[:like])).to be_truthy
expect(guardian.can_see_post_actors?(topic, PostActionType.types[:off_topic])).to be_falsey
expect(guardian.can_see_post_actors?(topic, PostActionType.types[:spam])).to be_falsey
expect(guardian.can_see_post_actors?(topic, PostActionType.types[:notify_user])).to be_falsey
expect(
Guardian.new(moderator).can_see_post_actors?(topic, PostActionType.types[:notify_user]),
).to be_truthy
end
end
describe "can_impersonate?" do
it "disallows impersonation when disabled globally" do
global_setting :allow_impersonation, false
expect(Guardian.new(admin).can_impersonate?(moderator)).to be_falsey
end
it "allows impersonation correctly" do
expect(Guardian.new(admin).can_impersonate?(nil)).to be_falsey
expect(Guardian.new.can_impersonate?(user)).to be_falsey
expect(Guardian.new(coding_horror).can_impersonate?(user)).to be_falsey
expect(Guardian.new(admin).can_impersonate?(admin)).to be_falsey
expect(Guardian.new(admin).can_impersonate?(another_admin)).to be_falsey
expect(Guardian.new(admin).can_impersonate?(user)).to be_truthy
expect(Guardian.new(admin).can_impersonate?(moderator)).to be_truthy
Rails.configuration.stubs(:developer_emails).returns([admin.email])
expect(Guardian.new(admin).can_impersonate?(another_admin)).to be_truthy
end
end
describe "can_view_action_logs?" do
it "is false for non-staff acting user" do
expect(Guardian.new(user).can_view_action_logs?(moderator)).to be_falsey
end
it "is false without a target user" do
expect(Guardian.new(moderator).can_view_action_logs?(nil)).to be_falsey
end
it "is true when target user is present" do
expect(Guardian.new(moderator).can_view_action_logs?(user)).to be_truthy
end
end
describe "can_invite_to_forum?" do
fab!(:user)
fab!(:moderator)
it "returns true if user has sufficient trust level" do
SiteSetting.invite_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
expect(Guardian.new(trust_level_2).can_invite_to_forum?).to be_truthy
expect(Guardian.new(moderator).can_invite_to_forum?).to be_truthy
end
it "returns false if user trust level does not have sufficient trust level" do
SiteSetting.invite_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
expect(Guardian.new(trust_level_1).can_invite_to_forum?).to be_falsey
end
it "doesn't allow anonymous users to invite" do
expect(Guardian.new.can_invite_to_forum?).to be_falsey
end
it "returns true when the site requires approving users" do
SiteSetting.must_approve_users = true
expect(Guardian.new(trust_level_2).can_invite_to_forum?).to be_truthy
end
it "returns false when max_invites_per_day is 0" do
# let's also break it while here
SiteSetting.max_invites_per_day = "a"
expect(Guardian.new(user).can_invite_to_forum?).to be_falsey
# staff should be immune to max_invites_per_day setting
expect(Guardian.new(moderator).can_invite_to_forum?).to be_truthy
end
context "with groups" do
let(:groups) { [group, another_group] }
before do
user.change_trust_level!(TrustLevel[2])
group.add_owner(user)
end
it "returns false when user is not allowed to edit a group" do
expect(Guardian.new(user).can_invite_to_forum?(groups)).to eq(false)
expect(Guardian.new(admin).can_invite_to_forum?(groups)).to eq(true)
end
it "returns true when user is allowed to edit groups" do
another_group.add_owner(user)
expect(Guardian.new(user).can_invite_to_forum?(groups)).to eq(true)
end
end
end
describe "can_invite_to?" do
describe "regular topics" do
before do
SiteSetting.invite_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: 2)
end
fab!(:category) { Fabricate(:category, read_restricted: true) }
fab!(:topic)
fab!(:private_topic) { Fabricate(:topic, category: category) }
fab!(:user) { topic.user }
let(:private_category) { Fabricate(:private_category, group: group) }
let(:group_private_topic) { Fabricate(:topic, category: private_category) }
let(:group_owner) { group_private_topic.user.tap { |u| group.add_owner(u) } }
it "handles invitation correctly" do
expect(Guardian.new(nil).can_invite_to?(topic)).to be_falsey
expect(Guardian.new(moderator).can_invite_to?(nil)).to be_falsey
expect(Guardian.new(moderator).can_invite_to?(topic)).to be_truthy
expect(Guardian.new(trust_level_1).can_invite_to?(topic)).to be_truthy
SiteSetting.max_invites_per_day = 0
expect(Guardian.new(user).can_invite_to?(topic)).to be_truthy
# staff should be immune to max_invites_per_day setting
expect(Guardian.new(moderator).can_invite_to?(topic)).to be_truthy
end
it "returns false for normal user on private topic" do
expect(Guardian.new(user).can_invite_to?(private_topic)).to be_falsey
end
it "returns false for admin on private topic" do
expect(Guardian.new(admin).can_invite_to?(private_topic)).to be(false)
end
it "returns true for a group owner" do
group_owner.update!(trust_level: 2)
expect(Guardian.new(group_owner).can_invite_to?(group_private_topic)).to be_truthy
end
it "return true for normal users even if must_approve_users" do
SiteSetting.must_approve_users = true
expect(Guardian.new(user).can_invite_to?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_to?(topic)).to be_truthy
end
describe "for a private category for automatic and non-automatic group" do
let(:category) do
Fabricate(:category, read_restricted: true).tap do |category|
category.groups << automatic_group
category.groups << group
end
end
let(:topic) { Fabricate(:topic, category: category) }
it "should return true for an admin user" do
expect(Guardian.new(admin).can_invite_to?(topic)).to eq(true)
end
it "should return true for a group owner" do
group_owner.update!(trust_level: 2)
expect(Guardian.new(group_owner).can_invite_to?(topic)).to eq(true)
end
it "should return false for a normal user" do
expect(Guardian.new(user).can_invite_to?(topic)).to eq(false)
end
end
describe "for a private category for automatic groups" do
let(:category) do
Fabricate(:private_category, group: automatic_group, read_restricted: true)
end
let(:group_owner) { Fabricate(:user).tap { |user| automatic_group.add_owner(user) } }
let(:topic) { Fabricate(:topic, category: category) }
it "should return false for all type of users" do
expect(Guardian.new(admin).can_invite_to?(topic)).to eq(false)
expect(Guardian.new(group_owner).can_invite_to?(topic)).to eq(false)
expect(Guardian.new(user).can_invite_to?(topic)).to eq(false)
end
end
end
describe "private messages" do
fab!(:user)
fab!(:pm) { Fabricate(:private_message_topic, user: user) }
before do
user.change_trust_level!(TrustLevel[2])
moderator.change_trust_level!(TrustLevel[2])
end
context "when private messages are disabled" do
it "allows an admin to invite to the pm" do
expect(Guardian.new(admin).can_invite_to?(pm)).to be_truthy
expect(Guardian.new(user).can_invite_to?(pm)).to be_truthy
end
end
context "when user does not belong to personal_message_enabled_groups" do
before { SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:staff] }
it "doesn't allow a regular user to invite" do
expect(Guardian.new(admin).can_invite_to?(pm)).to be_truthy
expect(Guardian.new(user).can_invite_to?(pm)).to be_falsey
end
end
context "when PM has reached the maximum number of recipients" do
before { SiteSetting.max_allowed_message_recipients = 2 }
it "doesn't allow a regular user to invite" do
expect(Guardian.new(user).can_invite_to?(pm)).to be_falsey
end
it "allows staff to invite" do
expect(Guardian.new(admin).can_invite_to?(pm)).to be_truthy
pm.grant_permission_to_user(moderator.email)
expect(Guardian.new(moderator).can_invite_to?(pm)).to be_truthy
end
end
end
end
describe "can_invite_via_email?" do
it "returns true for all (tl2 and above) users when sso is disabled, local logins are enabled, user approval is not required" do
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_truthy
end
it "returns true for all users when sso is enabled" do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_truthy
end
it "returns false for all users when local logins are disabled" do
SiteSetting.enable_local_logins = false
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_falsey
end
it "returns correct values when user approval is required" do
SiteSetting.must_approve_users = true
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_truthy
end
end
describe "can_see_deleted_post?" do
fab!(:post)
before { post.trash!(user) }
it "returns false for post that is not deleted" do
post.recover!
expect(Guardian.new(admin).can_see_deleted_post?(post)).to be_falsey
end
it "returns false for anon" do
expect(Guardian.new.can_see_deleted_post?(post)).to be_falsey
end
it "returns true for admin" do
expect(Guardian.new(admin).can_see_deleted_post?(post)).to be_truthy
end
it "returns true for mods" do
expect(Guardian.new(moderator).can_see_deleted_post?(post)).to be_truthy
end
it "returns false for < TL4 users" do
user.update!(trust_level: TrustLevel[1])
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_falsey
end
it "returns false if not the person who deleted it" do
post.update!(deleted_by: another_user)
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_falsey
end
it "returns true for TL4 users' own posts" do
user.update!(trust_level: TrustLevel[4])
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_truthy
end
end
describe "can_receive_post_notifications?" do
it "returns false with a nil object" do
expect(Guardian.new.can_receive_post_notifications?(nil)).to be_falsey
expect(Guardian.new(user).can_receive_post_notifications?(nil)).to be_falsey
end
it "does not allow anonymous to be notified" do
expect(Guardian.new.can_receive_post_notifications?(post)).to be_falsey
end
it "allows public categories" do
expect(Guardian.new(trust_level_0).can_receive_post_notifications?(post)).to be_truthy
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
end
it "disallows secure categories with no access" do
secure_category = Fabricate(:category, read_restricted: true)
post.topic.update!(category_id: secure_category.id)
expect(Guardian.new(trust_level_0).can_receive_post_notifications?(post)).to be_falsey
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
SiteSetting.suppress_secured_categories_from_admin = true
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_falsey
secure_category.set_permissions(group => :write)
secure_category.save!
group.add(admin)
group.save!
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
end
end
describe "can_see?" do
it "returns false with a nil object" do
expect(Guardian.new.can_see?(nil)).to be_falsey
end
it "returns false when no visibility method is defined for the object" do
unguarded_object = 42
expect(Guardian.new.can_see?(unguarded_object)).to be_falsey
end
describe "a Category" do
it "allows public categories" do
public_category = Fabricate(:category, read_restricted: false)
expect(Guardian.new.can_see?(public_category)).to be_truthy
end
it "correctly handles secure categories" do
normal_user = Fabricate(:user)
staged_user = Fabricate(:user, staged: true)
admin_user = Fabricate(:user, admin: true)
secure_category = Fabricate(:category, read_restricted: true)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category = Fabricate(:category, read_restricted: true, email_in: "foo@bar.com")
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category =
Fabricate(:category, read_restricted: true, email_in_allow_strangers: true)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category =
Fabricate(
:category,
read_restricted: true,
email_in: "foo2@bar.com",
email_in_allow_strangers: true,
)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_truthy
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
end
it "allows members of an authorized group" do
secure_category = plain_category
secure_category.set_permissions(group => :readonly)
secure_category.save
expect(Guardian.new(user).can_see?(secure_category)).to be_falsey
group.add(user)
group.save
expect(Guardian.new(user).can_see?(secure_category)).to be_truthy
end
end
describe "a Topic" do
it "allows non logged in users to view topics" do
expect(Guardian.new.can_see?(topic)).to be_truthy
end
it "correctly handles groups" do
category = Fabricate(:category, read_restricted: true)
category.set_permissions(group => :full)
category.save
topic = Fabricate(:topic, category: category)
expect(Guardian.new(user).can_see?(topic)).to be_falsey
group.add(user)
group.save
expect(Guardian.new(user).can_see?(topic)).to be_truthy
end
it "restricts deleted topics" do
topic = Fabricate(:topic)
topic.trash!(moderator)
expect(Guardian.new.can_see?(topic)).to be_falsey
expect(Guardian.new(user).can_see?(topic)).to be_falsey
expect(Guardian.new(moderator).can_see?(topic)).to be_truthy
expect(Guardian.new(admin).can_see?(topic)).to be_truthy
end
it "restricts private topics" do
private_topic = Fabricate(:private_message_topic, user: user)
expect(Guardian.new(private_topic.user).can_see?(private_topic)).to be_truthy
expect(Guardian.new(Fabricate(:user)).can_see?(private_topic)).to be_falsey
expect(Guardian.new(moderator).can_see?(private_topic)).to be_falsey
expect(Guardian.new(admin).can_see?(private_topic)).to be_truthy
end
it "restricts private deleted topics" do
private_topic = Fabricate(:private_message_topic, user: user)
private_topic.trash!(admin)
expect(Guardian.new(private_topic.user).can_see?(private_topic)).to be_falsey
expect(Guardian.new(Fabricate(:user)).can_see?(private_topic)).to be_falsey
expect(Guardian.new(moderator).can_see?(private_topic)).to be_falsey
expect(Guardian.new(admin).can_see?(private_topic)).to be_truthy
end
it "restricts static doc topics" do
tos_topic = Fabricate(:topic, user: Discourse.system_user)
SiteSetting.tos_topic_id = tos_topic.id
expect(Guardian.new(Fabricate(:user)).can_edit?(tos_topic)).to be_falsey
expect(Guardian.new(moderator).can_edit?(tos_topic)).to be_falsey
expect(Guardian.new(admin).can_edit?(tos_topic)).to be_truthy
end
it "allows moderators to see a flagged private message" do
private_topic = Fabricate(:private_message_topic, user: user)
first_post = Fabricate(:post, topic: private_topic, user: user)
expect(Guardian.new(moderator).can_see?(private_topic)).to be_falsey
PostActionCreator.create(user, first_post, :off_topic)
expect(Guardian.new(moderator).can_see?(private_topic)).to be_truthy
end
it "allows staff to set banner topics" do
topic = Fabricate(:topic)
expect(Guardian.new(admin).can_banner_topic?(nil)).to be_falsey
expect(Guardian.new(admin).can_banner_topic?(topic)).to be_truthy
end
it "respects category group moderator settings" do
group_user = Fabricate(:group_user)
user_gm = group_user.user
group = group_user.group
SiteSetting.enable_category_group_moderation = true
topic = Fabricate(:topic)
expect(Guardian.new(user_gm).can_see?(topic)).to be_truthy
topic.trash!(admin)
topic.reload
expect(Guardian.new(user_gm).can_see?(topic)).to be_falsey
topic.category.update!(reviewable_by_group_id: group.id, topic_id: post.topic.id)
expect(Guardian.new(user_gm).can_see?(topic)).to be_truthy
end
it "allows staged user to view own topic in restricted category when Category#email_in and Category#email_in_allow_strangers is set" do
secure_category =
Fabricate(
:category,
read_restricted: true,
email_in: "foo2@bar.com",
email_in_allow_strangers: true,
)
topic_in_secure_category = Fabricate(:topic, category: secure_category, user: user)
expect(Guardian.new(user).can_see?(topic_in_secure_category)).to eq(false)
user.update!(staged: true)
expect(Guardian.new(user).can_see?(topic_in_secure_category)).to eq(true)
end
end
describe "a Post" do
fab!(:post)
fab!(:another_admin) { Fabricate(:admin) }
it "correctly handles post visibility" do
topic = post.topic
expect(Guardian.new(user).can_see?(post)).to be_truthy
post.trash!(another_admin)
post.reload
expect(Guardian.new(user).can_see?(post)).to be_falsey
expect(Guardian.new(admin).can_see?(post)).to be_truthy
post.recover!
post.reload
topic.trash!(another_admin)
topic.reload
expect(Guardian.new(user).can_see?(post)).to be_falsey
expect(Guardian.new(admin).can_see?(post)).to be_truthy
end
it "respects category group moderator settings" do
group_user = Fabricate(:group_user)
user_gm = group_user.user
group = group_user.group
SiteSetting.enable_category_group_moderation = true
expect(Guardian.new(user_gm).can_see?(post)).to be_truthy
post.trash!(another_admin)
post.reload
expect(Guardian.new(user_gm).can_see?(post)).to be_falsey
post.topic.category.update!(reviewable_by_group_id: group.id, topic_id: post.topic.id)
expect(Guardian.new(user_gm).can_see?(post)).to be_truthy
end
it "TL4 users can see their deleted posts" do
user = Fabricate(:user, trust_level: 4)
user2 = Fabricate(:user, trust_level: 4)
post = Fabricate(:post, user: user, topic: Fabricate(:post).topic)
expect(Guardian.new(user).can_see?(post)).to eq(true)
PostDestroyer.new(user, post).destroy
expect(Guardian.new(user).can_see?(post)).to eq(true)
expect(Guardian.new(user2).can_see?(post)).to eq(false)
end
it "respects whispers" do
SiteSetting.whispers_allowed_groups = "#{Group::AUTO_GROUPS[:staff]}|#{group.id}"
regular_post = post
whisper_post = Fabricate(:post, post_type: Post.types[:whisper])
anon_guardian = Guardian.new
expect(anon_guardian.can_see?(regular_post)).to eq(true)
expect(anon_guardian.can_see?(whisper_post)).to eq(false)
regular_user = Fabricate(:user)
regular_guardian = Guardian.new(regular_user)
expect(regular_guardian.can_see?(regular_post)).to eq(true)
expect(regular_guardian.can_see?(whisper_post)).to eq(false)
# can see your own whispers
regular_whisper = Fabricate(:post, post_type: Post.types[:whisper], user: regular_user)
expect(regular_guardian.can_see?(regular_whisper)).to eq(true)
mod_guardian = Guardian.new(Fabricate(:moderator))
expect(mod_guardian.can_see?(regular_post)).to eq(true)
expect(mod_guardian.can_see?(whisper_post)).to eq(true)
admin_guardian = Guardian.new(Fabricate(:admin))
expect(admin_guardian.can_see?(regular_post)).to eq(true)
expect(admin_guardian.can_see?(whisper_post)).to eq(true)
whisperer_guardian = Guardian.new(Fabricate(:user, groups: [group]))
expect(whisperer_guardian.can_see?(regular_post)).to eq(true)
expect(whisperer_guardian.can_see?(whisper_post)).to eq(true)
end
end
describe "a PostRevision" do
fab!(:post_revision)
context "when edit_history_visible_to_public is true" do
before { SiteSetting.edit_history_visible_to_public = true }
it "is false for nil" do
expect(Guardian.new.can_see?(nil)).to be_falsey
end
it "is true if not logged in" do
expect(Guardian.new.can_see?(post_revision)).to be_truthy
end
it "is true when logged in" do
expect(Guardian.new(user).can_see?(post_revision)).to be_truthy
end
end
context "when edit_history_visible_to_public is false" do
before { SiteSetting.edit_history_visible_to_public = false }
it "is true for staff" do
expect(Guardian.new(admin).can_see?(post_revision)).to be_truthy
expect(Guardian.new(moderator).can_see?(post_revision)).to be_truthy
end
it "is false for trust level equal or lower than 4" do
expect(Guardian.new(trust_level_3).can_see?(post_revision)).to be_falsey
expect(Guardian.new(trust_level_4).can_see?(post_revision)).to be_falsey
end
end
end
end
describe "can_create?" do
describe "a Category" do
it "returns false when not logged in" do
expect(Guardian.new.can_create?(Category)).to be_falsey
end
it "returns false when a regular user" do
expect(Guardian.new(user).can_create?(Category)).to be_falsey
end
it "returns false when a moderator" do
expect(Guardian.new(moderator).can_create?(Category)).to be_falsey
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_create?(Category)).to be_truthy
end
end
describe "a Topic" do
it "does not allow moderators to create topics in readonly categories" do
category = plain_category
category.set_permissions(everyone: :read)
category.save
expect(Guardian.new(moderator).can_create?(Topic, category)).to be_falsey
end
it "should check for full permissions" do
category = plain_category
category.set_permissions(everyone: :create_post)
category.save
expect(Guardian.new(user).can_create?(Topic, category)).to be_falsey
end
it "is true for new users by default" do
expect(Guardian.new(user).can_create?(Topic, plain_category)).to be_truthy
end
it "is false if user has not met minimum trust level" do
SiteSetting.min_trust_to_create_topic = 1
SiteSetting.create_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(
Guardian.new(Fabricate(:user, trust_level: 0)).can_create?(Topic, plain_category),
).to be_falsey
end
it "is true if user has met or exceeded the minimum trust level" do
SiteSetting.create_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(
Guardian.new(Fabricate(:user, trust_level: TrustLevel[1])).can_create?(
Topic,
plain_category,
),
).to be_truthy
expect(
Guardian.new(Fabricate(:user, trust_level: TrustLevel[2])).can_create?(
Topic,
plain_category,
),
).to be_truthy
expect(
Guardian.new(Fabricate(:admin, trust_level: TrustLevel[0])).can_create?(
Topic,
plain_category,
),
).to be_truthy
expect(
Guardian.new(Fabricate(:moderator, trust_level: TrustLevel[0])).can_create?(
Topic,
plain_category,
),
).to be_truthy
end
end
describe "a Post" do
it "is false on readonly categories" do
category = plain_category
topic.category = category
category.set_permissions(everyone: :readonly)
category.save
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_falsey
end
it "is false when not logged in" do
expect(Guardian.new.can_create?(Post, topic)).to be_falsey
end
it "is true for a regular user" do
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_truthy
end
it "is false when you can't see the topic" do
Guardian.any_instance.expects(:can_see?).with(topic).returns(false)
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
end
context "with closed topic" do
before { topic.closed = true }
it "doesn't allow new posts from regular users" do
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
end
it "allows editing of posts" do
expect(Guardian.new(topic.user).can_edit?(post)).to be_truthy
end
it "allows new posts from moderators" do
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_truthy
end
it "allows new posts from admins" do
expect(Guardian.new(admin).can_create?(Post, topic)).to be_truthy
end
it "allows new posts from trust_level_4s" do
expect(Guardian.new(trust_level_4).can_create?(Post, topic)).to be_truthy
end
end
context "with archived topic" do
before { topic.archived = true }
context "with regular users" do
it "doesn't allow new posts from regular users" do
expect(Guardian.new(coding_horror).can_create?(Post, topic)).to be_falsey
end
it "does not allow editing of posts" do
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
end
end
it "allows new posts from moderators" do
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_truthy
end
it "allows new posts from admins" do
expect(Guardian.new(admin).can_create?(Post, topic)).to be_truthy
end
end
context "with trashed topic" do
before { topic.trash!(admin) }
it "doesn't allow new posts from regular users" do
expect(Guardian.new(coding_horror).can_create?(Post, topic)).to be_falsey
end
it "doesn't allow new posts from moderators users" do
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_falsey
end
it "doesn't allow new posts from admins" do
expect(Guardian.new(admin).can_create?(Post, topic)).to be_falsey
end
end
context "with system message" do
fab!(:private_message) do
Fabricate(
:topic,
archetype: Archetype.private_message,
subtype: "system_message",
category_id: nil,
)
end
before { user.save! }
it "allows the user to reply to system messages" do
expect(Guardian.new(user).can_create_post?(private_message)).to eq(true)
SiteSetting.enable_system_message_replies = false
expect(Guardian.new(user).can_create_post?(private_message)).to eq(false)
end
end
context "with private message" do
fab!(:private_message) do
Fabricate(:topic, archetype: Archetype.private_message, category_id: nil)
end
before { user.save! }
it "allows new posts by people included in the pm" do
private_message.topic_allowed_users.create!(user_id: user.id)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy
end
it "doesn't allow new posts by people not invited to the pm" do
expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey
end
it "allows new posts from silenced users included in the pm" do
user.update_attribute(:silenced_till, 1.year.from_now)
private_message.topic_allowed_users.create!(user_id: user.id)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy
end
it "doesn't allow new posts from silenced users not invited to the pm" do
user.update_attribute(:silenced_till, 1.year.from_now)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey
end
end
end # can_create? a Post
end
describe "post_can_act?" do
it "isn't allowed on nil" do
expect(Guardian.new(user).post_can_act?(nil, nil)).to be_falsey
end
describe "a Post" do
let(:guardian) { Guardian.new(user) }
it "isn't allowed when not logged in" do
expect(Guardian.new(nil).post_can_act?(post, :vote)).to be_falsey
end
it "is allowed as a regular user" do
expect(guardian.post_can_act?(post, :vote)).to be_truthy
end
it "isn't allowed on archived topics" do
topic.archived = true
expect(Guardian.new(user).post_can_act?(post, :like)).to be_falsey
end
end
end
describe "can_recover_topic?" do
fab!(:topic) { Fabricate(:topic, user: user) }
fab!(:post) { Fabricate(:post, user: user, topic: topic) }
it "returns false for a nil user" do
expect(Guardian.new(nil).can_recover_topic?(topic)).to be_falsey
end
it "returns false for a nil object" do
expect(Guardian.new(user).can_recover_topic?(nil)).to be_falsey
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_recover_topic?(topic)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
PostDestroyer.new(moderator, topic.first_post).destroy
expect(Guardian.new(trust_level_4).can_recover_topic?(topic)).to be_falsey
SiteSetting.delete_all_posts_and_topics_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(trust_level_4).can_recover_topic?(topic.reload)).to be_truthy
end
context "as a moderator" do
describe "when post has been deleted" do
it "should return the right value" do
expect(Guardian.new(moderator).can_recover_topic?(topic)).to be_falsey
PostDestroyer.new(moderator, topic.first_post).destroy
expect(Guardian.new(moderator).can_recover_topic?(topic.reload)).to be_truthy
end
end
describe "when post's user has been deleted" do
it "should return the right value" do
PostDestroyer.new(moderator, topic.first_post).destroy
topic.first_post.user.destroy!
expect(Guardian.new(moderator).can_recover_topic?(topic.reload)).to be_truthy
end
end
end
context "when category group moderation is enabled" do
fab!(:group_user)
before do
SiteSetting.enable_category_group_moderation = true
PostDestroyer.new(moderator, topic.first_post).destroy
topic.reload
end
it "returns false if user is not a member of the appropriate group" do
expect(Guardian.new(group_user.user).can_recover_topic?(topic)).to be_falsey
end
it "returns true if user is a member of the appropriate group" do
topic.category.update!(reviewable_by_group_id: group_user.group.id)
expect(Guardian.new(group_user.user).can_recover_topic?(topic)).to be_truthy
end
end
end
describe "can_recover_post?" do
it "returns false for a nil user" do
expect(Guardian.new(nil).can_recover_post?(post)).to be_falsey
end
it "returns false for a nil object" do
expect(Guardian.new(user).can_recover_post?(nil)).to be_falsey
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_recover_post?(post)).to be_falsey
end
context "as a moderator" do
fab!(:topic) { Fabricate(:topic, user: user) }
fab!(:post) { Fabricate(:post, user: user, topic: topic) }
describe "when post has been deleted" do
it "should return the right value" do
expect(Guardian.new(moderator).can_recover_post?(post)).to be_falsey
PostDestroyer.new(moderator, post).destroy
expect(Guardian.new(moderator).can_recover_post?(post.reload)).to be_truthy
end
describe "when post's user has been deleted" do
it "should return the right value" do
PostDestroyer.new(moderator, post).destroy
post.user.destroy!
expect(Guardian.new(moderator).can_recover_post?(post.reload)).to be_truthy
end
end
end
end
end
describe "#can_convert_topic?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_convert_topic?(nil)).to be_falsey
end
it "returns false when not logged in" do
expect(Guardian.new.can_convert_topic?(topic)).to be_falsey
end
it "returns false when not staff" do
expect(Guardian.new(trust_level_4).can_convert_topic?(topic)).to be_falsey
end
it "returns false for category definition topics" do
c = plain_category
topic = Topic.find_by(id: c.topic_id)
expect(Guardian.new(admin).can_convert_topic?(topic)).to be_falsey
end
it "returns true when a moderator" do
expect(Guardian.new(moderator).can_convert_topic?(topic)).to be_truthy
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_convert_topic?(topic)).to be_truthy
end
it "returns false when user is not in personal_message_enabled_groups" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(user).can_convert_topic?(topic)).to be_falsey
end
it "returns true if user is not in personal_message_enabled_groups but they are still admin" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(admin).can_convert_topic?(topic)).to be_truthy
end
end
describe "can_edit?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_edit?(nil)).to be_falsey
end
describe "a Post" do
it "returns false for silenced users" do
post.user.silenced_till = 1.day.from_now
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns false when not logged in" do
expect(Guardian.new.can_edit?(post)).to be_falsey
end
it "returns false when not logged in also for wiki post" do
post.wiki = true
expect(Guardian.new.can_edit?(post)).to be_falsey
end
it "returns true if you want to edit your own post" do
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns false if you try to edit a locked post" do
post.locked_by_id = moderator.id
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns false if the post is hidden due to flagging and it's too soon" do
post.hidden = true
post.hidden_at = Time.now
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns true if the post is hidden due to flagging and it been enough time" do
post.hidden = true
post.hidden_at = (SiteSetting.cooldown_minutes_after_hiding_posts + 1).minutes.ago
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns true if the post is hidden, it's been enough time and the edit window has expired" do
post.hidden = true
post.hidden_at = (SiteSetting.cooldown_minutes_after_hiding_posts + 1).minutes.ago
post.created_at = (SiteSetting.post_edit_time_limit + 1).minutes.ago
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns true if the post is hidden due to flagging and it's got a nil `hidden_at`" do
post.hidden = true
post.hidden_at = nil
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns false if you are trying to edit a post you soft deleted" do
post.user_deleted = true
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns false if another regular user tries to edit a soft deleted wiki post" do
post.wiki = true
post.user_deleted = true
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
end
it "returns false if you are trying to edit a deleted post" do
post.deleted_at = 1.day.ago
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns false if another regular user tries to edit a deleted wiki post" do
post.wiki = true
post.deleted_at = 1.day.ago
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
end
it "returns false if another regular user tries to edit your post" do
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
end
it "returns true if another regular user tries to edit wiki post" do
post.wiki = true
expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy
end
it "returns false if a wiki but the user can't create a post" do
c = plain_category
c.set_permissions(everyone: :readonly)
c.save
topic = Fabricate(:topic, category: c)
post = Fabricate(:post, topic: topic)
post.wiki = true
expect(Guardian.new(user).can_edit?(post)).to eq(false)
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(post)).to be_truthy
end
it "returns true as a moderator, even if locked" do
post.locked_by_id = admin.id
expect(Guardian.new(moderator).can_edit?(post)).to be_truthy
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(post)).to be_truthy
end
it "returns true as a trust level 4 user" do
expect(Guardian.new(trust_level_4).can_edit?(post)).to be_truthy
end
it "returns false when trying to edit a topic when the user is not in the allowed groups" do
SiteSetting.edit_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.user.change_trust_level!(TrustLevel[1])
expect(Guardian.new(topic.user).can_edit?(topic)).to be_falsey
end
it "returns false when trying to edit a post when the user is not in the allowed groups" do
SiteSetting.edit_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.user.change_trust_level!(TrustLevel[1])
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
it "returns true when editing a post when the user is in the allowed groups" do
SiteSetting.edit_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
post.user.change_trust_level!(TrustLevel[1])
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns true when editing a post when the user is admin regardless of groups" do
SiteSetting.edit_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.user.update!(admin: true)
post.user.change_trust_level!(TrustLevel[1])
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
it "returns false when another user is not member of edit wiki post group" do
SiteSetting.edit_wiki_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.wiki = true
Group.user_trust_level_change!(coding_horror.id, 1)
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
end
it "returns true when another user is member of edit wiki post group" do
SiteSetting.edit_wiki_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.wiki = true
Group.user_trust_level_change!(coding_horror.id, 2)
expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy
end
it "returns true for post author even when author is not member of edit wiki post group" do
SiteSetting.edit_wiki_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
post.wiki = true
Group.user_trust_level_change!(post.user, 1)
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
end
context "with shared drafts" do
fab!(:category)
let(:topic) { Fabricate(:topic, category: category) }
let(:post_with_draft) { Fabricate(:post, topic: topic) }
before do
SiteSetting.shared_drafts_category = category.id
SiteSetting.shared_drafts_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
Fabricate(:shared_draft, topic: topic)
end
it "returns true if a shared draft exists" do
expect(Guardian.new(trust_level_2).can_edit_post?(post_with_draft)).to eq(true)
end
it "returns false if the user has a lower trust level" do
expect(Guardian.new(trust_level_1).can_edit_post?(post_with_draft)).to eq(false)
end
it "returns false if the draft is from a different category" do
topic.update!(category: Fabricate(:category))
expect(Guardian.new(trust_level_2).can_edit_post?(post_with_draft)).to eq(false)
end
end
context "when category group moderation is enabled" do
fab!(:cat_mod_user) { Fabricate(:user) }
before do
SiteSetting.enable_category_group_moderation = true
GroupUser.create!(group_id: group.id, user_id: cat_mod_user.id)
post.topic.category.update!(reviewable_by_group_id: group.id)
end
it "returns true as a category group moderator user" do
expect(Guardian.new(cat_mod_user).can_edit?(post)).to eq(true)
end
it "returns false for a regular user" do
expect(Guardian.new(another_user).can_edit?(post)).to eq(false)
end
end
describe "post edit time limits" do
context "when post is older than post_edit_time_limit" do
let(:user) { Fabricate(:user, refresh_auto_groups: true) }
let(:topic) { Fabricate(:topic, user: user) }
let(:old_post) do
Fabricate(:post, topic: topic, user: topic.user, created_at: 6.minutes.ago)
end
before do
topic.user.update_columns(trust_level: 1)
SiteSetting.post_edit_time_limit = 5
end
it "returns false to the author of the post" do
expect(Guardian.new(old_post.user).can_edit?(old_post)).to be_falsey
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(old_post)).to eq(true)
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(old_post)).to eq(true)
end
it "returns false for another regular user trying to edit your post" do
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
it "returns true for another regular user trying to edit a wiki post" do
old_post.wiki = true
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_truthy
end
context "when unlimited owner edits on first post" do
let(:owner) { old_post.user }
it "returns true when the post topic's category allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: true)
expect(Guardian.new(owner).can_edit?(old_post)).to be_truthy
end
it "returns false when the post topic's category does not allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: false)
expect(Guardian.new(owner).can_edit?(old_post)).to be_falsey
end
it "returns false when the post topic's category allow_unlimited_owner_edits_on_first_post but the post is not the first in the topic" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: true)
new_post =
Fabricate(:post, user: owner, topic: old_post.topic, created_at: 6.minutes.ago)
expect(Guardian.new(owner).can_edit?(new_post)).to be_falsey
end
it "returns false when someone other than owner is editing and category allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: false)
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
end
end
context "when post is older than tl2_post_edit_time_limit" do
let(:old_post) do
Fabricate(:post, topic: topic, user: topic.user, created_at: 12.minutes.ago)
end
before do
topic.user.update_columns(trust_level: 2)
SiteSetting.tl2_post_edit_time_limit = 10
end
it "returns false to the author of the post" do
expect(Guardian.new(old_post.user).can_edit?(old_post)).to be_falsey
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(old_post)).to eq(true)
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(old_post)).to eq(true)
end
it "returns false for another regular user trying to edit your post" do
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
it "returns true for another regular user trying to edit a wiki post" do
old_post.wiki = true
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_truthy
end
end
end
context "with first post of a static page doc" do
let!(:tos_topic) { Fabricate(:topic, user: Discourse.system_user) }
let!(:tos_first_post) { Fabricate(:post, topic: tos_topic, user: tos_topic.user) }
before { SiteSetting.tos_topic_id = tos_topic.id }
it "restricts static doc posts" do
expect(Guardian.new(Fabricate(:user)).can_edit?(tos_first_post)).to be_falsey
expect(Guardian.new(moderator).can_edit?(tos_first_post)).to be_falsey
expect(Guardian.new(admin).can_edit?(tos_first_post)).to be_truthy
end
end
end
describe "a Topic" do
it "returns false when not logged in" do
expect(Guardian.new.can_edit?(topic)).to be_falsey
end
it "returns true for editing your own post" do
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(true)
end
it "returns false as a regular user" do
expect(Guardian.new(coding_horror).can_edit?(topic)).to be_falsey
end
context "when first post is hidden" do
let!(:topic) { Fabricate(:topic, user: user) }
let!(:post) do
Fabricate(:post, topic: topic, user: topic.user, hidden: true, hidden_at: Time.zone.now)
end
it "returns false for editing your own post while inside the cooldown window" do
SiteSetting.cooldown_minutes_after_hiding_posts = 30
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(false)
end
end
context "when locked" do
let(:post) { Fabricate(:post, locked_by_id: admin.id) }
let(:topic) { post.topic }
it "doesn't allow users to edit locked topics" do
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(false)
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
end
end
context "when not archived" do
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(topic)).to eq(true)
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
end
it "returns true at trust level 3" do
expect(Guardian.new(trust_level_3).can_edit?(topic)).to eq(true)
end
it "returns false when the category is read only" do
topic.category.set_permissions(everyone: :readonly)
topic.category.save
expect(Guardian.new(trust_level_3).can_edit?(topic)).to eq(false)
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
expect(Guardian.new(moderator).can_edit?(post)).to eq(false)
expect(Guardian.new(moderator).can_edit?(topic)).to eq(false)
end
it "returns false for trust level 3 if category is secured" do
topic.category.set_permissions(everyone: :create_post, staff: :full)
topic.category.save
expect(Guardian.new(trust_level_3).can_edit?(topic)).to eq(false)
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
expect(Guardian.new(moderator).can_edit?(topic)).to eq(true)
end
end
context "with private message" do
fab!(:private_message) { Fabricate(:private_message_topic) }
it "returns false at trust level 3" do
expect(Guardian.new(trust_level_3).can_edit?(private_message)).to eq(false)
end
it "returns false at trust level 4" do
expect(Guardian.new(trust_level_4).can_edit?(private_message)).to eq(false)
end
end
context "when archived" do
let(:archived_topic) { Fabricate(:topic, user: user, archived: true) }
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(archived_topic)).to be_truthy
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(archived_topic)).to be_truthy
end
it "returns true at trust level 4" do
expect(Guardian.new(trust_level_4).can_edit?(archived_topic)).to be_truthy
end
it "returns true if the user is in edit_all_post_groups" do
SiteSetting.edit_all_post_groups = "14"
expect(Guardian.new(trust_level_4).can_edit?(archived_topic)).to eq(true)
end
it "returns false if the user is not in edit_all_post_groups" do
SiteSetting.edit_all_post_groups = "14"
expect(Guardian.new(trust_level_3).can_edit?(archived_topic)).to eq(false)
end
it "returns false at trust level 3" do
expect(Guardian.new(trust_level_3).can_edit?(archived_topic)).to be_falsey
end
it "returns false as a topic creator" do
expect(Guardian.new(user).can_edit?(archived_topic)).to be_falsey
end
end
context "when very old" do
let(:old_topic) { Fabricate(:topic, user: user, created_at: 6.minutes.ago) }
before { SiteSetting.post_edit_time_limit = 5 }
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(old_topic)).to be_truthy
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(old_topic)).to be_truthy
end
it "returns true at trust level 3" do
expect(Guardian.new(trust_level_3).can_edit?(old_topic)).to be_truthy
end
it "returns false as a topic creator" do
expect(Guardian.new(user).can_edit?(old_topic)).to be_falsey
end
end
end
describe "a Category" do
it "returns false when not logged in" do
expect(Guardian.new.can_edit?(plain_category)).to be_falsey
end
it "returns false as a regular user" do
expect(Guardian.new(plain_category.user).can_edit?(plain_category)).to be_falsey
end
it "returns false as a moderator" do
expect(Guardian.new(moderator).can_edit?(plain_category)).to be_falsey
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(plain_category)).to be_truthy
end
end
describe "a User" do
it "returns false when not logged in" do
expect(Guardian.new.can_edit?(user)).to be_falsey
end
it "returns false as a different user" do
expect(Guardian.new(coding_horror).can_edit?(user)).to be_falsey
end
it "returns true when trying to edit yourself" do
expect(Guardian.new(user).can_edit?(user)).to be_truthy
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(user)).to be_truthy
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(user)).to be_truthy
end
end
end
describe "#can_moderate?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_moderate?(nil)).to be_falsey
end
context "when user is silenced" do
it "returns false" do
user.update_column(:silenced_till, 1.year.from_now)
expect(Guardian.new(user).can_moderate?(post)).to be(false)
expect(Guardian.new(user).can_moderate?(topic)).to be(false)
end
end
context "with a Topic" do
it "returns false when not logged in" do
expect(Guardian.new.can_moderate?(topic)).to be_falsey
end
it "returns false when not a moderator" do
expect(Guardian.new(user).can_moderate?(topic)).to be_falsey
end
it "returns true when a moderator" do
expect(Guardian.new(moderator).can_moderate?(topic)).to be_truthy
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_moderate?(topic)).to be_truthy
end
it "returns true when trust level 4" do
expect(Guardian.new(trust_level_4).can_moderate?(topic)).to be_truthy
end
end
end
describe "#can_see_flags?" do
it "returns false when there is no post" do
expect(Guardian.new(moderator).can_see_flags?(nil)).to be_falsey
end
it "returns false when there is no user" do
expect(Guardian.new(nil).can_see_flags?(post)).to be_falsey
end
it "allow regular users to see flags" do
expect(Guardian.new(user).can_see_flags?(post)).to be_falsey
end
it "allows moderators to see flags" do
expect(Guardian.new(moderator).can_see_flags?(post)).to be_truthy
end
it "allows moderators to see flags" do
expect(Guardian.new(admin).can_see_flags?(post)).to be_truthy
end
end
describe "#can_review_topic?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_review_topic?(nil)).to eq(false)
end
it "returns true for a staff user" do
expect(Guardian.new(moderator).can_review_topic?(topic)).to eq(true)
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_review_topic?(topic)).to eq(false)
end
it "returns true for a group member with reviewable status" do
SiteSetting.enable_category_group_moderation = true
GroupUser.create!(group_id: group.id, user_id: user.id)
topic.category.update!(reviewable_by_group_id: group.id)
expect(Guardian.new(user).can_review_topic?(topic)).to eq(true)
end
end
describe "#can_close_topic?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_close_topic?(nil)).to eq(false)
end
it "returns true for a staff user" do
expect(Guardian.new(moderator).can_close_topic?(topic)).to eq(true)
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_close_topic?(topic)).to eq(false)
end
it "returns true for a group member with reviewable status" do
SiteSetting.enable_category_group_moderation = true
GroupUser.create!(group_id: group.id, user_id: user.id)
topic.category.update!(reviewable_by_group_id: group.id)
expect(Guardian.new(user).can_close_topic?(topic)).to eq(true)
end
end
describe "#can_archive_topic?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_archive_topic?(nil)).to eq(false)
end
it "returns true for a staff user" do
expect(Guardian.new(moderator).can_archive_topic?(topic)).to eq(true)
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_archive_topic?(topic)).to eq(false)
end
it "returns true for a group member with reviewable status" do
SiteSetting.enable_category_group_moderation = true
GroupUser.create!(group_id: group.id, user_id: user.id)
topic.category.update!(reviewable_by_group_id: group.id)
expect(Guardian.new(user).can_archive_topic?(topic)).to eq(true)
end
end
describe "#can_edit_staff_notes?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_edit_staff_notes?(nil)).to eq(false)
end
it "returns true for a staff user" do
expect(Guardian.new(moderator).can_edit_staff_notes?(topic)).to eq(true)
end
it "returns false for a regular user" do
expect(Guardian.new(user).can_edit_staff_notes?(topic)).to eq(false)
end
it "returns true for a group member with reviewable status" do
SiteSetting.enable_category_group_moderation = true
GroupUser.create!(group_id: group.id, user_id: user.id)
topic.category.update!(reviewable_by_group_id: group.id)
expect(Guardian.new(user).can_edit_staff_notes?(topic)).to eq(true)
end
end
describe "#can_create_topic?" do
it "returns true for staff user" do
expect(Guardian.new(moderator).can_create_topic?(topic)).to eq(true)
end
it "returns false for user with insufficient trust level" do
SiteSetting.min_trust_to_create_topic = 3
SiteSetting.create_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_3]
expect(Guardian.new(user).can_create_topic?(topic)).to eq(false)
end
it "returns true for user with sufficient trust level" do
SiteSetting.create_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_3]
expect(Guardian.new(trust_level_4).can_create_topic?(topic)).to eq(true)
end
it 'returns false when posting in "uncategorized" is disabled and there is no other category available for posting' do
SiteSetting.allow_uncategorized_topics = false
plain_category.set_permissions(group => :readonly)
plain_category.save
expect(Guardian.new(user).can_create_topic?(topic)).to eq(false)
end
it "returns true when there is a category available for posting" do
SiteSetting.allow_uncategorized_topics = false
plain_category.set_permissions(group => :full)
plain_category.save
group.add(user)
group.save
expect(Guardian.new(user).can_create_topic?(topic)).to eq(true)
end
end
describe "#can_move_posts?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_move_posts?(nil)).to be_falsey
end
context "with a Topic" do
it "returns false when not logged in" do
expect(Guardian.new.can_move_posts?(topic)).to be_falsey
end
it "returns false when not a moderator" do
expect(Guardian.new(user).can_move_posts?(topic)).to be_falsey
end
it "returns true when a moderator" do
expect(Guardian.new(moderator).can_move_posts?(topic)).to be_truthy
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_move_posts?(topic)).to be_truthy
end
end
end
describe "#can_delete?" do
it "returns false with a nil object" do
expect(Guardian.new(user).can_delete?(nil)).to be_falsey
end
context "with a Topic" do
it "returns false when not logged in" do
expect(Guardian.new.can_delete?(topic)).to be_falsey
end
it "returns false when not a moderator" do
expect(Guardian.new(Fabricate(:user)).can_delete?(topic)).to be_falsey
end
it "returns true when a moderator" do
expect(Guardian.new(moderator).can_delete?(topic)).to be_truthy
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_delete?(topic)).to be_truthy
end
it "returns false for static doc topics" do
tos_topic = Fabricate(:topic, user: Discourse.system_user)
SiteSetting.tos_topic_id = tos_topic.id
expect(Guardian.new(admin).can_delete?(tos_topic)).to be_falsey
end
it "returns true for own topics" do
topic.update_attribute(:posts_count, 1)
topic.update_attribute(:created_at, Time.zone.now)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_truthy
end
it "returns false if topic has replies" do
topic.update!(posts_count: 2, created_at: Time.zone.now)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_delete?(topic)).to be_falsey
SiteSetting.delete_all_posts_and_topics_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(trust_level_4).can_delete?(topic)).to be_truthy
end
it "returns false if topic was created > 24h ago" do
topic.update!(posts_count: 1, created_at: 48.hours.ago)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_falsey
end
context "when category group moderation is enabled" do
fab!(:group_user)
before { SiteSetting.enable_category_group_moderation = true }
it "returns false if user is not a member of the appropriate group" do
expect(Guardian.new(group_user.user).can_delete?(topic)).to be_falsey
end
it "returns true if user is a member of the appropriate group" do
topic.category.update!(reviewable_by_group_id: group_user.group.id)
expect(Guardian.new(group_user.user).can_delete?(topic)).to be_truthy
end
end
end
context "with a Post" do
before { post.post_number = 2 }
it "returns false when not logged in" do
expect(Guardian.new.can_delete?(post)).to be_falsey
end
it "returns false when trying to delete your own post that has already been deleted" do
post = Fabricate(:post)
PostDestroyer.new(user, post).destroy
post.reload
expect(Guardian.new(user).can_delete?(post)).to be_falsey
end
it "returns true when trying to delete your own post" do
expect(Guardian.new(user).can_delete?(post)).to be_truthy
expect(Guardian.new(trust_level_0).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_1).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_2).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_3).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_falsey
SiteSetting.delete_all_posts_and_topics_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_truthy
end
it "returns false when self deletions are disabled" do
SiteSetting.max_post_deletions_per_day = 0
expect(Guardian.new(user).can_delete?(post)).to be_falsey
end
it "returns false when trying to delete another user's own post" do
expect(Guardian.new(Fabricate(:user)).can_delete?(post)).to be_falsey
end
it "returns false when it's the OP, even as a moderator if there are at least two posts" do
post = Fabricate(:post)
Fabricate(:post, topic: post.topic)
expect(Guardian.new(moderator).can_delete?(post)).to be_falsey
end
it "returns true when a moderator" do
expect(Guardian.new(moderator).can_delete?(post)).to be_truthy
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_delete?(post)).to be_truthy
end
it "returns true for category moderators" do
SiteSetting.enable_category_group_moderation = true
GroupUser.create(group: group, user: user)
category = Fabricate(:category, reviewable_by_group_id: group.id)
post.topic.update!(category: category)
expect(Guardian.new(user).can_delete?(post)).to eq(true)
end
it "returns false when post is first in a static doc topic" do
tos_topic = Fabricate(:topic, user: Discourse.system_user)
SiteSetting.tos_topic_id = tos_topic.id
post.update_attribute :post_number, 1
post.update_attribute :topic_id, tos_topic.id
expect(Guardian.new(admin).can_delete?(post)).to be_falsey
end
context "when the topic is archived" do
before { post.topic.archived = true }
it "allows a staff member to delete it" do
expect(Guardian.new(moderator).can_delete?(post)).to be_truthy
end
it "doesn't allow a regular user to delete it" do
expect(Guardian.new(post.user).can_delete?(post)).to be_falsey
end
end
end
context "with a Category" do
let(:category) { Fabricate(:category, user: moderator) }
it "returns false when not logged in" do
expect(Guardian.new.can_delete?(category)).to be_falsey
end
it "returns false when a regular user" do
expect(Guardian.new(user).can_delete?(category)).to be_falsey
end
it "returns false when a moderator" do
expect(Guardian.new(moderator).can_delete?(category)).to be_falsey
end
it "returns true when an admin" do
expect(Guardian.new(admin).can_delete?(category)).to be_truthy
end
it "can't be deleted if it has a forum topic" do
category.topic_count = 10
expect(Guardian.new(moderator).can_delete?(category)).to be_falsey
end
it "can't be deleted if it is the Uncategorized Category" do
uncategorized_cat_id = SiteSetting.uncategorized_category_id
uncategorized_category = Category.find(uncategorized_cat_id)
expect(Guardian.new(admin).can_delete?(uncategorized_category)).to be_falsey
end
it "can't be deleted if it has children" do
category.expects(:has_children?).returns(true)
expect(Guardian.new(admin).can_delete?(category)).to be_falsey
end
end
describe "#can_suspend?" do
it "returns false when a user tries to suspend another user" do
expect(Guardian.new(user).can_suspend?(coding_horror)).to be_falsey
end
it "returns true when an admin tries to suspend another user" do
expect(Guardian.new(admin).can_suspend?(coding_horror)).to be_truthy
end
it "returns true when a moderator tries to suspend another user" do
expect(Guardian.new(moderator).can_suspend?(coding_horror)).to be_truthy
end
it "returns false when staff tries to suspend staff" do
expect(Guardian.new(admin).can_suspend?(moderator)).to be_falsey
end
end
context "with a PostAction" do
let(:post_action) do
user.id = 1
post.id = 1
a = PostAction.new(user: user, post: post, post_action_type_id: 2)
a.created_at = 1.minute.ago
a
end
it "returns false when not logged in" do
expect(Guardian.new.can_delete?(post_action)).to be_falsey
end
it "returns false when not the user who created it" do
expect(Guardian.new(coding_horror).can_delete?(post_action)).to be_falsey
end
it "returns false if the window has expired" do
post_action.created_at = 20.minutes.ago
SiteSetting.post_undo_action_window_mins = 10
expect(Guardian.new(user).can_delete?(post_action)).to be_falsey
end
it "returns false if topic is archived" do
post.topic.update!(archived: true)
expect(Guardian.new(user).can_delete?(post_action)).to be_falsey
end
it "returns true if it's yours" do
expect(Guardian.new(user).can_delete?(post_action)).to be_truthy
end
end
end
describe "#can_delete_post_action" do
before do
SiteSetting.allow_anonymous_posting = true
Guardian.any_instance.stubs(:anonymous?).returns(true)
end
context "with allow_anonymous_likes enabled" do
before { SiteSetting.allow_anonymous_likes = true }
describe "an anonymous user" do
let(:post_action) do
user.id = anonymous_user.id
post.id = 1
a =
PostAction.new(
user: anonymous_user,
post: post,
post_action_type_id: PostActionType.types[:like],
)
a.created_at = 1.minute.ago
a
end
let(:non_like_post_action) do
user.id = anonymous_user.id
post.id = 1
a =
PostAction.new(
user: anonymous_user,
post: post,
post_action_type_id: PostActionType.types[:reply],
)
a.created_at = 1.minute.ago
a
end
let(:other_users_post_action) do
post.id = 1
a =
PostAction.new(user: user, post: post, post_action_type_id: PostActionType.types[:like])
a.created_at = 1.minute.ago
a
end
it "returns true if the post belongs to the anonymous user" do
expect(Guardian.new(anonymous_user).can_delete_post_action?(post_action)).to be_truthy
end
it "return false if the post belongs to another user" do
expect(
Guardian.new(anonymous_user).can_delete_post_action?(other_users_post_action),
).to be_falsey
end
it "returns false for any other action" do
expect(
Guardian.new(anonymous_user).can_delete_post_action?(non_like_post_action),
).to be_falsey
end
it "returns false if the window has expired" do
post_action.created_at = 20.minutes.ago
SiteSetting.post_undo_action_window_mins = 10
expect(Guardian.new(anonymous_user).can_delete?(post_action)).to be_falsey
end
end
end
context "with allow_anonymous_likes disabled" do
before do
SiteSetting.allow_anonymous_likes = false
SiteSetting.allow_anonymous_posting = true
end
describe "an anonymous user" do
let(:post_action) do
user.id = anonymous_user.id
post.id = 1
a =
PostAction.new(
user: anonymous_user,
post: post,
post_action_type_id: PostActionType.types[:like],
)
a.created_at = 1.minute.ago
a
end
let(:non_like_post_action) do
user.id = anonymous_user.id
post.id = 1
a =
PostAction.new(
user: anonymous_user,
post: post,
post_action_type_id: PostActionType.types[:reply],
)
a.created_at = 1.minute.ago
a
end
it "any action returns false" do
expect(Guardian.new(anonymous_user).can_delete_post_action?(post_action)).to be_falsey
expect(
Guardian.new(anonymous_user).can_delete_post_action?(non_like_post_action),
).to be_falsey
end
end
end
end
describe "#can_see_deleted_posts?" do
it "returns true if the user is an admin" do
expect(Guardian.new(admin).can_see_deleted_posts?(post.topic.category)).to be_truthy
end
it "returns true if the user is a moderator of category" do
expect(Guardian.new(moderator).can_see_deleted_posts?(post.topic.category)).to be_truthy
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_see_deleted_posts?(post)).to be_falsey
SiteSetting.delete_all_posts_and_topics_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
expect(Guardian.new(trust_level_4).can_see_deleted_posts?(post)).to be_truthy
end
end
describe "#can_approve?" do
it "wont allow a non-logged in user to approve" do
expect(Guardian.new.can_approve?(user)).to be_falsey
end
it "wont allow a non-admin to approve a user" do
expect(Guardian.new(coding_horror).can_approve?(user)).to be_falsey
end
it "returns false when the user is already approved" do
user.approved = true
expect(Guardian.new(admin).can_approve?(user)).to be_falsey
end
it "returns false when the user is not active" do
user.active = false
expect(Guardian.new(admin).can_approve?(user)).to be_falsey
end
it "allows an admin to approve a user" do
expect(Guardian.new(admin).can_approve?(user)).to be_truthy
end
it "allows a moderator to approve a user" do
expect(Guardian.new(moderator).can_approve?(user)).to be_truthy
end
end
describe "#can_grant_admin?" do
it "wont allow a non logged in user to grant an admin's access" do
expect(Guardian.new.can_grant_admin?(another_admin)).to be_falsey
end
it "wont allow a regular user to revoke an admin's access" do
expect(Guardian.new(user).can_grant_admin?(another_admin)).to be_falsey
end
it "wont allow an admin to grant their own access" do
expect(Guardian.new(admin).can_grant_admin?(admin)).to be_falsey
end
it "allows an admin to grant a regular user access" do
admin.id = 1
user.id = 2
expect(Guardian.new(admin).can_grant_admin?(user)).to be_truthy
end
it "should not allow an admin to grant admin access to a non real user" do
begin
Discourse.system_user.update!(admin: false)
expect(Guardian.new(admin).can_grant_admin?(Discourse.system_user)).to be(false)
ensure
Discourse.system_user.update!(admin: true)
end
end
end
describe "#can_revoke_admin?" do
it "wont allow a non logged in user to revoke an admin's access" do
expect(Guardian.new.can_revoke_admin?(another_admin)).to be_falsey
end
it "wont allow a regular user to revoke an admin's access" do
expect(Guardian.new(user).can_revoke_admin?(another_admin)).to be_falsey
end
it "wont allow an admin to revoke their own access" do
expect(Guardian.new(admin).can_revoke_admin?(admin)).to be_falsey
end
it "allows an admin to revoke another admin's access" do
admin.id = 1
another_admin.id = 2
expect(Guardian.new(admin).can_revoke_admin?(another_admin)).to be_truthy
end
it "should not allow an admin to revoke a no real user's admin access" do
expect(Guardian.new(admin).can_revoke_admin?(Discourse.system_user)).to be(false)
end
end
describe "#can_grant_moderation?" do
it "wont allow a non logged in user to grant an moderator's access" do
expect(Guardian.new.can_grant_moderation?(user)).to be_falsey
end
it "wont allow a regular user to revoke an moderator's access" do
expect(Guardian.new(user).can_grant_moderation?(moderator)).to be_falsey
end
it "will allow an admin to grant their own moderator access" do
expect(Guardian.new(admin).can_grant_moderation?(admin)).to be_truthy
end
it "wont allow an admin to grant it to an already moderator" do
expect(Guardian.new(admin).can_grant_moderation?(moderator)).to be_falsey
end
it "allows an admin to grant a regular user access" do
expect(Guardian.new(admin).can_grant_moderation?(user)).to be_truthy
end
it "should not allow an admin to grant moderation to a non real user" do
begin
Discourse.system_user.update!(moderator: false)
expect(Guardian.new(admin).can_grant_moderation?(Discourse.system_user)).to be(false)
ensure
Discourse.system_user.update!(moderator: true)
end
end
end
describe "#can_revoke_moderation?" do
it "wont allow a non logged in user to revoke an moderator's access" do
expect(Guardian.new.can_revoke_moderation?(moderator)).to be_falsey
end
it "wont allow a regular user to revoke an moderator's access" do
expect(Guardian.new(user).can_revoke_moderation?(moderator)).to be_falsey
end
it "wont allow a moderator to revoke their own moderator" do
expect(Guardian.new(moderator).can_revoke_moderation?(moderator)).to be_falsey
end
it "allows an admin to revoke a moderator's access" do
expect(Guardian.new(admin).can_revoke_moderation?(moderator)).to be_truthy
end
it "allows an admin to revoke a moderator's access from self" do
admin.moderator = true
expect(Guardian.new(admin).can_revoke_moderation?(admin)).to be_truthy
end
it "does not allow revoke from non moderators" do
expect(Guardian.new(admin).can_revoke_moderation?(admin)).to be_falsey
end
it "should not allow an admin to revoke moderation from a non real user" do
expect(Guardian.new(admin).can_revoke_moderation?(Discourse.system_user)).to be(false)
end
end
describe "#can_see_invite_details?" do
it "is false without a logged in user" do
expect(Guardian.new(nil).can_see_invite_details?(user)).to be_falsey
end
it "is false without a user to look at" do
expect(Guardian.new(user).can_see_invite_details?(nil)).to be_falsey
end
it "is true when looking at your own invites" do
expect(Guardian.new(user).can_see_invite_details?(user)).to be_truthy
end
end
describe "#can_access_forum?" do
let(:unapproved_user) { Fabricate(:user) }
context "when must_approve_users is false" do
before { SiteSetting.must_approve_users = false }
it "returns true for a nil user" do
expect(Guardian.new(nil).can_access_forum?).to be_truthy
end
it "returns true for an unapproved user" do
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
end
context "when must_approve_users is true" do
before { SiteSetting.must_approve_users = true }
it "returns false for a nil user" do
expect(Guardian.new(nil).can_access_forum?).to be_falsey
end
it "returns false for an unapproved user" do
expect(Guardian.new(unapproved_user).can_access_forum?).to be_falsey
end
it "returns true for an admin user" do
unapproved_user.admin = true
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
it "returns true for an approved user" do
unapproved_user.approved = true
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
end
end
describe "#can_delete_all_posts?" do
it "is false without a logged in user" do
expect(Guardian.new(nil).can_delete_all_posts?(user)).to be_falsey
end
it "is false without a user to look at" do
expect(Guardian.new(admin).can_delete_all_posts?(nil)).to be_falsey
end
it "is false for regular users" do
expect(Guardian.new(user).can_delete_all_posts?(coding_horror)).to be_falsey
end
context "for moderators" do
let(:actor) { moderator }
it "is true if user has no posts" do
SiteSetting.delete_user_max_post_age = 10
expect(
Guardian.new(actor).can_delete_all_posts?(Fabricate(:user, created_at: 100.days.ago)),
).to be_truthy
end
it "is true if user's first post is newer than delete_user_max_post_age days old" do
user = Fabricate(:user, created_at: 100.days.ago)
user.user_stat.update!(first_post_created_at: 9.days.ago)
SiteSetting.delete_user_max_post_age = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_truthy
end
it "is false if user's first post is older than delete_user_max_post_age days old" do
user = Fabricate(:user, created_at: 100.days.ago)
user.user_stat.update!(first_post_created_at: 11.days.ago)
SiteSetting.delete_user_max_post_age = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_falsey
end
it "is false if user is an admin" do
expect(Guardian.new(actor).can_delete_all_posts?(admin)).to be_falsey
end
it "is true if number of posts is small" do
user = Fabricate(:user, created_at: 1.day.ago)
user.user_stat.update!(post_count: 1)
SiteSetting.delete_all_posts_max = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_truthy
end
it "is false if number of posts is not small" do
user = Fabricate(:user, created_at: 1.day.ago)
user.user_stat.update!(post_count: 11)
SiteSetting.delete_all_posts_max = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_falsey
end
end
context "for admins" do
let(:actor) { admin }
it "is true if user has no posts" do
SiteSetting.delete_user_max_post_age = 10
expect(
Guardian.new(actor).can_delete_all_posts?(Fabricate(:user, created_at: 100.days.ago)),
).to be_truthy
end
it "is true if user's first post is newer than delete_user_max_post_age days old" do
user = Fabricate(:user, created_at: 100.days.ago)
user.stubs(:first_post_created_at).returns(9.days.ago)
SiteSetting.delete_user_max_post_age = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_truthy
end
it "is true if user's first post is older than delete_user_max_post_age days old" do
user = Fabricate(:user, created_at: 100.days.ago)
user.stubs(:first_post_created_at).returns(11.days.ago)
SiteSetting.delete_user_max_post_age = 10
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_truthy
end
it "is false if user is an admin" do
expect(Guardian.new(actor).can_delete_all_posts?(admin)).to be_falsey
end
it "is true if number of posts is small" do
u = Fabricate(:user, created_at: 1.day.ago)
u.stubs(:post_count).returns(1)
SiteSetting.delete_all_posts_max = 10
expect(Guardian.new(actor).can_delete_all_posts?(u)).to be_truthy
end
it "is true if number of posts is not small" do
u = Fabricate(:user, created_at: 1.day.ago)
u.stubs(:post_count).returns(11)
SiteSetting.delete_all_posts_max = 10
expect(Guardian.new(actor).can_delete_all_posts?(u)).to be_truthy
end
end
end
describe "can_anonymize_user?" do
it "is false without a logged in user" do
expect(Guardian.new(nil).can_anonymize_user?(user)).to be_falsey
end
it "is false without a user to look at" do
expect(Guardian.new(admin).can_anonymize_user?(nil)).to be_falsey
end
it "is false for a regular user" do
expect(Guardian.new(user).can_anonymize_user?(coding_horror)).to be_falsey
end
it "is false for myself" do
expect(Guardian.new(user).can_anonymize_user?(user)).to be_falsey
end
it "is false for an anonymized user" do
expect(Guardian.new(user).can_anonymize_user?(anonymous_user)).to be_falsey
end
it "is true for a user with no email" do
bad_state_user = Fabricate.build(:user, email: nil)
bad_state_user.skip_email_validation = true
expect(Guardian.new(moderator).can_anonymize_user?(bad_state_user)).to eq(true)
end
it "is true for admin anonymizing a regular user" do
expect(Guardian.new(admin).can_anonymize_user?(user)).to eq(true)
end
it "is true for moderator anonymizing a regular user" do
expect(Guardian.new(moderator).can_anonymize_user?(user)).to eq(true)
end
it "is false for admin anonymizing an admin" do
expect(Guardian.new(admin).can_anonymize_user?(Fabricate(:admin))).to be_falsey
end
it "is false for admin anonymizing a moderator" do
expect(Guardian.new(admin).can_anonymize_user?(moderator)).to be_falsey
end
it "is false for moderator anonymizing an admin" do
expect(Guardian.new(moderator).can_anonymize_user?(admin)).to be_falsey
end
it "is false for moderator anonymizing a moderator" do
expect(Guardian.new(moderator).can_anonymize_user?(moderator)).to be_falsey
end
end
describe "can_grant_title?" do
it "is false without a logged in user" do
expect(Guardian.new(nil).can_grant_title?(user)).to be_falsey
end
it "is false for regular users" do
expect(Guardian.new(user).can_grant_title?(user)).to be_falsey
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_grant_title?(user)).to be_truthy
end
it "is true for admins" do
expect(Guardian.new(admin).can_grant_title?(user)).to be_truthy
end
it "is false without a user to look at" do
expect(Guardian.new(admin).can_grant_title?(nil)).to be_falsey
end
context "with title argument" do
fab!(:title_badge) { Fabricate(:badge, name: "Helper", allow_title: true) }
fab!(:no_title_badge) { Fabricate(:badge, name: "Writer", allow_title: false) }
fab!(:group) { Fabricate(:group, title: "Groupie") }
it "returns true if title belongs to a badge that user has" do
BadgeGranter.grant(title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(true)
end
it "returns false if title belongs to a badge that user doesn't have" do
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(false)
end
it "returns false if title belongs to a badge that user has but can't be used as a title" do
BadgeGranter.grant(no_title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, no_title_badge.name)).to eq(false)
end
it "returns true if title is from a group the user belongs to" do
group.add(user)
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(true)
end
it "returns false if title is from a group the user doesn't belong to" do
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(false)
end
it "returns true if the title is set to an empty string" do
expect(Guardian.new(user).can_grant_title?(user, "")).to eq(true)
end
end
end
describe "can_use_primary_group?" do
fab!(:group) { Fabricate(:group, title: "Groupie") }
it "is false without a logged in user" do
expect(Guardian.new(nil).can_use_primary_group?(user)).to be_falsey
end
it "is false with no group_id" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, nil)).to be_falsey
end
it "is false if the group does not exist" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, Group.last.id + 1)).to be_falsey
end
it "is false if the user is not a part of the group" do
user.update(groups: [])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it "is false if the group is automatic" do
user.update(groups: [Group.new(name: "autooo", automatic: true)])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it "is true if the user is a part of the group, and the group is custom" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_truthy
end
end
describe "can_use_flair_group?" do
fab!(:group) { Fabricate(:group, title: "Groupie", flair_icon: "icon") }
it "is false without a logged in user" do
expect(Guardian.new(nil).can_use_flair_group?(user)).to eq(false)
end
it "is false if the group does not exist" do
expect(Guardian.new(user).can_use_flair_group?(user, nil)).to eq(false)
expect(Guardian.new(user).can_use_flair_group?(user, Group.last.id + 1)).to eq(false)
end
it "is false if the user is not a part of the group" do
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(false)
end
it "is false if the group does not have a flair" do
group.update(flair_icon: nil)
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(false)
end
it "is true if the user is a part of the group and the group has a flair" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(true)
end
end
describe "#can_change_primary_group?" do
it "returns false without a logged in user" do
expect(Guardian.new(nil).can_change_primary_group?(user, group)).to eq(false)
end
it "returns false for regular users" do
expect(Guardian.new(user).can_change_primary_group?(user, group)).to eq(false)
end
it "returns true for admins" do
expect(Guardian.new(admin).can_change_primary_group?(user, group)).to eq(true)
end
context "when moderators_manage_categories_and_groups site setting is enabled" do
before { SiteSetting.moderators_manage_categories_and_groups = true }
it "returns true for moderators" do
expect(Guardian.new(moderator).can_change_primary_group?(user, group)).to eq(true)
end
end
context "when moderators_manage_categories_and_groups site setting is disabled" do
before { SiteSetting.moderators_manage_categories_and_groups = false }
it "returns false for moderators" do
expect(Guardian.new(moderator).can_change_primary_group?(user, group)).to eq(false)
end
end
end
describe "can_change_trust_level?" do
it "is false without a logged in user" do
expect(Guardian.new(nil).can_change_trust_level?(user)).to be_falsey
end
it "is false for regular users" do
expect(Guardian.new(user).can_change_trust_level?(user)).to be_falsey
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_change_trust_level?(user)).to be_truthy
end
it "is true for admins" do
expect(Guardian.new(admin).can_change_trust_level?(user)).to be_truthy
end
end
describe "can_edit_username?" do
it "is false without a logged in user" do
expect(
Guardian.new(nil).can_edit_username?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's username" do
expect(
Guardian.new(Fabricate(:user)).can_edit_username?(
Fabricate(:user, created_at: 1.minute.ago),
),
).to be_falsey
end
shared_examples "staff can always change usernames" do
it "is true for moderators" do
expect(Guardian.new(moderator).can_edit_username?(user)).to be_truthy
end
it "is true for admins" do
expect(Guardian.new(admin).can_edit_username?(user)).to be_truthy
end
it "is true for admins when changing anonymous username" do
expect(Guardian.new(admin).can_edit_username?(anonymous_user)).to be_truthy
end
end
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_username?(anonymous_user)).to be_falsey
end
end
context "for a new user" do
fab!(:target_user) { Fabricate(:user, created_at: 1.minute.ago) }
include_examples "staff can always change usernames"
it "is true for the user to change their own username" do
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_truthy
end
end
context "for an old user" do
before { SiteSetting.username_change_period = 3 }
let(:target_user) { Fabricate(:user, created_at: 4.days.ago) }
context "with no posts" do
include_examples "staff can always change usernames"
it "is false for the user to change their own username" do
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_falsey
end
end
context "with posts" do
before { target_user.stubs(:post_count).returns(1) }
include_examples "staff can always change usernames"
it "is false for the user to change their own username" do
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_falsey
end
end
end
context "when editing is disabled in preferences" do
before { SiteSetting.username_change_period = 0 }
include_examples "staff can always change usernames"
it "is false for the user to change their own username" do
expect(Guardian.new(user).can_edit_username?(user)).to be_falsey
end
end
context "when SSO username override is active" do
before do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
SiteSetting.auth_overrides_username = true
end
it "is false for admins" do
expect(Guardian.new(admin).can_edit_username?(admin)).to be_falsey
end
it "is false for moderators" do
expect(Guardian.new(moderator).can_edit_username?(moderator)).to be_falsey
end
it "is false for users" do
expect(Guardian.new(user).can_edit_username?(user)).to be_falsey
end
end
end
describe "can_edit_email?" do
context "when allowed in settings" do
before { SiteSetting.email_editable = true }
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_email?(anonymous_user)).to be_falsey
end
end
it "is false when not logged in" do
expect(
Guardian.new(nil).can_edit_email?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's email" do
expect(
Guardian.new(Fabricate(:user)).can_edit_email?(
Fabricate(:user, created_at: 1.minute.ago),
),
).to be_falsey
end
it "is true for a regular user to edit their own email" do
expect(Guardian.new(user).can_edit_email?(user)).to be_truthy
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_edit_email?(user)).to be_truthy
end
it "is true for admins" do
expect(Guardian.new(admin).can_edit_email?(user)).to be_truthy
end
end
context "when not allowed in settings" do
before { SiteSetting.email_editable = false }
it "is false when not logged in" do
expect(
Guardian.new(nil).can_edit_email?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's email" do
expect(
Guardian.new(Fabricate(:user)).can_edit_email?(
Fabricate(:user, created_at: 1.minute.ago),
),
).to be_falsey
end
it "is false for a regular user to edit their own email" do
expect(Guardian.new(user).can_edit_email?(user)).to be_falsey
end
it "is false for admins" do
expect(Guardian.new(admin).can_edit_email?(user)).to be_falsey
end
it "is false for moderators" do
expect(Guardian.new(moderator).can_edit_email?(user)).to be_falsey
end
end
context "when SSO email override is active" do
before do
SiteSetting.email_editable = false
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
SiteSetting.auth_overrides_email = true
end
it "is false for admins" do
expect(Guardian.new(admin).can_edit_email?(admin)).to be_falsey
end
it "is false for moderators" do
expect(Guardian.new(moderator).can_edit_email?(moderator)).to be_falsey
end
it "is false for users" do
expect(Guardian.new(user).can_edit_email?(user)).to be_falsey
end
end
end
describe "can_edit_name?" do
it "is false without a logged in user" do
expect(
Guardian.new(nil).can_edit_name?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's name" do
expect(
Guardian.new(Fabricate(:user)).can_edit_name?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_name?(anonymous_user)).to be_falsey
end
end
context "for a new user" do
let(:target_user) { Fabricate(:user, created_at: 1.minute.ago) }
it "is true for the user to change their own name" do
expect(Guardian.new(target_user).can_edit_name?(target_user)).to be_truthy
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_edit_name?(user)).to be_truthy
end
it "is true for admins" do
expect(Guardian.new(admin).can_edit_name?(user)).to be_truthy
end
end
context "when name is disabled in preferences" do
before { SiteSetting.enable_names = false }
it "is false for the user to change their own name" do
expect(Guardian.new(user).can_edit_name?(user)).to be_falsey
end
it "is false for moderators" do
expect(Guardian.new(moderator).can_edit_name?(user)).to be_falsey
end
it "is false for admins" do
expect(Guardian.new(admin).can_edit_name?(user)).to be_falsey
end
end
context "when name is enabled in preferences" do
before { SiteSetting.enable_names = true }
context "when SSO is disabled" do
before do
SiteSetting.enable_discourse_connect = false
SiteSetting.auth_overrides_name = false
end
it "is true for admins" do
expect(Guardian.new(admin).can_edit_name?(admin)).to be_truthy
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_truthy
end
it "is true for users" do
expect(Guardian.new(user).can_edit_name?(user)).to be_truthy
end
end
context "when SSO is enabled" do
before do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
end
context "when SSO name override is active" do
before { SiteSetting.auth_overrides_name = true }
it "is false for admins" do
expect(Guardian.new(admin).can_edit_name?(admin)).to be_falsey
end
it "is false for moderators" do
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_falsey
end
it "is false for users" do
expect(Guardian.new(user).can_edit_name?(user)).to be_falsey
end
end
context "when SSO name override is not active" do
before { SiteSetting.auth_overrides_name = false }
it "is true for admins" do
expect(Guardian.new(admin).can_edit_name?(admin)).to be_truthy
end
it "is true for moderators" do
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_truthy
end
it "is true for users" do
expect(Guardian.new(user).can_edit_name?(user)).to be_truthy
end
end
end
end
end
describe "#can_export_entity?" do
let(:anonymous_guardian) { Guardian.new }
let(:user_guardian) { Guardian.new(user) }
let(:moderator_guardian) { Guardian.new(moderator) }
let(:admin_guardian) { Guardian.new(admin) }
it "only allows admins to export user_list" do
expect(user_guardian.can_export_entity?("user_list")).to be_falsey
expect(moderator_guardian.can_export_entity?("user_list")).to be_falsey
expect(admin_guardian.can_export_entity?("user_list")).to be_truthy
end
it "allow moderators to export other admin entities" do
expect(user_guardian.can_export_entity?("staff_action")).to be_falsey
expect(moderator_guardian.can_export_entity?("staff_action")).to be_truthy
expect(admin_guardian.can_export_entity?("staff_action")).to be_truthy
end
it "does not allow anonymous to export" do
expect(anonymous_guardian.can_export_entity?("user_archive")).to be_falsey
end
end
describe "#can_ignore_user?" do
before { SiteSetting.ignore_allowed_groups = Group::AUTO_GROUPS[:trust_level_1] }
let(:guardian) { Guardian.new(trust_level_2) }
context "when ignored user is the same as guardian user" do
it "does not allow ignoring user" do
expect(guardian.can_ignore_user?(trust_level_2)).to eq(false)
end
end
context "when ignored user is a staff user" do
let!(:admin) { Fabricate(:user, admin: true) }
it "does not allow ignoring user" do
expect(guardian.can_ignore_user?(admin)).to eq(false)
end
end
context "when ignored user is a normal user" do
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
context "when ignorer is staff" do
let(:guardian) { Guardian.new(admin) }
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
context "when ignorer is not in requred trust level group" do
let(:guardian) { Guardian.new(trust_level_0) }
it "does not allow ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(false)
end
end
context "when ignorer is in the required trust level group" do
let(:guardian) { Guardian.new(trust_level_1) }
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
context "when ignorer is in a higher than required trust level group" do
let(:guardian) { Guardian.new(trust_level_3) }
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
end
describe "#can_mute_user?" do
let(:guardian) { Guardian.new(trust_level_1) }
context "when muted user is the same as guardian user" do
it "does not allow muting user" do
expect(guardian.can_mute_user?(trust_level_1)).to eq(false)
end
end
context "when muted user is a staff user" do
let!(:admin) { Fabricate(:user, admin: true) }
it "does not allow muting user" do
expect(guardian.can_mute_user?(admin)).to eq(false)
end
end
context "when muted user is a normal user" do
it "allows muting user" do
expect(guardian.can_mute_user?(another_user)).to eq(true)
end
end
context "when muter's trust level is below tl1" do
let(:guardian) { Guardian.new(trust_level_0) }
fab!(:trust_level_0)
it "does not allow muting user" do
expect(guardian.can_mute_user?(another_user)).to eq(false)
end
end
context "when muter is staff" do
let(:guardian) { Guardian.new(admin) }
it "allows muting user" do
expect(guardian.can_mute_user?(another_user)).to eq(true)
end
end
context "when muters's trust level is tl1" do
let(:guardian) { Guardian.new(trust_level_1) }
it "allows muting user" do
expect(guardian.can_mute_user?(another_user)).to eq(true)
end
end
end
describe "#allow_themes?" do
let!(:theme) { Fabricate(:theme) }
let!(:theme2) { Fabricate(:theme) }
context "when in allowlist mode" do
before do
global_setting :allowed_theme_repos, " https://magic.com/repo.git, https://x.com/git"
end
it "should respect theme allowlisting" do
r = RemoteTheme.create!(remote_url: "https://magic.com/repo.git")
theme.update!(remote_theme_id: r.id)
guardian = Guardian.new(admin)
expect(guardian.allow_themes?([theme.id, theme2.id], include_preview: true)).to eq(false)
expect(guardian.allow_themes?([theme.id], include_preview: true)).to eq(true)
expect(guardian.allowed_theme_repo_import?("https://x.com/git")).to eq(true)
expect(guardian.allowed_theme_repo_import?("https:/evil.com/git")).to eq(false)
end
end
it "allows staff to use any themes" do
expect(Guardian.new(moderator).allow_themes?([theme.id, theme2.id])).to eq(false)
expect(Guardian.new(admin).allow_themes?([theme.id, theme2.id])).to eq(false)
expect(
Guardian.new(moderator).allow_themes?([theme.id, theme2.id], include_preview: true),
).to eq(true)
expect(Guardian.new(admin).allow_themes?([theme.id, theme2.id], include_preview: true)).to eq(
true,
)
end
it "only allows normal users to use user-selectable themes or default theme" do
user_guardian = Guardian.new(user)
expect(user_guardian.allow_themes?([theme.id, theme2.id])).to eq(false)
expect(user_guardian.allow_themes?([theme.id])).to eq(false)
expect(user_guardian.allow_themes?([theme2.id])).to eq(false)
theme.set_default!
expect(user_guardian.allow_themes?([theme.id])).to eq(true)
expect(user_guardian.allow_themes?([theme2.id])).to eq(false)
expect(user_guardian.allow_themes?([theme.id, theme2.id])).to eq(false)
theme2.update!(user_selectable: true)
expect(user_guardian.allow_themes?([theme2.id])).to eq(true)
expect(user_guardian.allow_themes?([theme2.id, theme.id])).to eq(false)
end
it "allows child themes to be only used with their parent" do
user_guardian = Guardian.new(user)
theme.update!(user_selectable: true)
theme2.update!(user_selectable: true)
expect(user_guardian.allow_themes?([theme.id, theme2.id])).to eq(false)
theme2.update!(user_selectable: false, component: true)
theme.add_relative_theme!(:child, theme2)
expect(user_guardian.allow_themes?([theme.id, theme2.id])).to eq(true)
expect(user_guardian.allow_themes?([theme2.id])).to eq(false)
end
end
describe "can_wiki?" do
let(:post) { Fabricate(:post, created_at: 1.minute.ago) }
it "returns false for regular user" do
expect(Guardian.new(coding_horror).can_wiki?(post)).to be_falsey
end
it "returns false when user does not satisfy trust level but owns the post" do
own_post = Fabricate(:post, user: trust_level_2)
expect(Guardian.new(trust_level_2).can_wiki?(own_post)).to be_falsey
end
it "returns false when user satisfies trust level but tries to wiki someone else's post" do
SiteSetting.self_wiki_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
expect(Guardian.new(trust_level_2).can_wiki?(post)).to be_falsey
end
it "returns true when user satisfies trust level and owns the post" do
SiteSetting.self_wiki_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
own_post = Fabricate(:post, user: trust_level_2)
expect(Guardian.new(trust_level_2).can_wiki?(own_post)).to be_truthy
end
it "returns true for admin user" do
expect(Guardian.new(admin).can_wiki?(post)).to be_truthy
end
it "returns true for trust_level_4 user" do
expect(Guardian.new(trust_level_4).can_wiki?(post)).to be_truthy
end
context "when post is older than post_edit_time_limit" do
let(:old_post) { Fabricate(:post, user: trust_level_2, created_at: 6.minutes.ago) }
before do
SiteSetting.min_trust_to_allow_self_wiki = 2
SiteSetting.tl2_post_edit_time_limit = 5
end
it "returns false when user satisfies trust level and owns the post" do
expect(Guardian.new(trust_level_2).can_wiki?(old_post)).to be_falsey
end
it "returns true for admin user" do
expect(Guardian.new(admin).can_wiki?(old_post)).to be_truthy
end
it "returns true for trust_level_4 user" do
expect(Guardian.new(trust_level_4).can_wiki?(post)).to be_truthy
end
end
end
describe "Tags" do
context "with tagging disabled" do
before { SiteSetting.tagging_enabled = false }
it "can_create_tag returns false" do
expect(Guardian.new(admin).can_create_tag?).to be_falsey
end
it "can_admin_tags returns false" do
expect(Guardian.new(admin).can_admin_tags?).to be_falsey
end
it "can_admin_tag_groups returns false" do
expect(Guardian.new(admin).can_admin_tag_groups?).to be_falsey
end
end
context "when tagging is enabled" do
before do
SiteSetting.tagging_enabled = true
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
end
context "when minimum trust level to create tags is 3" do
before do
SiteSetting.create_tag_allowed_groups = "1|3|#{Group::AUTO_GROUPS[:trust_level_3]}"
end
describe "#can_see_tag?" do
it "is always true" do
expect(Guardian.new.can_see_tag?(anything)).to be_truthy
end
end
describe "can_create_tag" do
it "returns false if trust level is too low" do
expect(Guardian.new(trust_level_2).can_create_tag?).to be_falsey
end
it "returns true if trust level is high enough" do
expect(Guardian.new(trust_level_3).can_create_tag?).to be_truthy
end
it "returns true for staff" do
expect(Guardian.new(admin).can_create_tag?).to be_truthy
expect(Guardian.new(moderator).can_create_tag?).to be_truthy
end
end
describe "can_tag_topics" do
it "returns false if trust level is too low" do
expect(
Guardian.new(
Fabricate(:user, trust_level: 0, refresh_auto_groups: true),
).can_tag_topics?,
).to be_falsey
end
it "returns true if trust level is high enough" do
expect(
Guardian.new(
Fabricate(:user, trust_level: 1, refresh_auto_groups: true),
).can_tag_topics?,
).to be_truthy
end
it "returns true for staff" do
expect(Guardian.new(admin).can_tag_topics?).to be_truthy
expect(Guardian.new(moderator).can_tag_topics?).to be_truthy
end
end
end
context "when staff and admin groups are allowed to create tags" do
before do
SiteSetting.min_trust_to_create_tag = "staff"
SiteSetting.create_tag_allowed_groups =
"#{Group::AUTO_GROUPS[:staff]}|#{Group::AUTO_GROUPS[:admins]}"
end
it "returns false if not staff" do
expect(Guardian.new(trust_level_4).can_create_tag?).to eq(false)
end
it "returns true if staff" do
expect(Guardian.new(admin).can_create_tag?).to be_truthy
expect(Guardian.new(moderator).can_create_tag?).to be_truthy
end
end
context "when only admin group is allowed to create tags" do
before do
SiteSetting.min_trust_to_create_tag = "admin"
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:admins]
end
it "returns false if not admin" do
expect(Guardian.new(trust_level_4).can_create_tag?).to eq(false)
expect(Guardian.new(moderator).can_create_tag?).to eq(false)
end
it "returns true if admin" do
expect(Guardian.new(admin).can_create_tag?).to be_truthy
end
end
end
context "when tagging PMs" do
it "pm_tags_allowed_for_groups contains everyone" do
SiteSetting.pm_tags_allowed_for_groups = "#{Group::AUTO_GROUPS[:everyone]}"
expect(Guardian.new(user).can_tag_pms?).to be_truthy
end
it "pm_tags_allowed_for_groups contains a group" do
SiteSetting.pm_tags_allowed_for_groups = "#{group.id}"
group.add(member)
expect(Guardian.new(user).can_tag_pms?).to be_falsey
expect(Guardian.new(member).can_tag_pms?).to be_truthy
end
end
end
describe "#can_see_group?" do
it "Correctly handles owner visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:owners])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(admin).can_see_group?(group)).to eq(true)
expect(Guardian.new(another_user).can_see_group?(group)).to eq(false)
expect(Guardian.new(moderator).can_see_group?(group)).to eq(false)
expect(Guardian.new(member).can_see_group?(group)).to eq(false)
expect(Guardian.new.can_see_group?(group)).to eq(false)
expect(Guardian.new(owner).can_see_group?(group)).to eq(true)
end
it "Correctly handles staff visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:staff])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(another_user).can_see_group?(group)).to eq(false)
expect(Guardian.new(member).can_see_group?(group)).to eq(false)
expect(Guardian.new(admin).can_see_group?(group)).to eq(true)
expect(Guardian.new(moderator).can_see_group?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group?(group)).to eq(true)
expect(Guardian.new.can_see_group?(group)).to eq(false)
end
it "Correctly handles member visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:members])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(moderator).can_see_group?(group)).to eq(true)
expect(Guardian.new.can_see_group?(group)).to eq(false)
expect(Guardian.new(another_user).can_see_group?(group)).to eq(false)
expect(Guardian.new(admin).can_see_group?(group)).to eq(true)
expect(Guardian.new(member).can_see_group?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group?(group)).to eq(true)
end
it "Correctly handles logged-on-user visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:logged_on_users])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new.can_see_group?(group)).to eq(false)
expect(Guardian.new(moderator).can_see_group?(group)).to eq(true)
expect(Guardian.new(admin).can_see_group?(group)).to eq(true)
expect(Guardian.new(member).can_see_group?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group?(group)).to eq(true)
expect(Guardian.new(another_user).can_see_group?(group)).to eq(true)
end
it "Correctly handles public groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:public])
expect(Guardian.new.can_see_group?(group)).to eq(true)
end
end
describe "#can_see_group_members?" do
it "Correctly handles group members visibility for owner" do
group = Group.new(name: "group", members_visibility_level: Group.visibility_levels[:owners])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(admin).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(another_user).can_see_group_members?(group)).to eq(false)
expect(Guardian.new(moderator).can_see_group_members?(group)).to eq(false)
expect(Guardian.new(member).can_see_group_members?(group)).to eq(false)
expect(Guardian.new.can_see_group_members?(group)).to eq(false)
expect(Guardian.new(owner).can_see_group_members?(group)).to eq(true)
end
it "Correctly handles group members visibility for staff" do
group = Group.new(name: "group", members_visibility_level: Group.visibility_levels[:staff])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(another_user).can_see_group_members?(group)).to eq(false)
expect(Guardian.new(member).can_see_group_members?(group)).to eq(false)
expect(Guardian.new(admin).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(moderator).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group_members?(group)).to eq(true)
expect(Guardian.new.can_see_group_members?(group)).to eq(false)
end
it "Correctly handles group members visibility for member" do
group = Group.new(name: "group", members_visibility_level: Group.visibility_levels[:members])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(moderator).can_see_group_members?(group)).to eq(true)
expect(Guardian.new.can_see_group_members?(group)).to eq(false)
expect(Guardian.new(another_user).can_see_group_members?(group)).to eq(false)
expect(Guardian.new(admin).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(member).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group_members?(group)).to eq(true)
end
it "Correctly handles group members visibility for logged-on-user" do
group =
Group.new(
name: "group",
members_visibility_level: Group.visibility_levels[:logged_on_users],
)
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new.can_see_group_members?(group)).to eq(false)
expect(Guardian.new(moderator).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(admin).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(member).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(owner).can_see_group_members?(group)).to eq(true)
expect(Guardian.new(another_user).can_see_group_members?(group)).to eq(true)
end
it "Correctly handles group members visibility for public" do
group = Group.new(name: "group", members_visibility_level: Group.visibility_levels[:public])
expect(Guardian.new.can_see_group_members?(group)).to eq(true)
end
end
describe "#can_see_groups?" do
it "correctly handles owner visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:owners])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(admin).can_see_groups?([group])).to eq(true)
expect(Guardian.new(another_user).can_see_groups?([group])).to eq(false)
expect(Guardian.new(moderator).can_see_groups?([group])).to eq(false)
expect(Guardian.new(member).can_see_groups?([group])).to eq(false)
expect(Guardian.new.can_see_groups?([group])).to eq(false)
expect(Guardian.new(owner).can_see_groups?([group])).to eq(true)
end
it "correctly handles the case where the user does not own every group" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:owners])
group2 = Group.new(name: "group2", visibility_level: Group.visibility_levels[:owners])
group2.save!
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(admin).can_see_groups?([group, group2])).to eq(true)
expect(Guardian.new(moderator).can_see_groups?([group, group2])).to eq(false)
expect(Guardian.new(member).can_see_groups?([group, group2])).to eq(false)
expect(Guardian.new.can_see_groups?([group, group2])).to eq(false)
expect(Guardian.new(owner).can_see_groups?([group, group2])).to eq(false)
expect(Guardian.new(another_user).can_see_groups?([group, group2])).to eq(false)
end
it "correctly handles staff visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:staff])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(member).can_see_groups?([group])).to eq(false)
expect(Guardian.new(admin).can_see_groups?([group])).to eq(true)
expect(Guardian.new(moderator).can_see_groups?([group])).to eq(true)
expect(Guardian.new(owner).can_see_groups?([group])).to eq(true)
expect(Guardian.new.can_see_groups?([group])).to eq(false)
expect(Guardian.new(another_user).can_see_groups?([group])).to eq(false)
end
it "correctly handles member visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:members])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(another_user).can_see_groups?([group])).to eq(false)
expect(Guardian.new(moderator).can_see_groups?([group])).to eq(true)
expect(Guardian.new.can_see_groups?([group])).to eq(false)
expect(Guardian.new(admin).can_see_groups?([group])).to eq(true)
expect(Guardian.new(member).can_see_groups?([group])).to eq(true)
expect(Guardian.new(owner).can_see_groups?([group])).to eq(true)
end
it "correctly handles logged-on-user visible groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:logged_on_users])
group.add(member)
group.save!
group.add_owner(owner)
group.reload
expect(Guardian.new(member).can_see_groups?([group])).to eq(true)
expect(Guardian.new(admin).can_see_groups?([group])).to eq(true)
expect(Guardian.new(moderator).can_see_groups?([group])).to eq(true)
expect(Guardian.new(owner).can_see_groups?([group])).to eq(true)
expect(Guardian.new.can_see_groups?([group])).to eq(false)
expect(Guardian.new(another_user).can_see_groups?([group])).to eq(true)
end
it "correctly handles the case where the user is not a member of every group" do
group1 = Group.new(name: "group", visibility_level: Group.visibility_levels[:members])
group2 = Group.new(name: "group2", visibility_level: Group.visibility_levels[:members])
group2.save!
group1.add(member)
group1.save!
group1.add_owner(owner)
group1.reload
expect(Guardian.new(moderator).can_see_groups?([group1, group2])).to eq(true)
expect(Guardian.new.can_see_groups?([group1, group2])).to eq(false)
expect(Guardian.new(admin).can_see_groups?([group1, group2])).to eq(true)
expect(Guardian.new(member).can_see_groups?([group1, group2])).to eq(false)
expect(Guardian.new(owner).can_see_groups?([group1, group2])).to eq(false)
end
it "correctly handles public groups" do
group = Group.new(name: "group", visibility_level: Group.visibility_levels[:public])
expect(Guardian.new.can_see_groups?([group])).to eq(true)
end
it "correctly handles case where not every group is public" do
group1 = Group.new(name: "group", visibility_level: Group.visibility_levels[:public])
group2 = Group.new(name: "group", visibility_level: Group.visibility_levels[:private])
expect(Guardian.new.can_see_groups?([group1, group2])).to eq(false)
end
end
describe "topic featured link category restriction" do
before { SiteSetting.topic_featured_link_enabled = true }
let(:guardian) { Guardian.new(user) }
let(:uncategorized) { Category.find(SiteSetting.uncategorized_category_id) }
context "when uncategorized" do
fab!(:link_category)
it "allows featured links if uncategorized allows it" do
uncategorized.topic_featured_link_allowed = true
uncategorized.save!
expect(guardian.can_edit_featured_link?(nil)).to eq(true)
end
it "forbids featured links if uncategorized forbids it" do
uncategorized.topic_featured_link_allowed = false
uncategorized.save!
expect(guardian.can_edit_featured_link?(nil)).to eq(false)
end
end
context "when exist" do
fab!(:category) { Fabricate(:category, topic_featured_link_allowed: false) }
fab!(:link_category)
it "returns true if the category is listed" do
expect(guardian.can_edit_featured_link?(link_category.id)).to eq(true)
end
it "returns false if the category does not allow it" do
expect(guardian.can_edit_featured_link?(category.id)).to eq(false)
end
end
end
describe "suspension reasons" do
it "will be shown by default" do
expect(Guardian.new.can_see_suspension_reason?(user)).to eq(true)
end
context "with hide suspension reason enabled" do
before { SiteSetting.hide_suspension_reasons = true }
it "will not be shown to anonymous users" do
expect(Guardian.new.can_see_suspension_reason?(user)).to eq(false)
end
it "users can see their own suspensions" do
expect(Guardian.new(user).can_see_suspension_reason?(user)).to eq(true)
end
it "staff can see suspensions" do
expect(Guardian.new(moderator).can_see_suspension_reason?(user)).to eq(true)
end
end
end
describe "#can_remove_allowed_users?" do
context "with staff users" do
it "should be true" do
expect(Guardian.new(moderator).can_remove_allowed_users?(topic)).to eq(true)
end
end
context "with trust_level >= 2 user" do
fab!(:topic_creator) { Fabricate(:user, trust_level: 2) }
fab!(:topic) { Fabricate(:topic, user: topic_creator) }
before do
topic.allowed_users << topic_creator
topic.allowed_users << another_user
end
it "should be true" do
expect(Guardian.new(topic_creator).can_remove_allowed_users?(topic)).to eq(true)
end
end
context "with normal user" do
fab!(:topic) { Fabricate(:topic, user: Fabricate(:user, trust_level: 1)) }
before do
topic.allowed_users << user
topic.allowed_users << another_user
end
it "should be false" do
expect(Guardian.new(user).can_remove_allowed_users?(topic)).to eq(false)
end
describe "target_user is the user" do
describe "when user is in a pm with another user" do
it "should return true" do
expect(Guardian.new(user).can_remove_allowed_users?(topic, user)).to eq(true)
end
end
describe "when user is the creator of the topic" do
it "should return false" do
expect(Guardian.new(topic.user).can_remove_allowed_users?(topic, topic.user)).to eq(
false,
)
end
end
describe "when user is the only user in the topic" do
it "should return false" do
topic.remove_allowed_user(Discourse.system_user, another_user.username)
expect(Guardian.new(user).can_remove_allowed_users?(topic, user)).to eq(false)
end
end
end
describe "target_user is not the user" do
it "should return false" do
expect(Guardian.new(user).can_remove_allowed_users?(topic, moderator)).to eq(false)
end
end
end
context "with anonymous users" do
fab!(:topic)
it "should be false" do
expect(Guardian.new.can_remove_allowed_users?(topic)).to eq(false)
end
it "should be false when the topic does not have a user (for example because the user was removed)" do
DB.exec("UPDATE topics SET user_id=NULL WHERE id=#{topic.id}")
topic.reload
expect(Guardian.new.can_remove_allowed_users?(topic)).to eq(false)
end
end
end
describe "#auth_token" do
it "returns the correct auth token" do
token = UserAuthToken.generate!(user_id: user.id)
cookie =
create_auth_cookie(
token: token.unhashed_auth_token,
user_id: user.id,
trust_level: user.trust_level,
issued_at: 5.minutes.ago,
)
env = create_request_env(path: "/").merge("HTTP_COOKIE" => "_t=#{cookie};")
guardian = Guardian.new(user, ActionDispatch::Request.new(env))
expect(guardian.auth_token).to eq(token.auth_token)
end
it "supports v0 of auth cookie" do
token = UserAuthToken.generate!(user_id: user.id)
cookie = token.unhashed_auth_token
env = create_request_env(path: "/").merge("HTTP_COOKIE" => "_t=#{cookie};")
guardian = Guardian.new(user, ActionDispatch::Request.new(env))
expect(guardian.auth_token).to eq(token.auth_token)
end
end
describe "can_publish_page?" do
context "when disabled" do
it "is false for staff" do
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(false)
end
end
context "when enabled" do
before { SiteSetting.enable_page_publishing = true }
it "is false for anonymous users" do
expect(Guardian.new.can_publish_page?(topic)).to eq(false)
end
it "is false for regular users" do
expect(Guardian.new(user).can_publish_page?(topic)).to eq(false)
end
it "is true for staff" do
expect(Guardian.new(moderator).can_publish_page?(topic)).to eq(true)
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(true)
end
it "is false if the topic is a private message" do
post = Fabricate(:private_message_post, user: admin)
expect(Guardian.new(admin).can_publish_page?(post.topic)).to eq(false)
end
context "when secure_uploads is also enabled" do
before do
setup_s3
SiteSetting.secure_uploads = true
end
it "is false for everyone" do
expect(Guardian.new(moderator).can_publish_page?(topic)).to eq(false)
expect(Guardian.new(user).can_publish_page?(topic)).to eq(false)
expect(Guardian.new.can_publish_page?(topic)).to eq(false)
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(false)
end
end
end
end
describe "#can_see_site_contact_details?" do
context "when login_required is enabled" do
before { SiteSetting.login_required = true }
it "is false for anonymous users" do
expect(Guardian.new.can_see_site_contact_details?).to eq(false)
end
it "is true for regular users" do
expect(Guardian.new(user).can_see_site_contact_details?).to eq(true)
end
end
context "when login_required is disabled" do
before { SiteSetting.login_required = false }
it "is true for anonymous users" do
expect(Guardian.new.can_see_site_contact_details?).to eq(true)
end
it "is true for regular users" do
expect(Guardian.new(user).can_see_site_contact_details?).to eq(true)
end
end
end
describe "#can_mention_here?" do
it "returns false if disabled" do
SiteSetting.max_here_mentioned = 0
expect(admin.guardian.can_mention_here?).to eq(false)
end
it "returns false if disabled" do
SiteSetting.here_mention = ""
expect(admin.guardian.can_mention_here?).to eq(false)
end
it "works with trust levels" do
SiteSetting.min_trust_level_for_here_mention = 2
SiteSetting.here_mention_allowed_groups = Group::AUTO_GROUPS[:trust_level_2]
expect(trust_level_0.guardian.can_mention_here?).to eq(false)
expect(trust_level_1.guardian.can_mention_here?).to eq(false)
expect(trust_level_2.guardian.can_mention_here?).to eq(true)
expect(trust_level_3.guardian.can_mention_here?).to eq(true)
expect(trust_level_4.guardian.can_mention_here?).to eq(true)
expect(moderator.guardian.can_mention_here?).to eq(true)
expect(admin.guardian.can_mention_here?).to eq(true)
end
it "works with staff" do
SiteSetting.min_trust_level_for_here_mention = "staff"
SiteSetting.here_mention_allowed_groups = Group::AUTO_GROUPS[:staff]
expect(trust_level_4.guardian.can_mention_here?).to eq(false)
expect(moderator.guardian.can_mention_here?).to eq(true)
expect(admin.guardian.can_mention_here?).to eq(true)
end
it "works with admin" do
SiteSetting.min_trust_level_for_here_mention = "admin"
SiteSetting.here_mention_allowed_groups = Group::AUTO_GROUPS[:admins]
expect(trust_level_4.guardian.can_mention_here?).to eq(false)
expect(moderator.guardian.can_mention_here?).to eq(false)
expect(admin.guardian.can_mention_here?).to eq(true)
end
end
describe "#is_category_group_moderator" do
before { SiteSetting.enable_category_group_moderation = true }
fab!(:category)
it "should correctly detect category moderation" do
group.add(user)
category.update!(reviewable_by_group_id: group.id)
guardian = Guardian.new(user)
# implementation detail, ensure memoization is good (hence testing twice)
expect(guardian.is_category_group_moderator?(category)).to eq(true)
expect(guardian.is_category_group_moderator?(category)).to eq(true)
expect(guardian.is_category_group_moderator?(plain_category)).to eq(false)
expect(guardian.is_category_group_moderator?(plain_category)).to eq(false)
# edge case ... site setting disabled while guardian instantiated (can help with test cases)
SiteSetting.enable_category_group_moderation = false
expect(guardian.is_category_group_moderator?(category)).to eq(false)
end
end
describe "#can_delete_reviewable_queued_post" do
context "when attempting to destroy a non personal reviewable" do
it "returns true for api requests from admins" do
api_key = Fabricate(:api_key).key
queued_post = Fabricate(:reviewable_queued_post, created_by: user)
opts = {
"HTTP_API_USERNAME" => admin.username,
"HTTP_API_KEY" => api_key,
"REQUEST_METHOD" => "DELETE",
"#{Auth::DefaultCurrentUserProvider::API_KEY_ENV}" => "foo",
}
env = create_request_env(path: "/review/#{queued_post.id}.json").merge(opts)
guardian = Guardian.new(admin, ActionDispatch::Request.new(env))
expect(guardian.can_delete_reviewable_queued_post?(queued_post)).to eq(true)
end
it "returns false for admin requests not via the API" do
queued_post = Fabricate(:reviewable_queued_post, created_by: user)
env =
create_request_env(path: "/review/#{queued_post.id}.json").merge(
{ "REQUEST_METHOD" => "DELETE" },
)
guardian = Guardian.new(admin, ActionDispatch::Request.new(env))
expect(guardian.can_delete_reviewable_queued_post?(queued_post)).to eq(false)
end
it "returns false for api requests from tl4 users" do
api_key = Fabricate(:api_key).key
queued_post = Fabricate(:reviewable_queued_post, created_by: user)
opts = {
"HTTP_API_USERNAME" => trust_level_4.username,
"HTTP_API_KEY" => api_key,
"REQUEST_METHOD" => "DELETE",
"#{Auth::DefaultCurrentUserProvider::API_KEY_ENV}" => "foo",
}
env = create_request_env(path: "/review/#{queued_post.id}.json").merge(opts)
guardian = Guardian.new(trust_level_4, ActionDispatch::Request.new(env))
expect(guardian.can_delete_reviewable_queued_post?(queued_post)).to eq(false)
end
end
context "when attempting to destroy your own reviewable" do
it "returns true" do
queued_post = Fabricate(:reviewable_queued_post, target_created_by: user)
env =
create_request_env(path: "/review/#{queued_post.id}.json").merge(
{ "REQUEST_METHOD" => "DELETE" },
)
guardian = Guardian.new(user, ActionDispatch::Request.new(env))
expect(guardian.can_delete_reviewable_queued_post?(queued_post)).to eq(true)
end
end
end
end