Change e-mail domain blocks to block IPs dynamically (#17635)
* Change e-mail domain blocks to block IPs dynamically * Update app/workers/scheduler/email_domain_block_refresh_scheduler.rb Co-authored-by: Yamagishi Kazutoshi <ykzts@desire.sh> * Update app/workers/scheduler/email_domain_block_refresh_scheduler.rb Co-authored-by: Yamagishi Kazutoshi <ykzts@desire.sh> Co-authored-by: Yamagishi Kazutoshi <ykzts@desire.sh>local
parent
91cc8d1e63
commit
a29a982eaa
20 changed files with 325 additions and 160 deletions
@ -0,0 +1,30 @@ |
|||||||
|
# frozen_string_literal: true |
||||||
|
|
||||||
|
class Form::EmailDomainBlockBatch |
||||||
|
include ActiveModel::Model |
||||||
|
include Authorization |
||||||
|
include AccountableConcern |
||||||
|
|
||||||
|
attr_accessor :email_domain_block_ids, :action, :current_account |
||||||
|
|
||||||
|
def save |
||||||
|
case action |
||||||
|
when 'delete' |
||||||
|
delete! |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def email_domain_blocks |
||||||
|
@email_domain_blocks ||= EmailDomainBlock.where(id: email_domain_block_ids) |
||||||
|
end |
||||||
|
|
||||||
|
def delete! |
||||||
|
email_domain_blocks.each do |email_domain_block| |
||||||
|
authorize(email_domain_block, :destroy?) |
||||||
|
email_domain_block.destroy! |
||||||
|
log_action :destroy, email_domain_block |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,15 +1,14 @@ |
|||||||
%tr |
.batch-table__row |
||||||
%td |
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox |
||||||
%samp= email_domain_block.domain |
= f.check_box :email_domain_block_ids, { multiple: true, include_hidden: false }, email_domain_block.id |
||||||
%td |
.batch-table__row__content.pending-account |
||||||
= table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(email_domain_block), method: :delete |
.pending-account__header |
||||||
|
%samp= link_to email_domain_block.domain, admin_accounts_path(email: "%@#{email_domain_block.domain}") |
||||||
|
|
||||||
- email_domain_block.children.each do |child_email_domain_block| |
%br/ |
||||||
%tr |
|
||||||
%td |
- if email_domain_block.parent.present? |
||||||
%samp= child_email_domain_block.domain |
= t('admin.email_domain_blocks.resolved_through_html', domain: content_tag(:samp, email_domain_block.parent.domain)) |
||||||
%span.muted-hint |
• |
||||||
= surround '(', ')' do |
|
||||||
= t('admin.email_domain_blocks.from_html', domain: content_tag(:samp, email_domain_block.domain)) |
= t('admin.email_domain_blocks.attempts_over_week', count: email_domain_block.history.reduce(0) { |sum, day| sum + day.accounts }) |
||||||
%td |
|
||||||
= table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(child_email_domain_block), method: :delete |
|
||||||
|
@ -1,14 +1,38 @@ |
|||||||
- content_for :page_title do |
- content_for :page_title do |
||||||
= t('.title') |
= t('.title') |
||||||
|
|
||||||
|
- content_for :header_tags do |
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous' |
||||||
|
|
||||||
= simple_form_for @email_domain_block, url: admin_email_domain_blocks_path do |f| |
= simple_form_for @email_domain_block, url: admin_email_domain_blocks_path do |f| |
||||||
= render 'shared/error_messages', object: @email_domain_block |
= render 'shared/error_messages', object: @email_domain_block |
||||||
|
|
||||||
.fields-group |
.fields-group |
||||||
= f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain') |
= f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain'), input_html: { readonly: defined?(@resolved_records) } |
||||||
|
|
||||||
.fields-group |
- if defined?(@resolved_records) |
||||||
= f.input :with_dns_records, as: :boolean, wrapper: :with_label |
%p.hint= t('admin.email_domain_blocks.resolved_dns_records_hint_html') |
||||||
|
|
||||||
|
.batch-table |
||||||
|
.batch-table__toolbar |
||||||
|
%label.batch-table__toolbar__select.batch-checkbox-all |
||||||
|
= check_box_tag :batch_checkbox_all, nil, false |
||||||
|
.batch-table__toolbar__actions |
||||||
|
.batch-table__body |
||||||
|
- @resolved_records.each do |record| |
||||||
|
.batch-table__row |
||||||
|
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox |
||||||
|
= f.input_field :other_domains, as: :boolean, checked_value: record.exchange.to_s, include_hidden: false, multiple: true |
||||||
|
.batch-table__row__content.pending-account |
||||||
|
.pending-account__header |
||||||
|
%samp= record.exchange.to_s |
||||||
|
%br |
||||||
|
= t('admin.email_domain_blocks.dns.types.mx') |
||||||
|
|
||||||
|
%hr.spacer/ |
||||||
|
|
||||||
.actions |
.actions |
||||||
= f.button :button, t('.create'), type: :submit |
- if defined?(@resolved_records) |
||||||
|
= f.button :button, t('.create'), type: :submit, name: :save |
||||||
|
- else |
||||||
|
= f.button :button, t('.resolve'), type: :submit, name: :resolve |
||||||
|
@ -0,0 +1,30 @@ |
|||||||
|
# frozen_string_literal: true |
||||||
|
|
||||||
|
class Scheduler::EmailDomainBlockRefreshScheduler |
||||||
|
include Sidekiq::Worker |
||||||
|
include Redisable |
||||||
|
|
||||||
|
sidekiq_options retry: 0 |
||||||
|
|
||||||
|
def perform |
||||||
|
Resolv::DNS.open do |dns| |
||||||
|
dns.timeouts = 5 |
||||||
|
|
||||||
|
EmailDomainBlock.find_each do |email_domain_block| |
||||||
|
ips = begin |
||||||
|
if ip?(email_domain_block.domain) |
||||||
|
[email_domain_block.domain] |
||||||
|
else |
||||||
|
dns.getresources(email_domain_block.domain, Resolv::DNS::Resource::IN::A).to_a + dns.getresources(email_domain_block.domain, Resolv::DNS::Resource::IN::AAAA).to_a.map { |resource| resource.address.to_s } |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
email_domain_block.update(ips: ips, last_refresh_at: Time.now.utc) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def ip?(str) |
||||||
|
str =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex]) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,6 @@ |
|||||||
|
class AddIpsToEmailDomainBlocks < ActiveRecord::Migration[6.1] |
||||||
|
def change |
||||||
|
add_column :email_domain_blocks, :ips, :inet, array: true |
||||||
|
add_column :email_domain_blocks, :last_refresh_at, :datetime |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue