diff --git a/app/controllers/post_actions_controller.rb b/app/controllers/post_actions_controller.rb index 7a2fbbd01..2b4964881 100644 --- a/app/controllers/post_actions_controller.rb +++ b/app/controllers/post_actions_controller.rb @@ -80,8 +80,8 @@ class PostActionsController < ApplicationController finder = Post.where(id: post_id) - # Include deleted posts if the user is a moderator (to guardian ?) - finder = finder.with_deleted if current_user.try(:moderator?) + # Include deleted posts if the user is a staff + finder = finder.with_deleted if guardian.is_staff? @post = finder.first guardian.ensure_can_see!(@post) diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 31f671021..52704a80d 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -31,7 +31,6 @@ class TopicsController < ApplicationController skip_before_filter :check_xhr, only: [:show, :feed] def show - flash["referer"] ||= request.referer # We'd like to migrate the wordpress feed to another url. This keeps up backwards compatibility with @@ -197,14 +196,20 @@ class TopicsController < ApplicationController def destroy topic = Topic.find_by(id: params[:id]) guardian.ensure_can_delete!(topic) - topic.trash!(current_user) + + first_post = topic.ordered_posts.first + PostDestroyer.new(current_user, first_post).destroy + render nothing: true end def recover topic = Topic.where(id: params[:topic_id]).with_deleted.first guardian.ensure_can_recover_topic!(topic) - topic.recover! + + first_post = topic.posts.with_deleted.order(:post_number).first + PostDestroyer.new(current_user, first_post).recover + render nothing: true end diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index 6c0c5aefd..f90b1eeda 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -8,16 +8,19 @@ module PostGuardian already_taken_this_action = taken.any? && taken.include?(PostActionType.types[action_key]) already_did_flagging = taken.any? && (taken & PostActionType.flag_types.values).any? - if authenticated? && post + if authenticated? && post # we allow flagging for trust level 1 and higher (is_flag && @user.has_trust_level?(:basic) && not(already_did_flagging)) || # not a flagging action, and haven't done it already not(is_flag || already_taken_this_action) && - # nothing except flagging on archived posts + # nothing except flagging on archived topics not(post.topic.archived?) && + # nothing except flagging on deleted posts + not(post.trashed?) && + # don't like your own stuff not(action_key == :like && is_my_own?(post)) && @@ -35,6 +38,7 @@ module PostGuardian # Can we see who acted on a post in a particular way? def can_see_post_actors?(topic, post_action_type_id) + return true if is_admin? return false unless topic type_symbol = PostActionType.types[post_action_type_id] @@ -49,10 +53,6 @@ module PostGuardian true end - def can_see_deleted_posts? - is_staff? - end - def can_delete_all_posts?(user) is_staff? && user && diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb index 7ade50a8f..4a62ac9b2 100644 --- a/lib/post_destroyer.rb +++ b/lib/post_destroyer.rb @@ -26,7 +26,8 @@ class PostDestroyer end def initialize(user, post) - @user, @post = user, post + @user = user + @post = post end def destroy @@ -38,11 +39,15 @@ class PostDestroyer end def recover + puts "@" * 100 + puts "staff? #{@user.staff?}" + puts "post.deleted_at #{@post.deleted_at}" if @user.staff? && @post.deleted_at staff_recovered elsif @user.staff? || @user.id == @post.user_id user_recovered end + @post.topic.recover! if @post.post_number == 1 @post.topic.update_statistics end @@ -68,7 +73,7 @@ class PostDestroyer @post.update_flagged_posts_count remove_associated_replies remove_associated_notifications - @post.topic.trash!(@user) if @post.topic and @post.post_number == 1 + @post.topic.trash!(@user) if @post.topic && @post.post_number == 1 update_associated_category_latest_topic end publish("deleted") diff --git a/lib/topic_view.rb b/lib/topic_view.rb index f9004cdbf..44e480e7f 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -190,6 +190,7 @@ class TopicView def has_deleted? @predelete_filtered_posts.with_deleted .where("posts.deleted_at IS NOT NULL") + .where("posts.post_number > 1") .exists? end @@ -352,7 +353,7 @@ class TopicView # copy the filter for has_deleted? method @predelete_filtered_posts = @filtered_posts.spawn if @guardian.can_see_deleted_posts? && !@show_deleted && has_deleted? - @filtered_posts = @filtered_posts.where(deleted_at: nil) + @filtered_posts = @filtered_posts.where("deleted_at IS NULL OR post_number = 1") @contains_gaps = true end diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index fcc004822..8512afd11 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -40,6 +40,11 @@ describe Guardian do Guardian.new(user).post_can_act?(post, :like).should be_false end + it "returns false when the post is deleted" do + post.deleted_at = Time.now + Guardian.new(user).post_can_act?(post, :like).should be_false + end + it "always allows flagging" do post.topic.archived = true Guardian.new(user).post_can_act?(post, :spam).should be_true diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 39e9ec9e5..27e2869fa 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -36,6 +36,12 @@ shared_examples 'finding and showing post' do xhr :get, action, params response.should be_success end + + it "can find posts as a admin" do + log_in(:admin) + xhr :get, action, params + response.should be_success + end end end diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index 88b46af2d..1a816302f 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -501,7 +501,7 @@ describe TopicsController do end it 'succeeds' do - Topic.any_instance.expects(:recover!) + PostDestroyer.any_instance.expects(:recover) xhr :put, :recover, topic_id: topic.id response.should be_success end @@ -516,33 +516,27 @@ describe TopicsController do end describe 'when logged in' do - before do - @topic = Fabricate(:topic, user: log_in) - end + let(:topic) { Fabricate(:topic, user: log_in) } describe 'without access' do it "raises an exception when the user doesn't have permission to delete the topic" do - Guardian.any_instance.expects(:can_delete?).with(@topic).returns(false) - xhr :delete, :destroy, id: @topic.id + Guardian.any_instance.expects(:can_delete?).with(topic).returns(false) + xhr :delete, :destroy, id: topic.id response.should be_forbidden end end describe 'with permission' do before do - Guardian.any_instance.expects(:can_delete?).with(@topic).returns(true) + Guardian.any_instance.expects(:can_delete?).with(topic).returns(true) end it 'succeeds' do - xhr :delete, :destroy, id: @topic.id + PostDestroyer.any_instance.expects(:destroy) + xhr :delete, :destroy, id: topic.id response.should be_success end - it 'deletes the topic' do - xhr :delete, :destroy, id: @topic.id - Topic.exists?(id: @topic_id).should be_false - end - end end