4 use RT::Test::SMIME tests => undef;
5 my $test = 'RT::Test::SMIME';
7 use RT::Action::SendEmail;
8 use File::Temp qw(tempdir);
10 use_ok('RT::Crypt::SMIME');
12 RT::Test::SMIME->import_key('sender@example.com');
14 my $user_email = 'root@example.com';
16 my $user = RT::Test->load_or_create_user(
17 Name => $user_email, EmailAddress => $user_email
19 ok $user && $user->id, 'loaded or created user';
20 RT::Test::SMIME->import_key($user_email, $user);
23 my $queue = RT::Test->load_or_create_queue(
25 CorrespondAddress => 'sender@example.com',
26 CommentAddress => 'sender@example.com',
28 ok $queue && $queue->id, 'loaded or created queue';
31 Principal => 'Everyone',
32 Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
35 my ($baseurl, $m) = RT::Test->started_ok;
36 ok $m->login, 'logged in';
42 { Sign => 1, Encrypt => 1 },
50 signed_encrypted => [],
53 diag "check in read-only mode that queue's props influence create/update ticket pages" if $ENV{TEST_VERBOSE};
55 foreach my $variant ( @variants ) {
56 set_queue_crypt_options( %$variant );
57 $m->goto_create_ticket( $queue );
58 $m->form_name('TicketCreate');
59 if ( $variant->{'Encrypt'} ) {
60 ok $m->value('Encrypt', 2), "encrypt tick box is checked";
62 ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
64 if ( $variant->{'Sign'} ) {
65 ok $m->value('Sign', 2), "sign tick box is checked";
67 ok !$m->value('Sign', 2), "sign tick box is unchecked";
71 # to avoid encryption/signing during create
72 set_queue_crypt_options();
74 my $ticket = RT::Ticket->new( $RT::SystemUser );
75 my ($id) = $ticket->Create(
78 Requestor => $user_email,
80 ok $id, 'ticket created';
82 foreach my $variant ( @variants ) {
83 set_queue_crypt_options( %$variant );
84 $m->goto_ticket( $id );
85 $m->follow_link_ok({text => 'Reply'}, '-> reply');
87 if ( $variant->{'Encrypt'} ) {
88 ok $m->value('Encrypt', 2), "encrypt tick box is checked";
90 ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
92 if ( $variant->{'Sign'} ) {
93 ok $m->value('Sign', 2), "sign tick box is checked";
95 ok !$m->value('Sign', 2), "sign tick box is unchecked";
100 # create a ticket for each combination
101 foreach my $queue_set ( @variants ) {
102 set_queue_crypt_options( %$queue_set );
103 foreach my $ticket_set ( @variants ) {
104 create_a_ticket( %$ticket_set );
110 my $ticket = RT::Ticket->new( $RT::SystemUser );
111 ($tid) = $ticket->Create(
114 Requestor => $user_email,
116 ok $tid, 'ticket created';
119 # again for each combination add a reply message
120 foreach my $queue_set ( @variants ) {
121 set_queue_crypt_options( %$queue_set );
122 foreach my $ticket_set ( @variants ) {
123 update_ticket( $tid, %$ticket_set );
128 # ------------------------------------------------------------------------------
129 # now delete all keys from the keyring and put back secret/pub pair for rt-test@
130 # and only public key for sender@ so we can verify signatures and decrypt
131 # like we are on another side recieving emails
132 # ------------------------------------------------------------------------------
134 my $keyring = $test->keyring_path;
135 unlink $_ foreach glob( $keyring ."/*" );
136 RT::Test::SMIME->import_key('sender@example.com.crt');
137 RT::Test::SMIME->import_key($user_email);
139 $queue = RT::Test->load_or_create_queue(
140 Name => 'Regression',
141 CorrespondAddress => $user_email,
142 CommentAddress => $user_email,
144 ok $queue && $queue->id, 'changed props of the queue';
146 foreach my $mail ( map cleanup_headers($_), @{ $mail{'plain'} } ) {
147 my ($status, $id) = RT::Test->send_via_mailgate($mail);
148 is ($status >> 8, 0, "The mail gateway exited normally");
149 ok ($id, "got id of a newly created ticket - $id");
151 my $tick = RT::Ticket->new( $RT::SystemUser );
153 ok ($tick->id, "loaded ticket #$id");
155 my $txn = $tick->Transactions->First;
156 my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef};
158 ok !$msg->GetHeader('X-RT-Privacy'), "RT's outgoing mail has no crypto";
159 is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Not encrypted',
160 "RT's outgoing mail looks not encrypted";
161 ok !$msg->GetHeader('X-RT-Incoming-Signature'),
162 "RT's outgoing mail looks not signed";
164 like $txn->Content, qr/Some content/, "RT's mail includes copy of ticket text";
167 foreach my $mail ( map cleanup_headers($_), @{ $mail{'signed'} } ) {
168 my ($status, $id) = RT::Test->send_via_mailgate($mail);
169 is ($status >> 8, 0, "The mail gateway exited normally");
170 ok ($id, "got id of a newly created ticket - $id");
172 my $tick = RT::Ticket->new( $RT::SystemUser );
174 ok ($tick->id, "loaded ticket #$id");
176 my $txn = $tick->Transactions->First;
177 my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef};
179 is $msg->GetHeader('X-RT-Privacy'), 'SMIME',
180 "RT's outgoing mail has crypto" or exit 0;
181 is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Not encrypted',
182 "RT's outgoing mail looks not encrypted";
183 like $msg->GetHeader('X-RT-Incoming-Signature'),
184 qr/<sender\@example\.com>/,
185 "RT's outgoing mail looks signed";
187 like $attachments[0]->Content, qr/Some content/,
188 "RT's mail includes copy of ticket text";
191 foreach my $mail ( map cleanup_headers($_), @{ $mail{'encrypted'} } ) {
192 my ($status, $id) = RT::Test->send_via_mailgate($mail);
193 is ($status >> 8, 0, "The mail gateway exited normally");
194 ok ($id, "got id of a newly created ticket - $id");
196 my $tick = RT::Ticket->new( $RT::SystemUser );
198 ok ($tick->id, "loaded ticket #$id");
200 my $txn = $tick->Transactions->First;
201 my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef};
203 is $msg->GetHeader('X-RT-Privacy'), 'SMIME',
204 "RT's outgoing mail has crypto";
205 is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Success',
206 "RT's outgoing mail looks encrypted";
207 ok !$msg->GetHeader('X-RT-Incoming-Signature'),
208 "RT's outgoing mail looks not signed";
210 like $attachments[0]->Content, qr/Some content/,
211 "RT's mail includes copy of ticket text";
214 foreach my $mail ( map cleanup_headers($_), @{ $mail{'signed_encrypted'} } ) {
215 my ($status, $id) = RT::Test->send_via_mailgate($mail);
216 is ($status >> 8, 0, "The mail gateway exited normally");
217 ok ($id, "got id of a newly created ticket - $id");
219 my $tick = RT::Ticket->new( $RT::SystemUser );
221 ok ($tick->id, "loaded ticket #$id");
223 my $txn = $tick->Transactions->First;
224 my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef};
226 is $msg->GetHeader('X-RT-Privacy'), 'SMIME',
227 "RT's outgoing mail has crypto";
228 is $msg->GetHeader('X-RT-Incoming-Encryption'), 'Success',
229 "RT's outgoing mail looks encrypted";
230 like $msg->GetHeader('X-RT-Incoming-Signature'),
231 qr/<sender\@example.com>/,
232 "RT's outgoing mail looks signed";
234 like $attachments[0]->Content, qr/Some content/,
235 "RT's mail includes copy of ticket text";
238 sub create_a_ticket {
241 RT::Test->clean_caught_mails;
243 describe_options('creating a ticket: ', %args);
245 $m->goto_create_ticket( $queue );
246 $m->form_name('TicketCreate');
247 $m->field( Subject => 'test' );
248 $m->field( Requestors => $user_email );
249 $m->field( Content => 'Some content' );
251 foreach ( qw(Sign Encrypt) ) {
255 $m->untick( $_ => 1 );
260 is $m->status, 200, "request successful";
262 unlike($m->content, qr/unable to sign outgoing email messages/);
264 $m->get_ok('/'); # ensure that the mail has been processed
266 my @mail = RT::Test->fetch_caught_mails;
267 check_text_emails( \%args, @mail );
274 RT::Test->clean_caught_mails;
276 describe_options('updating ticket #'. $tid .': ', %args);
278 ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
279 $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
281 $m->field( UpdateContent => 'Some content' );
283 foreach ( qw(Sign Encrypt) ) {
287 $m->untick( $_ => 1 );
291 $m->click('SubmitTicket');
292 is $m->status, 200, "request successful";
293 $m->content_like(qr/Correspondence added/, 'Correspondence added');# or diag $m->content;
295 $m->get_ok('/'); # ensure that the mail has been processed
297 my @mail = RT::Test->fetch_caught_mails;
298 check_text_emails( \%args, @mail );
304 sub check_text_emails {
305 my %args = %{ shift @_ };
308 describe_options('testing that we got at least one mail: ', %args);
310 ok scalar @mail, "got some mail";
311 for my $mail (@mail) {
312 if ( $args{'Encrypt'} ) {
313 unlike $mail, qr/Some content/, "outgoing email was encrypted";
315 like $mail, qr/Some content/, "outgoing email was not encrypted";
318 if ( $args{'Encrypt'} ) {
319 like $mail, qr/application\/(?:x-)?pkcs7-mime/, 'outgoing email was processed';
320 } elsif ( $args{'Sign'} ) {
321 like $mail, qr/(?:x-)?pkcs7-signature/, 'outgoing email was processed';
323 unlike $mail, qr/smime/, 'outgoing email was not processed';
326 if ( $args{'Sign'} && $args{'Encrypt'} ) {
327 push @{ $mail{'signed_encrypted'} }, @mail;
328 } elsif ( $args{'Sign'} ) {
329 push @{ $mail{'signed'} }, @mail;
330 } elsif ( $args{'Encrypt'} ) {
331 push @{ $mail{'encrypted'} }, @mail;
333 push @{ $mail{'plain'} }, @mail;
337 sub cleanup_headers {
339 # strip id from subject to create new ticket
340 $mail =~ s/^(Subject:)\s*\[.*?\s+#\d+\]\s*/$1 /m;
341 # strip several headers
342 foreach my $field ( qw(Message-ID RT-Originator RT-Ticket X-RT-Loop-Prevention) ) {
343 $mail =~ s/^$field:.*?\n(?! |\t)//gmsi;
348 sub set_queue_crypt_options {
351 describe_options('setting queue options: ', %args);
353 $m->get_ok("/Admin/Queues/Modify.html?id=". $queue->id);
354 $m->form_with_fields('Sign', 'Encrypt');
355 foreach my $opt ('Sign', 'Encrypt') {
359 $m->untick($opt => 1);
365 sub describe_options {
366 return unless $ENV{'TEST_VERBOSE'};
370 if ( $args{'Encrypt'} && $args{'Sign'} ) {
371 $msg .= 'encrypt and sign';
373 elsif ( $args{'Sign'} ) {
376 elsif ( $args{'Encrypt'} ) {
380 $msg .= 'no encrypt and no sign';