diff --git a/app/assets/stylesheets/specific/forum.css.scss b/app/assets/stylesheets/specific/forum.css.scss index 86396853a..f9a741458 100644 --- a/app/assets/stylesheets/specific/forum.css.scss +++ b/app/assets/stylesheets/specific/forum.css.scss @@ -55,6 +55,11 @@ div#c-forum-topics { span.locked-topic { color: #666; } + + span.level-topic { + color: #f66; + font-weight: bold; + } tr.forum-topic-row td:last-child { white-space: nowrap; diff --git a/app/controllers/forum_topics_controller.rb b/app/controllers/forum_topics_controller.rb index bf189cb07..2b25311a7 100644 --- a/app/controllers/forum_topics_controller.rb +++ b/app/controllers/forum_topics_controller.rb @@ -3,6 +3,8 @@ class ForumTopicsController < ApplicationController before_filter :member_only, :except => [:index, :show] before_filter :moderator_only, :only => [:new_merge, :create_merge] before_filter :normalize_search, :only => :index + before_filter :load_topic, :only => [:edit, :show, :update, :destroy, :undelete, :new_merge, :create_merge, :subscribe, :unsubscribe] + before_filter :check_min_level, :only => [:show, :edit, :update, :new_merge, :create_merge, :destroy, :undelete, :subscribe, :unsubscribe] def new @forum_topic = ForumTopic.new @@ -11,7 +13,6 @@ class ForumTopicsController < ApplicationController end def edit - @forum_topic = ForumTopic.find(params[:id]) check_privilege(@forum_topic) respond_with(@forum_topic) end @@ -27,7 +28,6 @@ class ForumTopicsController < ApplicationController end def show - @forum_topic = ForumTopic.find(params[:id]) unless CurrentUser.user.is_anonymous? @forum_topic.mark_as_read!(CurrentUser.user) end @@ -42,14 +42,12 @@ class ForumTopicsController < ApplicationController end def update - @forum_topic = ForumTopic.find(params[:id]) check_privilege(@forum_topic) @forum_topic.update_attributes(params[:forum_topic], :as => CurrentUser.role) respond_with(@forum_topic) end def destroy - @forum_topic = ForumTopic.find(params[:id]) check_privilege(@forum_topic) @forum_topic.delete! flash[:notice] = "Topic deleted" @@ -57,7 +55,6 @@ class ForumTopicsController < ApplicationController end def undelete - @forum_topic = ForumTopic.find(params[:id]) check_privilege(@forum_topic) @forum_topic.undelete! flash[:notice] = "Topic undeleted" @@ -71,18 +68,15 @@ class ForumTopicsController < ApplicationController end def new_merge - @forum_topic = ForumTopic.find(params[:id]) end def create_merge - @forum_topic = ForumTopic.find(params[:id]) @merged_topic = ForumTopic.find(params[:merged_id]) @forum_topic.merge(@merged_topic) redirect_to forum_topic_path(@merged_topic) end def subscribe - @forum_topic = ForumTopic.find(params[:id]) subscription = ForumSubscription.where(:forum_topic_id => @forum_topic.id, :user_id => CurrentUser.user.id).first unless subscription ForumSubscription.create(:forum_topic_id => @forum_topic.id, :user_id => CurrentUser.user.id, :last_read_at => @forum_topic.updated_at) @@ -91,7 +85,6 @@ class ForumTopicsController < ApplicationController end def unsubscribe - @forum_topic = ForumTopic.find(params[:id]) subscription = ForumSubscription.where(:forum_topic_id => @forum_topic.id, :user_id => CurrentUser.user.id).first if subscription subscription.destroy @@ -121,4 +114,29 @@ private raise User::PrivilegeError end end + + def load_topic + @forum_topic = ForumTopic.find(params[:id]) + end + + def check_min_level + if CurrentUser.user.level < @forum_topic.min_level + respond_with(@forum_topic) do |fmt| + fmt.html do + flash[:notice] = "Access denied" + redirect_to forum_topics_path + end + + fmt.json do + render :nothing => true, :status => 403 + end + + fmt.xml do + render :nothing => true, :status => 403 + end + end + + return false + end + end end diff --git a/app/models/forum_topic.rb b/app/models/forum_topic.rb index 2e3a2283d..196099bb8 100644 --- a/app/models/forum_topic.rb +++ b/app/models/forum_topic.rb @@ -6,7 +6,7 @@ class ForumTopic < ActiveRecord::Base } attr_accessible :title, :original_post_attributes, :category_id, :as => [:member, :builder, :gold, :platinum, :janitor, :moderator, :admin, :default] - attr_accessible :is_sticky, :is_locked, :is_deleted, :as => [:admin, :moderator] + attr_accessible :is_sticky, :is_locked, :is_deleted, :min_level, :as => [:admin, :moderator] belongs_to :creator, :class_name => "User" belongs_to :updater, :class_name => "User" has_many :posts, lambda {order("forum_posts.id asc")}, :class_name => "ForumPost", :foreign_key => "topic_id", :dependent => :destroy diff --git a/app/models/user.rb b/app/models/user.rb index 500f8c004..0c95c1b6f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -306,6 +306,37 @@ class User < ActiveRecord::Base "Admin" => Levels::ADMIN } end + + def level_string(value) + case value + when Levels::BLOCKED + "Banned" + + when Levels::MEMBER + "Member" + + when Levels::BUILDER + "Builder" + + when Levels::GOLD + "Gold" + + when Levels::PLATINUM + "Platinum" + + when Levels::JANITOR + "Janitor" + + when Levels::MODERATOR + "Moderator" + + when Levels::ADMIN + "Admin" + + else + "" + end + end end def promote_to!(new_level, options = {}) @@ -356,34 +387,7 @@ class User < ActiveRecord::Base end def level_string(value = nil) - case (value || level) - when Levels::BLOCKED - "Banned" - - when Levels::MEMBER - "Member" - - when Levels::BUILDER - "Builder" - - when Levels::GOLD - "Gold" - - when Levels::PLATINUM - "Platinum" - - when Levels::JANITOR - "Janitor" - - when Levels::MODERATOR - "Moderator" - - when Levels::ADMIN - "Admin" - - else - "" - end + User.level_string(value || level) end def is_anonymous? diff --git a/app/views/forum_topics/_form.html.erb b/app/views/forum_topics/_form.html.erb index 8faf6d932..a29dc3583 100644 --- a/app/views/forum_topics/_form.html.erb +++ b/app/views/forum_topics/_form.html.erb @@ -22,6 +22,10 @@ <%= f.input :is_locked %> <% end %> + <% if CurrentUser.is_builder? %> + <%= f.input :min_level, :as => :select, :collection => User.level_hash.to_a %> + <% end %> + <%= f.button :submit, "Submit", :data => { :disable_with => "Submitting..." } %> <%= dtext_preview_button "forum_post", "body", :input_id => "forum_post_body_for_#{forum_topic.original_post.id}", :preview_id => "dtext-preview-for-#{forum_topic.original_post.id}" %> <% end %> diff --git a/app/views/forum_topics/_listing.html.erb b/app/views/forum_topics/_listing.html.erb index 241213112..93b57db30 100644 --- a/app/views/forum_topics/_listing.html.erb +++ b/app/views/forum_topics/_listing.html.erb @@ -9,30 +9,36 @@ <% forum_topics.each do |topic| %> - - - <% if topic.is_sticky? %> - Sticky: - <% end %> + <% if CurrentUser.user.level >= topic.min_level %> + + + <% if topic.is_sticky? %> + Sticky: + <% end %> - <% unless topic.read_by?(CurrentUser.user) %> - NEW - <% end %> + <% unless topic.read_by?(CurrentUser.user) %> + NEW + <% end %> - <%= link_to topic.title, forum_topic_path(topic) %> + <%= link_to topic.title, forum_topic_path(topic) %> - <% if topic.response_count > Danbooru.config.posts_per_page %> - <%= link_to "page #{topic.last_page}", forum_topic_path(topic, :page => topic.last_page), :class => "last-page" %> - <% end %> + <% if topic.response_count > Danbooru.config.posts_per_page %> + <%= link_to "page #{topic.last_page}", forum_topic_path(topic, :page => topic.last_page), :class => "last-page" %> + <% end %> - <% if topic.is_locked? %> - (locked) - <% end %> - - <%= link_to_user topic.creator %> - <%= link_to_user topic.updater %> - <%= compact_time topic.updated_at %> - + <% if topic.is_locked? %> + (locked) + <% end %> + + <% if topic.min_level > 0 %> + (<%= User.level_string(topic.min_level).downcase %> only) + <% end %> + + <%= link_to_user topic.creator %> + <%= link_to_user topic.updater %> + <%= compact_time topic.updated_at %> + + <% end %> <% end %> \ No newline at end of file diff --git a/app/views/forum_topics/show.html.erb b/app/views/forum_topics/show.html.erb index 05a4bc02a..ecc2b1d98 100644 --- a/app/views/forum_topics/show.html.erb +++ b/app/views/forum_topics/show.html.erb @@ -2,8 +2,13 @@

Topic: <%= @forum_topic.title %> + + <% if @forum_topic.min_level >= User::Levels::BUILDER %> + (<%= User.level_string(@forum_topic.min_level).downcase %> only) + <% end %> + <% if @forum_topic.is_deleted? %> - (deleted) + (deleted) <% end %>

diff --git a/db/migrate/20161024220345_add_min_level_to_forum_topics.rb b/db/migrate/20161024220345_add_min_level_to_forum_topics.rb new file mode 100644 index 000000000..6dfacc31c --- /dev/null +++ b/db/migrate/20161024220345_add_min_level_to_forum_topics.rb @@ -0,0 +1,5 @@ +class AddMinLevelToForumTopics < ActiveRecord::Migration + def change + add_column :forum_topics, :min_level, :integer, :default => 0, :null => false + end +end diff --git a/db/structure.sql b/db/structure.sql index 38a30dec9..d03ad6b63 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2210,7 +2210,8 @@ CREATE TABLE forum_topics ( text_index tsvector NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, - category_id integer DEFAULT 0 NOT NULL + category_id integer DEFAULT 0 NOT NULL, + min_level integer DEFAULT 0 NOT NULL ); @@ -7456,3 +7457,5 @@ INSERT INTO schema_migrations (version) VALUES ('20160919234407'); INSERT INTO schema_migrations (version) VALUES ('20161018221128'); +INSERT INTO schema_migrations (version) VALUES ('20161024220345'); + diff --git a/test/functional/forum_topics_controller_test.rb b/test/functional/forum_topics_controller_test.rb index 528fa316c..a23192e2a 100644 --- a/test/functional/forum_topics_controller_test.rb +++ b/test/functional/forum_topics_controller_test.rb @@ -16,6 +16,17 @@ class ForumTopicsControllerTest < ActionController::TestCase CurrentUser.ip_addr = nil end + context "for a level restricted topic" do + setup do + @forum_topic.update_attribute(:min_level, 50) + end + + should "not allow users to see the topic" do + get :show, {:id => @forum_topic.id} + assert_redirected_to forum_topics_path + end + end + context "show action" do should "render" do get :show, {:id => @forum_topic.id}