From 2711b9dc831d8c58bc9ba7c1bd917e6e16aa107e Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Tue, 10 Oct 2017 23:50:13 +0200 Subject: [PATCH] Cleanup relayables where the signature is missing When we should have the signature but don't have it, the user data export fails. There are a few comments from back in 2011 where the signature is missing. Also some podmins maybe messed with signatures in their database, which would also break the exports now. closes #7637 --- Changelog.md | 1 + ...54_cleanup_relayables_without_signature.rb | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 db/migrate/20171009232054_cleanup_relayables_without_signature.rb diff --git a/Changelog.md b/Changelog.md index 05094101b..643dda44b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -27,6 +27,7 @@ * Fix export not downloadable because the filename was resetted on access [#7622](https://github.com/diaspora/diaspora/pull/7622) * Delete invalid oEmbed caches with binary titles [#7620](https://github.com/diaspora/diaspora/pull/7620) * Delete invalid diaspora IDs from friendica [#7630](https://github.com/diaspora/diaspora/pull/7630) +* Cleanup relayables where the signature is missing [#7637](https://github.com/diaspora/diaspora/pull/7637) ## Features * Ask for confirmation when leaving a submittable comment field [#7530](https://github.com/diaspora/diaspora/pull/7530) diff --git a/db/migrate/20171009232054_cleanup_relayables_without_signature.rb b/db/migrate/20171009232054_cleanup_relayables_without_signature.rb new file mode 100644 index 000000000..12af91f19 --- /dev/null +++ b/db/migrate/20171009232054_cleanup_relayables_without_signature.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +class CleanupRelayablesWithoutSignature < ActiveRecord::Migration[5.1] + class Comment < ApplicationRecord + belongs_to :commentable, polymorphic: true + + before_destroy do + Like.where(target_type: "Comment", target_id: id).destroy_all + ActsAsTaggableOn::Tagging.where(taggable_type: "Comment", taggable_id: id).destroy_all + end + + after_destroy do + commentable.update_comments_counter + end + end + + class Like < ApplicationRecord + belongs_to :target, polymorphic: true + + has_one :signature, class_name: "LikeSignature", dependent: :delete + + after_destroy do + target.update_likes_counter + end + end + + class PollParticipation < ApplicationRecord + belongs_to :poll_answer, counter_cache: :vote_count + end + + def up + cleanup_comments + cleanup_likes + cleanup_poll_participations + end + + def cleanup_comments + Comment.joins("INNER JOIN posts as post ON post.id = comments.commentable_id AND " \ + "comments.commentable_type = 'Post'") + .joins("INNER JOIN people as comment_author ON comment_author.id = comments.author_id") + .joins("INNER JOIN people as post_author ON post_author.id = post.author_id") + .where("comment_author.owner_id IS NULL AND post_author.owner_id IS NOT NULL " \ + "AND NOT EXISTS(" \ + "SELECT NULL FROM comment_signatures WHERE comment_signatures.comment_id = comments.id" \ + ")") + .destroy_all + end + + def cleanup_likes + Like.joins("INNER JOIN posts as post ON post.id = likes.target_id AND likes.target_type = 'Post'") + .joins("INNER JOIN people as like_author ON like_author.id = likes.author_id") + .joins("INNER JOIN people as post_author ON post_author.id = post.author_id") + .where("like_author.owner_id IS NULL AND post_author.owner_id IS NOT NULL " \ + "AND NOT EXISTS(" \ + "SELECT NULL FROM like_signatures WHERE like_signatures.like_id = likes.id" \ + ")") + .destroy_all + Like.joins("INNER JOIN comments as comment ON comment.id = likes.target_id AND likes.target_type = 'Comment'") + .joins("INNER JOIN posts as post ON post.id = comment.commentable_id AND comment.commentable_type = 'Post'") + .joins("INNER JOIN people as like_author ON like_author.id = likes.author_id") + .joins("INNER JOIN people as post_author ON post_author.id = post.author_id") + .where("like_author.owner_id IS NULL AND post_author.owner_id IS NOT NULL " \ + "AND NOT EXISTS(" \ + "SELECT NULL FROM like_signatures WHERE like_signatures.like_id = likes.id" \ + ")") + .destroy_all + end + + def cleanup_poll_participations + PollParticipation.joins("INNER JOIN polls as poll ON poll.id = poll_participations.poll_id") + .joins("INNER JOIN posts as post ON post.id = poll.status_message_id") + .joins("INNER JOIN people as pp_author ON pp_author.id = poll_participations.author_id") + .joins("INNER JOIN people as post_author ON post_author.id = post.author_id") + .where("pp_author.owner_id IS NULL AND post_author.owner_id IS NOT NULL " \ + "AND NOT EXISTS(" \ + "SELECT NULL FROM poll_participation_signatures " \ + "WHERE poll_participation_signatures.poll_participation_id = poll_participations.id" \ + ")") + .destroy_all + end +end