FEATURE: Introduce site setting to allow for non staff pm tagging (#16671)

Currently the only way to allow tagging on pms is to use the `allow_staff_to_tag_pms` site setting.  We are removing that site setting and replacing it with `pm_tags_allowed_for_groups` which will allow for non staff tagging. It will be group based permissions instead of requiring the user to be staff.

If the existing value of `allow_staff_to_tag_pms` is `true` then we include the `staff` groups as a default for `pm_tags_allowed_for_groups`.
This commit is contained in:
Isaac Janzen 2022-05-10 10:02:28 -05:00 committed by GitHub
parent cf273ec6e0
commit 1a12e4cfc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 103 additions and 38 deletions

View File

@ -2318,7 +2318,7 @@ en:
tags_sort_alphabetically: "Show tags in alphabetical order. Default is to show in order of popularity." tags_sort_alphabetically: "Show tags in alphabetical order. Default is to show in order of popularity."
tags_listed_by_group: "List tags by tag group on the <a href='%{base_path}/tags' target='_blank'>Tags page</a>." tags_listed_by_group: "List tags by tag group on the <a href='%{base_path}/tags' target='_blank'>Tags page</a>."
tag_style: "Visual style for tag badges." tag_style: "Visual style for tag badges."
allow_staff_to_tag_pms: "Allow staff members to tag any personal message" pm_tags_allowed_for_groups: "Allow members of included group(s) to tag any personal message"
min_trust_level_to_tag_topics: "Minimum trust level required to tag topics" min_trust_level_to_tag_topics: "Minimum trust level required to tag topics"
suppress_overlapping_tags_in_list: "If tags match exact words in topic titles, don't show the tag" suppress_overlapping_tags_in_list: "If tags match exact words in topic titles, don't show the tag"
remove_muted_tags_from_latest: "Don't show topics tagged only with muted tags in the latest topic list." remove_muted_tags_from_latest: "Don't show topics tagged only with muted tags in the latest topic list."

View File

@ -2581,8 +2581,13 @@ tags:
tags_listed_by_group: tags_listed_by_group:
client: true client: true
default: false default: false
allow_staff_to_tag_pms: pm_tags_allowed_for_groups:
default: false client: true
type: group_list
list_type: compact
default: ""
allow_any: false
refresh: true
suppress_overlapping_tags_in_list: suppress_overlapping_tags_in_list:
default: false default: false
client: true client: true

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class SetPmTagsAllowedForGroupsDefault < ActiveRecord::Migration[7.0]
def up
# if the old SiteSetting of `allow_staff_to_tag_pms` was set to true, update the new SiteSetting of
# `pm_tags_allowed_for_groups` default to include the staff group
allow_staff_to_tag_pms = DB.query_single("SELECT value FROM site_settings WHERE name = 'allow_staff_to_tag_pms'").first
# Dynamically sets the default value
if allow_staff_to_tag_pms == "t"
# Include all staff groups - admins/moderators/staff
default = "1|2|3"
execute "INSERT INTO site_settings (name, data_type, value, created_at, updated_at)
VALUES ('pm_tags_allowed_for_groups', 20, '#{default}', now(), now())"
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class RemoveAllowStaffToTagPmsSiteSetting < ActiveRecord::Migration[7.0]
def up
execute "DELETE FROM site_settings WHERE name = 'allow_staff_to_tag_pms'"
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -11,7 +11,8 @@ module TagGuardian
end end
def can_tag_pms? def can_tag_pms?
is_staff? && SiteSetting.tagging_enabled && SiteSetting.allow_staff_to_tag_pms return false if @user.blank?
SiteSetting.tagging_enabled && @user == Discourse.system_user || @user.group_users.exists?(group_id: SiteSetting.pm_tags_allowed_for_groups.to_s.split("|").map(&:to_i))
end end
def can_admin_tags? def can_admin_tags?

View File

@ -407,7 +407,7 @@ module Imap
end end
def tagging_enabled? def tagging_enabled?
SiteSetting.tagging_enabled && SiteSetting.allow_staff_to_tag_pms Guardian.new(Discourse.system_user).can_tag_pms?
end end
end end
end end

View File

@ -51,6 +51,10 @@ Fabricator(:moderator, from: :user) do
username { sequence(:username) { |i| "moderator#{i}" } } username { sequence(:username) { |i| "moderator#{i}" } }
email { sequence(:email) { |i| "moderator#{i}@discourse.org" } } email { sequence(:email) { |i| "moderator#{i}@discourse.org" } }
moderator true moderator true
after_create do |user|
user.group_users << Fabricate(:group_user, user: user, group: Group[:moderators])
end
end end
Fabricator(:admin, from: :user) do Fabricator(:admin, from: :user) do
@ -58,6 +62,10 @@ Fabricator(:admin, from: :user) do
username { sequence(:username) { |i| "anne#{i}" } } username { sequence(:username) { |i| "anne#{i}" } }
email { sequence(:email) { |i| "anne#{i}@discourse.org" } } email { sequence(:email) { |i| "anne#{i}@discourse.org" } }
admin true admin true
after_create do |user|
user.group_users << Fabricate(:group_user, user: user, group: Group[:admins])
end
end end
Fabricator(:newuser, from: :user) do Fabricator(:newuser, from: :user) do

View File

@ -6,7 +6,7 @@ describe Imap::Sync do
before do before do
SiteSetting.tagging_enabled = true SiteSetting.tagging_enabled = true
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
SiteSetting.enable_imap = true SiteSetting.enable_imap = true
@ -103,7 +103,6 @@ describe Imap::Sync do
context "when tagging not enabled" do context "when tagging not enabled" do
before do before do
SiteSetting.tagging_enabled = false SiteSetting.tagging_enabled = false
SiteSetting.allow_staff_to_tag_pms = false
end end
it "creates a topic from an incoming email but with no tags added" do it "creates a topic from an incoming email but with no tags added" do

View File

@ -1264,8 +1264,8 @@ describe PostMover do
)).to eq(true) )).to eq(true)
end end
it "can add tags to new message when allow_staff_to_tag_pms is enabled" do it "can add tags to new message when staff group is included in pm_tags_allowed_for_groups" do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
personal_message.move_posts(admin, [p2.id, p5.id], title: "new testing message name", tags: ["tag1", "tag2"], archetype: "private_message") personal_message.move_posts(admin, [p2.id, p5.id], title: "new testing message name", tags: ["tag1", "tag2"], archetype: "private_message")
p2.reload p2.reload

View File

@ -160,13 +160,13 @@ describe Tag do
expect(Tag.pm_tags(guardian: Guardian.new(regular_user))).to be_empty expect(Tag.pm_tags(guardian: Guardian.new(regular_user))).to be_empty
end end
it "returns nothing if allow_staff_to_tag_pms setting is disabled" do it "returns nothing if pm_tags_allowed_for_groups setting is empty" do
SiteSetting.allow_staff_to_tag_pms = false SiteSetting.pm_tags_allowed_for_groups = ""
expect(Tag.pm_tags(guardian: Guardian.new(admin)).sort).to be_empty expect(Tag.pm_tags(guardian: Guardian.new(admin)).sort).to be_empty
end end
it "returns all pm tags if user is a staff and pm tagging is enabled" do it "returns all pm tags if user is a staff and pm tagging is enabled" do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
tags = Tag.pm_tags(guardian: Guardian.new(admin), allowed_user: regular_user) tags = Tag.pm_tags(guardian: Guardian.new(admin), allowed_user: regular_user)
expect(tags.length).to eq(2) expect(tags.length).to eq(2)
expect(tags.map { |t| t[:id] }).to contain_exactly("tag-0", "tag-1") expect(tags.map { |t| t[:id] }).to contain_exactly("tag-0", "tag-1")

View File

@ -333,7 +333,7 @@ describe CategoriesController do
describe "logged in" do describe "logged in" do
it "raises an exception if they don't have permission to see it" do it "raises an exception if they don't have permission to see it" do
admin.update!(admin: false) admin.update!(admin: false, group_users: [])
sign_in(admin) sign_in(admin)
get "/c/#{category.id}/show.json" get "/c/#{category.id}/show.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)

View File

@ -91,7 +91,7 @@ describe GroupsController do
sign_in(user) sign_in(user)
end end
fab!(:other_group) { Fabricate(:group, name: "other_group", users: [user, other_user]) } fab!(:group_with_2_users) { Fabricate(:group, name: "other_group", users: [user, other_user]) }
context "with default (descending) order" do context "with default (descending) order" do
it "sorts by name" do it "sorts by name" do
@ -102,7 +102,7 @@ describe GroupsController do
body = response.parsed_body body = response.parsed_body
expect(body["groups"].map { |g| g["id"] }).to eq([ expect(body["groups"].map { |g| g["id"] }).to eq([
other_group.id, group.id, moderator_group_id group_with_2_users.id, group.id, moderator_group_id
]) ])
expect(body["load_more_groups"]).to eq("/groups?order=name&page=1") expect(body["load_more_groups"]).to eq("/groups?order=name&page=1")
@ -116,7 +116,7 @@ describe GroupsController do
body = response.parsed_body body = response.parsed_body
expect(body["groups"].map { |g| g["id"] }).to eq([ expect(body["groups"].map { |g| g["id"] }).to eq([
other_group.id, group.id, moderator_group_id group_with_2_users.id, moderator_group_id, group.id
]) ])
expect(body["load_more_groups"]).to eq("/groups?order=user_count&page=1") expect(body["load_more_groups"]).to eq("/groups?order=user_count&page=1")
@ -132,7 +132,7 @@ describe GroupsController do
body = response.parsed_body body = response.parsed_body
expect(body["groups"].map { |g| g["id"] }).to eq([ expect(body["groups"].map { |g| g["id"] }).to eq([
moderator_group_id, group.id, other_group.id moderator_group_id, group.id, group_with_2_users.id
]) ])
expect(body["load_more_groups"]).to eq("/groups?asc=true&order=name&page=1") expect(body["load_more_groups"]).to eq("/groups?asc=true&order=name&page=1")
@ -146,7 +146,7 @@ describe GroupsController do
body = response.parsed_body body = response.parsed_body
expect(body["groups"].map { |g| g["id"] }).to eq([ expect(body["groups"].map { |g| g["id"] }).to eq([
moderator_group_id, group.id, other_group.id moderator_group_id, group.id, group_with_2_users.id
]) ])
expect(body["load_more_groups"]).to eq("/groups?asc=true&order=user_count&page=1") expect(body["load_more_groups"]).to eq("/groups?asc=true&order=user_count&page=1")
@ -297,18 +297,18 @@ describe GroupsController do
end end
describe 'my groups' do describe 'my groups' do
it 'should return the right response' do it 'should return the groups admin is a member of' do
expect_type_to_return_right_groups('my', [group.id]) expect_type_to_return_right_groups('my', admin.group_users.map(&:group_id))
end end
end end
describe 'owner groups' do describe 'owner groups' do
it 'should return the right response' do it 'should return the groups admin is a owner of' do
group2 = Fabricate(:group) group2 = Fabricate(:group)
_group3 = Fabricate(:group) _group3 = Fabricate(:group)
group2.add_owner(admin) group2.add_owner(admin)
expect_type_to_return_right_groups('owner', [group.id, group2.id]) expect_type_to_return_right_groups('owner', admin.group_users.where(owner: true).map(&:group_id))
end end
end end
@ -794,8 +794,7 @@ describe GroupsController do
context "when user is group admin" do context "when user is group admin" do
before do before do
user.update!(admin: true) sign_in(admin)
sign_in(user)
end end
it 'should be able to update the group' do it 'should be able to update the group' do
@ -839,7 +838,7 @@ describe GroupsController do
.to eq(group.id) .to eq(group.id)
end end
it "should be able to update an automatic group" do it "they should be able to update an automatic group" do
group = Group.find(Group::AUTO_GROUPS[:admins]) group = Group.find(Group::AUTO_GROUPS[:admins])
group.update!( group.update!(
@ -861,7 +860,8 @@ describe GroupsController do
default_notification_level: 1, default_notification_level: 1,
tracking_category_ids: [category.id], tracking_category_ids: [category.id],
tracking_tags: [tag.name] tracking_tags: [tag.name]
} },
update_existing_users: false
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)

View File

@ -148,7 +148,7 @@ RSpec.describe ListController do
before do before do
SiteSetting.tagging_enabled = true SiteSetting.tagging_enabled = true
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
Fabricate(:topic_tag, tag: tag, topic: private_message) Fabricate(:topic_tag, tag: tag, topic: private_message)
end end
@ -158,8 +158,8 @@ RSpec.describe ListController do
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
it 'should fail for staff users if disabled' do it 'should fail for staff users if empty' do
SiteSetting.allow_staff_to_tag_pms = false SiteSetting.pm_tags_allowed_for_groups = ""
[moderator, admin].each do |user| [moderator, admin].each do |user|
sign_in(user) sign_in(user)

View File

@ -30,7 +30,7 @@ describe TagsController do
end end
end end
context "with allow_staff_to_tag_pms" do context "with pm_tags_allowed_for_groups" do
fab!(:admin) { Fabricate(:admin) } fab!(:admin) { Fabricate(:admin) }
fab!(:topic) { Fabricate(:topic, tags: [topic_tag]) } fab!(:topic) { Fabricate(:topic, tags: [topic_tag]) }
fab!(:pm) do fab!(:pm) do
@ -45,7 +45,7 @@ describe TagsController do
context "enabled" do context "enabled" do
before do before do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
sign_in(admin) sign_in(admin)
end end
@ -66,7 +66,7 @@ describe TagsController do
context "disabled" do context "disabled" do
before do before do
SiteSetting.allow_staff_to_tag_pms = false SiteSetting.pm_tags_allowed_for_groups = ""
sign_in(admin) sign_in(admin)
end end
@ -239,7 +239,7 @@ describe TagsController do
end end
it "handles special tag 'none'" do it "handles special tag 'none'" do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
sign_in(admin) sign_in(admin)
@ -477,7 +477,7 @@ describe TagsController do
fab!(:tag) { Fabricate(:tag, topics: [personal_message], name: 'test') } fab!(:tag) { Fabricate(:tag, topics: [personal_message], name: 'test') }
before do before do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
end end
context "as a regular user" do context "as a regular user" do

View File

@ -417,7 +417,7 @@ RSpec.describe TopicsController do
before { sign_in(admin) } before { sign_in(admin) }
it "returns success" do it "returns success" do
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
expect do expect do
post "/t/#{message.id}/move-posts.json", params: { post "/t/#{message.id}/move-posts.json", params: {

View File

@ -14,6 +14,7 @@ describe TopicViewSerializer do
fab!(:topic) { Fabricate(:topic) } fab!(:topic) { Fabricate(:topic) }
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:user_2) { Fabricate(:user) }
fab!(:admin) { Fabricate(:admin) } fab!(:admin) { Fabricate(:admin) }
describe '#featured_link and #featured_link_root_domain' do describe '#featured_link and #featured_link_root_domain' do
@ -198,9 +199,17 @@ describe TopicViewSerializer do
]) ])
end end
fab!(:group) { Fabricate(:group) }
fab!(:pm_between_reg_users) do
Fabricate(:private_message_topic, tags: [tag], topic_allowed_users: [
Fabricate.build(:topic_allowed_user, user: user),
Fabricate.build(:topic_allowed_user, user: user_2)
])
end
before do before do
SiteSetting.tagging_enabled = true SiteSetting.tagging_enabled = true
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3|4"
end end
it "should not include the tag for normal users" do it "should not include the tag for normal users" do
@ -215,8 +224,19 @@ describe TopicViewSerializer do
end end
end end
it "should include the tag for users in allowed groups" do
SiteSetting.pm_tags_allowed_for_groups = "1|2|3|#{group.id}"
user.group_users << Fabricate(:group_user, group: group, user: user)
json = serialize_topic(pm_between_reg_users, user)
expect(json[:tags]).to eq([tag.name])
json = serialize_topic(pm_between_reg_users, user_2)
expect(json[:tags]).to eq(nil)
end
it "should not include the tag if pm tags disabled" do it "should not include the tag if pm tags disabled" do
SiteSetting.allow_staff_to_tag_pms = false SiteSetting.pm_tags_allowed_for_groups = ""
[moderator, admin].each do |user| [moderator, admin].each do |user|
json = serialize_topic(pm, user) json = serialize_topic(pm, user)

View File

@ -1438,7 +1438,7 @@ describe PostAlerter do
before do before do
SiteSetting.tagging_enabled = true SiteSetting.tagging_enabled = true
SiteSetting.allow_staff_to_tag_pms = true SiteSetting.pm_tags_allowed_for_groups = "1|2|3"
Jobs.run_immediately! Jobs.run_immediately!
TopicUser.change(user.id, post.topic.id, notification_level: TopicUser.notification_levels[:watching]) TopicUser.change(user.id, post.topic.id, notification_level: TopicUser.notification_levels[:watching])
TopicUser.change(staged.id, post.topic.id, notification_level: TopicUser.notification_levels[:watching]) TopicUser.change(staged.id, post.topic.id, notification_level: TopicUser.notification_levels[:watching])