Commit 5fa6e3fe authored by IKEDA Soji's avatar IKEDA Soji
Browse files

Limit personalization: Only when posted from WWSympa, entire text will be...

Limit personalization: Only when posted from WWSympa, entire text will be converted. Otherwise only footer/header will be converted.
parent 90b6c391
......@@ -53,7 +53,7 @@
<textarea name="body" id="body" cols="80" rows="25">[% body %]</textarea>
<br />
[% IF merge_feature %]
[% IF listconf.merge_feature == 'on' %]
<br />
<b>[%|loc%]Messages customization: use the template syntax:[%END%] <a href="http://www.tt2.org">TT2</a></b>
<br />
......
......@@ -214,7 +214,8 @@ sub process {
if $row_mailer->{verp_bulkmailer};
$message->{shelved}{tracking} = $row_mailer->{tracking_bulkmailer}
if $row_mailer->{tracking_bulkmailer};
$message->{shelved}{merge} = 1 if $row_mailer->{merge_bulkmailer};
# Compatibility: On earlier version only 'all' mode was available.
$message->{shelved}{merge} = 'all' if $row_mailer->{merge_bulkmailer};
# Not a typo: column name was recEipients_bulkmailer.
my $rcpt_string = $row_mailer->{receipients_bulkmailer};
......
......@@ -14562,8 +14562,8 @@ sub do_compose_mail {
$param->{'topic_required'} = $list->is_msg_topic_tagging_required();
}
 
$param->{'merge_feature'} =
Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'}, 'on');
#$param->{'merge_feature'} =
# Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'}, 'on');
 
return 1;
}
......@@ -14905,7 +14905,7 @@ sub do_send_mail {
# - Add footer / header.
$u_message->prepare_message_according_to_mode('mail', $list);
# - Shelve personalization.
$u_message->{shelved}{merge} = 1
$u_message->{shelved}{merge} = 'all'
if Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'},
'on');
 
......
......@@ -1393,7 +1393,6 @@ sub personalize {
my $self = shift;
my $list = shift;
my $rcpt = shift || undef;
my $data = shift || {};
my $content_type = lc($self->{_head}->mime_attr('Content-Type') || '');
if ( $content_type eq 'multipart/encrypted'
......@@ -1406,8 +1405,23 @@ sub personalize {
my $entity = $self->as_entity->dup;
# Initialize parameters at first only once.
$data->{'headers'} ||= {};
my $data = $self->_personalize_attrs;
unless (defined _merge_msg($entity, $list, $rcpt, $data)) {
return undef;
}
$self->set_entity($entity);
return $self;
}
sub _personalize_attrs {
my $self = shift;
my $entity = $self->as_entity;
my $headers = $entity->head;
my $data = {headers => {}};
foreach my $key (
qw/subject x-originating-ip message-id date x-original-to from to thread-topic content-type/
) {
......@@ -1415,16 +1429,11 @@ sub personalize {
my $value = $headers->get($key, 0);
chomp $value;
$value =~ s/(?:\r\n|\r|\n)(?=[ \t])//g; # unfold
$data->{'headers'}{$key} = $value;
}
$data->{'subject'} = $self->{'decoded_subject'};
unless (defined _merge_msg($entity, $list, $rcpt, $data)) {
return undef;
$data->{headers}{$key} = $value;
}
$data->{subject} = $self->{decoded_subject};
$self->set_entity($entity);
return $self;
return $data;
}
sub _merge_msg {
......@@ -1581,7 +1590,7 @@ sub personalize_text {
my $message_output;
my $user = $list->get_list_member($rcpt);
my $user = $list->get_list_member($rcpt) if $rcpt;
if ($user) {
$user->{'escaped_email'} = URI::Escape::uri_escape($rcpt);
......@@ -1599,9 +1608,18 @@ sub personalize_text {
# Parse the template in the message : replace the tags and the parameters
# by the corresponding values
my $template = Sympa::Template->new(undef);
return undef
unless $template->parse($data, \$body, \$message_output,
is_not_template => 1);
unless (
$template->parse(
$data, \$body, \$message_output, is_not_template => 1
)
) {
$log->syslog(
'err',
'Failed parsing template: %s',
$template->{last_error}
);
return undef;
}
return $message_output;
}
......@@ -1632,9 +1650,10 @@ sub prepare_message_according_to_mode {
if (_as_singlepart($entity, 'text/plain')) {
$log->syslog('notice', 'Multipart message changed to singlepart');
}
## Add a footer
_decorate_parts($entity, $list);
$self->set_entity($entity);
# Add a footer
$self->{shelved}{decorate} = 1;
} elsif ($mode eq 'urlize') {
# Prepare message for urlize reception mode.
# Not extract message/rfc822 parts.
......@@ -1649,44 +1668,40 @@ sub prepare_message_according_to_mode {
my $entity = $parser->parse_data($msg_string);
_urlize_parts($entity, $list, $self->{'message_id'});
## Add a footer
_decorate_parts($entity, $list);
$self->set_entity($entity);
# Add a footer
$self->{shelved}{decorate} = 1;
} else { # 'mail'
# Prepare message for normal reception mode,
# and add a footer.
unless ($self->{'protected'}) {
my $entity = $self->as_entity->dup;
_decorate_parts($entity, $list);
$self->set_entity($entity);
}
$self->{shelved}{decorate} = 1
unless $self->{'protected'};
}
return $self;
}
# OBSOLETED. Use prepare_message_according_to_mode('mail').
# Old name:
# Sympa::List::add_parts() or Message::add_parts(), n.b. not add_part().
# Sympa::Message::_decorate_parts().
sub decorate {
my $self = shift;
$log->syslog('debug3', '(%s, %s, %s => %s)', @_);
my $self = shift;
my $list = shift;
my $rcpt = shift;
my %options = @_;
return $self->prepare_message_according_to_mode('mail', $self->{context});
}
return unless ref $list eq 'Sympa::List';
# Old name:
# Sympa::List::add_parts() or Message::add_parts(), n.b. not add_part().
sub _decorate_parts {
$log->syslog('debug3', '(%s, %s)');
my $entity = shift;
my $list = shift;
my $entity = $self->as_entity->dup;
my $mode = $options{mode} || '';
my $type = $list->{'admin'}{'footer_type'};
my $eff_type = $entity->effective_type || 'text/plain';
## Signed or encrypted messages won't be modified.
if ($eff_type =~ /^multipart\/(signed|encrypted)$/i) {
return $entity;
}
return 1 if $eff_type =~ /^multipart\/(signed|encrypted)$/i;
my $header =
($type eq 'mime')
......@@ -1707,6 +1722,11 @@ sub _decorate_parts {
or $footer and -s $footer
or $global_footer and -s $global_footer;
my $data;
if ($mode) {
$data = $self->_personalize_attrs;
}
if ($type eq 'append') {
## append footer/header
my ($global_footer_text, $footer_text, $header_text) = ('', '', '');
......@@ -1715,6 +1735,14 @@ sub _decorate_parts {
$header_text = do { local $RS; <$fh> };
close $fh;
}
if ($mode) {
$header_text =
personalize_text($header_text, $list, $rcpt, $data);
unless (defined $header_text) {
$log->syslog('info', 'Error personalizing header');
$header_text = '';
}
}
$header_text = '' unless $header_text =~ /\S/;
}
if ($footer and -s $footer) {
......@@ -1722,6 +1750,14 @@ sub _decorate_parts {
$footer_text = do { local $RS; <$fh> };
close $fh;
}
if ($mode) {
$footer_text =
personalize_text($footer_text, $list, $rcpt, $data);
unless (defined $footer_text) {
$log->syslog('info', 'Error personalizing footer');
$footer_text = '';
}
}
$footer_text = '' unless $footer_text =~ /\S/;
}
if ($global_footer and -s $global_footer) {
......@@ -1729,6 +1765,15 @@ sub _decorate_parts {
$global_footer_text = do { local $RS; <$fh> };
close $fh;
}
if ($mode) {
$global_footer_text =
personalize_text($global_footer_text, $list, $rcpt,
$data);
unless (defined $global_footer_text) {
$log->syslog('info', 'Error personalizing global footer');
$global_footer_text = '';
}
}
$global_footer_text = '' unless $global_footer_text =~ /\S/;
}
if ( length $header_text
......@@ -1767,6 +1812,10 @@ sub _decorate_parts {
if ($EVAL_ERROR) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$header, $parser->last_error);
} elsif ($mode
and not
defined _merge_msg($header_part, $list, $rcpt, $data)) {
$log->syslog('info', 'Error personalizing header');
} else {
$entity->make_multipart unless $entity->is_multipart;
## Add AS FIRST PART (0)
......@@ -1774,18 +1823,31 @@ sub _decorate_parts {
}
} else {
## text/plain header
$entity->make_multipart unless $entity->is_multipart;
my $header_text = do { local $RS; <$fh> };
close $fh;
my $header_part = MIME::Entity->build(
Data => $header_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
$entity->add_part($header_part, 0);
my $header_part;
eval {
$header_part = MIME::Entity->build(
Data => $header_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
};
unless ($header_part) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$header, $EVAL_ERROR);
} elsif ($mode
and not
defined _merge_msg($header_part, $list, $rcpt, $data)) {
$log->syslog('info', 'Error personalizing header');
} else {
$entity->make_multipart unless $entity->is_multipart;
# Add as the first part (0)
$entity->add_part($header_part, 0);
}
}
}
if ($footer and -s $footer) {
......@@ -1799,23 +1861,40 @@ sub _decorate_parts {
if ($EVAL_ERROR) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$footer, $parser->last_error);
} elsif ($mode
and not
defined _merge_msg($footer_part, $list, $rcpt, $data)) {
$log->syslog('info', 'Error personalizing footer');
} else {
$entity->make_multipart unless $entity->is_multipart;
$entity->add_part($footer_part);
}
} else {
## text/plain footer
$entity->make_multipart unless $entity->is_multipart;
my $footer_text = do { local $RS; <$fh> };
close $fh;
$entity->attach(
Data => $footer_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
my $footer_part;
eval {
$footer_part = MIME::Entity->build(
Data => $footer_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
};
unless ($footer_part) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$footer, $EVAL_ERROR);
} elsif ($mode
and not
defined _merge_msg($footer_part, $list, $rcpt, $data)) {
$log->syslog('info', 'Error personalizing footer');
} else {
$entity->make_multipart unless $entity->is_multipart;
$entity->add_part($footer_part);
}
}
}
if ($global_footer and -s $global_footer) {
......@@ -1829,28 +1908,48 @@ sub _decorate_parts {
if ($EVAL_ERROR) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$global_footer, $parser->last_error);
} elsif ($mode
and not
defined _merge_msg($global_footer_part, $list, $rcpt,
$data)) {
$log->syslog('info', 'Error personalizing global footer');
} else {
$entity->make_multipart unless $entity->is_multipart;
$entity->add_part($global_footer_part);
}
} else {
## text/plain global_footer
$entity->make_multipart unless $entity->is_multipart;
my $global_footer_text = do { local $RS; <$fh> };
close $fh;
$entity->attach(
Data => $global_footer_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
my $global_footer_part;
eval {
$global_footer_part = MIME::Entity->build(
Data => $global_footer_text,
Type => "text/plain",
Filename => undef,
'X-Mailer' => undef,
Encoding => "8bit",
Charset => "UTF-8"
);
};
unless ($global_footer_part) {
$log->syslog('err', 'Failed to parse MIME data %s: %s',
$global_footer, $EVAL_ERROR);
} elsif ($mode
and not
defined _merge_msg($global_footer_part, $list, $rcpt,
$data)) {
$log->syslog('info', 'Error personalizing global footer');
} else {
$entity->make_multipart unless $entity->is_multipart;
$entity->add_part($global_footer_part);
}
}
}
}
return $entity;
$self->set_entity($entity);
return 1;
}
## Append header/footer/global_footer to text/plain body.
......@@ -3953,7 +4052,7 @@ Returns:
C<1> if the message is considered signed.
C<0> otherwise.
=item personalize ( $list, [ $rcpt ], [ $data ] )
=item personalize ( $list, [ $rcpt ] )
I<Instance method>.
Personalizes a message with custom attributes of a user.
......@@ -4040,10 +4139,7 @@ the message is not modified.
Returns modified message object itself, or C<undef> if transformation failed.
=item decorate ( )
OBSOLETED.
Use prepare_message_according_to_mode('mail', $list).
=item decorate ($list, [ mode =E<gt> I<personalization mode> ] )
I<Instance method>.
Adds footer/header to a message.
......@@ -4279,6 +4375,10 @@ Currently these items are available:
=over
=item decorate =E<gt> 1
Adding footer/header if any.
=item dkim_sign =E<gt> 1
Adding DKIM signature.
......@@ -4287,10 +4387,12 @@ Adding DKIM signature.
DMARC protection. See also L</dmarc_protect>().
=item merge =E<gt> 1
=item merge =E<gt> C<footer>|C<all>
Personalizing.
On Sympa 6.2.58 or earlier, there was no distiction between C<footer> and C<all>.
=item smime_encrypt =E<gt> 1
Adding S/MIME encryption.
......
......@@ -179,7 +179,9 @@ sub _twist {
}
# Check TT2 syntax for merge_feature.
unless (_test_personalize($message, $list)) {
if ( $message->{shelved}{merge}
and $message->{shelved}{merge} ne 'footer'
and not _test_personalize($message, $list)) {
$log->syslog(
'err',
'Failed to personalize. Message %s for list %s was rejected',
......@@ -200,7 +202,9 @@ sub _twist {
and $action =~ /^request_auth\b/
) {
## Check syntax for merge_feature.
unless (_test_personalize($message, $list)) {
if ( $message->{shelved}{merge}
and $message->{shelved}{merge} ne 'footer'
and not _test_personalize($message, $list)) {
$log->syslog(
'err',
'Failed to personalize. Message %s for list %s was rejected',
......@@ -216,7 +220,9 @@ sub _twist {
$self->{quiet} ||= ($action =~ /,\s*quiet\b/); # Overwrite
# Check syntax for merge_feature.
unless (_test_personalize($message, $list)) {
if ( $message->{shelved}{merge}
and $message->{shelved}{merge} ne 'footer'
and not _test_personalize($message, $list)) {
$log->syslog(
'err',
'Failed to personalize. Message %s for list %s was rejected',
......@@ -232,7 +238,9 @@ sub _twist {
$self->{quiet} ||= ($action =~ /,\s*quiet\b/); # Overwrite
# Check syntax for merge_feature.
unless (_test_personalize($message, $list)) {
if ( $message->{shelved}{merge}
and $message->{shelved}{merge} ne 'footer'
and not _test_personalize($message, $list)) {
$log->syslog(
'err',
'Failed to personalize. Message %s for list %s was rejected',
......@@ -326,8 +334,8 @@ sub _test_personalize {
my $list = shift;
return 1
unless Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'},
'on');
unless $message->{shelved}{merge}
and $message->{shelved}{merge} ne 'footer';
# Get available recipients to test.
my $available_recipients = $list->get_recipients_per_mode($message) || {};
......@@ -346,7 +354,7 @@ sub _test_personalize {
@{$available_recipients->{$mode}{'verp'} || []},
@{$available_recipients->{$mode}{'noverp'} || []}
) {
unless ($new_message->personalize($list, $rcpt, {})) {
unless ($new_message->personalize($list, $rcpt)) {
return undef;
}
}
......
......@@ -215,7 +215,7 @@ sub _twist {
# Message transformation should be done in the folowing order:
# -1 headers modifications (done in sympa.pl)
# -2 DMARC protection
# -3 personalize (a.k.a. "merge")
# -3 personalization ("merge") and decoration (adding footer/header)
# -4 S/MIME signing
# -5 S/MIME encryption
# -6 remove existing signature if altered
......@@ -281,7 +281,8 @@ sub _twist {
$return_path = Sympa::get_address($robot, 'owner');
}
if ($new_message->{shelved}{merge}) {
if ($new_message->{shelved}{merge}
and $new_message->{shelved}{merge} ne 'footer') {
unless ($new_message->personalize($list, $rcpt)) {
$log->syslog('err', 'Erreur d appel personalize()');
Sympa::send_notify_to_listmaster($list, 'bulk_failed',
......@@ -291,6 +292,10 @@ sub _twist {
}
delete $new_message->{shelved}{merge};
}
if ($new_message->{shelved}{decorate}) {
$new_message->decorate($list, $rcpt, mode => $new_message->{shelved}{merge});
delete $new_message->{shelved}{decorate};
}
if ($new_message->{shelved}{smime_sign}) {
$new_message->smime_sign;
......@@ -379,6 +384,11 @@ sub _twist {
$return_path = Sympa::get_address($robot, 'owner');
}
if ($new_message->{shelved}{decorate}) {
$new_message->decorate($list, undef);
delete $new_message->{shelved}{decorate};
}
if ($new_message->{shelved}{smime_sign}) {
$new_message->smime_sign;
delete $new_message->{shelved}{smime_sign};
......@@ -471,6 +481,7 @@ Processing for tracking and VERP (see also <Sympa::Tracking>)
=item *
Personalization (a.k.a. "merge")
and decoration (adding footer/header)
=item *
......
......@@ -406,8 +406,9 @@ sub _mail_message {
and $list->{'admin'}{'dmarc_protection'}{'mode'}
and not $list->{'admin'}{'anonymous_sender'};
# Shelve personalization.
$message->{shelved}{merge} = 1
# Shelve personalization if not yet shelved.
# Note that only 'footer' mode will be allowed unless otherwise requested.
$message->{shelved}{merge} ||= 'footer'
if Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'},
'on');
# Shelve re-encryption with S/MIME.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment