mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 08:46:19 +08:00
94b258deda
The commitse62e93f83a
andd6bd4ad7ee
caused a regression to the behaviour added for https://meta.discourse.org/t/allow-tl0-to-write-messages-to-staff-group-not-to-other-members-or-non-staff/124335, which allowed a user to message a group with the messageable_level set to Everyone even if they were TL0 (or otherwise did not reach the appropriate trust level). This commit fixes the issue and adjusts the spec to reflect the real scenario. c.f. https://meta.discourse.org/t/tl0-cant-message-groups-with-messageable-level-everyone-recession/249205
4095 lines
143 KiB
Ruby
4095 lines
143 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe Guardian do
|
|
fab!(:user) { Fabricate(:user) }
|
|
fab!(:another_user) { Fabricate(:user) }
|
|
fab!(:member) { Fabricate(:user) }
|
|
fab!(:owner) { Fabricate(:user) }
|
|
fab!(:moderator) { Fabricate(:moderator) }
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
fab!(:anonymous_user) { Fabricate(:anonymous) }
|
|
fab!(:staff_post) { Fabricate(:post, user: moderator) }
|
|
fab!(:group) { Fabricate(:group) }
|
|
fab!(:another_group) { Fabricate(:group) }
|
|
fab!(:automatic_group) { Fabricate(:group, automatic: true) }
|
|
fab!(:plain_category) { Fabricate(:category) }
|
|
|
|
fab!(:trust_level_0) { Fabricate(:user, trust_level: 0) }
|
|
fab!(:trust_level_1) { Fabricate(:user, trust_level: 1) }
|
|
fab!(:trust_level_2) { Fabricate(:user, trust_level: 2) }
|
|
fab!(:trust_level_3) { Fabricate(:user, trust_level: 3) }
|
|
fab!(:trust_level_4) { Fabricate(:user, trust_level: 4) }
|
|
fab!(:another_admin) { Fabricate(:admin) }
|
|
fab!(:coding_horror) { Fabricate(:coding_horror) }
|
|
|
|
fab!(:topic) { Fabricate(:topic, user: user) }
|
|
fab!(:post) { Fabricate(:post, topic: topic, user: topic.user) }
|
|
|
|
before do
|
|
Group.refresh_automatic_groups!
|
|
Guardian.enable_topic_can_see_consistency_check
|
|
end
|
|
|
|
after do
|
|
Guardian.disable_topic_can_see_consistency_check
|
|
end
|
|
|
|
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 none for a user of a low trust level" do
|
|
user.trust_level = 0
|
|
SiteSetting.min_trust_to_post_links = 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.trust_level = 0
|
|
SiteSetting.min_trust_to_post_links = 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.trust_level = 0
|
|
SiteSetting.min_trust_to_post_links = 0
|
|
expect(Guardian.new(user).can_post_link?(host: host)).to eq(true)
|
|
SiteSetting.min_trust_to_post_links = 1
|
|
expect(Guardian.new(user).can_post_link?(host: host)).to eq(false)
|
|
end
|
|
|
|
describe "allowlisted host" do
|
|
before do
|
|
SiteSetting.allowed_link_domains = host
|
|
end
|
|
|
|
it "allows a new user to post the link to the host" do
|
|
user.trust_level = 0
|
|
SiteSetting.min_trust_to_post_links = 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) }
|
|
fab!(:post) { Fabricate(:post) }
|
|
|
|
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 do
|
|
SiteSetting.allow_flagging_staff = false
|
|
end
|
|
|
|
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
|
|
it "returns true for a new user liking something" do
|
|
user.trust_level = TrustLevel[0]
|
|
expect(Guardian.new(user).post_can_act?(post, :like)).to be_truthy
|
|
end
|
|
|
|
it "returns false for a new user flagging as spam" do
|
|
user.trust_level = TrustLevel[0]
|
|
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.min_trust_to_flag_posts = 0
|
|
user.trust_level = TrustLevel[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) { Fabricate(:user) }
|
|
fab!(:moderator) { Fabricate(:moderator) }
|
|
|
|
context "when enabled" do
|
|
before do
|
|
SiteSetting.enable_safe_mode = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.enable_safe_mode = false
|
|
end
|
|
|
|
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) { Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago) }
|
|
|
|
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 do
|
|
SiteSetting.personal_message_enabled_groups = group.id
|
|
end
|
|
|
|
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 = [: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 do
|
|
another_user.user_option.update!(allow_private_messages: false)
|
|
end
|
|
|
|
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) { Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago) }
|
|
|
|
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 do
|
|
SiteSetting.personal_message_enabled_groups = group.id
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.personal_message_enabled_groups = group.id
|
|
end
|
|
|
|
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) { Fabricate(: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 '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) { Fabricate(:user) }
|
|
fab!(:moderator) { Fabricate(:moderator) }
|
|
|
|
it 'returns true if user has sufficient trust level' do
|
|
SiteSetting.min_trust_level_to_allow_invite = 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.min_trust_level_to_allow_invite = 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.update!(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.min_trust_level_to_allow_invite = 2
|
|
user.update!(trust_level: SiteSetting.min_trust_level_to_allow_invite)
|
|
end
|
|
fab!(:category) { Fabricate(:category, read_restricted: true) }
|
|
fab!(:topic) { Fabricate(: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: SiteSetting.min_trust_level_to_allow_invite)
|
|
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: SiteSetting.min_trust_level_to_allow_invite)
|
|
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) { Fabricate(:user) }
|
|
fab!(:pm) { Fabricate(:private_message_topic, user: user) }
|
|
|
|
before do
|
|
user.change_trust_level!(SiteSetting.min_trust_level_to_allow_invite)
|
|
moderator.change_trust_level!(SiteSetting.min_trust_level_to_allow_invite)
|
|
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 do
|
|
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:staff]
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.max_allowed_message_recipients = 2
|
|
end
|
|
|
|
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?' do
|
|
|
|
it 'returns false with a nil object' do
|
|
expect(Guardian.new.can_see?(nil)).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) { Fabricate(: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) { Fabricate(: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
|
|
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.min_trust_to_create_topic = 1
|
|
expect(Guardian.new(Fabricate(:user, trust_level: 1)).can_create?(Topic, plain_category)).to be_truthy
|
|
expect(Guardian.new(Fabricate(:user, trust_level: 2)).can_create?(Topic, plain_category)).to be_truthy
|
|
expect(Guardian.new(Fabricate(:admin, trust_level: 0)).can_create?(Topic, plain_category)).to be_truthy
|
|
expect(Guardian.new(Fabricate(:moderator, trust_level: 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 do
|
|
topic.closed = true
|
|
end
|
|
|
|
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 do
|
|
topic.archived = true
|
|
end
|
|
|
|
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 do
|
|
topic.trash!(admin)
|
|
end
|
|
|
|
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) {
|
|
Fabricate(
|
|
:topic,
|
|
archetype: Archetype.private_message,
|
|
subtype: 'system_message',
|
|
category_id: nil
|
|
)
|
|
}
|
|
|
|
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) { Fabricate(:topic, archetype: Archetype.private_message, category_id: nil) }
|
|
|
|
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) do
|
|
Guardian.new(user)
|
|
end
|
|
|
|
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
|
|
|
|
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) { Fabricate(: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
|
|
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 as a TL4 user if trusted_users_can_edit_others is false' do
|
|
SiteSetting.trusted_users_can_edit_others = false
|
|
expect(Guardian.new(trust_level_4).can_edit?(post)).to eq(false)
|
|
end
|
|
|
|
it 'returns false when trying to edit a topic with no trust' do
|
|
SiteSetting.min_trust_to_edit_post = 2
|
|
post.user.trust_level = 1
|
|
|
|
expect(Guardian.new(topic.user).can_edit?(topic)).to be_falsey
|
|
end
|
|
|
|
it 'returns false when trying to edit a post with no trust' do
|
|
SiteSetting.min_trust_to_edit_post = 2
|
|
post.user.trust_level = 1
|
|
|
|
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
|
|
end
|
|
|
|
it 'returns true when trying to edit a post with trust' do
|
|
SiteSetting.min_trust_to_edit_post = 1
|
|
post.user.trust_level = 1
|
|
|
|
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
|
|
end
|
|
|
|
it 'returns false when another user has too low trust level to edit wiki post' do
|
|
SiteSetting.min_trust_to_edit_wiki_post = 2
|
|
post.wiki = true
|
|
coding_horror.trust_level = 1
|
|
|
|
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
|
|
end
|
|
|
|
it 'returns true when another user has adequate trust level to edit wiki post' do
|
|
SiteSetting.min_trust_to_edit_wiki_post = 2
|
|
post.wiki = true
|
|
coding_horror.trust_level = 2
|
|
|
|
expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy
|
|
end
|
|
|
|
it 'returns true for post author even when he has too low trust level to edit wiki post' do
|
|
SiteSetting.min_trust_to_edit_wiki_post = 2
|
|
post.wiki = true
|
|
post.user.trust_level = 1
|
|
|
|
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
|
|
end
|
|
|
|
context "with shared drafts" do
|
|
fab!(:category) { Fabricate(: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_min_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(:topic) { Fabricate(:topic) }
|
|
let(:old_post) { Fabricate(:post, topic: topic, user: topic.user, created_at: 6.minutes.ago) }
|
|
|
|
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) { Fabricate(:post, topic: topic, user: topic.user, created_at: 12.minutes.ago) }
|
|
|
|
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) { Fabricate(:post, topic: topic, user: topic.user, hidden: true, hidden_at: Time.zone.now) }
|
|
|
|
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 'is false at TL3, if `trusted_users_can_edit_others` is false' do
|
|
SiteSetting.trusted_users_can_edit_others = false
|
|
expect(Guardian.new(trust_level_3).can_edit?(topic)).to eq(false)
|
|
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 'is false at TL4, if `trusted_users_can_edit_others` is false' do
|
|
SiteSetting.trusted_users_can_edit_others = false
|
|
expect(Guardian.new(trust_level_4).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
|
|
expect(Guardian.new(user).can_create_topic?(topic)).to eq(false)
|
|
end
|
|
|
|
it 'returns true for user with sufficient trust level' do
|
|
SiteSetting.min_trust_to_create_topic = 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 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) { Fabricate(:group_user) }
|
|
|
|
before do
|
|
SiteSetting.enable_category_group_moderation = true
|
|
end
|
|
|
|
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 do
|
|
post.post_number = 2
|
|
end
|
|
|
|
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 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 do
|
|
post.topic.archived = true
|
|
end
|
|
|
|
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) {
|
|
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
|
|
}
|
|
|
|
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_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 do
|
|
SiteSetting.must_approve_users = false
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.must_approve_users = true
|
|
end
|
|
|
|
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 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 do
|
|
SiteSetting.moderators_manage_categories_and_groups = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.moderators_manage_categories_and_groups = false
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.allow_anonymous_posting = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.username_change_period = 3
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.username_change_period = 0
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.email_editable = true
|
|
end
|
|
|
|
context "for anonymous user" do
|
|
before do
|
|
SiteSetting.allow_anonymous_posting = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.email_editable = false
|
|
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 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 do
|
|
SiteSetting.allow_anonymous_posting = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.enable_names = false
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.enable_names = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.auth_overrides_name = true
|
|
end
|
|
|
|
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 do
|
|
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
|
|
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 do
|
|
SiteSetting.min_trust_level_to_allow_ignore = 1
|
|
end
|
|
|
|
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's trust level is below min_trust_level_to_allow_ignore" 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's trust level is equal to min_trust_level_to_allow_ignore site setting" 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's trust level is above min_trust_level_to_allow_ignore site setting" 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) }
|
|
let!(:trust_level_0) { Fabricate(:user, 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.min_trust_to_allow_self_wiki = 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.min_trust_to_allow_self_wiki = 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 do
|
|
SiteSetting.tagging_enabled = false
|
|
end
|
|
|
|
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.min_trust_level_to_tag_topics = 1
|
|
end
|
|
|
|
context 'when min_trust_to_create_tag is 3' do
|
|
before do
|
|
SiteSetting.min_trust_to_create_tag = 3
|
|
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)).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)).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 min_trust_to_create_tag is "staff"' do
|
|
before do
|
|
SiteSetting.min_trust_to_create_tag = 'staff'
|
|
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 min_trust_to_create_tag is "admin"' do
|
|
before do
|
|
SiteSetting.min_trust_to_create_tag = 'admin'
|
|
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) { Fabricate(: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) { Fabricate(: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 do
|
|
SiteSetting.hide_suspension_reasons = true
|
|
end
|
|
|
|
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) { Fabricate(: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 do
|
|
SiteSetting.enable_page_publishing = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.login_required = true
|
|
end
|
|
|
|
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 do
|
|
SiteSetting.login_required = false
|
|
end
|
|
|
|
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
|
|
|
|
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'
|
|
|
|
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'
|
|
|
|
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 do
|
|
SiteSetting.enable_category_group_moderation = true
|
|
end
|
|
|
|
fab!(:category) { Fabricate(: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 instansiated (can help with test cases)
|
|
SiteSetting.enable_category_group_moderation = false
|
|
expect(guardian.is_category_group_moderator?(category)).to eq(false)
|
|
end
|
|
end
|
|
end
|