[Rt-commit] rt branch, 4.4/per-queue-outgoing-encryption-protocol, updated. rt-4.4.4-180-g9bd2a2dea0
Dianne Skoll
dianne at bestpractical.com
Thu Nov 19 16:47:29 EST 2020
The branch, 4.4/per-queue-outgoing-encryption-protocol has been updated
via 9bd2a2dea0ef7e1c82894ae3f0c4f0574832bc4c (commit)
from 00fac86816c034410587e025d529630cd6a4166d (commit)
Summary of changes:
lib/RT/Test/{Crypt.pm => GnuPG.pm} | 157 +++++---------------
lib/RT/Test/SMIME.pm | 163 +++++++++++++++++++++
...db.t => attachments-in-db-using-old-test-lib.t} | 3 +-
...ients.t => bad-recipients-using-old-test-lib.t} | 6 +-
4 files changed, 200 insertions(+), 129 deletions(-)
copy lib/RT/Test/{Crypt.pm => GnuPG.pm} (75%)
create mode 100644 lib/RT/Test/SMIME.pm
copy t/crypt/gnupg/{attachments-in-db.t => attachments-in-db-using-old-test-lib.t} (96%)
copy t/crypt/smime/{bad-recipients.t => bad-recipients-using-old-test-lib.t} (89%)
- Log -----------------------------------------------------------------
commit 9bd2a2dea0ef7e1c82894ae3f0c4f0574832bc4c
Author: Dianne Skoll <dianne at bestpractical.com>
Date: Thu Nov 19 16:46:49 2020 -0500
Restore the old RT::Test::GnuPG and RT::Test::SMIME files.
Also add a couple of tests to make sure they still work, seeing
as all the other tests have been converted to RT::Test::Crypt.
diff --git a/lib/RT/Test/GnuPG.pm b/lib/RT/Test/GnuPG.pm
new file mode 100644
index 0000000000..7720a5c10e
--- /dev/null
+++ b/lib/RT/Test/GnuPG.pm
@@ -0,0 +1,414 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2019 Best Practical Solutions, LLC
+# <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+package RT::Test::GnuPG;
+use strict;
+use warnings;
+use Test::More;
+use base qw(RT::Test);
+use File::Temp qw(tempdir);
+use IPC::Run3 'run3';
+use File::Copy;
+use 5.010;
+
+our @EXPORT =
+ qw(create_a_ticket update_ticket cleanup_headers set_queue_crypt_options
+ check_text_emails send_email_and_check_transaction
+ create_and_test_outgoing_emails
+ );
+
+sub import {
+ my $class = shift;
+ my %args = @_;
+ my $t = $class->builder;
+
+ RT::Test::plan( skip_all => 'ENV SKIP_GPG_TESTS is set to true.' )
+ if $ENV{'SKIP_GPG_TESTS'};
+ RT::Test::plan( skip_all => 'GnuPG required.' )
+ unless GnuPG::Interface->require;
+ RT::Test::plan( skip_all => 'gpg executable is required.' )
+ unless RT::Test->find_executable('gpg');
+
+ $class->SUPER::import(%args);
+ return $class->export_to_level(1)
+ if $^C;
+
+ RT::Test::diag "GnuPG --homedir " . RT->Config->Get('GnuPGOptions')->{'homedir'};
+
+ $class->set_rights(
+ Principal => 'Everyone',
+ Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
+ );
+
+ $class->export_to_level(1);
+}
+
+sub bootstrap_more_config {
+ my $self = shift;
+ my $handle = shift;
+ my $args = shift;
+
+ $self->SUPER::bootstrap_more_config($handle, $args, @_);
+
+ my %gnupg_options = (
+ 'no-permission-warning' => undef,
+ $args->{gnupg_options} ? %{ $args->{gnupg_options} } : (),
+ );
+ $gnupg_options{homedir} ||= new_homedir();
+
+ my $conf = File::Spec->catfile( $gnupg_options{homedir}, 'gpg.conf' );
+ if ( gnupg_version() >= 2 ) {
+ open my $fh, '>', $conf or die $!;
+ print $fh "pinentry-mode loopback\n";
+ close $fh;
+ }
+ else {
+ unlink $conf if -e $conf;
+ }
+
+ use Data::Dumper;
+ local $Data::Dumper::Terse = 1; # "{...}" instead of "$VAR1 = {...};"
+ my $dumped_gnupg_options = Dumper(\%gnupg_options);
+
+ print $handle qq{
+Set(\%GnuPG, (
+ Enable => 1,
+ OutgoingMessagesFormat => 'RFC',
+));
+Set(\%GnuPGOptions => \%{ $dumped_gnupg_options });
+};
+
+}
+
+sub create_a_ticket {
+ my $queue = shift;
+ my $mail = shift;
+ my $m = shift;
+ my %args = (@_);
+
+ RT::Test->clean_caught_mails;
+
+ $m->goto_create_ticket( $queue );
+ $m->form_name('TicketCreate');
+ $m->field( Subject => 'test' );
+ $m->field( Requestors => 'rt-test at example.com' );
+ $m->field( Content => 'Some content' );
+
+ foreach ( qw(Sign Encrypt) ) {
+ if ( $args{ $_ } ) {
+ $m->tick( $_ => 1 );
+ } else {
+ $m->untick( $_ => 1 );
+ }
+ }
+
+ $m->submit;
+ is $m->status, 200, "request successful";
+
+ $m->content_lacks("unable to sign outgoing email messages");
+
+
+ my @mail = RT::Test->fetch_caught_mails;
+ check_text_emails(\%args, @mail );
+ categorize_emails($mail, \%args, @mail );
+}
+
+sub update_ticket {
+ my $tid = shift;
+ my $mail = shift;
+ my $m = shift;
+ my %args = (@_);
+
+ RT::Test->clean_caught_mails;
+
+ $m->get( $m->rt_base_url . "/Ticket/Update.html?Action=Respond&id=$tid" );
+ $m->form_number(3);
+ $m->field( UpdateContent => 'Some content' );
+
+ foreach ( qw(Sign Encrypt) ) {
+ if ( $args{ $_ } ) {
+ $m->tick( $_ => 1 );
+ } else {
+ $m->untick( $_ => 1 );
+ }
+ }
+
+ $m->click('SubmitTicket');
+ is $m->status, 200, "request successful";
+ $m->content_contains("Correspondence added", 'Correspondence added') or diag $m->content;
+
+
+ my @mail = RT::Test->fetch_caught_mails;
+ check_text_emails(\%args, @mail );
+ categorize_emails($mail, \%args, @mail );
+}
+
+sub categorize_emails {
+ my $mail = shift;
+ my $args = shift;
+ my @mail = @_;
+
+ if ( $args->{'Sign'} && $args->{'Encrypt'} ) {
+ push @{ $mail->{'signed_encrypted'} }, @mail;
+ }
+ elsif ( $args->{'Sign'} ) {
+ push @{ $mail->{'signed'} }, @mail;
+ }
+ elsif ( $args->{'Encrypt'} ) {
+ push @{ $mail->{'encrypted'} }, @mail;
+ }
+ else {
+ push @{ $mail->{'plain'} }, @mail;
+ }
+}
+
+sub check_text_emails {
+ my %args = %{ shift @_ };
+ my @mail = @_;
+
+ ok scalar @mail, "got some mail";
+ for my $mail (@mail) {
+ for my $type ('email', 'attachment') {
+ next if $type eq 'attachment' && !$args{'Attachment'};
+
+ my $content = $type eq 'email'
+ ? "Some content"
+ : $args{Attachment};
+
+ if ( $args{'Encrypt'} ) {
+ unlike $mail, qr/$content/, "outgoing $type is not in plaintext";
+ my $entity = RT::Test::parse_mail($mail);
+ my @res = RT::Crypt->VerifyDecrypt(Entity => $entity);
+ like $res[0]{'status'}, qr/DECRYPTION_OKAY/, "Decrypts OK";
+ like $entity->as_string, qr/$content/, "outgoing decrypts to contain $type content";
+ } else {
+ like $mail, qr/$content/, "outgoing $type was not encrypted";
+ }
+
+ next unless $type eq 'email';
+
+ if ( $args{'Sign'} && $args{'Encrypt'} ) {
+ like $mail, qr/BEGIN PGP MESSAGE/, 'outgoing email was signed';
+ } elsif ( $args{'Sign'} ) {
+ like $mail, qr/SIGNATURE/, 'outgoing email was signed';
+ } else {
+ unlike $mail, qr/SIGNATURE/, 'outgoing email was not signed';
+ }
+ }
+ }
+}
+
+sub cleanup_headers {
+ my $mail = shift;
+ # strip id from subject to create new ticket
+ $mail =~ s/^(Subject:)\s*\[.*?\s+#\d+\]\s*/$1 /m;
+ # strip several headers
+ foreach my $field ( qw(Message-ID RT-Originator RT-Ticket X-RT-Loop-Prevention) ) {
+ $mail =~ s/^$field:.*?\n(?! |\t)//gmsi;
+ }
+ return $mail;
+}
+
+sub set_queue_crypt_options {
+ my $queue = shift;
+ my %args = @_;
+ $queue->SetEncrypt($args{'Encrypt'});
+ $queue->SetSign($args{'Sign'});
+}
+
+sub send_email_and_check_transaction {
+ my $mail = shift;
+ my $type = shift;
+
+ my ( $status, $id ) = RT::Test->send_via_mailgate($mail);
+ is( $status >> 8, 0, "The mail gateway exited normally" );
+ ok( $id, "got id of a newly created ticket - $id" );
+
+ my $tick = RT::Ticket->new( RT->SystemUser );
+ $tick->Load($id);
+ ok( $tick->id, "loaded ticket #$id" );
+
+ my $txn = $tick->Transactions->First;
+ my ( $msg, @attachments ) = @{ $txn->Attachments->ItemsArrayRef };
+
+ if ( $attachments[0] ) {
+ like $attachments[0]->Content, qr/Some content/,
+ "RT's mail includes copy of ticket text";
+ }
+ else {
+ like $msg->Content, qr/Some content/,
+ "RT's mail includes copy of ticket text";
+ }
+
+ if ( $type eq 'plain' ) {
+ ok !$msg->GetHeader('X-RT-Privacy'), "RT's outgoing mail has no crypto";
+ is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Not encrypted',
+ "RT's outgoing mail looks not encrypted";
+ ok !$msg->GetHeader('X-RT-Incoming-Signature'),
+ "RT's outgoing mail looks not signed";
+ }
+ elsif ( $type eq 'signed' ) {
+ is $msg->GetHeader('X-RT-Privacy'), 'GnuPG',
+ "RT's outgoing mail has crypto";
+ is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Not encrypted',
+ "RT's outgoing mail looks not encrypted";
+ like $msg->GetHeader('X-RT-Incoming-Signature'),
+ qr/<rt-recipient\@example.com>/,
+ "RT's outgoing mail looks signed";
+ }
+ elsif ( $type eq 'encrypted' ) {
+ is $msg->GetHeader('X-RT-Privacy'), 'GnuPG',
+ "RT's outgoing mail has crypto";
+ is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Success',
+ "RT's outgoing mail looks encrypted";
+ ok !$msg->GetHeader('X-RT-Incoming-Signature'),
+ "RT's outgoing mail looks not signed";
+
+ }
+ elsif ( $type eq 'signed_encrypted' ) {
+ is $msg->GetHeader('X-RT-Privacy'), 'GnuPG',
+ "RT's outgoing mail has crypto";
+ is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Success',
+ "RT's outgoing mail looks encrypted";
+ like $msg->GetHeader('X-RT-Incoming-Signature'),
+ qr/<rt-recipient\@example.com>/,
+ "RT's outgoing mail looks signed";
+ }
+ else {
+ die "unknown type: $type";
+ }
+}
+
+sub create_and_test_outgoing_emails {
+ my $queue = shift;
+ my $m = shift;
+ my @variants =
+ ( {}, { Sign => 1 }, { Encrypt => 1 }, { Sign => 1, Encrypt => 1 }, );
+
+ # collect emails
+ my %mail;
+
+ # create a ticket for each combination
+ foreach my $ticket_set (@variants) {
+ create_a_ticket( $queue, \%mail, $m, %$ticket_set );
+ }
+
+ my $tid;
+ {
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ ($tid) = $ticket->Create(
+ Subject => 'test',
+ Queue => $queue->id,
+ Requestor => 'rt-test at example.com',
+ );
+ ok $tid, 'ticket created';
+ }
+
+ # again for each combination add a reply message
+ foreach my $ticket_set (@variants) {
+ update_ticket( $tid, \%mail, $m, %$ticket_set );
+ }
+
+# ------------------------------------------------------------------------------
+# now delete all keys from the keyring and put back secret/pub pair for rt-test@
+# and only public key for rt-recipient@ so we can verify signatures and decrypt
+# like we are on another side recieve emails
+# ------------------------------------------------------------------------------
+
+ unlink $_
+ foreach glob( RT->Config->Get('GnuPGOptions')->{'homedir'} . "/*" );
+ RT::Test->import_gnupg_key( 'rt-recipient at example.com', 'public' );
+ RT::Test->import_gnupg_key('rt-test at example.com');
+
+ $queue = RT::Test->load_or_create_queue(
+ Name => 'Regression',
+ CorrespondAddress => 'rt-test at example.com',
+ CommentAddress => 'rt-test at example.com',
+ );
+ ok $queue && $queue->id, 'changed props of the queue';
+
+ for my $type ( keys %mail ) {
+ for my $mail ( map cleanup_headers($_), @{ $mail{$type} } ) {
+ send_email_and_check_transaction( $mail, $type );
+ }
+ }
+}
+
+sub gnupg_version {
+ GnuPG::Interface->require or return;
+ require version;
+ state $gnupg_version = version->parse(GnuPG::Interface->new->version);
+}
+
+sub new_homedir {
+ my $source = shift;
+ my $dir = tempdir();
+
+ if ($source) {
+ opendir my $dh, $source or die $!;
+ for my $file ( grep {/\.gpg$/} readdir $dh ) {
+ copy( File::Spec->catfile( $source, $file ), File::Spec->catfile( $dir, $file ) ) or die $!;
+ }
+ closedir $dh;
+ if ( gnupg_version() >= 2 ) {
+ # Do the data migration
+ run3( [ 'gpg', '--homedir', $dir, '--list-secret-keys' ], \undef, \undef, \undef );
+ }
+ }
+
+ return $dir;
+}
+
+END {
+ if ( gnupg_version() >= 2 ) {
+ system( 'gpgconf', '--homedir', RT->Config->Get('GnuPGOptions')->{homedir}, '--quiet', '--kill', 'gpg-agent' )
+ && warn $!;
+ }
+}
+
+1;
diff --git a/lib/RT/Test/SMIME.pm b/lib/RT/Test/SMIME.pm
new file mode 100644
index 0000000000..25b3a43a2f
--- /dev/null
+++ b/lib/RT/Test/SMIME.pm
@@ -0,0 +1,163 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2019 Best Practical Solutions, LLC
+# <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+use strict;
+use warnings;
+use 5.010;
+
+package RT::Test::SMIME;
+
+use Test::More;
+use base qw(RT::Test);
+use File::Temp qw(tempdir);
+
+sub import {
+ my $class = shift;
+ my %args = @_;
+ my $t = $class->builder;
+
+ RT::Test::plan( skip_all => 'openssl executable is required.' )
+ unless RT::Test->find_executable('openssl');
+
+ require RT::Crypt;
+ $class->SUPER::import(%args);
+
+ $class->set_rights(
+ Principal => 'Everyone',
+ Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
+ );
+
+ $class->export_to_level(1);
+}
+
+sub bootstrap_more_config {
+ my $self = shift;
+ my $handle = shift;
+ my $args = shift;
+
+ $self->SUPER::bootstrap_more_config($handle, $args, @_);
+
+ my $openssl = $self->find_executable('openssl');
+
+ my $keyring = $self->keyring_path;
+ mkdir($keyring);
+
+ my $ca = $self->key_path("demoCA", "cacert.pem");
+
+ print $handle qq{
+ Set(\%GnuPG, Enable => 0);
+ Set(\%SMIME =>
+ Enable => 1,
+ Passphrase => {
+ 'root\@example.com' => '123456',
+ 'sender\@example.com' => '123456',
+ },
+ OpenSSL => q{$openssl},
+ Keyring => q{$keyring},
+ CAPath => q{$ca},
+ );
+ };
+
+}
+
+sub keyring_path {
+ return File::Spec->catfile( RT::Test->temp_directory, "smime" );
+}
+
+sub key_path {
+ my $self = shift;
+ my $keys = RT::Test::get_abs_relocatable_dir(
+ (File::Spec->updir()) x 2,
+ qw(data smime keys),
+ );
+ return File::Spec->catfile( $keys => @_ ),
+}
+
+sub mail_set_path {
+ my $self = shift;
+ return RT::Test::get_abs_relocatable_dir(
+ (File::Spec->updir()) x 2,
+ qw(data smime mails),
+ );
+}
+
+sub import_key {
+ my $self = shift;
+ my $key = shift;
+ my $user = shift;
+
+ my $path = RT::Test::find_relocatable_path( 'data', 'smime', 'keys' );
+ die "can't find the dir where smime keys are stored"
+ unless $path;
+
+ my $keyring = RT->Config->Get('SMIME')->{'Keyring'};
+ die "SMIME keyring '$keyring' doesn't exist"
+ unless $keyring && -e $keyring;
+
+ $key .= ".pem" unless $key =~ /\.(pem|crt|key)$/;
+
+ my $content = RT::Test->file_content( [ $path, $key ] );
+
+ if ( $user ) {
+ my ($status, $msg) = $user->SetSMIMECertificate( $content );
+ die "Couldn't set CF: $msg" unless $status;
+ } else {
+ my $keyring = RT->Config->Get('SMIME')->{'Keyring'};
+ die "SMIME keyring '$keyring' doesn't exist"
+ unless $keyring && -e $keyring;
+
+ open my $fh, '>:raw', File::Spec->catfile($keyring, $key)
+ or die "can't open file: $!";
+ print $fh $content;
+ close $fh;
+ }
+
+ return;
+}
+
+1;
diff --git a/t/crypt/gnupg/attachments-in-db-using-old-test-lib.t b/t/crypt/gnupg/attachments-in-db-using-old-test-lib.t
new file mode 100644
index 0000000000..1a377c341a
--- /dev/null
+++ b/t/crypt/gnupg/attachments-in-db-using-old-test-lib.t
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+use RT::Test::GnuPG
+ tests => 12,
+ gnupg_options => {
+ passphrase => 'recipient',
+ 'trust-model' => 'always',
+ }
+;
+
+RT->Config->Get('Crypt')->{'AllowEncryptDataInDB'} = 1;
+
+RT::Test->import_gnupg_key('general at example.com', 'public');
+RT::Test->import_gnupg_key('general at example.com', 'secret');
+my $queue = RT::Test->load_or_create_queue(
+ Name => 'General',
+ CorrespondAddress => 'general at example.com',
+);
+ok $queue && $queue->id, 'loaded or created queue';
+
+{
+ my $ticket = RT::Test->create_ticket(
+ Queue => $queue->id,
+ Subject => 'test',
+ Content => 'test',
+ );
+
+ my $txn = $ticket->Transactions->First;
+ ok $txn && $txn->id, 'found first transaction';
+ is $txn->Type, 'Create', 'it is Create transaction';
+
+ my $attach = $txn->Attachments->First;
+ ok $attach && $attach->id, 'found attachment';
+ is $attach->Content, 'test', 'correct content';
+
+ my ($status, $msg) = $attach->Encrypt;
+ ok $status, 'encrypted attachment';
+
+ isnt $attach->Content, 'test', 'correct content';
+
+ ($status, $msg) = $attach->Decrypt;
+ ok $status, 'decrypted attachment';
+
+ is $attach->Content, 'test', 'correct content';
+}
+
+
+
diff --git a/t/crypt/smime/bad-recipients-using-old-test-lib.t b/t/crypt/smime/bad-recipients-using-old-test-lib.t
new file mode 100644
index 0000000000..1dc097adec
--- /dev/null
+++ b/t/crypt/smime/bad-recipients-using-old-test-lib.t
@@ -0,0 +1,58 @@
+use strict;
+use warnings;
+
+use RT::Test::SMIME tests => undef;
+
+use RT::Tickets;
+
+RT::Test::SMIME->import_key('sender at example.com');
+my $queue = RT::Test->load_or_create_queue(
+ Name => 'General',
+ CorrespondAddress => 'sender at example.com',
+);
+ok $queue && $queue->id, 'loaded or created queue';
+
+{
+ my ($status, $msg) = $queue->SetEncrypt(1);
+ ok $status, "turn on encyption by default"
+ or diag "error: $msg";
+}
+
+my $root;
+{
+ $root = RT::User->new($RT::SystemUser);
+ ok($root->LoadByEmail('root at localhost'), "Loaded user 'root'");
+ ok($root->Load('root'), "Loaded user 'root'");
+ is($root->EmailAddress, 'root at localhost');
+
+ RT::Test::SMIME->import_key( 'root at example.com.crt' => $root );
+}
+
+my $bad_user;
+{
+ $bad_user = RT::Test->load_or_create_user(
+ Name => 'bad_user',
+ EmailAddress => 'baduser at example.com',
+ );
+ ok $bad_user && $bad_user->id, 'created a user without key';
+}
+
+RT::Test->clean_caught_mails;
+
+use Test::Warn;
+
+warnings_like {
+ my $ticket = RT::Ticket->new(RT->SystemUser);
+ my ($status, undef, $msg) = $ticket->Create( Queue => $queue->id, Requestor => [$root->id, $bad_user->id] );
+ ok $status, "created a ticket" or diag "error: $msg";
+
+ my @mails = RT::Test->fetch_caught_mails;
+ is scalar @mails, 3, "autoreply, to bad user, to RT owner";
+
+ like $mails[0], qr{To: baduser\@example\.com}, "notification to bad user";
+ like $mails[1], qr{To: root}, "notification to RT owner";
+ like $mails[1], qr{Recipient 'baduser\@example\.com' is unusable, the reason is 'Key not found'},
+ "notification to owner has error";
+} [qr{Recipient 'baduser\@example\.com' is unusable, the reason is 'Key not found'}];
+
+done_testing;
-----------------------------------------------------------------------
More information about the rt-commit
mailing list