[Rt-commit] r8947 - in rt/branches/3.7-EXPERIMENTAL/t: mail

ruz at bestpractical.com ruz at bestpractical.com
Wed Sep 5 22:32:37 EDT 2007


Author: ruz
Date: Wed Sep  5 22:32:36 2007
New Revision: 8947

Added:
   rt/branches/3.7-EXPERIMENTAL/t/web/gnupg-outgoing.t
Removed:
   rt/branches/3.7-EXPERIMENTAL/t/mail/gnupg-outcoming.t

Log:
test encryption and signing of outgoing emails
* use fine-tuned keyring when we generate emails and when we recieve
* test that queue's options influence create and update page
* test that we do the right thing for 4 combinations of queue's
  options and 4 ticket's ooptions, so 16 in total
* TODO: write tests for update

Added: rt/branches/3.7-EXPERIMENTAL/t/web/gnupg-outgoing.t
==============================================================================
--- (empty file)
+++ rt/branches/3.7-EXPERIMENTAL/t/web/gnupg-outgoing.t	Wed Sep  5 22:32:36 2007
@@ -0,0 +1,301 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+
+use Test::More tests => 231;
+use RT::Test;
+use RT::Action::SendEmail;
+use File::Temp qw(tempdir);
+
+RT::Test->set_mail_catcher;
+
+RT->Config->Set( LogToScreen => 'debug' );
+RT->Config->Set( LogStackTraces => 'error' );
+
+use_ok('RT::Crypt::GnuPG');
+
+RT->Config->Set( GnuPG =>
+    Enable => 1,
+    OutgoingMessagesFormat => 'RFC',
+);
+
+RT->Config->Set( GnuPGOptions =>
+    homedir => scalar tempdir( CLEANUP => 1 ),
+    passphrase => 'rt-test',
+    'no-permission-warning' => undef,
+    'trust-model' => 'always',
+);
+RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
+
+RT::Test->import_gnupg_key('rt-recipient at example.com');
+RT::Test->import_gnupg_key('rt-test at example.com', 'public');
+
+my $queue = RT::Test->load_or_create_queue(
+    Name              => 'Regression',
+    CorrespondAddress => 'rt-recipient at example.com',
+    CommentAddress    => 'rt-recipient at example.com',
+);
+ok $queue && $queue->id, 'loaded or created queue';
+
+RT::Test->set_rights(
+    Principal => 'Everyone',
+    Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ModifyTicket'],
+);
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+my @variants = (
+    {},
+    { Sign => 1 },
+    { Encrypt => 1 },
+    { Sign => 1, Encrypt => 1 },
+);
+
+# collect emails
+my %mail = (
+    plain            => [],
+    signed           => [],
+    encrypted        => [],
+    signed_encrypted => [],
+);
+
+diag "check in read-only mode that queue's props influence create/update ticket pages";
+{
+    foreach my $variant ( @variants ) {
+        set_queue_crypt_options( %$variant );
+        $m->goto_create_ticket( $queue );
+        $m->form_name('TicketCreate');
+        if ( $variant->{'Encrypt'} ) {
+            ok $m->value('Encrypt', 2), "encrypt tick box is checked";
+        } else {
+            ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
+        }
+        if ( $variant->{'Sign'} ) {
+            ok $m->value('Sign', 2), "sign tick box is checked";
+        } else {
+            ok !$m->value('Sign', 2), "sign tick box is unchecked";
+        }
+    }
+
+    # to avoid encryption/signing during create
+    set_queue_crypt_options();
+
+    my $ticket = RT::Ticket->new( $RT::SystemUser );
+    my ($id) = $ticket->Create(
+        Subject   => 'test',
+        Queue     => $queue->id,
+        Requestor => 'rt-test at example.com',
+    );
+    ok $id, 'ticket created';
+
+    foreach my $variant ( @variants ) {
+        set_queue_crypt_options( %$variant );
+        $m->goto_ticket( $id );
+        $m->follow_link_ok({text => 'Reply'}, '-> reply');
+        $m->form_number(3);
+        if ( $variant->{'Encrypt'} ) {
+            ok $m->value('Encrypt', 2), "encrypt tick box is checked";
+        } else {
+            ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
+        }
+        if ( $variant->{'Sign'} ) {
+            ok $m->value('Sign', 2), "sign tick box is checked";
+        } else {
+            ok !$m->value('Sign', 2), "sign tick box is unchecked";
+        }
+    }
+}
+
+foreach my $queue_set ( @variants ) {
+    set_queue_crypt_options( %$queue_set );
+    foreach my $ticket_set ( @variants ) {
+        create_a_ticket( %$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';
+
+foreach my $mail ( map cleanup_headers($_), @{ $mail{'plain'} } ) {
+    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};
+
+    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";
+
+    like $msg->Content, qr/Some content/, "RT's mail includes copy of ticket text";
+}
+
+foreach my $mail ( map cleanup_headers($_), @{ $mail{'signed'} } ) {
+    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};
+
+    is $msg->GetHeader('X-RT-Privacy'), 'PGP',
+        "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";
+
+    like $attachments[0]->Content, qr/Some content/,
+        "RT's mail includes copy of ticket text";
+}
+
+foreach my $mail ( map cleanup_headers($_), @{ $mail{'encrypted'} } ) {
+    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};
+
+    is $msg->GetHeader('X-RT-Privacy'), 'PGP',
+        "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";
+
+    like $attachments[0]->Content, qr/Some content/,
+        "RT's mail includes copy of ticket text";
+}
+
+foreach my $mail ( map cleanup_headers($_), @{ $mail{'signed_encrypted'} } ) {
+    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};
+
+    is $msg->GetHeader('X-RT-Privacy'), 'PGP',
+        "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";
+
+    like $attachments[0]->Content, qr/Some content/,
+        "RT's mail includes copy of ticket text";
+}
+
+sub create_a_ticket {
+    my %args = (@_);
+
+    # cleanup mail catcher's storage
+    unlink "t/mailbox";
+
+    $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->get_ok('/'); # ensure that the mail has been processed
+
+    my @mail = RT::Test->fetch_caught_mails;
+    ok scalar @mail, "got some mail";
+    for my $mail (@mail) {
+        if ( $args{'Encrypt'} ) {
+            unlike $mail, qr/Some content/, "outgoing email was encrypted";
+        } else {
+            like $mail, qr/Some content/, "outgoing email was not encrypted";
+        } 
+        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';
+        }
+    }
+    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 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 X-RT-Original-Encoding RT-Originator RT-Ticket X-RT-Loop-Prevention) ) {
+        $mail =~ s/^$field:.*?\n(?! |\t)//gmsi;
+    }
+    return $mail;
+}
+
+sub set_queue_crypt_options {
+    my %args = @_;
+    $m->get_ok("/Admin/Queues/Modify.html?id=". $queue->id);
+    $m->form_with_fields('Sign', 'Encrypt');
+    foreach my $opt ('Sign', 'Encrypt') {
+        if ( $args{$opt} ) {
+            $m->tick($opt => 1);
+        } else {
+            $m->untick($opt => 1);
+        }
+    }
+    $m->submit;
+}
+


More information about the Rt-commit mailing list