Make tootctl aware of new 'require approval' for email domains

This commit is contained in:
Eashwar Ranganathan 2025-04-29 22:16:59 -04:00
parent 8b34daf254
commit 624f06e756
No known key found for this signature in database
4 changed files with 87 additions and 8 deletions

View File

@ -538,7 +538,7 @@ and provided thanks to the work of the following contributors:
* [Drew Schuster](mailto:dtschust@gmail.com) * [Drew Schuster](mailto:dtschust@gmail.com)
* [Dryusdan](mailto:dryusdan@dryusdan.fr) * [Dryusdan](mailto:dryusdan@dryusdan.fr)
* [Eai](mailto:eai@mizle.net) * [Eai](mailto:eai@mizle.net)
* [Eashwar Ranganathan](mailto:eranganathan@lyft.com) * [Eashwar Ranganathan](mailto:eashwar@eashwar.com)
* [Ed Knutson](mailto:knutsoned@gmail.com) * [Ed Knutson](mailto:knutsoned@gmail.com)
* [Elizabeth Martín Campos](mailto:me@elizabeth.sh) * [Elizabeth Martín Campos](mailto:me@elizabeth.sh)
* [Elizabeth Myers](mailto:elizabeth@interlinked.me) * [Elizabeth Myers](mailto:elizabeth@interlinked.me)

View File

@ -5,9 +5,33 @@ require_relative 'base'
module Mastodon::CLI module Mastodon::CLI
class EmailDomainBlocks < Base class EmailDomainBlocks < Base
option :only_blocked, type: :boolean, defaut: false
option :only_with_approval, type: :boolean, default: false
desc 'list', 'List blocked e-mail domains' desc 'list', 'List blocked e-mail domains'
long_desc <<-LONG_DESC
By default this command lists all domains in the email domain block list
and their associated MX records (if included).
If the --only-blocked option is provided, this command will list only email
domains that are fully blocked from signup.
If the --only-with-approval option is provided, this command will list only
email domains that are allowed to be used but require manual approval.
The --only-blocked and --only-with-approval options are mutually exclusive.
LONG_DESC
def list def list
EmailDomainBlock.parents.find_each do |parent| fail_with_message 'Cannot specify both --only-blocked and --only-with-approval' if options[:only_blocked] && options[:only_with_approval]
base_query = EmailDomainBlock.where(parent_id: nil)
if options[:only_blocked]
base_query = base_query.where(allow_with_approval: false)
elsif options[:only_with_approval]
base_query = base_query.where(allow_with_approval: true)
end
base_query.find_each do |parent|
say(parent.domain.to_s, :white) say(parent.domain.to_s, :white)
shell.indent do shell.indent do
@ -19,6 +43,7 @@ module Mastodon::CLI
end end
option :with_dns_records, type: :boolean option :with_dns_records, type: :boolean
option :allow_with_approval, type: :boolean, defaut: false
desc 'add DOMAIN...', 'Block e-mail domain(s)' desc 'add DOMAIN...', 'Block e-mail domain(s)'
long_desc <<-LONG_DESC long_desc <<-LONG_DESC
Blocking an e-mail domain prevents users from signing up Blocking an e-mail domain prevents users from signing up
@ -30,6 +55,9 @@ module Mastodon::CLI
This can be helpful if you are blocking an e-mail server that has many This can be helpful if you are blocking an e-mail server that has many
different domains pointing to it as it allows you to essentially block different domains pointing to it as it allows you to essentially block
it at the root. it at the root.
When the --allow-with-approval option is set, the email domains provided will
have to be manually approved for signup.
LONG_DESC LONG_DESC
def add(*domains) def add(*domains)
fail_with_message 'No domain(s) given' if domains.empty? fail_with_message 'No domain(s) given' if domains.empty?
@ -47,19 +75,18 @@ module Mastodon::CLI
other_domains = [] other_domains = []
other_domains = DomainResource.new(domain).mx if options[:with_dns_records] other_domains = DomainResource.new(domain).mx if options[:with_dns_records]
email_domain_block = EmailDomainBlock.new(domain: domain, other_domains: other_domains) email_domain_block = EmailDomainBlock.new(domain: domain, other_domains: other_domains, allow_with_approval: options[:allow_with_approval])
email_domain_block.save! email_domain_block.save!
processed += 1 processed += 1
(email_domain_block.other_domains || []).uniq.each do |hostname| (email_domain_block.other_domains || []).uniq.each do |hostname|
another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: email_domain_block)
if EmailDomainBlock.exists?(domain: hostname) if EmailDomainBlock.exists?(domain: hostname)
say("#{hostname} is already blocked.", :yellow) say("#{hostname} is already blocked.", :yellow)
skipped += 1 skipped += 1
next next
end end
another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: email_domain_block, allow_with_approval: options[:allow_with_approval])
another_email_domain_block.save! another_email_domain_block.save!
processed += 1 processed += 1
end end

View File

@ -15,17 +15,62 @@ RSpec.describe Mastodon::CLI::EmailDomainBlocks do
describe '#list' do describe '#list' do
let(:action) { :list } let(:action) { :list }
context 'with both --only-blocked and --only-with-approval' do
let(:options) { { only_blocked: true, only_with_approval: true } }
it 'warns about usage and exits' do
expect { subject }
.to raise_error(Thor::Error, 'Cannot specify both --only-blocked and --only-with-approval')
end
end
context 'with email domain block records' do context 'with email domain block records' do
let!(:parent_block) { Fabricate(:email_domain_block) } let!(:parent_block) { Fabricate(:email_domain_block) }
let!(:child_block) { Fabricate(:email_domain_block, parent: parent_block) } let!(:child_block) { Fabricate(:email_domain_block, parent: parent_block) }
let!(:parent_allow_block) { Fabricate(:email_domain_block, allow_with_approval: true) }
let!(:child_allow_block) { Fabricate(:email_domain_block, parent: parent_allow_block, allow_with_approval: true) }
it 'lists the blocks' do it 'lists all the blocks by default' do
expect { subject } expect { subject }
.to output_results( .to output_results(
parent_block.domain, parent_block.domain,
child_block.domain child_block.domain,
parent_allow_block.domain,
child_allow_block.domain
) )
end end
context 'with the --only-blocked flag set' do
let(:options) { { only_blocked: true } }
it 'lists only blocked domains' do
expect { subject }
.to output_results(
parent_block.domain,
child_block.domain
)
.and not_output_results(
parent_allow_block.domain,
child_allow_block.domain
)
end
end
context 'with the --only-with-approval flag set' do
let(:options) { { only_with_approval: true } }
it 'lists only manually approvable domains' do
expect { subject }
.to output_results(
parent_allow_block.domain,
child_allow_block.domain
)
.and not_output_results(
parent_block.domain,
child_block.domain
)
end
end
end end
end end
@ -56,6 +101,7 @@ RSpec.describe Mastodon::CLI::EmailDomainBlocks do
context 'when no blocks exist' do context 'when no blocks exist' do
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] } let(:arguments) { [domain] }
let(:options) { { allow_with_approval: false } }
it 'adds a new block' do it 'adds a new block' do
expect { subject } expect { subject }
@ -67,7 +113,7 @@ RSpec.describe Mastodon::CLI::EmailDomainBlocks do
context 'with --with-dns-records true' do context 'with --with-dns-records true' do
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] } let(:arguments) { [domain] }
let(:options) { { with_dns_records: true } } let(:options) { { allow_with_approval: false, with_dns_records: true } }
before do before do
configure_mx(domain: domain, exchange: 'other.host') configure_mx(domain: domain, exchange: 'other.host')

View File

@ -6,4 +6,10 @@ module CommandLineHelpers
include(*) include(*)
).to_stdout ).to_stdout
end end
def not_output_results(*)
output(
not_include(*)
).to_stdout
end
end end