From 8ba57c0ffd4c447e28bdae32d270f7643d2406ed Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 13 Apr 2016 15:59:38 +1000 Subject: [PATCH] FIX: restrict moderators from creating/editing topics in readonly categories In the past moderators had blanket access to all categories they were allowed to see. This tightens down the restriction. --- app/models/category.rb | 2 +- lib/guardian/post_guardian.rb | 5 ++++- lib/guardian/topic_guardian.rb | 11 +++++++++-- spec/components/guardian_spec.rb | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 5dcaaa46bfd..520c86c07f6 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -90,7 +90,7 @@ class Category < ActiveRecord::Base end def self.scoped_to_permissions(guardian, permission_types) - if guardian && guardian.is_staff? + if guardian && guardian.is_admin? all elsif !guardian || guardian.anonymous? if permission_types.include?(:readonly) diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index 9c07db3380d..072e1162246 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -73,6 +73,7 @@ module PostGuardian # Creating Method def can_create_post?(parent) + (!SpamRule::AutoBlock.block?(@user) || (!!parent.try(:private_message?) && parent.allowed_users.include?(@user))) && ( !parent || !parent.category || @@ -86,8 +87,10 @@ module PostGuardian return false end + return true if is_admin? + if is_staff? || @user.has_trust_level?(TrustLevel[4]) - return true + return can_create_post?(post.topic) end if post.topic.archived? || post.user_deleted || post.deleted_at diff --git a/lib/guardian/topic_guardian.rb b/lib/guardian/topic_guardian.rb index 655273b7cdb..c6963214d3c 100644 --- a/lib/guardian/topic_guardian.rb +++ b/lib/guardian/topic_guardian.rb @@ -21,17 +21,24 @@ module TopicGuardian def can_create_post_on_topic?(topic) # No users can create posts on deleted topics return false if topic.trashed? + return true if is_admin? - is_staff? || (authenticated? && user.has_trust_level?(TrustLevel[4])) || (not(topic.closed? || topic.archived? || topic.trashed?) && can_create_post?(topic)) + trusted = (authenticated? && user.has_trust_level?(TrustLevel[4])) || is_moderator? + + (!(topic.closed? || topic.archived?) || trusted) && can_create_post?(topic) end # Editing Method def can_edit_topic?(topic) return false if Discourse.static_doc_topic_ids.include?(topic.id) && !is_admin? return false unless can_see?(topic) - return true if is_staff? + + return true if is_admin? + return true if is_moderator? && can_create_post?(topic) + # TL4 users can edit archived topics, but can not edit private messages return true if (topic.archived && !topic.private_message? && user.has_trust_level?(TrustLevel[4]) && can_create_post?(topic)) + # TL3 users can not edit archived topics and private messages return true if (!topic.archived && !topic.private_message? && user.has_trust_level?(TrustLevel[3]) && can_create_post?(topic)) diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 8f5ef5ae10e..c7a5146f635 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -621,6 +621,14 @@ describe Guardian do end describe 'a Topic' do + it 'does not allow moderators to create topics in readonly categories' do + category = Fabricate(:category) + category.set_permissions(:everyone => :read) + category.save + + expect(Guardian.new(moderator).can_create?(Topic,category)).to be_falsey + end + it 'should check for full permissions' do category = Fabricate(:category) category.set_permissions(:everyone => :create_post) @@ -655,6 +663,7 @@ describe Guardian do category.save expect(Guardian.new(topic.user).can_create?(Post, topic)).to be_falsey + expect(Guardian.new(moderator).can_create?(Post, topic)).to be_falsey end it "is false when not logged in" do @@ -1042,6 +1051,11 @@ describe Guardian do 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 end