| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SuspendAccountService < BaseService | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |   ASSOCIATIONS_ON_SUSPEND = %w(
 | 
					
						
							|  |  |  |     account_pins | 
					
						
							|  |  |  |     active_relationships | 
					
						
							|  |  |  |     block_relationships | 
					
						
							|  |  |  |     blocked_by_relationships | 
					
						
							|  |  |  |     conversation_mutes | 
					
						
							|  |  |  |     conversations | 
					
						
							|  |  |  |     custom_filters | 
					
						
							|  |  |  |     domain_blocks | 
					
						
							|  |  |  |     favourites | 
					
						
							|  |  |  |     follow_requests | 
					
						
							|  |  |  |     list_accounts | 
					
						
							|  |  |  |     media_attachments | 
					
						
							|  |  |  |     mute_relationships | 
					
						
							|  |  |  |     muted_by_relationships | 
					
						
							|  |  |  |     notifications | 
					
						
							|  |  |  |     owned_lists | 
					
						
							|  |  |  |     passive_relationships | 
					
						
							|  |  |  |     report_notes | 
					
						
							| 
									
										
										
										
											2019-01-05 12:43:28 +01:00
										 |  |  |     scheduled_statuses | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |     status_pins | 
					
						
							|  |  |  |     stream_entries | 
					
						
							|  |  |  |     subscriptions | 
					
						
							|  |  |  |   ).freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ASSOCIATIONS_ON_DESTROY = %w(
 | 
					
						
							|  |  |  |     reports | 
					
						
							|  |  |  |     targeted_moderation_notes | 
					
						
							|  |  |  |     targeted_reports | 
					
						
							|  |  |  |   ).freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Suspend an account and remove as much of its data as possible | 
					
						
							|  |  |  |   # @param [Account] | 
					
						
							|  |  |  |   # @param [Hash] options | 
					
						
							|  |  |  |   # @option [Boolean] :including_user Remove the user record as well | 
					
						
							|  |  |  |   # @option [Boolean] :destroy Remove the account record instead of suspending | 
					
						
							| 
									
										
										
										
											2017-12-06 19:41:57 +09:00
										 |  |  |   def call(account, **options) | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  |     @account = account | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |     @options = options | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 16:18:58 +01:00
										 |  |  |     reject_follows! | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |     purge_user! | 
					
						
							|  |  |  |     purge_profile! | 
					
						
							|  |  |  |     purge_content! | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 16:18:58 +01:00
										 |  |  |   def reject_follows! | 
					
						
							|  |  |  |     return if @account.local? || !@account.activitypub? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ActivityPub::DeliveryWorker.push_bulk(Follow.where(account: @account)) do |follow| | 
					
						
							|  |  |  |       [build_reject_json(follow), follow.target_account_id, follow.account.inbox_url] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |   def purge_user! | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |     return if !@account.local? || @account.user.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if @options[:including_user] | 
					
						
							|  |  |  |       @account.user.destroy | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |       @account.user.disable! | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-06-14 18:01:27 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |   def purge_content! | 
					
						
							| 
									
										
										
										
											2019-03-19 16:33:30 +01:00
										 |  |  |     distribute_delete_actor! if @account.local? && !@options[:skip_distribution] | 
					
						
							| 
									
										
										
										
											2018-01-04 14:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 18:01:35 +02:00
										 |  |  |     @account.statuses.reorder(nil).find_in_batches do |statuses| | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |       BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:destroy]) | 
					
						
							| 
									
										
										
										
											2016-12-06 18:32:36 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |     associations_for_destruction.each do |association_name| | 
					
						
							|  |  |  |       destroy_all(@account.public_send(association_name)) | 
					
						
							| 
									
										
										
										
											2017-05-05 06:44:39 +09:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @account.destroy if @options[:destroy] | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 19:06:44 +01:00
										 |  |  |   def purge_profile! | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |     # If the account is going to be destroyed | 
					
						
							|  |  |  |     # there is no point wasting time updating | 
					
						
							|  |  |  |     # its values first | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return if @options[:destroy] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @account.silenced         = false | 
					
						
							|  |  |  |     @account.suspended        = true | 
					
						
							|  |  |  |     @account.locked           = false | 
					
						
							|  |  |  |     @account.display_name     = '' | 
					
						
							|  |  |  |     @account.note             = '' | 
					
						
							| 
									
										
										
										
											2019-03-05 15:19:54 +01:00
										 |  |  |     @account.fields           = [] | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |     @account.statuses_count   = 0
 | 
					
						
							|  |  |  |     @account.followers_count  = 0
 | 
					
						
							|  |  |  |     @account.following_count  = 0
 | 
					
						
							|  |  |  |     @account.moved_to_account = nil | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  |     @account.avatar.destroy | 
					
						
							|  |  |  |     @account.header.destroy | 
					
						
							|  |  |  |     @account.save! | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 06:44:39 +09:00
										 |  |  |   def destroy_all(association) | 
					
						
							|  |  |  |     association.in_batches.destroy_all | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-01-04 14:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |   def distribute_delete_actor! | 
					
						
							|  |  |  |     ActivityPub::DeliveryWorker.push_bulk(delivery_inboxes) do |inbox_url| | 
					
						
							|  |  |  |       [delete_actor_json, @account.id, inbox_url] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-02-12 05:10:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ActivityPub::LowPriorityDeliveryWorker.push_bulk(low_priority_delivery_inboxes) do |inbox_url| | 
					
						
							|  |  |  |       [delete_actor_json, @account.id, inbox_url] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 14:40:49 +01:00
										 |  |  |   def delete_actor_json | 
					
						
							| 
									
										
										
										
											2018-07-13 02:16:06 +02:00
										 |  |  |     return @delete_actor_json if defined?(@delete_actor_json) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 14:40:49 +01:00
										 |  |  |     payload = ActiveModelSerializers::SerializableResource.new( | 
					
						
							|  |  |  |       @account, | 
					
						
							|  |  |  |       serializer: ActivityPub::DeleteActorSerializer, | 
					
						
							|  |  |  |       adapter: ActivityPub::Adapter | 
					
						
							|  |  |  |     ).as_json | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-13 02:16:06 +02:00
										 |  |  |     @delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account)) | 
					
						
							| 
									
										
										
										
											2018-01-04 14:40:49 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-08-20 13:28:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 16:18:58 +01:00
										 |  |  |   def build_reject_json(follow) | 
					
						
							|  |  |  |     ActiveModelSerializers::SerializableResource.new( | 
					
						
							|  |  |  |       follow, | 
					
						
							|  |  |  |       serializer: ActivityPub::RejectFollowSerializer, | 
					
						
							|  |  |  |       adapter: ActivityPub::Adapter | 
					
						
							|  |  |  |     ).to_json | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-20 13:28:05 +02:00
										 |  |  |   def delivery_inboxes | 
					
						
							| 
									
										
										
										
											2019-02-12 05:10:43 +01:00
										 |  |  |     @delivery_inboxes ||= @account.followers.inboxes + Relay.enabled.pluck(:inbox_url) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def low_priority_delivery_inboxes | 
					
						
							|  |  |  |     Account.inboxes - delivery_inboxes | 
					
						
							| 
									
										
										
										
											2018-08-20 13:28:05 +02:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-12-03 01:32:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def associations_for_destruction | 
					
						
							|  |  |  |     if @options[:destroy] | 
					
						
							|  |  |  |       ASSOCIATIONS_ON_SUSPEND + ASSOCIATIONS_ON_DESTROY | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       ASSOCIATIONS_ON_SUSPEND | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-12-06 17:41:42 +01:00
										 |  |  | end |