mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
FIX: use PostDestroyer when deleting/recovering a topic
This commit is contained in:
parent
ee40a95e58
commit
3ae1ebdfc3
8 changed files with 43 additions and 27 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue