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 5cf37248cc
commit 2da143ab90
No known key found for this signature in database
4 changed files with 86 additions and 9 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,10 +5,36 @@ 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| if options[:only_blocked] && options[:only_with_approval]
say(parent.domain.to_s, :white) fail_with_message 'Cannot specify both --only-blocked and --only-with-approval'
end
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 |entry|
say(entry.domain.to_s, :white)
shell.indent do shell.indent do
EmailDomainBlock.where(parent_id: parent.id).find_each do |child| EmailDomainBlock.where(parent_id: parent.id).find_each do |child|
@ -19,6 +45,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 +57,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 +77,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

@ -7,7 +7,6 @@ RSpec.describe Mastodon::CLI::EmailDomainBlocks do
subject { cli.invoke(action, arguments, options) } subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} } let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
@ -15,15 +14,58 @@ 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(:arguments) { ['--only-blocked', '--only-with-approval'] }
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 all the blocks by default' do
let(:arguments) { [] }
it 'lists the blocks' 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
it 'lists only blocked domains with --only-blocked' do
let(:arguments) { ['--only-blocked'] }
expect { subject }
.to output_results(
parent_block.domain,
child_block.domain,
)
.and not_output_results(
parent_allow_block.domain,
child_allow_block.domain,
)
end
it 'lists only manually approvable domains with --only-with-approval' do
let(:arguments) { ['--only-with-approval'] }
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

View File

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