FIX: tags in a 'visible by everyone but usable only by staff' group weren't visible by everyone
This commit is contained in:
parent
6ee0eae335
commit
5e97a9bfb7
|
@ -1,71 +1,62 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import RestModel from 'discourse/models/rest';
|
import RestModel from "discourse/models/rest";
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
import PermissionType from 'discourse/models/permission-type';
|
import PermissionType from "discourse/models/permission-type";
|
||||||
|
|
||||||
const TagGroup = RestModel.extend({
|
export default RestModel.extend({
|
||||||
@computed('name', 'tag_names')
|
@computed("name", "tag_names", "saving")
|
||||||
disableSave() {
|
disableSave(name, tagNames, saving) {
|
||||||
return Ember.isEmpty(this.get('name')) || Ember.isEmpty(this.get('tag_names')) || this.get('saving');
|
return saving || Ember.isEmpty(name) || Ember.isEmpty(tagNames);
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('permissions')
|
@computed("permissions")
|
||||||
permissionName: {
|
permissionName: {
|
||||||
get(permissions) {
|
get(permissions) {
|
||||||
if (!permissions) return 'public';
|
if (!permissions) return "public";
|
||||||
|
|
||||||
if (permissions['everyone'] === PermissionType.FULL) {
|
if (permissions["everyone"] === PermissionType.FULL) {
|
||||||
return 'public';
|
return "public";
|
||||||
} else if (permissions['everyone'] === PermissionType.READONLY) {
|
} else if (permissions["everyone"] === PermissionType.READONLY) {
|
||||||
return 'visible';
|
return "visible";
|
||||||
} else {
|
} else {
|
||||||
return 'private';
|
return "private";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value === 'private') {
|
if (value === "private") {
|
||||||
this.set('permissions', {'staff': PermissionType.FULL});
|
this.set("permissions", { "staff": PermissionType.FULL });
|
||||||
} else if (value === 'visible') {
|
} else if (value === "visible") {
|
||||||
this.set('permissions', {'staff': PermissionType.FULL, 'everyone': PermissionType.READONLY});
|
this.set("permissions", { "staff": PermissionType.FULL, "everyone": PermissionType.READONLY });
|
||||||
} else {
|
} else {
|
||||||
this.set('permissions', {'everyone': PermissionType.FULL});
|
this.set("permissions", { "everyone": PermissionType.FULL });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
let url = "/tag_groups";
|
this.set("savingStatus", I18n.t("saving"));
|
||||||
const self = this,
|
this.set("saving", true);
|
||||||
isNew = this.get('id') === 'new';
|
|
||||||
if (!isNew) {
|
|
||||||
url = "/tag_groups/" + this.get('id');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.set('savingStatus', I18n.t('saving'));
|
const isNew = this.get("id") === "new";
|
||||||
this.set('saving', true);
|
const url = isNew ? "/tag_groups" : `/tag_groups/${this.get("id")}`;
|
||||||
|
const data = this.getProperties("name", "tag_names", "parent_tag_name", "one_per_topic", "permissions");
|
||||||
|
|
||||||
return ajax(url, {
|
return ajax(url, {
|
||||||
data: {
|
data,
|
||||||
name: this.get('name'),
|
type: isNew ? "POST" : "PUT"
|
||||||
tag_names: this.get('tag_names'),
|
}).then(result => {
|
||||||
parent_tag_name: this.get('parent_tag_name') ? this.get('parent_tag_name') : undefined,
|
if (result.tag_group && result.tag_group.id) {
|
||||||
one_per_topic: this.get('one_per_topic'),
|
this.set("id", result.tag_group.id);
|
||||||
permissions: this.get('permissions')
|
|
||||||
},
|
|
||||||
type: isNew ? 'POST' : 'PUT'
|
|
||||||
}).then(function(result) {
|
|
||||||
if(result.tag_group && result.tag_group.id) {
|
|
||||||
self.set('id', result.tag_group.id);
|
|
||||||
}
|
}
|
||||||
self.set('savingStatus', I18n.t('saved'));
|
}).finally(() => {
|
||||||
self.set('saving', false);
|
this.set("savingStatus", I18n.t("saved"));
|
||||||
|
this.set("saving", false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
return ajax("/tag_groups/" + this.get('id'), {type: "DELETE"});
|
return ajax(`/tag_groups/${this.get("id")}`, { type: "DELETE" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default TagGroup;
|
|
||||||
|
|
|
@ -30,15 +30,15 @@
|
||||||
|
|
||||||
<section class="group-visibility">
|
<section class="group-visibility">
|
||||||
<div>
|
<div>
|
||||||
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="public" id="public-permission" selection=model.permissionName}}
|
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="public" id="public-permission" selection=model.permissionName onChange="changed"}}
|
||||||
<label class="radio" for="public-permission">{{i18n 'tagging.groups.everyone_can_use'}}</label>
|
<label class="radio" for="public-permission">{{i18n 'tagging.groups.everyone_can_use'}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="visible" id="visible-permission" selection=model.permissionName}}
|
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="visible" id="visible-permission" selection=model.permissionName onChange="changed"}}
|
||||||
<label class="radio" for="visible-permission">{{i18n 'tagging.groups.usable_only_by_staff'}}</label>
|
<label class="radio" for="visible-permission">{{i18n 'tagging.groups.usable_only_by_staff'}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="private" id="private-permission" selection=model.permissionName}}
|
{{radio-button class="tag-permissions-choice" name="tag-permissions-choice" value="private" id="private-permission" selection=model.permissionName onChange="changed"}}
|
||||||
<label class="radio" for="private-permission">{{i18n 'tagging.groups.visible_only_to_staff'}}</label>
|
<label class="radio" for="private-permission">{{i18n 'tagging.groups.visible_only_to_staff'}}</label>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TagGroupsController < ApplicationController
|
||||||
if @tag_group.save
|
if @tag_group.save
|
||||||
render_serialized(@tag_group, TagGroupSerializer)
|
render_serialized(@tag_group, TagGroupSerializer)
|
||||||
else
|
else
|
||||||
return render_json_error(@tag_group)
|
render_json_error(@tag_group)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,8 +52,7 @@ class TagGroupsController < ApplicationController
|
||||||
|
|
||||||
def search
|
def search
|
||||||
matches = if params[:q].present?
|
matches = if params[:q].present?
|
||||||
term = params[:q].strip.downcase
|
TagGroup.where('lower(name) ILIKE ?', "%#{params[:q].strip}%")
|
||||||
TagGroup.where('lower(name) like ?', "%#{term}%")
|
|
||||||
else
|
else
|
||||||
TagGroup.all
|
TagGroup.all
|
||||||
end
|
end
|
||||||
|
@ -82,7 +81,7 @@ class TagGroupsController < ApplicationController
|
||||||
:one_per_topic,
|
:one_per_topic,
|
||||||
tag_names: [],
|
tag_names: [],
|
||||||
parent_tag_name: [],
|
parent_tag_name: [],
|
||||||
permissions: [*permissions&.keys]
|
permissions: permissions&.keys,
|
||||||
)
|
)
|
||||||
result[:tag_names] ||= []
|
result[:tag_names] ||= []
|
||||||
result[:parent_tag_name] ||= []
|
result[:parent_tag_name] ||= []
|
||||||
|
|
|
@ -32,27 +32,26 @@ class TagsController < ::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
ungrouped_tags = Tag.where("tags.id NOT IN (select tag_id from tag_group_memberships)")
|
show_all_tags = guardian.can_admin_tags? && guardian.is_admin?
|
||||||
|
|
||||||
# show all the tags to admins
|
|
||||||
unless guardian.can_admin_tags? && guardian.is_admin?
|
|
||||||
ungrouped_tags = ungrouped_tags.where("tags.topic_count > 0")
|
|
||||||
end
|
|
||||||
|
|
||||||
if SiteSetting.tags_listed_by_group
|
if SiteSetting.tags_listed_by_group
|
||||||
grouped_tag_counts = TagGroup.allowed(guardian).order('name ASC').includes(:tags).map do |tag_group|
|
ungrouped_tags = Tag.where("tags.id NOT IN (SELECT tag_id FROM tag_group_memberships)")
|
||||||
|
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) }
|
{ id: tag_group.id, name: tag_group.name, tags: self.class.tag_counts_json(tag_group.tags) }
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
tags: self.class.tag_counts_json(ungrouped_tags), # tags that don't belong to a group
|
tags: self.class.tag_counts_json(ungrouped_tags),
|
||||||
extras: { tag_groups: grouped_tag_counts }
|
extras: { tag_groups: grouped_tag_counts }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
unrestricted_tags = DiscourseTagging.filter_visible(ungrouped_tags, guardian)
|
tags = show_all_tags ? Tag.all : Tag.where("tags.topic_count > 0")
|
||||||
|
unrestricted_tags = DiscourseTagging.filter_visible(tags, guardian)
|
||||||
|
|
||||||
categories = Category.where("id in (select category_id from category_tags)")
|
categories = Category.where("id IN (SELECT category_id FROM category_tags)")
|
||||||
.where("id in (?)", guardian.allowed_category_ids)
|
.where("id IN (?)", guardian.allowed_category_ids)
|
||||||
.includes(:tags)
|
.includes(:tags)
|
||||||
|
|
||||||
category_tag_counts = categories.map do |c|
|
category_tag_counts = categories.map do |c|
|
||||||
|
|
|
@ -39,9 +39,6 @@ class TagGroup < ActiveRecord::Base
|
||||||
mapped = permissions.map do |group, permission|
|
mapped = permissions.map do |group, permission|
|
||||||
group_id = Group.group_id_from_param(group)
|
group_id = Group.group_id_from_param(group)
|
||||||
permission = TagGroupPermission.permission_types[permission] unless permission.is_a?(Integer)
|
permission = TagGroupPermission.permission_types[permission] unless permission.is_a?(Integer)
|
||||||
|
|
||||||
return [] if group_id == everyone_group_id && permission == full
|
|
||||||
|
|
||||||
[group_id, permission]
|
[group_id, permission]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -65,27 +62,21 @@ class TagGroup < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.allowed(guardian)
|
def self.visible(guardian)
|
||||||
if guardian.is_staff?
|
if guardian.is_staff?
|
||||||
TagGroup
|
TagGroup
|
||||||
else
|
else
|
||||||
category_permissions_filter_sql = <<~SQL
|
filter_sql = <<~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))
|
id IN (SELECT tag_group_id FROM category_tag_groups WHERE category_id IN (?))
|
||||||
AND id IN (
|
) OR (
|
||||||
SELECT tag_group_id
|
id NOT IN (SELECT tag_group_id FROM category_tag_groups)
|
||||||
FROM tag_group_permissions
|
AND
|
||||||
WHERE group_id = ?
|
id IN (SELECT tag_group_id FROM tag_group_permissions WHERE group_id = ?)
|
||||||
AND permission_type = ?
|
|
||||||
)
|
)
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
TagGroup.where(
|
TagGroup.where(filter_sql, guardian.allowed_category_ids, Group::AUTO_GROUPS[:everyone])
|
||||||
category_permissions_filter_sql,
|
|
||||||
guardian.allowed_category_ids,
|
|
||||||
Group::AUTO_GROUPS[:everyone],
|
|
||||||
TagGroupPermission.permission_types[:full]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe TagGroup do
|
describe TagGroup do
|
||||||
describe '#allowed' do
|
describe '#visible' do
|
||||||
let(:user1) { Fabricate(:user) }
|
let(:user1) { Fabricate(:user) }
|
||||||
let(:user2) { Fabricate(:user) }
|
let(:user2) { Fabricate(:user) }
|
||||||
let(:admin) { Fabricate(:admin) }
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
@ -9,6 +9,10 @@ describe TagGroup do
|
||||||
|
|
||||||
let(:group) { Fabricate(:group) }
|
let(:group) { Fabricate(:group) }
|
||||||
|
|
||||||
|
let!(:everyone_tag_group) { Fabricate(:tag_group, name: 'Visible & usable by everyone', tag_names: ['foo-bar']) }
|
||||||
|
let!(:visible_tag_group) { Fabricate(:tag_group, name: 'Visible by everyone, usable by staff', tag_names: ['foo']) }
|
||||||
|
let!(:staff_only_tag_group) { Fabricate(:tag_group, name: 'Staff only', tag_names: ['bar']) }
|
||||||
|
|
||||||
let!(:public_tag_group) { Fabricate(:tag_group, name: 'Public', tag_names: ['public1']) }
|
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!(: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!(:staff_tag_group) { Fabricate(:tag_group, name: 'Staff Talk', tag_names: ['stafftag1']) }
|
||||||
|
@ -16,26 +20,56 @@ describe TagGroup do
|
||||||
|
|
||||||
let!(:public_category) { Fabricate(:category, name: 'Public Category') }
|
let!(:public_category) { Fabricate(:category, name: 'Public Category') }
|
||||||
let!(:private_category) { Fabricate(:private_category, group: group) }
|
let!(:private_category) { Fabricate(:private_category, group: group) }
|
||||||
let(:staff_category) { Fabricate(:category, name: 'Secret') }
|
let!(:staff_category) { Fabricate(:category, name: 'Secret') }
|
||||||
|
|
||||||
|
let(:everyone) { Group::AUTO_GROUPS[:everyone] }
|
||||||
|
let(:staff) { Group::AUTO_GROUPS[:staff] }
|
||||||
|
|
||||||
|
let(:full) { TagGroupPermission.permission_types[:full] }
|
||||||
|
let(:readonly) { TagGroupPermission.permission_types[:readonly] }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
group.add(user2)
|
group.add(user2)
|
||||||
group.save!
|
group.save!
|
||||||
|
|
||||||
staff_category.set_permissions(admins: :full)
|
staff_category.set_permissions(admins: :full)
|
||||||
staff_category.save!
|
staff_category.save!
|
||||||
|
|
||||||
private_category.set_permissions(staff: :full, group => :full)
|
private_category.set_permissions(staff: :full, group => :full)
|
||||||
private_category.save!
|
private_category.save!
|
||||||
|
|
||||||
public_category.allowed_tag_groups = [public_tag_group.name]
|
public_category.allowed_tag_groups = [public_tag_group.name]
|
||||||
private_category.allowed_tag_groups = [private_tag_group.name]
|
private_category.allowed_tag_groups = [private_tag_group.name]
|
||||||
staff_category.allowed_tag_groups = [staff_tag_group.name]
|
staff_category.allowed_tag_groups = [staff_tag_group.name]
|
||||||
|
|
||||||
|
everyone_tag_group.permissions = [[everyone, full]]
|
||||||
|
everyone_tag_group.save!
|
||||||
|
|
||||||
|
visible_tag_group.permissions = [[everyone, readonly], [staff, full]]
|
||||||
|
visible_tag_group.save!
|
||||||
|
|
||||||
|
staff_only_tag_group.permissions = [[staff, full]]
|
||||||
|
staff_only_tag_group.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns correct groups based on category permissions" do
|
it "returns correct groups based on category & tag group permissions" do
|
||||||
expect(TagGroup.allowed(Guardian.new(admin)).pluck(:name)).to match_array(TagGroup.pluck(:name))
|
expect(TagGroup.visible(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.visible(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.visible(Guardian.new(user2)).pluck(:name)).to match_array([
|
||||||
expect(TagGroup.allowed(Guardian.new(nil)).pluck(:name)).to match_array([public_tag_group.name, unrestricted_tag_group.name])
|
public_tag_group.name, unrestricted_tag_group.name, private_tag_group.name,
|
||||||
|
everyone_tag_group.name, visible_tag_group.name,
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(TagGroup.visible(Guardian.new(user1)).pluck(:name)).to match_array([
|
||||||
|
public_tag_group.name, unrestricted_tag_group.name, everyone_tag_group.name,
|
||||||
|
visible_tag_group.name,
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(TagGroup.visible(Guardian.new(nil)).pluck(:name)).to match_array([
|
||||||
|
public_tag_group.name, unrestricted_tag_group.name, everyone_tag_group.name,
|
||||||
|
visible_tag_group.name,
|
||||||
|
])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue