discourse/spec/lib/guardian_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

4198 lines
148 KiB
Ruby
Raw Normal View History

# 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) }
2019-05-06 21:11:28 +08:00
fab!(:group) { Fabricate(:group) }
fab!(:another_group) { Fabricate(:group) }
fab!(:automatic_group) { Fabricate(:group, automatic: true) }
2019-05-07 16:37:42 +08:00
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) }
2013-02-06 03:16:51 +08:00
fab!(:topic) { Fabricate(:topic, user: user) }
fab!(:post) { Fabricate(:post, topic: topic, user: topic.user) }
2013-02-06 03:16:51 +08:00
before do
Group.refresh_automatic_groups!
Guardian.enable_topic_can_see_consistency_check
end
after { Guardian.disable_topic_can_see_consistency_check }
2013-02-06 03:16:51 +08:00
it "can be created without a user (not logged in)" do
2015-01-10 00:34:37 +08:00
expect { Guardian.new }.not_to raise_error
2013-02-06 03:16:51 +08:00
end
it "can be instantiated with a user instance" do
2015-01-10 00:34:37 +08:00
expect { Guardian.new(user) }.not_to raise_error
2013-02-06 03:16:51 +08:00
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 { SiteSetting.allowed_link_domains = host }
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) }
2013-02-06 03:16:51 +08:00
it "returns false when the user is nil" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).post_can_act?(post, :like)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when the post is nil" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(nil, :like)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when the topic is archived" do
post.topic.archived = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :like)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when the post is deleted" do
post.deleted_at = Time.now
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_truthy
end
it "does not allow flagging of hidden posts" do
post.hidden = true
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_falsey
end
it "allows flagging of staff posts when allow_flagging_staff is true" do
SiteSetting.allow_flagging_staff = true
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to be_truthy
end
describe "when allow_flagging_staff is false" do
before { SiteSetting.allow_flagging_staff = false }
it "doesn't allow flagging of staff posts" do
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to eq(false)
end
it "allows flagging of staff posts when staff has been deleted" do
staff_post.user.destroy!
staff_post.reload
expect(Guardian.new(user).post_can_act?(staff_post, :spam)).to eq(true)
end
it "allows liking of staff" do
expect(Guardian.new(user).post_can_act?(staff_post, :like)).to eq(true)
end
end
2013-02-06 03:16:51 +08:00
it "returns false when liking yourself" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(post.user).post_can_act?(post, :like)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
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
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
describe "trust levels" do
it "returns true for a new user liking something" do
user.trust_level = TrustLevel[0]
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :like)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns false for a new user flagging as spam" do
user.trust_level = TrustLevel[0]
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2015-01-08 23:06:43 +08:00
it "returns true for a new user flagging a private message as spam" do
post = Fabricate(:private_message_post, user: admin)
2015-01-08 23:06:43 +08:00
user.trust_level = TrustLevel[0]
post.topic.allowed_users << user
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :spam)).to be_truthy
2015-01-08 23:06:43 +08:00
end
2013-02-06 03:16:51 +08:00
it "returns false for a new user flagging something as off topic" do
user.trust_level = TrustLevel[0]
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :off_topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false for a new user flagging with notify_user" do
user.trust_level = TrustLevel[0]
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :notify_user)).to be_falsey # because new users can't send private messages
end
2013-02-06 03:16:51 +08:00
end
end
describe "can_enable_safe_mode" do
fab!(:user) { Fabricate(:user) }
fab!(:moderator) { Fabricate(:moderator) }
context "when enabled" do
before { SiteSetting.enable_safe_mode = true }
it "can be performed" do
expect(Guardian.new.can_enable_safe_mode?).to eq(true)
expect(Guardian.new(user).can_enable_safe_mode?).to eq(true)
expect(Guardian.new(moderator).can_enable_safe_mode?).to eq(true)
end
end
context "when disabled" do
before { SiteSetting.enable_safe_mode = false }
it "can be performed" do
expect(Guardian.new.can_enable_safe_mode?).to eq(false)
expect(Guardian.new(user).can_enable_safe_mode?).to eq(false)
expect(Guardian.new(moderator).can_enable_safe_mode?).to eq(true)
end
end
end
2013-02-06 03:16:51 +08:00
describe "can_send_private_message" do
fab!(:suspended_user) do
Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago)
end
2013-02-06 03:16:51 +08:00
it "returns false when the user is nil" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_send_private_message?(user)).to be_falsey
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
it "returns false when the target user is nil" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_send_private_message?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
end
it "returns true to another user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "disallows pms to other users if trust level is not met" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: TrustLevel[1])
Group.user_trust_level_change!(user.id, TrustLevel[1])
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey
end
context "when personal_message_enabled_groups does not contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns false if user is not staff member" do
expect(Guardian.new(trust_level_4).can_send_private_message?(another_user)).to be_falsey
GroupUser.create(user: trust_level_4, group: group)
trust_level_4.reload
expect(Guardian.new(trust_level_4).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for staff member" do
expect(Guardian.new(moderator).can_send_private_message?(another_user)).to be_truthy
expect(Guardian.new(admin).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for bot user" do
expect(Guardian.new(Fabricate(:bot)).can_send_private_message?(another_user)).to be_truthy
end
it "returns true for system user" do
expect(
Guardian.new(Discourse.system_user).can_send_private_message?(another_user),
).to be_truthy
end
end
context "when target user is suspended" do
it "returns true for staff" do
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_send_private_message?(suspended_user)).to be_falsey
end
end
context "when author is silenced" do
before do
user.silenced_till = 1.year.from_now
user.save
end
it "returns true if target is staff" do
expect(Guardian.new(user).can_send_private_message?(admin)).to be_truthy
expect(Guardian.new(user).can_send_private_message?(moderator)).to be_truthy
end
it "returns false if target is not staff" do
expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey
end
it "returns true if target is a staff group" do
Group::STAFF_GROUPS.each do |name|
g = Group[name]
g.update!(messageable_level: Group::ALIAS_LEVELS[:everyone])
expect(Guardian.new(user).can_send_private_message?(g)).to be_truthy
end
end
end
it "respects the group's messageable_level" do
Group::ALIAS_LEVELS.each do |level, _|
group.update!(messageable_level: Group::ALIAS_LEVELS[level])
user_output = level == :everyone ? true : false
admin_output = level != :nobody
mod_output = %i[nobody only_admins].exclude?(level)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(user_output)
expect(Guardian.new(admin).can_send_private_message?(group)).to eq(admin_output)
expect(Guardian.new(moderator).can_send_private_message?(group)).to eq(mod_output)
end
end
it "allows TL0 to message group with messageable_level = everyone regardless of personal_message_enabled_groups" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:everyone])
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_1]
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(true)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
end
it "respects the group members messageable_level" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:members_mods_and_admins])
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_0]
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(false)
# user must have both a group from personal_message_enabled_groups to send messages in general,
# and be a member of this group to send the message to this group for this messageable_level
group.add(trust_level_0)
expect(Guardian.new(trust_level_0).can_send_private_message?(group)).to eq(true)
end
it "respects the group owners messageable_level" do
group.update!(messageable_level: Group::ALIAS_LEVELS[:owners_mods_and_admins])
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(false)
group.add_owner(user)
expect(Guardian.new(user).can_send_private_message?(group)).to eq(true)
end
context "when target user has private message disabled" do
before { another_user.user_option.update!(allow_private_messages: false) }
context "for a normal user" do
it "should return false" do
expect(Guardian.new(user).can_send_private_message?(another_user)).to eq(false)
end
end
context "for a staff user" do
it "should return true" do
[admin, moderator].each do |staff_user|
expect(Guardian.new(staff_user).can_send_private_message?(another_user)).to eq(true)
end
end
end
end
2013-02-06 03:16:51 +08:00
end
describe "can_send_private_messages" do
fab!(:suspended_user) do
Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago)
end
it "returns false when the user is nil" do
expect(Guardian.new(nil).can_send_private_messages?).to be_falsey
end
it "disallows pms to other users if the user is not in the automated trust level used for personal_message_enabled_groups" do
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_2]
user.update!(trust_level: TrustLevel[1])
Group.user_trust_level_change!(user.id, TrustLevel[1])
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_falsey
user.update!(trust_level: TrustLevel[2])
Group.user_trust_level_change!(user.id, TrustLevel[2])
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
context "when personal_message_enabled_groups does contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns true" do
expect(Guardian.new(user).can_send_private_messages?).to be_falsey
GroupUser.create(user: user, group: group)
user.reload
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
end
context "when personal_message_enabled_groups does not contain the user" do
let(:group) { Fabricate(:group) }
before { SiteSetting.personal_message_enabled_groups = group.id }
it "returns false if user is not staff member" do
expect(Guardian.new(trust_level_4).can_send_private_messages?).to be_falsey
GroupUser.create(user: trust_level_4, group: group)
trust_level_4.reload
expect(Guardian.new(trust_level_4).can_send_private_messages?).to be_truthy
end
it "returns true for staff member" do
expect(Guardian.new(moderator).can_send_private_messages?).to be_truthy
expect(Guardian.new(admin).can_send_private_messages?).to be_truthy
end
it "returns true for bot user" do
expect(Guardian.new(Fabricate(:bot)).can_send_private_messages?).to be_truthy
end
it "returns true for system user" do
expect(Guardian.new(Discourse.system_user).can_send_private_messages?).to be_truthy
end
end
context "when author is silenced" do
before do
user.silenced_till = 1.year.from_now
user.save
end
it "returns true, since there is no target user, we do that check separately" do
expect(Guardian.new(user).can_send_private_messages?).to be_truthy
end
end
end
2013-02-06 03:16:51 +08:00
describe "can_reply_as_new_topic" do
fab!(:topic) { Fabricate(:topic) }
fab!(:private_message) { Fabricate(:private_message_topic) }
2013-02-06 03:16:51 +08:00
it "returns false for a non logged in user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_reply_as_new_topic?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false for a nil topic" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_reply_as_new_topic?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false for an untrusted user" do
user.trust_level = TrustLevel[0]
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_reply_as_new_topic?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true for a trusted user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_reply_as_new_topic?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true for a private message" do
expect(Guardian.new(user).can_reply_as_new_topic?(private_message)).to be_truthy
end
2013-02-06 03:16:51 +08:00
end
describe "can_see_post_actors?" do
let(:topic) { Fabricate(:topic, user: coding_horror) }
it "displays visibility correctly" do
guardian = Guardian.new(user)
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
end
end
describe "can_impersonate?" do
it "disallows impersonation when disabled globally" do
global_setting :allow_impersonation, false
expect(Guardian.new(admin).can_impersonate?(moderator)).to be_falsey
end
it "allows impersonation correctly" do
2015-01-10 00:34:37 +08:00
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])
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_impersonate?(another_admin)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
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
2019-05-07 16:51:32 +08:00
Fabricate(:private_category, group: automatic_group, read_restricted: true)
end
2019-05-07 16:51:32 +08:00
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 { SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:staff] }
it "doesn't allow a regular user to invite" do
expect(Guardian.new(admin).can_invite_to?(pm)).to be_truthy
expect(Guardian.new(user).can_invite_to?(pm)).to be_falsey
end
end
context "when PM has reached the maximum number of recipients" do
before { SiteSetting.max_allowed_message_recipients = 2 }
it "doesn't allow a regular user to invite" do
expect(Guardian.new(user).can_invite_to?(pm)).to be_falsey
end
it "allows staff to invite" do
expect(Guardian.new(admin).can_invite_to?(pm)).to be_truthy
pm.grant_permission_to_user(moderator.email)
expect(Guardian.new(moderator).can_invite_to?(pm)).to be_truthy
end
end
end
2013-02-06 03:16:51 +08:00
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
FEATURE: Allow using invites when DiscourseConnect SSO is enabled (#12419) This PR allows invitations to be used when the DiscourseConnect SSO is enabled for a site (`enable_discourse_connect`) and local logins are disabled. Previously invites could not be accepted with SSO enabled simply because we did not have the code paths to handle that logic. The invitation methods that are supported include: * Inviting people to groups via email address * Inviting people to topics via email address * Using invitation links generated by the Invite Users UI in the /my/invited/pending route The flow works like this: 1. User visits an invite URL 2. The normal invitation validations (redemptions/expiry) happen at that point 3. We store the invite key in a secure session 4. The user clicks "Accept Invitation and Continue" (see below) 5. The user is redirected to /session/sso then to the SSO provider URL then back to /session/sso_login 6. We retrieve the invite based on the invite key in secure session. We revalidate the invitation. We show an error to the user if it is not valid. An additional check here for invites with an email specified is to check the SSO email matches the invite email 7. If the invite is OK we create the user via the normal SSO methods 8. We redeem the invite and activate the user. We clear the invite key in secure session. 9. If the invite had a topic we redirect the user there, otherwise we redirect to / Note that we decided for SSO-based invites the `must_approve_users` site setting is ignored, because the invite is a form of pre-approval, and because regular non-staff users cannot send out email invites or generally invite to the forum in this case. Also deletes some group invite checks as per https://github.com/discourse/discourse/pull/12353
2021-03-19 08:20:10 +08:00
it "returns true for all users when sso is enabled" do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
FEATURE: Allow using invites when DiscourseConnect SSO is enabled (#12419) This PR allows invitations to be used when the DiscourseConnect SSO is enabled for a site (`enable_discourse_connect`) and local logins are disabled. Previously invites could not be accepted with SSO enabled simply because we did not have the code paths to handle that logic. The invitation methods that are supported include: * Inviting people to groups via email address * Inviting people to topics via email address * Using invitation links generated by the Invite Users UI in the /my/invited/pending route The flow works like this: 1. User visits an invite URL 2. The normal invitation validations (redemptions/expiry) happen at that point 3. We store the invite key in a secure session 4. The user clicks "Accept Invitation and Continue" (see below) 5. The user is redirected to /session/sso then to the SSO provider URL then back to /session/sso_login 6. We retrieve the invite based on the invite key in secure session. We revalidate the invitation. We show an error to the user if it is not valid. An additional check here for invites with an email specified is to check the SSO email matches the invite email 7. If the invite is OK we create the user via the normal SSO methods 8. We redeem the invite and activate the user. We clear the invite key in secure session. 9. If the invite had a topic we redirect the user there, otherwise we redirect to / Note that we decided for SSO-based invites the `must_approve_users` site setting is ignored, because the invite is a form of pre-approval, and because regular non-staff users cannot send out email invites or generally invite to the forum in this case. Also deletes some group invite checks as per https://github.com/discourse/discourse/pull/12353
2021-03-19 08:20:10 +08:00
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_truthy
end
it "returns false for all users when local logins are disabled" do
SiteSetting.enable_local_logins = false
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_falsey
end
it "returns correct values when user approval is required" do
SiteSetting.must_approve_users = true
expect(Guardian.new(trust_level_2).can_invite_via_email?(topic)).to be_falsey
expect(Guardian.new(moderator).can_invite_via_email?(topic)).to be_truthy
expect(Guardian.new(admin).can_invite_via_email?(topic)).to be_truthy
end
end
describe "can_see_deleted_post?" do
fab!(:post) { Fabricate(:post) }
before { post.trash!(user) }
it "returns false for post that is not deleted" do
post.recover!
expect(Guardian.new(admin).can_see_deleted_post?(post)).to be_falsey
end
it "returns false for anon" do
expect(Guardian.new.can_see_deleted_post?(post)).to be_falsey
end
it "returns true for admin" do
expect(Guardian.new(admin).can_see_deleted_post?(post)).to be_truthy
end
it "returns true for mods" do
expect(Guardian.new(moderator).can_see_deleted_post?(post)).to be_truthy
end
it "returns false for < TL4 users" do
user.update!(trust_level: TrustLevel[1])
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_falsey
end
it "returns false if not ther person who deleted it" do
post.update!(deleted_by: another_user)
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_falsey
end
it "returns true for TL4 users' own posts" do
user.update!(trust_level: TrustLevel[4])
expect(Guardian.new(user).can_see_deleted_post?(post)).to be_truthy
end
end
describe "can_receive_post_notifications?" do
it "returns false with a nil object" do
expect(Guardian.new.can_receive_post_notifications?(nil)).to be_falsey
expect(Guardian.new(user).can_receive_post_notifications?(nil)).to be_falsey
end
it "does not allow anonymous to be notified" do
expect(Guardian.new.can_receive_post_notifications?(post)).to be_falsey
end
it "allows public categories" do
expect(Guardian.new(trust_level_0).can_receive_post_notifications?(post)).to be_truthy
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
end
it "diallows secure categories with no access" do
secure_category = Fabricate(:category, read_restricted: true)
post.topic.update!(category_id: secure_category.id)
expect(Guardian.new(trust_level_0).can_receive_post_notifications?(post)).to be_falsey
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
SiteSetting.suppress_secured_categories_from_admin = true
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_falsey
secure_category.set_permissions(group => :write)
secure_category.save!
group.add(admin)
group.save!
expect(Guardian.new(admin).can_receive_post_notifications?(post)).to be_truthy
end
end
2013-02-06 03:16:51 +08:00
describe "can_see?" do
it "returns false with a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_see?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when no visibility method is defined for the object" do
unguarded_object = 42
expect(Guardian.new.can_see?(unguarded_object)).to be_falsey
end
describe "a Category" do
it "allows public categories" do
public_category = Fabricate(:category, read_restricted: false)
expect(Guardian.new.can_see?(public_category)).to be_truthy
end
it "correctly handles secure categories" do
normal_user = Fabricate(:user)
staged_user = Fabricate(:user, staged: true)
admin_user = Fabricate(:user, admin: true)
secure_category = Fabricate(:category, read_restricted: true)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category = Fabricate(:category, read_restricted: true, email_in: "foo@bar.com")
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category =
Fabricate(:category, read_restricted: true, email_in_allow_strangers: true)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
secure_category =
Fabricate(
:category,
read_restricted: true,
email_in: "foo2@bar.com",
email_in_allow_strangers: true,
)
expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey
expect(Guardian.new(staged_user).can_see?(secure_category)).to be_truthy
expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy
end
it "allows members of an authorized group" do
2019-05-07 16:37:42 +08:00
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
2013-02-06 03:16:51 +08:00
describe "a Topic" do
it "allows non logged in users to view topics" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_see?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "correctly handles groups" do
category = Fabricate(:category, read_restricted: true)
category.set_permissions(group => :full)
category.save
topic = Fabricate(:topic, category: category)
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see?(topic)).to be_falsey
group.add(user)
group.save
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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)
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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)
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see?(post)).to be_truthy
2013-07-10 03:20:18 +08:00
post.trash!(another_admin)
post.reload
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see?(post)).to be_falsey
expect(Guardian.new(admin).can_see?(post)).to be_truthy
post.recover!
post.reload
2013-07-10 03:20:18 +08:00
topic.trash!(another_admin)
topic.reload
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see?(post)).to be_falsey
expect(Guardian.new(admin).can_see?(post)).to be_truthy
end
2015-09-11 04:01:23 +08:00
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
2015-09-11 04:01:23 +08:00
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])
2015-09-11 04:01:23 +08:00
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)
2015-09-11 04:01:23 +08:00
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)
2015-09-11 04:01:23 +08:00
expect(regular_guardian.can_see?(regular_whisper)).to eq(true)
mod_guardian = Guardian.new(Fabricate(:moderator))
2015-09-11 04:01:23 +08:00
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))
2015-09-11 04:01:23 +08:00
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)
2015-09-11 04:01:23 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_see?(nil)).to be_falsey
end
it "is true if not logged in" do
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
end
end
describe "can_create?" do
describe "a Category" do
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_create?(Category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when a regular user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_create?(Category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_create?(Category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_create?(Category)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
describe "a Topic" do
it "does not allow moderators to create topics in readonly categories" do
2019-05-07 16:37:42 +08:00
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
2019-05-07 16:37:42 +08:00
category = plain_category
category.set_permissions(everyone: :create_post)
category.save
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_create?(Topic, category)).to be_falsey
end
it "is true for new users by default" do
2019-05-07 16:37:42 +08:00
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),
2015-01-10 00:34:37 +08:00
).to be_truthy
end
end
2013-02-06 03:16:51 +08:00
describe "a Post" do
it "is false on readonly categories" do
2019-05-07 16:37:42 +08:00
category = plain_category
topic.category = category
category.set_permissions(everyone: :readonly)
category.save
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_falsey
end
2013-02-06 03:16:51 +08:00
it "is false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_create?(Post, topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "is true for a regular user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "is false when you can't see the topic" do
Guardian.any_instance.expects(:can_see?).with(topic).returns(false)
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
context "with closed topic" do
2013-02-06 03:16:51 +08:00
before { topic.closed = true }
it "doesn't allow new posts from regular users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "allows editing of posts" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_edit?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "allows new posts from moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "allows new posts from admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_create?(Post, topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
2014-09-05 14:52:40 +08:00
it "allows new posts from trust_level_4s" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(trust_level_4).can_create?(Post, topic)).to be_truthy
end
2013-02-06 03:16:51 +08:00
end
context "with archived topic" do
2013-02-06 03:16:51 +08:00
before { topic.archived = true }
context "with regular users" do
2013-02-06 03:16:51 +08:00
it "doesn't allow new posts from regular users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_create?(Post, topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "does not allow editing of posts" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
end
2013-02-26 00:42:20 +08:00
2013-02-06 03:16:51 +08:00
it "allows new posts from moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "allows new posts from admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_create?(Post, topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
context "with trashed topic" do
before { topic.trash!(admin) }
it "doesn't allow new posts from regular users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_create?(Post, topic)).to be_falsey
end
it "doesn't allow new posts from moderators users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_create?(Post, topic)).to be_falsey
end
it "doesn't allow new posts from admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_create?(Post, topic)).to be_falsey
end
end
context "with system message" do
fab!(:private_message) do
Fabricate(
:topic,
archetype: Archetype.private_message,
subtype: "system_message",
category_id: nil,
)
end
before { user.save! }
it "allows the user to reply to system messages" do
expect(Guardian.new(user).can_create_post?(private_message)).to eq(true)
SiteSetting.enable_system_message_replies = false
expect(Guardian.new(user).can_create_post?(private_message)).to eq(false)
end
end
context "with private message" do
fab!(:private_message) do
Fabricate(:topic, archetype: Archetype.private_message, category_id: nil)
end
before { user.save! }
it "allows new posts by people included in the pm" do
private_message.topic_allowed_users.create!(user_id: user.id)
expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy
end
it "doesn't allow new posts by people not invited to the pm" do
expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey
end
2017-11-11 01:18:08 +08:00
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
2017-11-11 01:18:08 +08:00
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
2013-02-06 03:16:51 +08:00
end
describe "post_can_act?" do
it "isn't allowed on nil" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(nil, nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
describe "a Post" do
2013-02-26 00:42:20 +08:00
let (:guardian) do
2013-02-06 03:16:51 +08:00
Guardian.new(user)
end
it "isn't allowed when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).post_can_act?(post, :vote)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "is allowed as a regular user" do
2015-01-10 00:34:37 +08:00
expect(guardian.post_can_act?(post, :vote)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "isn't allowed on archived topics" do
topic.archived = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).post_can_act?(post, :like)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_recover_topic?(topic)).to be_falsey
end
it "returns false for a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_recover_topic?(nil)).to be_falsey
end
it "returns false for a regular user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_recover_topic?(topic)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
PostDestroyer.new(moderator, topic.first_post).destroy
expect(Guardian.new(trust_level_4).can_recover_topic?(topic)).to be_falsey
SiteSetting.tl4_delete_posts_and_topics = true
expect(Guardian.new(trust_level_4).can_recover_topic?(topic.reload)).to be_truthy
end
context "as a moderator" do
describe "when post has been deleted" do
it "should return the right value" do
expect(Guardian.new(moderator).can_recover_topic?(topic)).to be_falsey
PostDestroyer.new(moderator, topic.first_post).destroy
expect(Guardian.new(moderator).can_recover_topic?(topic.reload)).to be_truthy
end
end
describe "when post's user has been deleted" do
it "should return the right value" do
PostDestroyer.new(moderator, topic.first_post).destroy
topic.first_post.user.destroy!
expect(Guardian.new(moderator).can_recover_topic?(topic.reload)).to be_truthy
end
end
end
context "when category group moderation is enabled" do
fab!(:group_user) { 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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_recover_post?(post)).to be_falsey
end
it "returns false for a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_recover_post?(nil)).to be_falsey
end
it "returns false for a regular user" do
2015-01-10 00:34:37 +08:00
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
2019-05-07 16:37:42 +08:00
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
2013-02-06 03:16:51 +08:00
describe "can_edit?" do
it "returns false with a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_edit?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
2014-05-13 20:53:11 +08:00
it "returns false when not logged in also for wiki post" do
post.wiki = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_edit?(post)).to be_falsey
2014-05-13 20:53:11 +08:00
end
2013-02-06 03:16:51 +08:00
it "returns true if you want to edit your own post" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(post.user).can_edit?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
2014-05-13 20:53:11 +08:00
it "returns false if another regular user tries to edit a soft deleted wiki post" do
post.wiki = true
post.user_deleted = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
2014-05-13 20:53:11 +08:00
end
it "returns false if you are trying to edit a deleted post" do
post.deleted_at = 1.day.ago
2015-01-10 00:34:37 +08:00
expect(Guardian.new(post.user).can_edit?(post)).to be_falsey
end
2014-05-13 20:53:11 +08:00
it "returns false if another regular user tries to edit a deleted wiki post" do
post.wiki = true
post.deleted_at = 1.day.ago
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
2014-05-13 20:53:11 +08:00
end
2013-02-06 03:16:51 +08:00
it "returns false if another regular user tries to edit your post" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
2014-05-13 20:53:11 +08:00
it "returns true if another regular user tries to edit wiki post" do
post.wiki = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy
2014-05-13 20:53:11 +08:00
end
it "returns false if a wiki but the user can't create a post" do
2019-05-07 16:37:42 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns true as a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns true as an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true as a trust level 4 user" do
2015-01-10 00:34:37 +08:00
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) do
Fabricate(:post, topic: topic, user: topic.user, created_at: 6.minutes.ago)
end
before do
topic.user.update_columns(trust_level: 1)
SiteSetting.post_edit_time_limit = 5
end
it "returns false to the author of the post" do
expect(Guardian.new(old_post.user).can_edit?(old_post)).to be_falsey
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(old_post)).to eq(true)
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(old_post)).to eq(true)
end
it "returns false for another regular user trying to edit your post" do
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
it "returns true for another regular user trying to edit a wiki post" do
old_post.wiki = true
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_truthy
end
context "when unlimited owner edits on first post" do
let(:owner) { old_post.user }
it "returns true when the post topic's category allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: true)
expect(Guardian.new(owner).can_edit?(old_post)).to be_truthy
end
it "returns false when the post topic's category does not allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: false)
expect(Guardian.new(owner).can_edit?(old_post)).to be_falsey
end
it "returns false when the post topic's category allow_unlimited_owner_edits_on_first_post but the post is not the first in the topic" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: true)
new_post =
Fabricate(:post, user: owner, topic: old_post.topic, created_at: 6.minutes.ago)
expect(Guardian.new(owner).can_edit?(new_post)).to be_falsey
end
it "returns false when someone other than owner is editing and category allow_unlimited_owner_edits_on_first_post" do
old_post.topic.category.update(allow_unlimited_owner_edits_on_first_post: false)
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
end
end
2014-05-13 20:53:11 +08:00
context "when post is older than tl2_post_edit_time_limit" do
let(:old_post) do
Fabricate(:post, topic: topic, user: topic.user, created_at: 12.minutes.ago)
end
before do
topic.user.update_columns(trust_level: 2)
SiteSetting.tl2_post_edit_time_limit = 10
end
it "returns false to the author of the post" do
expect(Guardian.new(old_post.user).can_edit?(old_post)).to be_falsey
end
it "returns true as a moderator" do
expect(Guardian.new(moderator).can_edit?(old_post)).to eq(true)
end
it "returns true as an admin" do
expect(Guardian.new(admin).can_edit?(old_post)).to eq(true)
end
it "returns false for another regular user trying to edit your post" do
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_falsey
end
it "returns true for another regular user trying to edit a wiki post" do
old_post.wiki = true
expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_truthy
end
2014-05-13 20:53:11 +08:00
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
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
end
describe "a Topic" do
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_edit?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true for editing your own post" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(true)
2013-02-06 03:16:51 +08:00
end
it "returns false as a regular user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
context "when first post is hidden" do
let!(:topic) { Fabricate(:topic, user: user) }
let!(:post) do
Fabricate(:post, topic: topic, user: topic.user, hidden: true, hidden_at: Time.zone.now)
end
it "returns false for editing your own post while inside the cooldown window" do
SiteSetting.cooldown_minutes_after_hiding_posts = 30
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(false)
end
end
context "when locked" do
let(:post) { Fabricate(:post, locked_by_id: admin.id) }
let(:topic) { post.topic }
it "doesn't allow users to edit locked topics" do
expect(Guardian.new(topic.user).can_edit?(topic)).to eq(false)
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
end
end
context "when not archived" do
it "returns true as a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit?(topic)).to eq(true)
end
it "returns true as an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit?(topic)).to eq(true)
end
it "returns true at trust level 3" do
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
end
end
describe "a Category" do
it "returns false when not logged in" do
2019-05-07 16:40:54 +08:00
expect(Guardian.new.can_edit?(plain_category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false as a regular user" do
2019-05-07 16:40:54 +08:00
expect(Guardian.new(plain_category.user).can_edit?(plain_category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false as a moderator" do
2019-05-07 16:40:54 +08:00
expect(Guardian.new(moderator).can_edit?(plain_category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true as an admin" do
2019-05-07 16:40:54 +08:00
expect(Guardian.new(admin).can_edit?(plain_category)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
describe "a User" do
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_edit?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false as a different user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_edit?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when trying to edit yourself" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit?(user)).to be_truthy
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
it "returns true as a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true as an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
end
describe "#can_moderate?" do
2013-02-06 03:16:51 +08:00
it "returns false with a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_moderate?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
2017-11-11 01:18:08 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_moderate?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when not a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_moderate?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_moderate?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_moderate?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true when trust level 4" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(trust_level_4).can_moderate?(topic)).to be_truthy
end
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
end
describe "#can_see_flags?" do
2013-02-06 03:16:51 +08:00
it "returns false when there is no post" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_see_flags?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when there is no user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_see_flags?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
2013-08-14 04:08:29 +08:00
it "allow regular users to see flags" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see_flags?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "allows moderators to see flags" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_see_flags?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "allows moderators to see flags" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_see_flags?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns false with a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_move_posts?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
context "with a Topic" do
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_move_posts?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when not a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_move_posts?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_move_posts?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_move_posts?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
end
describe "#can_delete?" do
2013-02-06 03:16:51 +08:00
it "returns false with a nil object" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
context "with a Topic" do
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_delete?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when not a moderator" do
expect(Guardian.new(Fabricate(:user)).can_delete?(topic)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(topic)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns false for static doc topics" do
tos_topic = Fabricate(:topic, user: Discourse.system_user)
SiteSetting.tos_topic_id = tos_topic.id
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(tos_topic)).to be_falsey
end
it "returns true for own topics" do
topic.update_attribute(:posts_count, 1)
topic.update_attribute(:created_at, Time.zone.now)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_truthy
end
it "returns false if topic has replies" do
topic.update!(posts_count: 2, created_at: Time.zone.now)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_delete?(topic)).to be_falsey
SiteSetting.tl4_delete_posts_and_topics = true
expect(Guardian.new(trust_level_4).can_delete?(topic)).to be_truthy
end
it "returns false if topic was created > 24h ago" do
topic.update!(posts_count: 1, created_at: 48.hours.ago)
expect(Guardian.new(topic.user).can_delete?(topic)).to be_falsey
end
context "when category group moderation is enabled" do
fab!(:group_user) { Fabricate(:group_user) }
before { SiteSetting.enable_category_group_moderation = true }
it "returns false if user is not a member of the appropriate group" do
expect(Guardian.new(group_user.user).can_delete?(topic)).to be_falsey
end
it "returns true if user is a member of the appropriate group" do
topic.category.update!(reviewable_by_group_id: group_user.group.id)
expect(Guardian.new(group_user.user).can_delete?(topic)).to be_truthy
end
end
2013-02-06 03:16:51 +08:00
end
context "with a Post" do
2013-02-06 03:16:51 +08:00
before { post.post_number = 2 }
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_delete?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when trying to delete your own post" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(post)).to be_truthy
expect(Guardian.new(trust_level_0).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_1).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_2).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_3).can_delete?(post)).to be_falsey
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_falsey
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_falsey
SiteSetting.tl4_delete_posts_and_topics = true
expect(Guardian.new(trust_level_4).can_delete?(post)).to be_truthy
end
it "returns false when self deletions are disabled" do
SiteSetting.max_post_deletions_per_day = 0
expect(Guardian.new(user).can_delete?(post)).to be_falsey
end
it "returns false when trying to delete another user's own post" do
2015-01-10 00:34:37 +08:00
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)
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(post)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(post)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(post)).to be_falsey
end
context "when the topic is archived" do
before { post.topic.archived = true }
it "allows a staff member to delete it" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(post)).to be_truthy
end
it "doesn't allow a regular user to delete it" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(post.user).can_delete?(post)).to be_falsey
end
end
2013-02-06 03:16:51 +08:00
end
context "with a Category" do
let(:category) { Fabricate(:category, user: moderator) }
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_delete?(category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when a regular user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when a moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns true when an admin" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(category)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "can't be deleted if it has a forum topic" do
category.topic_count = 10
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_delete?(category)).to be_falsey
2013-02-06 03:16:51 +08:00
end
2014-02-13 04:24:44 +08:00
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)
2015-01-10 00:34:37 +08:00
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)
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete?(category)).to be_falsey
end
2013-02-06 03:16:51 +08:00
end
describe "#can_suspend?" do
it "returns false when a user tries to suspend another user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_suspend?(coding_horror)).to be_falsey
end
it "returns true when an admin tries to suspend another user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_suspend?(coding_horror)).to be_truthy
end
it "returns true when a moderator tries to suspend another user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_suspend?(coding_horror)).to be_truthy
end
it "returns false when staff tries to suspend staff" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_suspend?(moderator)).to be_falsey
end
end
context "with a PostAction" do
let(:post_action) do
user.id = 1
post.id = 1
a = PostAction.new(user: user, post: post, post_action_type_id: 2)
a.created_at = 1.minute.ago
a
end
2013-02-06 03:16:51 +08:00
it "returns false when not logged in" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_delete?(post_action)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when not the user who created it" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_delete?(post_action)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false if the window has expired" do
post_action.created_at = 20.minutes.ago
SiteSetting.post_undo_action_window_mins = 10
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(post_action)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
it "returns true if it's yours" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_delete?(post_action)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
end
describe "#can_see_deleted_posts?" do
it "returns true if the user is an admin" do
expect(Guardian.new(admin).can_see_deleted_posts?(post.topic.category)).to be_truthy
end
it "returns true if the user is a moderator of category" do
expect(Guardian.new(moderator).can_see_deleted_posts?(post.topic.category)).to be_truthy
end
it "returns true when tl4 can delete posts and topics" do
expect(Guardian.new(trust_level_4).can_see_deleted_posts?(post)).to be_falsey
SiteSetting.tl4_delete_posts_and_topics = true
expect(Guardian.new(trust_level_4).can_see_deleted_posts?(post)).to be_truthy
end
end
describe "#can_approve?" do
2013-02-06 03:16:51 +08:00
it "wont allow a non-logged in user to approve" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_approve?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "wont allow a non-admin to approve a user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(coding_horror).can_approve?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "returns false when the user is already approved" do
user.approved = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_approve?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
it "allows an admin to approve a user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_approve?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "allows a moderator to approve a user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_approve?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
describe "#can_grant_admin?" do
2013-02-06 03:16:51 +08:00
it "wont allow a non logged in user to grant an admin's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_grant_admin?(another_admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "wont allow a regular user to revoke an admin's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_grant_admin?(another_admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "wont allow an admin to grant their own access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_grant_admin?(admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "allows an admin to grant a regular user access" do
admin.id = 1
user.id = 2
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_grant_admin?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
it "should not allow an admin to grant admin access to a non real user" do
2017-01-06 15:25:49 +08:00
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
2013-02-06 03:16:51 +08:00
end
describe "#can_revoke_admin?" do
2013-02-06 03:16:51 +08:00
it "wont allow a non logged in user to revoke an admin's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_revoke_admin?(another_admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "wont allow a regular user to revoke an admin's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_revoke_admin?(another_admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "wont allow an admin to revoke their own access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_revoke_admin?(admin)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "allows an admin to revoke another admin's access" do
admin.id = 1
another_admin.id = 2
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_revoke_admin?(another_admin)).to be_truthy
2013-02-06 03:16:51 +08:00
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
2013-02-06 03:16:51 +08:00
end
describe "#can_grant_moderation?" do
it "wont allow a non logged in user to grant an moderator's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_grant_moderation?(user)).to be_falsey
end
it "wont allow a regular user to revoke an moderator's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_grant_moderation?(moderator)).to be_falsey
end
it "will allow an admin to grant their own moderator access" do
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_grant_moderation?(moderator)).to be_falsey
end
it "allows an admin to grant a regular user access" do
2015-01-10 00:34:37 +08:00
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
2017-01-06 15:25:49 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new.can_revoke_moderation?(moderator)).to be_falsey
end
it "wont allow a regular user to revoke an moderator's access" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_revoke_moderation?(moderator)).to be_falsey
end
it "wont allow a moderator to revoke their own moderator" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_revoke_moderation?(moderator)).to be_falsey
end
it "allows an admin to revoke a moderator's access" do
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_revoke_moderation?(admin)).to be_truthy
end
it "does not allow revoke from non moderators" do
2015-01-10 00:34:37 +08:00
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
2013-02-06 03:16:51 +08:00
it "is false without a logged in user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_see_invite_details?(user)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "is false without a user to look at" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see_invite_details?(nil)).to be_falsey
2013-02-06 03:16:51 +08:00
end
it "is true when looking at your own invites" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_see_invite_details?(user)).to be_truthy
2013-02-06 03:16:51 +08:00
end
end
describe "#can_access_forum?" do
let(:unapproved_user) { Fabricate(:user) }
context "when must_approve_users is false" do
before { SiteSetting.must_approve_users = false }
it "returns true for a nil user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_access_forum?).to be_truthy
end
it "returns true for an unapproved user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
end
context "when must_approve_users is true" do
before { SiteSetting.must_approve_users = true }
it "returns false for a nil user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_access_forum?).to be_falsey
end
it "returns false for an unapproved user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(unapproved_user).can_access_forum?).to be_falsey
end
it "returns true for an admin user" do
unapproved_user.admin = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
it "returns true for an approved user" do
unapproved_user.approved = true
2015-01-10 00:34:37 +08:00
expect(Guardian.new(unapproved_user).can_access_forum?).to be_truthy
end
end
2013-02-06 03:16:51 +08:00
end
describe "#can_delete_all_posts?" do
it "is false without a logged in user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_delete_all_posts?(user)).to be_falsey
end
it "is false without a user to look at" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_delete_all_posts?(nil)).to be_falsey
end
it "is false for regular users" do
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(actor).can_delete_all_posts?(user)).to be_falsey
end
it "is false if user is an admin" do
2015-01-10 00:34:37 +08:00
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 "it false for an anonymized user" do
expect(Guardian.new(user).can_anonymize_user?(anonymous_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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_grant_title?(user)).to be_falsey
end
it "is false for regular users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_grant_title?(user)).to be_falsey
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_grant_title?(user)).to be_truthy
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_grant_title?(user)).to be_truthy
end
it "is false without a user to look at" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_grant_title?(nil)).to be_falsey
end
context "with title argument" do
fab!(:title_badge) { Fabricate(:badge, name: "Helper", allow_title: true) }
fab!(:no_title_badge) { Fabricate(:badge, name: "Writer", allow_title: false) }
fab!(:group) { Fabricate(:group, title: "Groupie") }
it "returns true if title belongs to a badge that user has" do
BadgeGranter.grant(title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(true)
end
it "returns false if title belongs to a badge that user doesn't have" do
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(false)
end
it "returns false if title belongs to a badge that user has but can't be used as a title" do
BadgeGranter.grant(no_title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, no_title_badge.name)).to eq(false)
end
it "returns true if title is from a group the user belongs to" do
group.add(user)
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(true)
end
it "returns false if title is from a group the user doesn't belong to" do
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(false)
end
it "returns true if the title is set to an empty string" do
expect(Guardian.new(user).can_grant_title?(user, "")).to eq(true)
end
end
end
describe "can_use_primary_group?" do
fab!(:group) { Fabricate(:group, title: "Groupie") }
it "is false without a logged in user" do
expect(Guardian.new(nil).can_use_primary_group?(user)).to be_falsey
end
it "is false with no group_id" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, nil)).to be_falsey
end
it "is false if the group does not exist" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, Group.last.id + 1)).to be_falsey
end
it "is false if the user is not a part of the group" do
user.update(groups: [])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it "is false if the group is automatic" do
user.update(groups: [Group.new(name: "autooo", automatic: true)])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it "is true if the user is a part of the group, and the group is custom" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_truthy
end
end
describe "can_use_flair_group?" do
fab!(:group) { Fabricate(:group, title: "Groupie", flair_icon: "icon") }
it "is false without a logged in user" do
expect(Guardian.new(nil).can_use_flair_group?(user)).to eq(false)
end
it "is false if the group does not exist" do
expect(Guardian.new(user).can_use_flair_group?(user, nil)).to eq(false)
expect(Guardian.new(user).can_use_flair_group?(user, Group.last.id + 1)).to eq(false)
end
it "is false if the user is not a part of the group" do
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(false)
end
it "is false if the group does not have a flair" do
group.update(flair_icon: nil)
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(false)
end
it "is true if the user is a part of the group and the group has a flair" do
user.update(groups: [group])
expect(Guardian.new(user).can_use_flair_group?(user, group.id)).to eq(true)
end
end
describe "#can_change_primary_group?" do
it "returns false without a logged in user" do
expect(Guardian.new(nil).can_change_primary_group?(user, group)).to eq(false)
end
it "returns false for regular users" do
expect(Guardian.new(user).can_change_primary_group?(user, group)).to eq(false)
end
it "returns true for admins" do
expect(Guardian.new(admin).can_change_primary_group?(user, group)).to eq(true)
end
context "when moderators_manage_categories_and_groups site setting is enabled" do
before { SiteSetting.moderators_manage_categories_and_groups = true }
it "returns true for moderators" do
expect(Guardian.new(moderator).can_change_primary_group?(user, group)).to eq(true)
end
end
context "when moderators_manage_categories_and_groups site setting is disabled" do
before { SiteSetting.moderators_manage_categories_and_groups = false }
it "returns false for moderators" do
expect(Guardian.new(moderator).can_change_primary_group?(user, group)).to eq(false)
end
end
end
2013-07-23 07:13:48 +08:00
describe "can_change_trust_level?" do
it "is false without a logged in user" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(nil).can_change_trust_level?(user)).to be_falsey
2013-07-23 07:13:48 +08:00
end
it "is false for regular users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_change_trust_level?(user)).to be_falsey
2013-07-23 07:13:48 +08:00
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_change_trust_level?(user)).to be_truthy
2013-07-23 07:13:48 +08:00
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_change_trust_level?(user)).to be_truthy
2013-07-23 07:13:48 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_username?(user)).to be_truthy
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_username?(user)).to be_truthy
end
it "is true for admins when changing anonymous username" do
expect(Guardian.new(admin).can_edit_username?(anonymous_user)).to be_truthy
end
end
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_username?(anonymous_user)).to be_falsey
end
end
context "for a new user" do
fab!(:target_user) { Fabricate(:user, created_at: 1.minute.ago) }
include_examples "staff can always change usernames"
2013-12-03 12:49:54 +08:00
it "is true for the user to change their own username" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_truthy
end
end
context "for an old user" do
before { SiteSetting.username_change_period = 3 }
let(:target_user) { Fabricate(:user, created_at: 4.days.ago) }
context "with no posts" do
include_examples "staff can always change usernames"
it "is false for the user to change their own username" do
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_falsey
end
end
context "with posts" do
before { target_user.stubs(:post_count).returns(1) }
include_examples "staff can always change usernames"
2013-12-03 12:49:54 +08:00
it "is false for the user to change their own username" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(target_user).can_edit_username?(target_user)).to be_falsey
end
end
end
context "when editing is disabled in preferences" do
before { SiteSetting.username_change_period = 0 }
include_examples "staff can always change usernames"
2013-12-03 12:49:54 +08:00
it "is false for the user to change their own username" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_username?(user)).to be_falsey
end
end
context "when SSO username override is active" do
before do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_username?(admin)).to be_falsey
end
it "is false for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_username?(moderator)).to be_falsey
end
it "is false for users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_username?(user)).to be_falsey
end
end
end
describe "can_edit_email?" do
context "when allowed in settings" do
before { SiteSetting.email_editable = true }
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_email?(anonymous_user)).to be_falsey
end
end
it "is false when not logged in" do
expect(
Guardian.new(nil).can_edit_email?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's email" do
expect(
Guardian.new(Fabricate(:user)).can_edit_email?(
Fabricate(:user, created_at: 1.minute.ago),
),
).to be_falsey
end
2013-12-03 12:49:54 +08:00
it "is true for a regular user to edit their own email" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_email?(user)).to be_truthy
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_email?(user)).to be_truthy
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_email?(user)).to be_truthy
end
end
context "when not allowed in settings" do
before { SiteSetting.email_editable = false }
it "is false when not logged in" do
expect(
Guardian.new(nil).can_edit_email?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's email" do
expect(
Guardian.new(Fabricate(:user)).can_edit_email?(
Fabricate(:user, created_at: 1.minute.ago),
),
).to be_falsey
end
2013-12-03 12:49:54 +08:00
it "is false for a regular user to edit their own email" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_email?(user)).to be_falsey
end
it "is false for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_email?(user)).to be_falsey
end
it "is false for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_email?(user)).to be_falsey
end
end
context "when SSO email override is active" do
before do
2017-07-10 10:12:21 +08:00
SiteSetting.email_editable = false
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
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
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_email?(admin)).to be_falsey
end
it "is false for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_email?(moderator)).to be_falsey
end
it "is false for users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_email?(user)).to be_falsey
end
end
end
describe "can_edit_name?" do
it "is false without a logged in user" do
expect(
Guardian.new(nil).can_edit_name?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
it "is false for regular users to edit another user's name" do
expect(
Guardian.new(Fabricate(:user)).can_edit_name?(Fabricate(:user, created_at: 1.minute.ago)),
).to be_falsey
end
context "for anonymous user" do
before { SiteSetting.allow_anonymous_posting = true }
it "is false" do
expect(Guardian.new(anonymous_user).can_edit_name?(anonymous_user)).to be_falsey
end
end
context "for a new user" do
let(:target_user) { Fabricate(:user, created_at: 1.minute.ago) }
it "is true for the user to change their own name" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(target_user).can_edit_name?(target_user)).to be_truthy
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_name?(user)).to be_truthy
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_name?(user)).to be_truthy
end
end
context "when name is disabled in preferences" do
before { SiteSetting.enable_names = false }
it "is false for the user to change their own name" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_name?(user)).to be_falsey
end
it "is false for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_name?(user)).to be_falsey
end
it "is false for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_name?(user)).to be_falsey
end
end
context "when name is enabled in preferences" do
before { SiteSetting.enable_names = true }
context "when SSO is disabled" do
before do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
SiteSetting.enable_discourse_connect = false
SiteSetting.auth_overrides_name = false
end
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_name?(admin)).to be_truthy
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_truthy
end
it "is true for users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_name?(user)).to be_truthy
end
end
context "when SSO is enabled" do
before do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
end
context "when SSO name override is active" do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
before { SiteSetting.auth_overrides_name = true }
it "is false for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_name?(admin)).to be_falsey
end
it "is false for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_falsey
end
it "is false for users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_name?(user)).to be_falsey
end
end
context "when SSO name override is not active" do
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 18:04:33 +08:00
before { SiteSetting.auth_overrides_name = false }
it "is true for admins" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(admin).can_edit_name?(admin)).to be_truthy
end
it "is true for moderators" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(moderator).can_edit_name?(moderator)).to be_truthy
end
it "is true for users" do
2015-01-10 00:34:37 +08:00
expect(Guardian.new(user).can_edit_name?(user)).to be_truthy
end
end
end
end
end
2014-05-13 20:53:11 +08:00
describe "#can_export_entity?" do
let(:anonymous_guardian) { Guardian.new }
let(:user_guardian) { Guardian.new(user) }
let(:moderator_guardian) { Guardian.new(moderator) }
let(:admin_guardian) { Guardian.new(admin) }
it "only allows admins to export user_list" do
expect(user_guardian.can_export_entity?("user_list")).to be_falsey
expect(moderator_guardian.can_export_entity?("user_list")).to be_falsey
expect(admin_guardian.can_export_entity?("user_list")).to be_truthy
end
it "allow moderators to export other admin entities" do
expect(user_guardian.can_export_entity?("staff_action")).to be_falsey
expect(moderator_guardian.can_export_entity?("staff_action")).to be_truthy
expect(admin_guardian.can_export_entity?("staff_action")).to be_truthy
end
it "does not allow anonymous to export" do
expect(anonymous_guardian.can_export_entity?("user_archive")).to be_falsey
end
end
describe "#can_ignore_user?" do
before { SiteSetting.min_trust_level_to_allow_ignore = 1 }
let(:guardian) { Guardian.new(trust_level_2) }
context "when ignored user is the same as guardian user" do
it "does not allow ignoring user" do
expect(guardian.can_ignore_user?(trust_level_2)).to eq(false)
end
end
context "when ignored user is a staff user" do
let!(:admin) { Fabricate(:user, admin: true) }
it "does not allow ignoring user" do
expect(guardian.can_ignore_user?(admin)).to eq(false)
end
end
context "when ignored user is a normal user" do
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
context "when ignorer is staff" do
let(:guardian) { Guardian.new(admin) }
it "allows ignoring user" do
expect(guardian.can_ignore_user?(another_user)).to eq(true)
end
end
context "when ignorer'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
2014-05-13 20:53:11 +08:00
describe "can_wiki?" do
let(:post) { Fabricate(:post, created_at: 1.minute.ago) }
2014-05-13 20:53:11 +08:00
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
2014-05-13 20:53:11 +08:00
end
it "returns true for admin user" do
expect(Guardian.new(admin).can_wiki?(post)).to be_truthy
2014-05-13 20:53:11 +08:00
end
2014-09-05 14:52:40 +08:00
it "returns true for trust_level_4 user" do
expect(Guardian.new(trust_level_4).can_wiki?(post)).to be_truthy
2014-05-13 20:53:11 +08:00
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
2014-05-13 20:53:11 +08:00
end
2016-06-07 02:18:15 +08:00
describe "Tags" do
context "with tagging disabled" do
2016-06-07 02:18:15 +08:00
before { SiteSetting.tagging_enabled = false }
it "can_create_tag returns false" do
expect(Guardian.new(admin).can_create_tag?).to be_falsey
end
it "can_admin_tags returns false" do
expect(Guardian.new(admin).can_admin_tags?).to be_falsey
end
it "can_admin_tag_groups returns false" do
expect(Guardian.new(admin).can_admin_tag_groups?).to be_falsey
end
end
context "when tagging is enabled" do
2016-06-07 02:18:15 +08:00
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 { SiteSetting.min_trust_to_create_tag = 3 }
2016-06-07 02:18:15 +08:00
describe "#can_see_tag?" do
it "is always true" do
expect(Guardian.new.can_see_tag?(anything)).to be_truthy
end
end
describe "can_create_tag" do
it "returns false if trust level is too low" do
expect(Guardian.new(trust_level_2).can_create_tag?).to be_falsey
end
it "returns true if trust level is high enough" do
expect(Guardian.new(trust_level_3).can_create_tag?).to be_truthy
end
it "returns true for staff" do
expect(Guardian.new(admin).can_create_tag?).to be_truthy
expect(Guardian.new(moderator).can_create_tag?).to be_truthy
end
2016-06-07 02:18:15 +08:00
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 { SiteSetting.min_trust_to_create_tag = "staff" }
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
2016-06-07 02:18:15 +08:00
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 { SiteSetting.min_trust_to_create_tag = "admin" }
2016-06-07 02:18:15 +08:00
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)
2016-06-07 02:18:15 +08:00
end
it "returns true if admin" do
expect(Guardian.new(admin).can_create_tag?).to be_truthy
2016-06-07 02:18:15 +08:00
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
2016-06-07 02:18:15 +08:00
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 { SiteSetting.hide_suspension_reasons = true }
it "will not be shown to anonymous users" do
expect(Guardian.new.can_see_suspension_reason?(user)).to eq(false)
end
it "users can see their own suspensions" do
expect(Guardian.new(user).can_see_suspension_reason?(user)).to eq(true)
end
it "staff can see suspensions" do
expect(Guardian.new(moderator).can_see_suspension_reason?(user)).to eq(true)
end
end
end
2017-10-10 16:26:56 +08:00
describe "#can_remove_allowed_users?" do
context "with staff users" do
2017-10-10 16:26:56 +08:00
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)) }
2017-10-10 16:26:56 +08:00
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
2017-10-10 16:26:56 +08:00
end
describe "#auth_token" do
it "returns the correct auth token" do
token = UserAuthToken.generate!(user_id: user.id)
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706) Currently, Discourse rate limits all incoming requests by the IP address they originate from regardless of the user making the request. This can be frustrating if there are multiple users using Discourse simultaneously while sharing the same IP address (e.g. employees in an office). This commit implements a new feature to make Discourse apply rate limits by user id rather than IP address for users at or higher than the configured trust level (1 is the default). For example, let's say a Discourse instance is configured to allow 200 requests per minute per IP address, and we have 10 users at trust level 4 using Discourse simultaneously from the same IP address. Before this feature, the 10 users could only make a total of 200 requests per minute before they got rate limited. But with the new feature, each user is allowed to make 200 requests per minute because the rate limits are applied on user id rather than the IP address. The minimum trust level for applying user-id-based rate limits can be configured by the `skip_per_ip_rate_limit_trust_level` global setting. The default is 1, but it can be changed by either adding the `DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the desired value to your `app.yml`, or changing the setting's value in the `discourse.conf` file. Requests made with API keys are still rate limited by IP address and the relevant global settings that control API keys rate limits. Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters string that Discourse used to lookup the current user from the database and the cookie contained no additional information about the user. However, we had to change the cookie content in this commit so we could identify the user from the cookie without making a database query before the rate limits logic and avoid introducing a bottleneck on busy sites. Besides the 32 characters auth token, the cookie now includes the user id, trust level and the cookie's generation date, and we encrypt/sign the cookie to prevent tampering. Internal ticket number: t54739.
2021-11-18 04:27:30 +08:00
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};")
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706) Currently, Discourse rate limits all incoming requests by the IP address they originate from regardless of the user making the request. This can be frustrating if there are multiple users using Discourse simultaneously while sharing the same IP address (e.g. employees in an office). This commit implements a new feature to make Discourse apply rate limits by user id rather than IP address for users at or higher than the configured trust level (1 is the default). For example, let's say a Discourse instance is configured to allow 200 requests per minute per IP address, and we have 10 users at trust level 4 using Discourse simultaneously from the same IP address. Before this feature, the 10 users could only make a total of 200 requests per minute before they got rate limited. But with the new feature, each user is allowed to make 200 requests per minute because the rate limits are applied on user id rather than the IP address. The minimum trust level for applying user-id-based rate limits can be configured by the `skip_per_ip_rate_limit_trust_level` global setting. The default is 1, but it can be changed by either adding the `DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the desired value to your `app.yml`, or changing the setting's value in the `discourse.conf` file. Requests made with API keys are still rate limited by IP address and the relevant global settings that control API keys rate limits. Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters string that Discourse used to lookup the current user from the database and the cookie contained no additional information about the user. However, we had to change the cookie content in this commit so we could identify the user from the cookie without making a database query before the rate limits logic and avoid introducing a bottleneck on busy sites. Besides the 32 characters auth token, the cookie now includes the user id, trust level and the cookie's generation date, and we encrypt/sign the cookie to prevent tampering. Internal ticket number: t54739.
2021-11-18 04:27:30 +08:00
guardian = Guardian.new(user, ActionDispatch::Request.new(env))
expect(guardian.auth_token).to eq(token.auth_token)
end
end
describe "can_publish_page?" do
context "when disabled" do
it "is false for staff" do
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(false)
end
end
context "when enabled" do
before { SiteSetting.enable_page_publishing = true }
it "is false for anonymous users" do
expect(Guardian.new.can_publish_page?(topic)).to eq(false)
end
it "is false for regular users" do
expect(Guardian.new(user).can_publish_page?(topic)).to eq(false)
end
it "is true for staff" do
expect(Guardian.new(moderator).can_publish_page?(topic)).to eq(true)
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(true)
end
it "is false if the topic is a private message" do
post = Fabricate(:private_message_post, user: admin)
expect(Guardian.new(admin).can_publish_page?(post.topic)).to eq(false)
end
context "when secure_uploads is also enabled" do
before do
setup_s3
SiteSetting.secure_uploads = true
end
it "is false for everyone" do
expect(Guardian.new(moderator).can_publish_page?(topic)).to eq(false)
expect(Guardian.new(user).can_publish_page?(topic)).to eq(false)
expect(Guardian.new.can_publish_page?(topic)).to eq(false)
expect(Guardian.new(admin).can_publish_page?(topic)).to eq(false)
end
end
end
end
describe "#can_see_site_contact_details?" do
context "when login_required is enabled" do
before { SiteSetting.login_required = true }
it "is false for anonymous users" do
expect(Guardian.new.can_see_site_contact_details?).to eq(false)
end
it "is true for regular users" do
expect(Guardian.new(user).can_see_site_contact_details?).to eq(true)
end
end
context "when login_required is disabled" do
before { SiteSetting.login_required = false }
it "is true for anonymous users" do
expect(Guardian.new.can_see_site_contact_details?).to eq(true)
end
it "is true for regular users" do
expect(Guardian.new(user).can_see_site_contact_details?).to eq(true)
end
end
end
describe "#can_mention_here?" do
it "returns false if disabled" do
SiteSetting.max_here_mentioned = 0
expect(admin.guardian.can_mention_here?).to eq(false)
end
it "returns false if disabled" do
SiteSetting.here_mention = ""
expect(admin.guardian.can_mention_here?).to eq(false)
end
it "works with trust levels" do
SiteSetting.min_trust_level_for_here_mention = 2
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 { SiteSetting.enable_category_group_moderation = true }
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
2013-02-06 03:16:51 +08:00
end