work in progress, add fidelity to category group permissions (full, create posts, readonly)

This commit is contained in:
Sam 2013-07-14 11:24:16 +10:00
parent 8d947535a8
commit ecf17cfebb
38 changed files with 349 additions and 126 deletions

View file

@ -101,14 +101,12 @@ Discourse.EditCategoryController = Discourse.ObjectController.extend(Discourse.M
return false;
},
addGroup: function(){
this.get('model').addGroup(this.get("selectedGroup"));
addPermission: function(group, permission_id){
this.get('model').addPermission({group_name: group + "", permission: Discourse.PermissionType.create({id: permission_id})});
},
removeGroup: function(group){
// OBVIOUS, Ember treats this as Ember.String, we need a real string here
group = group + "";
this.get('model').removeGroup(group);
removePermission: function(permission){
this.get('model').removePermission(permission);
},
saveCategory: function() {

View file

@ -11,9 +11,21 @@ Discourse.Category = Discourse.Model.extend({
init: function() {
this._super();
this.set("availableGroups", Em.A(this.get("available_groups")));
this.set("groups", Em.A(this.groups));
this.set("permissions", Em.A(_.map(this.group_permissions, function(elem){
return {
group_name: elem.group_name,
permission: Discourse.PermissionType.create({id: elem.permission_type})
};
})));
},
availablePermissions: function(){
return [ Discourse.PermissionType.create({id: Discourse.PermissionType.FULL}),
Discourse.PermissionType.create({id: Discourse.PermissionType.CREATE_POST}),
Discourse.PermissionType.create({id: Discourse.PermissionType.READONLY})
];
}.property(),
searchContext: function() {
return ({ type: 'category', id: this.get('id'), category: this });
}.property('id'),
@ -37,15 +49,20 @@ Discourse.Category = Discourse.Model.extend({
}
return Discourse.ajax(url, {
data: {
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({
name: this.get('name'),
color: this.get('color'),
text_color: this.get('text_color'),
hotness: this.get('hotness'),
secure: this.get('secure'),
group_names: this.get('groups').join(","),
permissions: _.map(
this.get('permissions'), function(p){
return { group_name: p.group_name, permission_type: p.permission.id};
}),
auto_close_days: this.get('auto_close_days')
},
}),
type: this.get('id') ? 'PUT' : 'POST'
});
},
@ -54,22 +71,30 @@ Discourse.Category = Discourse.Model.extend({
return Discourse.ajax("/categories/" + (this.get('slug') || this.get('id')), { type: 'DELETE' });
},
addGroup: function(group){
this.get("groups").addObject(group);
this.get("availableGroups").removeObject(group);
addPermission: function(permission){
this.get("permissions").addObject(permission);
this.get("availableGroups").removeObject(permission.group_name);
},
removeGroup: function(group){
this.get("groups").removeObject(group);
this.get("availableGroups").addObject(group);
removePermission: function(permission){
this.get("permissions").removeObject(permission);
this.get("availableGroups").addObject(permission.group_name);
},
// note, this is used in a data attribute, data attributes get downcased
// to avoid confusion later on using this naming here.
description_text: function(){
return $("<div>" + this.get("description") + "</div>").text();
}.property("description")
}.property("description"),
permissions: function(){
return Em.A([
{group_name: "everyone", permission: Discourse.PermissionType.create({id: 1})},
{group_name: "admins", permission: Discourse.PermissionType.create({id: 2}) },
{group_name: "crap", permission: Discourse.PermissionType.create({id: 3}) }
]);
}.property()
});

View file

@ -0,0 +1,23 @@
Discourse.PermissionType = Discourse.Model.extend({
description: function(){
var key = "";
switch(this.get("id")){
case 1:
key = "full";
break;
case 2:
key = "create_post";
break;
case 3:
key = "readonly";
break;
}
return I18n.t("permission_types." + key);
}.property("id")
});
Discourse.PermissionType.FULL = 1;
Discourse.PermissionType.CREATE_POST = 2;
Discourse.PermissionType.READONLY = 3;

View file

@ -60,25 +60,18 @@
{{#unless isUncategorized}}
<div {{bindAttr class=":modal-tab :options-tab securitySelected::invisible"}}>
<section class='field'>
<label>
{{input type="checkbox" checked=secure}}
{{i18n category.is_secure}}
</label>
{{#if secure}}
<div class="secure-category-options">
<label>{{i18n category.allowed_groups}}</label>
<ul class="badge-list">
{{#each groups}}
<li class="badge-group">
{{this}}
<a {{action removeGroup this}}><i class="icon icon-remove-sign"></i></a>
</li>
{{/each}}
</ul>
{{view Ember.Select contentBinding="availableGroups" valueBinding="selectedGroup"}}
<button {{action addGroup}} class="btn btn-small">{{i18n category.add_group}}</button>
</div>
{{/if}}
<ul>
{{#each permissions}}
<li>
<span class="badge-group">{{group_name}}</span>
<span class="permission">{{permission.description}}</span>
<a {{action removePermission this}}><i class="icon icon-remove-sign"></i></a>
</li>
{{/each}}
</ul>
{{view Ember.Select contentBinding="availableGroups" valueBinding="selectedGroup"}}
{{view Ember.Select optionValuePath="content.id" optionLabelPath="content.description" contentBinding="availablePermissions" valueBinding="selectedPermission"}}
<button {{action addPermission selectedGroup selectedPermission}} class="btn btn-small">{{i18n category.add_group}}</button>
</section>
</div>
<div {{bindAttr class=":modal-tab :options-tab settingsSelected::invisible"}}>

View file

@ -102,7 +102,7 @@ class ApplicationController < ActionController::Base
guardian.current_user.sync_notification_channel_position
end
store_preloaded("site", Site.cached_json(current_user))
store_preloaded("site", Site.cached_json(guardian))
if current_user.present?
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, root: false)))

View file

@ -53,7 +53,7 @@ class CategoriesController < ApplicationController
end
def category_param_keys
[required_param_keys, :hotness, :secure, :group_names, :auto_close_days].flatten!
[required_param_keys, :hotness, :read_restricted, :permissions, :auto_close_days].flatten!
end
def category_params

View file

@ -22,6 +22,7 @@ class Category < ActiveRecord::Base
before_validation :ensure_slug
after_save :invalidate_site_cache
before_save :apply_permissions
after_create :create_category_definition
after_create :publish_categories_list
after_destroy :invalidate_site_cache
@ -34,16 +35,49 @@ class Category < ActiveRecord::Base
scope :secured, ->(guardian = nil) {
ids = guardian.secure_category_ids if guardian
if ids.present?
where("NOT categories.secure or categories.id in (:cats)", cats: ids)
where("NOT categories.read_restricted or categories.id in (:cats)", cats: ids)
else
where("NOT categories.secure")
where("NOT categories.read_restricted")
end
}
scope :topic_create_allowed, ->(guardian) {
scoped_to_permissions(guardian, [:full])
}
scope :post_create_allowed, ->(guardian) {
scoped_to_permissions(guardian, [:create_post, :full])
}
delegate :post_template, to: 'self.class'
attr_accessor :displayable_topics
def self.scoped_to_permissions(guardian, permission_types)
if guardian && guardian.is_staff?
scoped
else
permission_types = permission_types.map{ |permission_type|
CategoryGroup.permission_types[permission_type]
}
where("categories.id in (
SELECT c.id FROM categories c
WHERE (
NOT c.read_restricted AND
NOT EXISTS(
SELECT 1 FROM category_groups cg WHERE cg.category_id = categories.id )
) OR EXISTS(
SELECT 1 FROM category_groups cg
WHERE permission_type in (?) AND
cg.category_id = categories.id AND
group_id IN (
SELECT g.group_id FROM group_users g where g.user_id = ?
)
)
)", permission_types,(!guardian || guardian.user.blank?) ? -1 : guardian.user.id)
end
end
# Internal: Update category stats: # of topics in past year, month, week for
# all categories.
def self.update_stats
@ -119,28 +153,65 @@ class Category < ActiveRecord::Base
end
end
def deny(group)
if group == :all
self.secure = true
end
# will reset permission on a topic to a particular
# set.
#
# Available permissions are, :full, :create_post, :readonly
# hash can be:
#
# :everyone => :full - everyone has everything
# :everyone => :readonly, :staff => :full
# 7 => 1 # you can pass a group_id and permission id
def set_permissions(permissions)
self.read_restricted, @permissions = Category.resolve_permissions(permissions)
# Ideally we can just call .clear here, but it runs SQL, we only want to run it
# on save.
end
def allow(group)
if group == :all
self.secure = false
# this is kind of annoying, there should be a clean way of queuing this stuff
category_groups.destroy_all unless new_record?
else
groups.push(group)
def apply_permissions
if @permissions
category_groups.destroy_all
@permissions.each do |group_id, permission_type|
category_groups.build(group_id: group_id, permission_type: permission_type)
end
@permissions = nil
end
end
def secure_group_ids
if self.secure
if self.read_restricted?
groups.pluck("groups.id")
end
end
def self.resolve_permissions(permissions)
read_restricted = true
everyone = Group::AUTO_GROUPS[:everyone]
full = CategoryGroup.permission_types[:full]
mapped = permissions.map do |group,permission|
group = group.id if Group === group
# subtle, using Group[] ensures the group exists in the DB
group = Group[group].id unless Fixnum === group
permission = CategoryGroup.permission_types[permission] unless Fixnum === permission
[group, permission]
end
mapped.each do |group, permission|
if group == everyone && permission == full
return [false, []]
end
read_restricted = false if group == everyone
end
[read_restricted, mapped]
end
end
# == Schema Information
@ -162,7 +233,7 @@ end
# description :text
# text_color :string(6) default("FFFFFF"), not null
# hotness :float default(5.0), not null
# secure :boolean default(FALSE), not null
# read_restricted :boolean default(FALSE), not null
# auto_close_days :float
#
# Indexes

View file

@ -1,16 +1,22 @@
class CategoryGroup < ActiveRecord::Base
belongs_to :category
belongs_to :group
def self.permission_types
@permission_types ||= Enum.new(:full, :create_post, :readonly)
end
end
# == Schema Information
#
# Table name: category_groups
#
# id :integer not null, primary key
# category_id :integer not null
# group_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# category_id :integer not null
# group_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# permission_type :integer default(1)
#

View file

@ -10,6 +10,7 @@ class Group < ActiveRecord::Base
validate :name_format_validator
AUTO_GROUPS = {
:everyone => 0,
:admins => 1,
:moderators => 2,
:staff => 3,
@ -34,6 +35,10 @@ class Group < ActiveRecord::Base
group.save!
end
# the everyone group is special, it can include non-users so there is no
# way to have the membership in a table
return group if name == :everyone
group.name = I18n.t("groups.default_names.#{name}")
# don't allow shoddy localization to break this

View file

@ -59,6 +59,7 @@ end
# created_at :datetime not null
# updated_at :datetime not null
# deleted_at :datetime
# deleted_by_id :integer
#
# Indexes
#

View file

@ -412,6 +412,8 @@ end
# percent_rank :float default(1.0)
# notify_user_count :integer default(0), not null
# like_score :integer default(0), not null
# deleted_by_id :integer
# nuked_user :boolean default(FALSE)
#
# Indexes
#

View file

@ -27,7 +27,7 @@ class Site
def categories
Category
.secured(@guardian)
.topic_create_allowed(@guardian)
.latest
.includes(:topic_only_relative_url)
end

View file

@ -103,9 +103,9 @@ class Topic < ActiveRecord::Base
# Query conditions
condition =
if ids.present?
["NOT c.secure or c.id in (:cats)", cats: ids]
["NOT c.read_restricted or c.id in (:cats)", cats: ids]
else
["NOT c.secure"]
["NOT c.read_restricted"]
end
where("category_id IS NULL OR category_id IN (
@ -629,8 +629,8 @@ class Topic < ActiveRecord::Base
self
end
def secure_category?
category && category.secure
def read_restricted_category?
category && category.read_restricted
end
private
@ -692,6 +692,7 @@ end
# auto_close_at :datetime
# auto_close_user_id :integer
# auto_close_started_at :datetime
# deleted_by_id :integer
#
# Indexes
#

View file

@ -113,11 +113,11 @@ class TopicTrackingState
((#{unread}) OR (#{new})) AND
(topics.visible OR u.admin OR u.moderator) AND
topics.deleted_at IS NULL AND
( category_id IS NULL OR NOT c.secure OR category_id IN (
( category_id IS NULL OR NOT c.read_restricted OR category_id IN (
SELECT c2.id FROM categories c2
JOIN category_groups cg ON cg.category_id = c2.id
JOIN group_users gu ON gu.user_id = u.id AND cg.group_id = gu.group_id
WHERE c2.secure )
WHERE c2.read_restricted )
)
SQL

View file

@ -486,10 +486,14 @@ class User < ActiveRecord::Base
end
def secure_category_ids
cats = self.staff? ? Category.select(:id).where(secure: true) : secure_categories.select('categories.id')
cats = self.staff? ? Category.select(:id).where(read_restricted: true) : secure_categories.select('categories.id')
cats.map { |c| c.id }.sort
end
def topic_create_allowed_category_ids
Category.topic_create_allowed(self.id).select(:id)
end
# Flag all posts from a user as spam
def flag_linked_posts_as_spam
admin = Discourse.system_user
@ -660,6 +664,7 @@ end
# topic_reply_count :integer default(0), not null
# blocked :boolean default(FALSE)
# dynamic_favicon :boolean default(FALSE), not null
# title :string(255)
#
# Indexes
#

View file

@ -179,7 +179,7 @@ ORDER BY p.created_at desc
# move into Topic perhaps
group_ids = nil
if topic && topic.category && topic.category.secure
if topic && topic.category && topic.category.read_restricted
group_ids = topic.category.groups.pluck("groups.id")
end
@ -232,11 +232,11 @@ ORDER BY p.created_at desc
unless guardian.is_staff?
allowed = guardian.secure_category_ids
if allowed.present?
builder.where("( c.secure IS NULL OR
c.secure = 'f' OR
(c.secure = 't' and c.id in (:cats)) )", cats: guardian.secure_category_ids )
builder.where("( c.read_restricted IS NULL OR
NOT c.read_restricted OR
(c.read_restricted and c.id in (:cats)) )", cats: guardian.secure_category_ids )
else
builder.where("(c.secure IS NULL OR c.secure = 'f')")
builder.where("(c.read_restricted IS NULL OR NOT c.read_restricted)")
end
end
end

View file

@ -9,6 +9,6 @@ class BasicCategorySerializer < ApplicationSerializer
:description,
:topic_url,
:hotness,
:secure
:read_restricted
end

View file

@ -1,13 +1,24 @@
class CategorySerializer < BasicCategorySerializer
attributes :secure, :groups, :available_groups, :auto_close_days
attributes :read_restricted, :groups, :available_groups, :auto_close_days, :group_permissions
def groups
@groups ||= object.groups.order("name").all.map(&:name)
def group_permissions
@group_permissions ||= begin
perms = object.category_groups.joins(:group).order("groups.name").map do |cg|
{
permission_type: cg.permission_type,
group_name: cg.group.name
}
end
if perms.length == 0 && !object.read_restricted
perms << {permission_type: CategoryGroup.permission_types[:full], group_name: :everyone}
end
perms
end
end
def available_groups
Group.order("name").map(&:name) - groups
Group.order("name").pluck(:name) - group_permissions.map{|g| g[:group_name]}
end
end

View file

@ -999,6 +999,11 @@ en:
browser_update: 'Unfortunately, <a href="http://www.discourse.org/faq/#browser">your browser is too old to work on this Discourse forum</a>. Please <a href="http://browsehappy.com">upgrade your browser</a>.'
permission_types:
full: "Create Topics, Create Posts and Read"
create_post: "Create Posts and Read"
readonly: "Read Only"
# This section is exported to the javascript for i18n in the admin section
admin_js:
type_to_filter: "type to filter..."
@ -1245,3 +1250,4 @@ en:
title: 'Settings'
reset: 'reset to default'
none: 'none'

View file

@ -0,0 +1,9 @@
class AddPermissionTypeToCategoryGroups < ActiveRecord::Migration
def change
# 1 is full permissions
add_column :category_groups, :permission_type, :integer, default: 1
# secure is ambiguous after this change, it should be read_restricted
rename_column :categories, :secure, :read_restricted
end
end

View file

@ -7,6 +7,7 @@ class Guardian
def staff?; false; end
def approved?; false; end
def secure_category_ids; []; end
def topic_create_allowed_category_ids; []; end
def has_trust_level?(level); false; end
end
@ -328,7 +329,7 @@ class Guardian
topic.deleted_at.nil? &&
# not secure, or I can see it
(not(topic.secure_category?) || can_see_category?(topic.category)) &&
(not(topic.read_restricted_category?) || can_see_category?(topic.category)) &&
# not private, or I am allowed (or an admin)
(not(topic.private_message?) || authenticated? && (topic.all_allowed_users.where(id: @user.id).exists? || is_admin?))
@ -340,7 +341,7 @@ class Guardian
end
def can_see_category?(category)
not(category.secure) || secure_category_ids.include?(category.id)
not(category.read_restricted) || secure_category_ids.include?(category.id)
end
def can_vote?(post, opts={})
@ -378,6 +379,10 @@ class Guardian
@secure_category_ids ||= @user.secure_category_ids
end
def topic_create_allowed_category_ids
@topic_create_allowed_category_ids ||= @user.topic_create_allowed_category_ids
end
private
def is_my_own?(obj)

View file

@ -116,7 +116,7 @@ class PostCreator
protected
def secure_group_ids(topic)
@secure_group_ids ||= if topic.category && topic.category.secure?
@secure_group_ids ||= if topic.category && topic.category.read_restricted?
topic.category.secure_group_ids
end
end

View file

@ -160,9 +160,9 @@ class Search
.order("topics.bumped_at DESC")
if secure_category_ids.present?
posts = posts.where("(categories.id IS NULL) OR (NOT categories.secure) OR (categories.id IN (?))", secure_category_ids)
posts = posts.where("(categories.id IS NULL) OR (NOT categories.read_restricted) OR (categories.id IN (?))", secure_category_ids)
else
posts = posts.where("(categories.id IS NULL) OR (NOT categories.secure)")
posts = posts.where("(categories.id IS NULL) OR (NOT categories.read_restricted)")
end
posts.limit(limit)
end

View file

@ -18,9 +18,9 @@ class SqlBuilder
def secure_category(secure_category_ids, category_alias = 'c')
if secure_category_ids.present?
where("NOT COALESCE(" << category_alias << ".secure, false) OR " << category_alias << ".id IN (:secure_category_ids)", secure_category_ids: secure_category_ids)
where("NOT COALESCE(" << category_alias << ".read_restricted, false) OR " << category_alias << ".id IN (:secure_category_ids)", secure_category_ids: secure_category_ids)
else
where("NOT COALESCE(" << category_alias << ".secure, false)")
where("NOT COALESCE(" << category_alias << ".read_restricted, false)")
end
self
end

View file

@ -239,9 +239,9 @@ class TopicQuery
unless @user && @user.moderator?
category_ids = @user.secure_category_ids if @user
if category_ids.present?
result = result.where('categories.secure IS NULL OR categories.secure = ? OR categories.id IN (?)', false, category_ids)
result = result.where('categories.read_restricted IS NULL OR categories.read_restricted = ? OR categories.id IN (?)', false, category_ids)
else
result = result.where('categories.secure IS NULL OR categories.secure = ?', false)
result = result.where('categories.read_restricted IS NULL OR categories.read_restricted = ?', false)
end
end

View file

@ -41,8 +41,7 @@ describe CategoryList do
cat = Fabricate(:category)
topic = Fabricate(:topic, category: cat)
cat.deny(:all)
cat.allow(Group[:admins])
cat.set_permissions(:admins => :full)
cat.save
CategoryList.new(Guardian.new admin).categories.count.should == 1

View file

@ -215,8 +215,9 @@ describe Guardian do
it 'correctly handles groups' do
group = Fabricate(:group)
category = Fabricate(:category, secure: true)
category.allow(group)
category = Fabricate(:category, read_restricted: true)
category.set_permissions(group => :full)
category.save
topic = Fabricate(:topic, category: category)

View file

@ -62,8 +62,7 @@ describe PostCreator do
admin = Fabricate(:admin)
cat = Fabricate(:category)
cat.deny(:all)
cat.allow(Group[:admins])
cat.set_permissions(:admins => :full)
cat.save
created_post = nil

View file

@ -171,8 +171,7 @@ describe Search do
topic.category_id = category.id
topic.save
category.deny(:all)
category.allow(Group[:staff])
category.set_permissions(:staff => :full)
category.save
result(nil).should_not be_present
@ -211,7 +210,7 @@ describe Search do
r[:title].should == category.name
r[:url].should == "/category/#{category.slug}"
category.deny(:all)
category.set_permissions({})
category.save
result.should_not be_present

View file

@ -14,9 +14,8 @@ describe TopicQuery do
context 'secure category' do
it "filters categories out correctly" do
category = Fabricate(:category)
category.deny(:all)
group = Fabricate(:group)
category.allow(group)
category.set_permissions(group => :full)
category.save
topic = Fabricate(:topic, category: category)

View file

@ -134,11 +134,11 @@ describe CategoriesController do
describe 'success' do
before do
# might as well test this as well
@category.allow(Group[:admins])
# might as well test this while at it
@category.set_permissions(:admins => :full)
@category.save
xhr :put, :update, id: @category.id, name: 'science', color: '000', text_color: '0ff', group_names: Group[:staff].name, secure: 'true'
xhr :put, :update, id: @category.id, name: 'science', color: '000', text_color: '0ff', group_names: Group[:staff].name, read_restricted: 'true'
@category.reload
end
@ -146,7 +146,7 @@ describe CategoriesController do
@category.name.should == 'science'
@category.color.should == '000'
@category.text_color.should == '0ff'
@category.secure?.should be_true
@category.read_restricted?.should be_true
@category.groups.count.should == 1
end
end

View file

@ -15,8 +15,7 @@ describe CategoryFeaturedTopic do
# so much dancing, I am thinking fixures make sense here.
user.change_trust_level!(:basic)
category.deny(:all)
category.allow(Group[:trust_level_1])
category.set_permissions(:trust_level_1 => :full)
category.save
uncategorized_post = PostCreator.create(user, raw: "this is my new post 123 post", title: "hello world")

View file

@ -18,6 +18,57 @@ describe Category do
it { should have_many :category_featured_topics }
it { should have_many :featured_topics }
describe "resolve_permissions" do
it "can determine read_restricted" do
read_restricted, resolved = Category.resolve_permissions(:everyone => :full)
read_restricted.should be_false
resolved.should == []
end
end
describe "topic_create_allowed and post_create_allowed" do
it "works" do
default_category = Fabricate(:category)
full_category = Fabricate(:category)
can_post_category = Fabricate(:category)
can_read_category = Fabricate(:category)
user = Fabricate(:user)
group = Fabricate(:group)
group.add(user)
group.save
admin = Fabricate(:admin)
full_category.set_permissions(group => :full)
full_category.save
can_post_category.set_permissions(group => :create_post)
can_post_category.save
can_read_category.set_permissions(group => :readonly)
can_read_category.save
guardian = Guardian.new(admin)
Category.topic_create_allowed(guardian).count.should == 4
Category.post_create_allowed(guardian).count.should == 4
Category.secured(guardian).count.should == 4
guardian = Guardian.new(user)
Category.secured(guardian).count.should == 4
Category.post_create_allowed(guardian).count.should == 3
Category.topic_create_allowed(guardian).count.should == 2 # explicitly allowed once, default allowed once
end
end
describe "post_create_allowed" do
end
describe "security" do
let(:category) { Fabricate(:category) }
let(:category_2) { Fabricate(:category) }
@ -25,20 +76,20 @@ describe Category do
let(:group) { Fabricate(:group) }
it "secures categories correctly" do
category.secure?.should be_false
category.read_restricted?.should be_false
category.deny(:all)
category.secure?.should be_true
category.set_permissions({})
category.read_restricted?.should be_true
category.allow(:all)
category.secure?.should be_false
category.set_permissions(:everyone => :full)
category.read_restricted?.should be_false
user.secure_categories.should be_empty
group.add(user)
group.save
category.allow(group)
category.set_permissions(group.id => :full)
category.save
user.reload
@ -47,13 +98,13 @@ describe Category do
it "lists all secured categories correctly" do
group.add(user)
category.allow(group)
category.set_permissions(group.id => :full)
category.save
category_2.set_permissions(group.id => :full)
category_2.save
Category.secured.should == [category]
category_2.allow(group)
Category.secured.should =~ [category, category_2]
Category.secured.should =~ []
Category.secured(Guardian.new(user)).should =~ [category, category_2]
end
end

16
spec/models/site_spec.rb Normal file
View file

@ -0,0 +1,16 @@
require 'spec_helper'
require_dependency 'site'
describe Site do
it "omits categories users can not write to from the category list" do
category = Fabricate(:category)
user = Fabricate(:user)
Site.new(Guardian.new(user)).categories.count.should == 1
category.set_permissions(:everyone => :create_post)
category.save
Site.new(Guardian.new(user)).categories.count.should == 0
end
end

View file

@ -258,8 +258,7 @@ describe TopicLink do
TopicLink.topic_summary(Guardian.new, post.topic_id).count.should == 1
TopicLink.counts_for(Guardian.new, post.topic, [post]).length.should == 1
category.deny(:all)
category.allow(Group[:staff])
category.set_permissions(:staff => :full)
category.save
admin = Fabricate(:admin)

View file

@ -192,7 +192,7 @@ describe Topic do
context "secure categories" do
let(:user) { Fabricate(:user) }
let(:category) { Fabricate(:category, secure: true) }
let(:category) { Fabricate(:category, read_restricted: true) }
before do
topic.category = category
@ -1263,7 +1263,7 @@ describe Topic do
describe 'secured' do
it 'can remove secure groups' do
category = Fabricate(:category, secure: true)
category = Fabricate(:category, read_restricted: true)
topic = Fabricate(:topic, category: category)
Topic.secured(Guardian.new(nil)).count.should == 0
@ -1280,17 +1280,17 @@ describe Topic do
let(:category){ Category.new }
it "is true if the category is secure" do
category.stubs(:secure).returns(true)
Topic.new(:category => category).should be_secure_category
category.stubs(:read_restricted).returns(true)
Topic.new(:category => category).should be_read_restricted_category
end
it "is false if the category is not secure" do
category.stubs(:secure).returns(false)
Topic.new(:category => category).should_not be_secure_category
category.stubs(:read_restricted).returns(false)
Topic.new(:category => category).should_not be_read_restricted_category
end
it "is false if there is no category" do
Topic.new(:category => nil).should_not be_secure_category
Topic.new(:category => nil).should_not be_read_restricted_category
end
end

View file

@ -51,7 +51,7 @@ describe TopicTrackingState do
row.user_id.should == post.user_id
# when we have no permission to see a category, don't show its stats
category = Fabricate(:category, secure: true)
category = Fabricate(:category, read_restricted: true)
post.topic.category_id = category.id
post.topic.save

View file

@ -68,7 +68,7 @@ describe UserAction do
# groups
category = Fabricate(:category, secure: true)
category = Fabricate(:category, read_restricted: true)
public_topic.recover!
public_topic.category = category
@ -82,7 +82,7 @@ describe UserAction do
group.add(u)
group.save
category.allow(group)
category.set_permissions(group => :full)
category.save
stats_for_user(u).should == [UserAction::NEW_TOPIC]