diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 069768cc457..e635a8815d9 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -144,6 +144,10 @@ class ListController < ApplicationController def self.generate_message_route(action) define_method("#{action}") do + if action == :private_messages_tag && !guardian.can_tag_pms? + raise Discourse::NotFound + end + list_opts = build_topic_list_options target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option]) guardian.ensure_can_see_private_messages!(target_user.id) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 51cbb5297b5..16b697bf0c6 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -37,10 +37,10 @@ class TagsController < ::ApplicationController ungrouped_tags = ungrouped_tags.where("tags.topic_count > 0") unless show_all_tags grouped_tag_counts = TagGroup.visible(guardian).order('name ASC').includes(:tags).map do |tag_group| - { id: tag_group.id, name: tag_group.name, tags: self.class.tag_counts_json(tag_group.tags.where(target_tag_id: nil)) } + { id: tag_group.id, name: tag_group.name, tags: self.class.tag_counts_json(tag_group.tags.where(target_tag_id: nil), show_pm_tags: guardian.can_tag_pms?) } end - @tags = self.class.tag_counts_json(ungrouped_tags) + @tags = self.class.tag_counts_json(ungrouped_tags, show_pm_tags: guardian.can_tag_pms?) @extras = { tag_groups: grouped_tag_counts } else tags = show_all_tags ? Tag.all : Tag.where("tags.topic_count > 0") @@ -54,7 +54,7 @@ class TagsController < ::ApplicationController { id: c.id, tags: self.class.tag_counts_json(c.tags.where(target_tag_id: nil)) } end - @tags = self.class.tag_counts_json(unrestricted_tags) + @tags = self.class.tag_counts_json(unrestricted_tags, show_pm_tags: guardian.can_tag_pms?) @extras = { categories: category_tag_counts } end @@ -231,7 +231,7 @@ class TagsController < ::ApplicationController filter_params ) - tags = self.class.tag_counts_json(tags_with_counts) + tags = self.class.tag_counts_json(tags_with_counts, show_pm_tags: guardian.can_tag_pms?) json_response = { results: tags } @@ -336,17 +336,19 @@ class TagsController < ::ApplicationController raise Discourse::NotFound if DiscourseTagging.hidden_tag_names(guardian).include?(params[:tag_id]) end - def self.tag_counts_json(tags) + def self.tag_counts_json(tags, show_pm_tags: true) target_tags = Tag.where(id: tags.map(&:target_tag_id).compact.uniq).select(:id, :name) tags.map do |t| + next if t.topic_count == 0 && t.pm_topic_count > 0 && !show_pm_tags + { id: t.name, text: t.name, count: t.topic_count, - pm_count: t.pm_topic_count, + pm_count: show_pm_tags ? t.pm_topic_count : 0, target_tag: t.target_tag_id ? target_tags.find { |x| x.id == t.target_tag_id }&.name : nil } - end + end.compact end def set_category_from_params diff --git a/config/routes.rb b/config/routes.rb index 0de10003e56..f34b9123d42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -736,7 +736,7 @@ Discourse::Application.routes.draw do get "private-messages-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent", defaults: { format: :json } get "private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive", defaults: { format: :json } get "private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread", defaults: { format: :json } - get "private-messages-tags/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", constraints: StaffConstraint.new + get "private-messages-tags/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", defaults: { format: :json } get "groups/:group_name" => "list#group_topics", as: "group_topics", group_name: RouteFormat.username scope "/private-messages-group/:username", group_name: RouteFormat.username do diff --git a/spec/requests/list_controller_spec.rb b/spec/requests/list_controller_spec.rb index 710b044467f..2fea625c058 100644 --- a/spec/requests/list_controller_spec.rb +++ b/spec/requests/list_controller_spec.rb @@ -142,6 +142,16 @@ RSpec.describe ListController do expect(response.status).to eq(404) end + it 'should fail for staff users if disabled' do + SiteSetting.allow_staff_to_tag_pms = false + + [moderator, admin].each do |user| + sign_in(user) + get "/topics/private-messages-tags/#{user.username}/#{tag.name}.json" + expect(response.status).to eq(404) + end + end + it 'should be success for staff users' do [moderator, admin].each do |user| sign_in(user) diff --git a/spec/requests/tags_controller_spec.rb b/spec/requests/tags_controller_spec.rb index 926e506e35c..53b1cf96ba3 100644 --- a/spec/requests/tags_controller_spec.rb +++ b/spec/requests/tags_controller_spec.rb @@ -33,6 +33,55 @@ describe TagsController do end end + context "with allow_staff_to_tag_pms" do + fab!(:admin) { Fabricate(:admin) } + fab!(:topic) { Fabricate(:topic, tags: [topic_tag]) } + fab!(:pm) do + Fabricate( + :private_message_topic, + tags: [test_tag], + topic_allowed_users: [ + Fabricate.build(:topic_allowed_user, user: admin) + ] + ) + end + + context "enabled" do + before do + SiteSetting.allow_staff_to_tag_pms = true + sign_in(admin) + end + + it "shows topic tags and pm tags" do + get "/tags.json" + tags = response.parsed_body["tags"] + expect(tags.length).to eq(2) + + serialized_tag = tags.find { |t| t["id"] == topic_tag.name } + expect(serialized_tag["count"]).to eq(2) + expect(serialized_tag["pm_count"]).to eq(0) + + serialized_tag = tags.find { |t| t["id"] == test_tag.name } + expect(serialized_tag["count"]).to eq(0) + expect(serialized_tag["pm_count"]).to eq(1) + end + end + + context "disabled" do + before do + SiteSetting.allow_staff_to_tag_pms = false + sign_in(admin) + end + + it "hides pm tags" do + get "/tags.json" + tags = response.parsed_body["tags"] + expect(tags.length).to eq(1) + expect(tags[0]["id"]).to eq(topic_tag.name) + end + end + end + context "with tags_listed_by_group enabled" do before { SiteSetting.tags_listed_by_group = true } include_examples "successfully retrieve tags with topic_count > 0"