From 6d68275ef9fb63f13c1ba14b8d172efec3090b05 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Fri, 12 Jan 2018 14:24:58 -0500 Subject: [PATCH] don't show tag groups if they're restricted to categories you can't access --- app/controllers/tags_controller.rb | 2 +- app/models/tag_group.rb | 13 ++++++++++ spec/models/tag_group_spec.rb | 41 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 spec/models/tag_group_spec.rb diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index a0bb276fde0..a73416d04f3 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -30,7 +30,7 @@ class TagsController < ::ApplicationController format.json do if SiteSetting.tags_listed_by_group - grouped_tag_counts = TagGroup.order('name ASC').includes(:tags).map do |tag_group| + grouped_tag_counts = TagGroup.allowed(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) } end diff --git a/app/models/tag_group.rb b/app/models/tag_group.rb index 772d9036272..ccc97798d0f 100644 --- a/app/models/tag_group.rb +++ b/app/models/tag_group.rb @@ -21,6 +21,19 @@ class TagGroup < ActiveRecord::Base end end end + + def self.allowed(guardian) + if guardian.is_staff? + TagGroup + else + category_permissions_filter = <<~SQL + id IN ( SELECT tag_group_id FROM category_tag_groups WHERE category_id IN (?)) + OR id NOT IN (SELECT tag_group_id FROM category_tag_groups) + SQL + + TagGroup.where(category_permissions_filter, guardian.allowed_category_ids) + end + end end # == Schema Information diff --git a/spec/models/tag_group_spec.rb b/spec/models/tag_group_spec.rb new file mode 100644 index 00000000000..8dc4d45373a --- /dev/null +++ b/spec/models/tag_group_spec.rb @@ -0,0 +1,41 @@ +require 'rails_helper' + +describe TagGroup do + describe '#allowed' do + let(:user1) { Fabricate(:user) } + let(:user2) { Fabricate(:user) } + let(:admin) { Fabricate(:admin) } + let(:moderator) { Fabricate(:moderator) } + + let(:group) { Fabricate(:group) } + + let!(:public_tag_group) { Fabricate(:tag_group, name: 'Public', tag_names: ['public1']) } + let!(:private_tag_group) { Fabricate(:tag_group, name: 'Private', tag_names: ['privatetag1']) } + let!(:staff_tag_group) { Fabricate(:tag_group, name: 'Staff Talk', tag_names: ['stafftag1']) } + let!(:unrestricted_tag_group) { Fabricate(:tag_group, name: 'Unrestricted', tag_names: ['use-anywhere']) } + + let!(:public_category) { Fabricate(:category, name: 'Public Category') } + let!(:private_category) { Fabricate(:private_category, group: group) } + let(:staff_category) { Fabricate(:category, name: 'Secret') } + + before do + group.add(user2) + group.save! + staff_category.set_permissions(admins: :full) + staff_category.save! + private_category.set_permissions(staff: :full, group => :full) + private_category.save! + public_category.allowed_tag_groups = [public_tag_group.name] + private_category.allowed_tag_groups = [private_tag_group.name] + staff_category.allowed_tag_groups = [staff_tag_group.name] + end + + it "returns correct groups based on category permissions" do + expect(TagGroup.allowed(Guardian.new(admin)).pluck(:name)).to match_array(TagGroup.pluck(:name)) + expect(TagGroup.allowed(Guardian.new(moderator)).pluck(:name)).to match_array(TagGroup.pluck(:name)) + expect(TagGroup.allowed(Guardian.new(user2)).pluck(:name)).to match_array([public_tag_group.name, unrestricted_tag_group.name, private_tag_group.name]) + expect(TagGroup.allowed(Guardian.new(user1)).pluck(:name)).to match_array([public_tag_group.name, unrestricted_tag_group.name]) + expect(TagGroup.allowed(Guardian.new(nil)).pluck(:name)).to match_array([public_tag_group.name, unrestricted_tag_group.name]) + end + end +end