FEATURE: Non-staff users can use shared drafts. (#11329)

You can let non-staff users use shared drafts by modifying the `shared_drafts_min_trust_level` site setting. These users must have access to the shared draft category.
This commit is contained in:
Roman Rizzi 2020-12-03 11:07:57 -03:00 committed by GitHub
parent e773e21f0a
commit 9fb36290e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 3 deletions

View File

@ -1964,7 +1964,7 @@ en:
label: "New Topic"
shared_draft:
label: "Shared Draft"
desc: "Draft a topic that will only be visible to staff"
desc: "Draft a topic that will only be visible to allowed users"
toggle_topic_bump:
label: "Toggle topic bump"
desc: "Reply without changing latest reply date"

View File

@ -2252,6 +2252,7 @@ en:
city_for_disputes: "City for Disputes"
shared_drafts_category: "Enable the Shared Drafts feature by designating a category for topic drafts. Topics in this category will be suppressed from topic lists for staff users."
shared_drafts_min_trust_level: "Allow users to see and edit Shared Drafts."
push_notifications_prompt: "Display user consent prompt."
push_notifications_icon: "The badge icon that appears in the notification corner. A 96×96 monochromatic PNG with transparency is recommended."

View File

@ -772,6 +772,9 @@ posting:
shared_drafts_category:
type: category
default: ""
shared_drafts_min_trust_level:
default: "staff"
enum: "TrustLevelAndStaffSetting"
post_edit_time_limit:
default: 1440
max: 10080

View File

@ -139,6 +139,14 @@ module PostGuardian
return false
end
return true if (
can_see_post?(post) &&
can_create_post?(post.topic) &&
post.topic.category_id == SiteSetting.shared_drafts_category.to_i &&
can_see_category?(post.topic.category) &&
can_create_shared_draft?
)
if post.wiki && (@user.trust_level >= SiteSetting.min_trust_to_edit_wiki_post.to_i)
return can_create_post?(post.topic)
end

View File

@ -22,7 +22,12 @@ module TopicGuardian
alias :can_moderate_topic? :can_review_topic?
def can_create_shared_draft?
is_staff? && SiteSetting.shared_drafts_enabled?
return false unless SiteSetting.shared_drafts_enabled?
return is_admin? if SiteSetting.shared_drafts_min_trust_level.to_s == 'admin'
return is_staff? if SiteSetting.shared_drafts_min_trust_level.to_s == 'staff'
@user.has_trust_level?(SiteSetting.shared_drafts_min_trust_level.to_i)
end
def can_create_whisper?
@ -34,7 +39,7 @@ module TopicGuardian
end
def can_publish_topic?(topic, category)
is_staff? && can_see?(topic) && can_create_topic?(category)
can_create_shared_draft? && can_see?(topic) && can_create_topic_on_category?(category)
end
# Creating Methods
@ -91,6 +96,16 @@ module TopicGuardian
return false if !can_create_topic_on_category?(topic.category)
end
# Editing a shared draft.
return true if (
!topic.archived &&
!topic.private_message? &&
topic.category_id == SiteSetting.shared_drafts_category.to_i &&
can_see_category?(topic.category) &&
can_create_shared_draft? &&
can_create_post?(topic)
)
# TL4 users can edit archived topics, but can not edit private messages
return true if (
SiteSetting.trusted_users_can_edit_others? &&

View File

@ -0,0 +1,86 @@
# frozen_string_literal: true
require 'rails_helper'
describe TopicGuardian do
fab!(:admin) { Fabricate(:admin) }
fab!(:tl3_user) { Fabricate(:leader) }
fab!(:moderator) { Fabricate(:moderator) }
fab!(:category) { Fabricate(:category) }
describe '#can_create_shared_draft?' do
it 'when shared_drafts are disabled' do
SiteSetting.shared_drafts_min_trust_level = 'admin'
expect(Guardian.new(admin).can_create_shared_draft?).to eq(false)
end
it 'when user is a moderator and access is set to admin' do
SiteSetting.shared_drafts_category = category.id
SiteSetting.shared_drafts_min_trust_level = 'admin'
expect(Guardian.new(moderator).can_create_shared_draft?).to eq(false)
end
it 'when user is a moderator and access is set to staff' do
SiteSetting.shared_drafts_category = category.id
SiteSetting.shared_drafts_min_trust_level = 'staff'
expect(Guardian.new(moderator).can_create_shared_draft?).to eq(true)
end
it 'when user is TL3 and access is set to TL2' do
SiteSetting.shared_drafts_category = category.id
SiteSetting.shared_drafts_min_trust_level = '2'
expect(Guardian.new(tl3_user).can_create_shared_draft?).to eq(true)
end
end
describe '#can_edit_topic?' do
context 'when the topic is a shared draft' do
let(:tl2_user) { Fabricate(:user, trust_level: TrustLevel[2]) }
before do
SiteSetting.shared_drafts_category = category.id
SiteSetting.shared_drafts_min_trust_level = '2'
end
it 'returns false if the topic is a PM' do
pm_with_draft = Fabricate(:private_message_topic, category: category)
Fabricate(:shared_draft, topic: pm_with_draft)
expect(Guardian.new(tl2_user).can_edit_topic?(pm_with_draft)).to eq(false)
end
it 'returns false if the topic is archived' do
archived_topic = Fabricate(:topic, archived: true, category: category)
Fabricate(:shared_draft, topic: archived_topic)
expect(Guardian.new(tl2_user).can_edit_topic?(archived_topic)).to eq(false)
end
it 'returns true if a shared draft exists' do
topic = Fabricate(:topic, category: category)
Fabricate(:shared_draft, topic: topic)
expect(Guardian.new(tl2_user).can_edit_topic?(topic)).to eq(true)
end
it 'returns false if the user has a lower trust level' do
tl1_user = Fabricate(:user, trust_level: TrustLevel[1])
topic = Fabricate(:topic, category: category)
Fabricate(:shared_draft, topic: topic)
expect(Guardian.new(tl1_user).can_edit_topic?(topic)).to eq(false)
end
it 'returns true if the shared_draft is from a different category' do
topic = Fabricate(:topic, category: Fabricate(:category))
Fabricate(:shared_draft, topic: topic)
expect(Guardian.new(tl2_user).can_edit_topic?(topic)).to eq(false)
end
end
end
end

View File

@ -456,4 +456,31 @@ describe UserGuardian do
end
end
describe '#can_edit_post?' 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
end