FIX: use PostDestroyer when deleting/recovering a topic

This commit is contained in:
Régis Hanol 2014-08-07 19:12:35 +02:00
parent ee40a95e58
commit 3ae1ebdfc3
8 changed files with 43 additions and 27 deletions

View file

@ -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)

View file

@ -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

View file

@ -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 &&

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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