diff --git a/lib/discourse_tagging.rb b/lib/discourse_tagging.rb index bf635e79439..b991595f0d5 100644 --- a/lib/discourse_tagging.rb +++ b/lib/discourse_tagging.rb @@ -11,9 +11,12 @@ module DiscourseTagging new_tag_names = tag_names - old_tag_names removed_tag_names = old_tag_names - tag_names + hidden_tags = DiscourseTagging.hidden_tag_names + # Protect staff-only tags unless guardian.is_staff? - staff_tags = DiscourseTagging.staff_only_tags(new_tag_names) + staff_tags = DiscourseTagging.staff_only_tags(new_tag_names) || [] + staff_tags += hidden_tags & new_tag_names if staff_tags.present? topic.errors[:base] << I18n.t("tags.staff_tag_disallowed", tag: staff_tags.join(" ")) return false @@ -24,6 +27,8 @@ module DiscourseTagging topic.errors[:base] << I18n.t("tags.staff_tag_remove_disallowed", tag: staff_tags.join(" ")) return false end + + tag_names += removed_tag_names & hidden_tags end category = topic.category diff --git a/spec/components/discourse_tagging_spec.rb b/spec/components/discourse_tagging_spec.rb index 60ed771a938..51a636fca26 100644 --- a/spec/components/discourse_tagging_spec.rb +++ b/spec/components/discourse_tagging_spec.rb @@ -125,5 +125,28 @@ describe DiscourseTagging do expect(topic.errors[:base]).to be_empty end end + + context 'hidden tags' do + let(:hidden_tag) { Fabricate(:tag) } + let!(:staff_tag_group) { Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: [hidden_tag.name]) } + let(:topic) { Fabricate(:topic, user: user) } + let(:post) { Fabricate(:post, user: user, topic: topic, post_number: 1) } + + it 'user cannot add hidden tag by knowing its name' do + expect(PostRevisor.new(post).revise!(topic.user, raw: post.raw + " edit", tags: [hidden_tag.name])).to be_falsey + expect(topic.reload.tags).to be_empty + end + + it 'admin can add hidden tag' do + expect(PostRevisor.new(post).revise!(admin, raw: post.raw, tags: [hidden_tag.name])).to be_truthy + expect(topic.reload.tags).to eq([hidden_tag]) + end + + it 'user does not get an error when editing their topic with a hidden tag' do + PostRevisor.new(post).revise!(admin, raw: post.raw, tags: [hidden_tag.name]) + expect(PostRevisor.new(post).revise!(topic.user, raw: post.raw + " edit", tags: [])).to be_truthy + expect(topic.reload.tags).to eq([hidden_tag]) + end + end end end