diff options
author | Matthew Somerville <matthew@mysociety.org> | 2017-03-17 22:18:45 +0000 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2017-03-28 13:10:38 +0100 |
commit | b26da0da5e1f8631646a34fdacbce9bb5bc3b706 (patch) | |
tree | cd42e16d51054606b85bf6ff28a47e586437406c /perllib/FixMyStreet | |
parent | 02fcb1606bc2b739fdc798e5ca06f2ed1b6bf6ea (diff) |
Upgrade to using Email::Sender.
Email::Send is long deprecated and uses submodules that no longer work
correctly (e.g. Net::SMTP::TLS breaks with recent IO::Socket::SSL). We
create an Email::Sender subclass to perform the same functionality and
this also simplifies the email code with simpler envelope handling.
Bundle Email::Sender::Transport::SMTP to include fix from
https://github.com/rjbs/Email-Sender/issues/46
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r-- | perllib/FixMyStreet/App.pm | 11 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Model/EmailSend.pm | 19 | ||||
-rw-r--r-- | perllib/FixMyStreet/Email.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/Email/Sender.pm | 50 | ||||
-rw-r--r-- | perllib/FixMyStreet/EmailSend.pm | 78 | ||||
-rw-r--r-- | perllib/FixMyStreet/EmailSend/Variable.pm | 17 | ||||
-rw-r--r-- | perllib/FixMyStreet/TestMech.pm | 9 |
7 files changed, 66 insertions, 122 deletions
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index 9660d327a..35e8c2537 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -9,9 +9,11 @@ use FixMyStreet::Cobrand; use Memcached; use FixMyStreet::Map; use FixMyStreet::Email; +use FixMyStreet::Email::Sender; use Utils; use Path::Tiny 'path'; +use Try::Tiny; use URI; use URI::QueryParam; @@ -346,8 +348,13 @@ sub send_email { $data->{_html_images_} = \@inline_images if @inline_images; my $email = mySociety::Locale::in_gb_locale { FixMyStreet::Email::construct_email($data) }; - my $return = $c->model('EmailSend')->send($email); - $c->log->error("$return") if !$return; + + try { + FixMyStreet::Email::Sender->send($email, { from => $sender }); + } catch { + my $error = $_ || 'unknown error'; + $c->log->error("$error"); + }; return $email; } diff --git a/perllib/FixMyStreet/App/Model/EmailSend.pm b/perllib/FixMyStreet/App/Model/EmailSend.pm deleted file mode 100644 index 93751d4a6..000000000 --- a/perllib/FixMyStreet/App/Model/EmailSend.pm +++ /dev/null @@ -1,19 +0,0 @@ -package FixMyStreet::App::Model::EmailSend; -use base 'Catalyst::Model::Factory'; - -use strict; -use warnings; - -=head1 NAME - -FixMyStreet::App::Model::EmailSend - -=head1 DESCRIPTION - -Catalyst Model wrapper around FixMyStreet::EmailSend - -=cut - -__PACKAGE__->config( - class => 'FixMyStreet::EmailSend', -); diff --git a/perllib/FixMyStreet/Email.pm b/perllib/FixMyStreet/Email.pm index e0d82a8ef..ea84e3966 100644 --- a/perllib/FixMyStreet/Email.pm +++ b/perllib/FixMyStreet/Email.pm @@ -17,7 +17,7 @@ use mySociety::Random qw(random_bytes); use Utils::Email; use FixMyStreet; use FixMyStreet::DB; -use FixMyStreet::EmailSend; +use FixMyStreet::Email::Sender; sub test_dmarc { my $email = shift; @@ -187,7 +187,7 @@ sub send_cron { print $email->as_string; return 1; # Failure } else { - my $result = FixMyStreet::EmailSend->new({ env_from => $env_from })->send($email); + my $result = FixMyStreet::Email::Sender->try_to_send($email, { from => $env_from }); return $result ? 0 : 1; } } diff --git a/perllib/FixMyStreet/Email/Sender.pm b/perllib/FixMyStreet/Email/Sender.pm new file mode 100644 index 000000000..e6148a56c --- /dev/null +++ b/perllib/FixMyStreet/Email/Sender.pm @@ -0,0 +1,50 @@ +package FixMyStreet::Email::Sender; + +use parent Email::Sender::Simple; +use strict; +use warnings; + +use Email::Sender::Util; +use FixMyStreet; + +=head1 NAME + +FixMyStreet::Email::Sender + +=head1 DESCRIPTION + +Subclass of Email::Sender - configuring it correctly according to our config. + +If the config value 'SMTP_SMARTHOST' is set then email is routed via SMTP to +that. Otherwise it is sent using a 'sendmail' like binary on the local system. + +And finally if if FixMyStreet->test_mode returns true then emails are not sent +at all but are stored in memory for the test suite to inspect (using +Email::Send::Test). + +=cut + +sub build_default_transport { + if ( FixMyStreet->test_mode ) { + Email::Sender::Util->easy_transport(Test => {}); + } elsif ( my $smtp_host = FixMyStreet->config('SMTP_SMARTHOST') ) { + my $type = FixMyStreet->config('SMTP_TYPE') || ''; + my $port = FixMyStreet->config('SMTP_PORT') || ''; + my $username = FixMyStreet->config('SMTP_USERNAME') || ''; + my $password = FixMyStreet->config('SMTP_PASSWORD') || ''; + + my $ssl = $type eq 'tls' ? 'starttls' : $type eq 'ssl' ? 'ssl' : ''; + my $args = { + host => $smtp_host, + ssl => $ssl, + sasl_username => $username, + sasl_password => $password, + }; + $args->{port} = $port if $port; + Email::Sender::Util->easy_transport(SMTP => $args); + } else { + Email::Sender::Util->easy_transport(Sendmail => {}); + } +} + +1; diff --git a/perllib/FixMyStreet/EmailSend.pm b/perllib/FixMyStreet/EmailSend.pm deleted file mode 100644 index 09f434931..000000000 --- a/perllib/FixMyStreet/EmailSend.pm +++ /dev/null @@ -1,78 +0,0 @@ -package FixMyStreet::EmailSend; - -use strict; -use warnings; - -BEGIN { - # Should move away from Email::Send, but until then: - $Return::Value::NO_CLUCK = 1; -} - -use FixMyStreet; -use Email::Send; - -=head1 NAME - -FixMyStreet::EmailSend - -=head1 DESCRIPTION - -Thin wrapper around Email::Send - configuring it correctly according to our config. - -If the config value 'SMTP_SMARTHOST' is set then email is routed via SMTP to -that. Otherwise it is sent using a 'sendmail' like binary on the local system. - -And finally if if FixMyStreet->test_mode returns true then emails are not sent -at all but are stored in memory for the test suite to inspect (using -Email::Send::Test). - -=cut - -my $args = undef; - -if ( FixMyStreet->test_mode ) { - # Email::Send::Test - $args = { mailer => 'Test', }; -} elsif ( my $smtp_host = FixMyStreet->config('SMTP_SMARTHOST') ) { - # Email::Send::SMTP - my $type = FixMyStreet->config('SMTP_TYPE') || ''; - my $port = FixMyStreet->config('SMTP_PORT') || ''; - my $username = FixMyStreet->config('SMTP_USERNAME') || ''; - my $password = FixMyStreet->config('SMTP_PASSWORD') || ''; - - unless ($port) { - $port = 25; - $port = 465 if $type eq 'ssl'; - $port = 587 if $type eq 'tls'; - } - - my $mailer_args = [ - Host => $smtp_host, - Port => $port, - ]; - push @$mailer_args, ssl => 1 if $type eq 'ssl'; - push @$mailer_args, tls => 1 if $type eq 'tls'; - push @$mailer_args, username => $username, password => $password - if $username && $password; - $args = { - mailer => 'FixMyStreet::EmailSend::Variable', - mailer_args => $mailer_args, - }; -} else { - # Email::Send::Sendmail - $args = { mailer => 'Sendmail' }; -} - -sub new { - my ($cls, $hash) = @_; - $hash ||= {}; - my %args = ( %$args, %$hash ); - - my $sender = delete($args{env_from}); - if ($sender) { - $args{mailer_args} = [ @{$args{mailer_args}} ] if $args{mailer_args}; - push @{$args{mailer_args}}, env_from => $sender; - } - - return Email::Send->new(\%args); -} diff --git a/perllib/FixMyStreet/EmailSend/Variable.pm b/perllib/FixMyStreet/EmailSend/Variable.pm deleted file mode 100644 index 4ba56dd41..000000000 --- a/perllib/FixMyStreet/EmailSend/Variable.pm +++ /dev/null @@ -1,17 +0,0 @@ -package FixMyStreet::EmailSend::Variable; -use base Email::Send::SMTP; -use FixMyStreet; - -my $sender; - -sub send { - my ($class, $message, %args) = @_; - $sender = delete($args{env_from}) || FixMyStreet->config('DO_NOT_REPLY_EMAIL'); - $class->SUPER::send($message, %args); -} - -sub get_env_sender { - $sender; -} - -1; diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm index 122a5d0c9..c22789fb0 100644 --- a/perllib/FixMyStreet/TestMech.pm +++ b/perllib/FixMyStreet/TestMech.pm @@ -13,7 +13,7 @@ use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; use Test::More; use Web::Scraper; use Carp; -use Email::Send::Test; +use FixMyStreet::Email::Sender; use JSON::MaybeXS; =head1 NAME @@ -182,7 +182,7 @@ Clear the email queue. sub clear_emails_ok { my $mech = shift; - Email::Send::Test->clear; + FixMyStreet::Email::Sender->default_transport->clear_deliveries; $mech->builder->ok( 1, 'cleared email queue' ); return 1; } @@ -199,7 +199,7 @@ sub email_count_is { my $mech = shift; my $number = shift || 0; - $mech->builder->is_num( scalar( Email::Send::Test->emails ), + $mech->builder->is_num( scalar( FixMyStreet::Email::Sender->default_transport->delivery_count ), $number, "checking for $number email(s) in the queue" ); } @@ -215,7 +215,8 @@ In list context returns all the emails (or none). sub get_email { my $mech = shift; - my @emails = Email::Send::Test->emails; + my @emails = FixMyStreet::Email::Sender->default_transport->deliveries; + @emails = map { $_->{email}->object } @emails; return @emails if wantarray; |