From 2e0eac71ddf0f5b61b6e395f57b7bc3f805cbf87 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Wed, 7 Jul 2021 21:17:00 +0200
Subject: [PATCH] Add --by-uri option to `tootctl domains purge` (#16434)

Fixes #16410
---
 lib/mastodon/domains_cli.rb | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
index 4ebd8a1e2c..a7c78c4a7a 100644
--- a/lib/mastodon/domains_cli.rb
+++ b/lib/mastodon/domains_cli.rb
@@ -17,6 +17,7 @@ module Mastodon
     option :verbose, type: :boolean, aliases: [:v]
     option :dry_run, type: :boolean
     option :limited_federation_mode, type: :boolean
+    option :by_uri, type: :boolean
     desc 'purge [DOMAIN...]', 'Remove accounts from a DOMAIN without a trace'
     long_desc <<-LONG_DESC
       Remove all accounts from a given DOMAIN without leaving behind any
@@ -26,6 +27,12 @@ module Mastodon
       When the --limited-federation-mode option is given, instead of purging accounts
       from a single domain, all accounts from domains that have not been explicitly allowed
       are removed from the database.
+
+      When the --by-uri option is given, DOMAIN is used to match the domain part of actor
+      URIs rather than the domain part of the webfinger handle. For instance, an account
+      that has the handle `foo@bar.com` but whose profile is at the URL
+      `https://mastodon-bar.com/users/foo`, would be purged by either
+      `tootctl domains purge bar.com` or `tootctl domains purge --by-uri mastodon-bar.com`.
     LONG_DESC
     def purge(*domains)
       dry_run = options[:dry_run] ? ' (DRY RUN)' : ''
@@ -34,7 +41,11 @@ module Mastodon
         if options[:limited_federation_mode]
           Account.remote.where.not(domain: DomainAllow.pluck(:domain))
         elsif !domains.empty?
-          Account.remote.where(domain: domains)
+          if options[:by_uri]
+            domains.map { |domain| Account.remote.where(Account.arel_table[:uri].matches("https://#{domain}/%", false, true)) }.reduce(:or)
+          else
+            Account.remote.where(domain: domains)
+          end
         else
           say('No domain(s) given', :red)
           exit(1)