Skip to content

Commit

Permalink
Feature/wildcard mail relay (hitobito#638)
Browse files Browse the repository at this point in the history
Allow mail address wildcards in mailing lists
  • Loading branch information
Tschet1 authored and MartinGantenbein committed Mar 22, 2020
1 parent 7436c42 commit 5085b3a
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 3 deletions.
10 changes: 9 additions & 1 deletion app/domain/mail_relay/lists.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,18 @@ def prepare_bounced_message(list_address, sender_address)
message.smtp_envelope_from = env_sender
end

def valid_domain?(domain)
domain !~ /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/
end

def sender_is_additional_sender?
additional_senders = mailing_list.additional_sender.to_s
list = additional_senders.split(/[,;]/).collect(&:strip).select(&:present?)
list.include?(sender_email)
sender_domain = sender_email.sub(/^[^@]*@/, '*@')
# check if the domain is valid, if the sender is in the senders
# list or if the domain is whitelisted
list.include?(sender_email) ||
(valid_domain?(sender_domain) && list.include?(sender_domain))
end

def sender_is_group_email?
Expand Down
3 changes: 3 additions & 0 deletions app/models/mailing_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class MailingList < ActiveRecord::Base
allow_blank: true
validates :description, length: { allow_nil: true, maximum: 2**16 - 1 }
validate :assert_mail_name_is_not_protected
validates :additional_sender,
allow_blank: true,
format: /\A *(([a-z][a-z0-9\-\_\.]*|\*)@([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,} *(,|;|\Z) *)+\Z/

DEFAULT_LABEL = '_main'.freeze

Expand Down
4 changes: 2 additions & 2 deletions app/views/mailing_lists/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
= f.input_field(:mail_name, class: 'span3')
%span.add-on= "@#{entry.mail_domain}"

= f.labeled_input_field(:additional_sender, help: t('.help_additional_sender'))
= f.labeled_input_field(:additional_sender, help: t('.help_additional_sender'), placeholder: "hans.muster@pfadi-beispiel.ch; *@pfadi-muster.ch")

%fieldset
= f.labeled(:preferred_labels) do
Expand Down Expand Up @@ -46,4 +46,4 @@
= f.indented do
= f.boolean_field(:anyone_may_post, caption: t('.caption_anyone_may_post'))
= f.indented do
= f.boolean_field(:delivery_report, caption: t('.caption_delivery_report'))
= f.boolean_field(:delivery_report, caption: t('.caption_delivery_report'))
4 changes: 4 additions & 0 deletions config/locales/models.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ de:
invalid_check_digit: 'ist nicht gültig; Inkorrekte Prüfziffer'
payee:
to_long: 'darf höchstens 2 Zeilen enthalten'
mailing_list:
attributes:
additional_sender:
invalid: "muss Mailadressen vom Format abcd@ee.ch oder *@ee.ch enthalten. Mehrere Adressen müssen mit ',' oder ';' abgetrennt werden."

models:
acts_as_taggable_on/tag:
Expand Down
43 changes: 43 additions & 0 deletions spec/domain/mail_relay/lists_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,49 @@
end
end

context 'additional wildcard sender' do
let(:from) { 'news@example.com' }

before { create_individual_subscribers }
before { list.update_column(:additional_sender, "*@example.com") }

it { is_expected.to be_sender_allowed }
its(:sender_email) { is_expected.to eq from }
its(:potential_senders) { is_expected.to be_blank }
its(:receivers) { is_expected.to match_array subscribers.collect(&:email) }

it 'relays' do
expect { subject.relay }.to change { ActionMailer::Base.deliveries.size }.by(1)

expect(last_email.smtp_envelope_to).to match_array(subscribers.collect(&:email))
end
end

context 'additional wildcard sender not allowed' do
before { create_individual_subscribers }
context 'wrong sender' do
let(:from) { 'news@other.com' }
before { list.update_column(:additional_sender, "*@example.com") }
it { is_expected.not_to be_sender_allowed }
end
context 'invalid list' do
let(:from) { 'news@example.com' }
test_mails = ['*ws@example.com', 'ne@ws@example.com', 'ne*@example.com', 'n*s@example.com']
test_mails.each { |x|
before { list.update_column(:additional_sender, x) }
it { is_expected.not_to be_sender_allowed }
}
end
context 'invalid domain' do
test_mails = ['ws@exa-mple.com', 'ne@ws@example.com', 'ne@exam*ple.com', 'n*s@exa_mple.com']
test_mails.each { |x|
let(:from) { x }
it { is_expected.not_to be_sender_allowed }
}
end
end


context 'list member' do
before { create_individual_subscribers }

Expand Down
17 changes: 17 additions & 0 deletions spec/models/mailing_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@
list.mail_name = 'foo'
expect(list).to have(1).error_on(:mail_name)
end

it 'succeed with additional_sender' do
list.additional_sender = ''
expect(list).to be_valid
end
it 'succeed with additional_sender' do
list.additional_sender = 'abc@de.ft; *@df.dfd.ee,test@test.test'
expect(list).to be_valid
end
it 'succeed with additional_sender' do
list.additional_sender = 'abc*dv@test.ch'
expect(list).to have(1).error_on(:additional_sender)
end
it 'succeed with additional_sender' do
list.additional_sender = 'abc@de.ft;as*d@df.dfd.ee,test@test.test'
expect(list).to have(1).error_on(:additional_sender)
end
end

describe '#subscribed?' do
Expand Down

0 comments on commit 5085b3a

Please sign in to comment.