aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/Email.pm
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2015-12-02 17:45:03 +0000
committerMatthew Somerville <matthew@mysociety.org>2015-12-02 17:45:03 +0000
commitb6fcd966d204d35c149b2bff91513e732f3101c8 (patch)
tree75fb01b3910fc4093584bb3b9056e9ea6dbe0eba /perllib/FixMyStreet/Email.pm
parent8543192128ed15c9bc73e3686ab03324ee5e2b11 (diff)
parent7b20745945638cce030879eafc8cac8f8bd81c56 (diff)
Merge branch 'reduce-fixmystreet-app'
Diffstat (limited to 'perllib/FixMyStreet/Email.pm')
-rw-r--r--perllib/FixMyStreet/Email.pm124
1 files changed, 124 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/Email.pm b/perllib/FixMyStreet/Email.pm
index 4a2784787..a65a5e340 100644
--- a/perllib/FixMyStreet/Email.pm
+++ b/perllib/FixMyStreet/Email.pm
@@ -1,7 +1,13 @@
package FixMyStreet::Email;
+use Encode;
+use Template;
+use mySociety::Email;
+use mySociety::Locale;
+use mySociety::Random qw(random_bytes);
use Utils::Email;
use FixMyStreet;
+use FixMyStreet::EmailSend;
sub test_dmarc {
my $email = shift;
@@ -9,4 +15,122 @@ sub test_dmarc {
return Utils::Email::test_dmarc($email);
}
+sub is_abuser {
+ my ($schema, $to) = @_;
+
+ my $email;
+ if (ref($to) eq 'ARRAY') {
+ if (ref($to->[0]) eq 'ARRAY') {
+ $email = $to->[0][0];
+ } else {
+ $email = $to->[0];
+ }
+ } else {
+ $email = $to;
+ }
+
+ my ($domain) = $email =~ m{ @ (.*) \z }x;
+ return $schema->resultset('Abuse')->search( { email => [ $email, $domain ] } )->first;
+}
+
+sub send_cron {
+ my ( $schema, $params, $env_from, $nomail, $cobrand, $lang_code ) = @_;
+
+ my $sender = FixMyStreet->config('DO_NOT_REPLY_EMAIL');
+ $env_from ||= $sender;
+ if (!$params->{From}) {
+ my $sender_name = $cobrand->contact_name;
+ $params->{From} = [ $sender, _($sender_name) ];
+ }
+
+ return 1 if is_abuser($schema, $params->{To});
+
+ $params->{'Message-ID'} = sprintf('<fms-cron-%s-%s@%s>', time(),
+ unpack('h*', random_bytes(5, 1)), FixMyStreet->config('EMAIL_DOMAIN')
+ );
+
+ # This is all to set the path for the templates processor so we can override
+ # signature and site names in emails using templates in the old style emails.
+ # It's a bit involved as not everywhere we use it knows about the cobrand so
+ # we can't assume there will be one.
+ my $include_path = FixMyStreet->path_to( 'templates', 'email', 'default' )->stringify;
+ if ( $cobrand ) {
+ $include_path =
+ FixMyStreet->path_to( 'templates', 'email', $cobrand->moniker )->stringify . ':'
+ . $include_path;
+ if ( $lang_code ) {
+ $include_path =
+ FixMyStreet->path_to( 'templates', 'email', $cobrand->moniker, $lang_code )->stringify . ':'
+ . $include_path;
+ }
+ }
+ my $tt = Template->new({
+ INCLUDE_PATH => $include_path
+ });
+ my ($sig, $site_name);
+ $tt->process( 'signature.txt', $params, \$sig );
+ $sig = Encode::decode('utf8', $sig);
+ $params->{_parameters_}->{signature} = $sig;
+
+ $tt->process( 'site-name.txt', $params, \$site_name );
+ $site_name = Utils::trim_text(Encode::decode('utf8', $site_name));
+ $params->{_parameters_}->{site_name} = $site_name;
+
+ $params->{_line_indent} = '';
+ my $attachments = delete $params->{attachments};
+
+ my $email = mySociety::Locale::in_gb_locale { mySociety::Email::construct_email($params) };
+
+ $email = munge_attachments($email, $attachments) if $attachments;
+
+ if ($nomail) {
+ print $email;
+ return 1; # Failure
+ } else {
+ my %model_args;
+ if (!FixMyStreet->test_mode && $env_from eq FixMyStreet->config('CONTACT_EMAIL')) {
+ $model_args{mailer} = 'FixMyStreet::EmailSend::ContactEmail';
+ }
+ my $result = FixMyStreet::EmailSend->new(%model_args)->send($email);
+ return $result ? 0 : 1;
+ }
+}
+
+sub munge_attachments {
+ my ($message, $attachments) = @_;
+ # $attachments should be an array_ref of things that can be parsed to Email::MIME,
+ # for example
+ # [
+ # body => $binary_data,
+ # attributes => {
+ # content_type => 'image/jpeg',
+ # encoding => 'base64',
+ # filename => '1234.1.jpeg',
+ # name => '1234.1.jpeg',
+ # },
+ # ...
+ # ]
+ #
+ # XXX: mySociety::Email::construct_email isn't using a MIME library and
+ # requires more analysis to refactor, so for now, we'll simply parse the
+ # generated MIME and add attachments.
+ #
+ # (Yes, this means that the email is constructed by Email::Simple, munged
+ # manually by custom code, turned back into Email::Simple, and then munged
+ # with Email::MIME. What's your point?)
+
+ require Email::MIME;
+ my $mime = Email::MIME->new($message);
+ $mime->parts_add([ map { Email::MIME->create(%$_)} @$attachments ]);
+ my $data = $mime->as_string;
+
+ # unsure why Email::MIME adds \r\n. Possibly mail client should handle
+ # gracefully, BUT perhaps as the segment constructed by
+ # mySociety::Email::construct_email strips to \n, they seem not to.
+ # So we re-run the same regexp here to the added part.
+ $data =~ s/\r\n/\n/gs;
+
+ return $data;
+}
+
1;