suspend_account_service.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. # frozen_string_literal: true
  2. class SuspendAccountService < BaseService
  3. include Payloadable
  4. def call(account)
  5. @account = account
  6. suspend!
  7. reject_remote_follows!
  8. distribute_update_actor!
  9. unmerge_from_home_timelines!
  10. unmerge_from_list_timelines!
  11. privatize_media_attachments!
  12. end
  13. private
  14. def suspend!
  15. @account.suspend! unless @account.suspended?
  16. end
  17. def reject_remote_follows!
  18. return if @account.local? || !@account.activitypub?
  19. # When suspending a remote account, the account obviously doesn't
  20. # actually become suspended on its origin server, i.e. unlike a
  21. # locally suspended account it continues to have access to its home
  22. # feed and other content. To prevent it from being able to continue
  23. # to access toots it would receive because it follows local accounts,
  24. # we have to force it to unfollow them. Unfortunately, there is no
  25. # counterpart to this operation, i.e. you can't then force a remote
  26. # account to re-follow you, so this part is not reversible.
  27. follows = Follow.where(account: @account).to_a
  28. ActivityPub::DeliveryWorker.push_bulk(follows) do |follow|
  29. [Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), follow.target_account_id, @account.inbox_url]
  30. end
  31. follows.each(&:destroy)
  32. end
  33. def distribute_update_actor!
  34. ActivityPub::UpdateDistributionWorker.perform_async(@account.id) if @account.local?
  35. end
  36. def unmerge_from_home_timelines!
  37. @account.followers_for_local_distribution.find_each do |follower|
  38. FeedManager.instance.unmerge_from_home(@account, follower)
  39. end
  40. end
  41. def unmerge_from_list_timelines!
  42. @account.lists_for_local_distribution.find_each do |list|
  43. FeedManager.instance.unmerge_from_list(@account, list)
  44. end
  45. end
  46. def privatize_media_attachments!
  47. attachment_names = MediaAttachment.attachment_definitions.keys
  48. @account.media_attachments.find_each do |media_attachment|
  49. attachment_names.each do |attachment_name|
  50. attachment = media_attachment.public_send(attachment_name)
  51. styles = [:original] | attachment.styles.keys
  52. styles.each do |style|
  53. case Paperclip::Attachment.default_options[:storage]
  54. when :s3
  55. attachment.s3_object(style).acl.put(acl: 'private')
  56. when :fog
  57. # Not supported
  58. when :filesystem
  59. begin
  60. FileUtils.chmod(0o600 & ~File.umask, attachment.path(style)) unless attachment.path(style).nil?
  61. rescue Errno::ENOENT
  62. Rails.logger.warn "Tried to change permission on non-existent file #{attachment.path(style)}"
  63. end
  64. end
  65. CacheBusterWorker.perform_async(attachment.path(style)) if Rails.configuration.x.cache_buster_enabled
  66. end
  67. end
  68. end
  69. end
  70. end