import rt 3.8.7
[freeside.git] / rt / t / web / gnupg-select-keys-on-update.t
1 #!/usr/bin/perl -w
2 use strict;
3 use warnings;
4
5 use RT::Test tests => 68;
6
7 plan skip_all => 'GnuPG required.'
8     unless eval 'use GnuPG::Interface; 1';
9 plan skip_all => 'gpg executable is required.'
10     unless RT::Test->find_executable('gpg');
11
12
13 use RT::Action::SendEmail;
14 use File::Temp qw(tempdir);
15
16 RT::Test->set_mail_catcher;
17
18 use_ok('RT::Crypt::GnuPG');
19
20 RT->Config->Set( GnuPG =>
21     Enable => 1,
22     OutgoingMessagesFormat => 'RFC',
23 );
24
25 RT->Config->Set( GnuPGOptions =>
26     homedir => scalar tempdir( CLEANUP => 0 ),
27     passphrase => 'rt-test',
28     'no-permission-warning' => undef,
29 );
30 diag "GnuPG --homedir ". RT->Config->Get('GnuPGOptions')->{'homedir'} if $ENV{TEST_VERBOSE};
31
32 RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
33
34 my $queue = RT::Test->load_or_create_queue(
35     Name              => 'Regression',
36     CorrespondAddress => 'rt-recipient@example.com',
37     CommentAddress    => 'rt-recipient@example.com',
38 );
39 ok $queue && $queue->id, 'loaded or created queue';
40
41 RT::Test->set_rights(
42     Principal => 'Everyone',
43     Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
44 );
45
46 my ($baseurl, $m) = RT::Test->started_ok;
47 ok $m->login, 'logged in';
48
49
50 my $tid;
51 {
52     my $ticket = RT::Ticket->new( $RT::SystemUser );
53     ($tid) = $ticket->Create(
54         Subject   => 'test',
55         Queue     => $queue->id,
56     );
57     ok $tid, 'ticket created';
58 }
59
60 diag "check that signing doesn't work if there is no key" if $ENV{TEST_VERBOSE};
61 {
62     RT::Test->clean_caught_mails;
63
64     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
65     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
66     $m->form_number(3);
67     $m->tick( Sign => 1 );
68     $m->field( UpdateCc => 'rt-test@example.com' );
69     $m->field( UpdateContent => 'Some content' );
70     $m->click('SubmitTicket');
71     $m->content_like(
72         qr/unable to sign outgoing email messages/i,
73         'problems with passphrase'
74     );
75
76     my @mail = RT::Test->fetch_caught_mails;
77     ok !@mail, 'there are no outgoing emails';
78 }
79
80 {
81     RT::Test->import_gnupg_key('rt-recipient@example.com');
82     RT::Test->trust_gnupg_key('rt-recipient@example.com');
83     my %res = RT::Crypt::GnuPG::GetKeysInfo('rt-recipient@example.com');
84     is $res{'info'}[0]{'TrustTerse'}, 'ultimate', 'ultimately trusted key';
85 }
86
87 diag "check that things don't work if there is no key" if $ENV{TEST_VERBOSE};
88 {
89     RT::Test->clean_caught_mails;
90
91     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
92     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
93     $m->form_number(3);
94     $m->tick( Encrypt => 1 );
95     $m->field( UpdateCc => 'rt-test@example.com' );
96     $m->field( UpdateContent => 'Some content' );
97     $m->click('SubmitTicket');
98     $m->content_like(
99         qr/You are going to encrypt outgoing email messages/i,
100         'problems with keys'
101     );
102     $m->content_like(
103         qr/There is no key suitable for encryption/i,
104         'problems with keys'
105     );
106
107     my $form = $m->form_number(3);
108     ok !$form->find_input( 'UseKey-rt-test@example.com' ), 'no key selector';
109
110     my @mail = RT::Test->fetch_caught_mails;
111     ok !@mail, 'there are no outgoing emails';
112 }
113
114
115 diag "import first key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
116 my $fpr1 = '';
117 {
118     RT::Test->import_gnupg_key('rt-test@example.com', 'public');
119     my %res = RT::Crypt::GnuPG::GetKeysInfo('rt-test@example.com');
120     is $res{'info'}[0]{'TrustLevel'}, 0, 'is not trusted key';
121     $fpr1 = $res{'info'}[0]{'Fingerprint'};
122 }
123
124 diag "check that things still doesn't work if key is not trusted" if $ENV{TEST_VERBOSE};
125 {
126     RT::Test->clean_caught_mails;
127
128     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
129     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
130     $m->form_number(3);
131     $m->tick( Encrypt => 1 );
132     $m->field( UpdateCc => 'rt-test@example.com' );
133     $m->field( UpdateContent => 'Some content' );
134     $m->click('SubmitTicket');
135     $m->content_like(
136         qr/You are going to encrypt outgoing email messages/i,
137         'problems with keys'
138     );
139     $m->content_like(
140         qr/There is one suitable key, but trust level is not set/i,
141         'problems with keys'
142     );
143
144     my $form = $m->form_number(3);
145     ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
146     is scalar $input->possible_values, 1, 'one option';
147
148     $m->select( 'UseKey-rt-test@example.com' => $fpr1 );
149     $m->click('SubmitTicket');
150     $m->content_like(
151         qr/You are going to encrypt outgoing email messages/i,
152         'problems with keys'
153     );
154     $m->content_like(
155         qr/Selected key either is not trusted/i,
156         'problems with keys'
157     );
158
159     my @mail = RT::Test->fetch_caught_mails;
160     ok !@mail, 'there are no outgoing emails';
161 }
162
163 diag "import a second key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
164 my $fpr2 = '';
165 {
166     RT::Test->import_gnupg_key('rt-test@example.com.2', 'public');
167     my %res = RT::Crypt::GnuPG::GetKeysInfo('rt-test@example.com');
168     is $res{'info'}[1]{'TrustLevel'}, 0, 'is not trusted key';
169     $fpr2 = $res{'info'}[2]{'Fingerprint'};
170 }
171
172 diag "check that things still doesn't work if two keys are not trusted" if $ENV{TEST_VERBOSE};
173 {
174     RT::Test->clean_caught_mails;
175
176     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
177     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
178     $m->form_number(3);
179     $m->tick( Encrypt => 1 );
180     $m->field( UpdateCc => 'rt-test@example.com' );
181     $m->field( UpdateContent => 'Some content' );
182     $m->click('SubmitTicket');
183     $m->content_like(
184         qr/You are going to encrypt outgoing email messages/i,
185         'problems with keys'
186     );
187     $m->content_like(
188         qr/There are several keys suitable for encryption/i,
189         'problems with keys'
190     );
191
192     my $form = $m->form_number(3);
193     ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
194     is scalar $input->possible_values, 2, 'two options';
195
196     $m->select( 'UseKey-rt-test@example.com' => $fpr1 );
197     $m->click('SubmitTicket');
198     $m->content_like(
199         qr/You are going to encrypt outgoing email messages/i,
200         'problems with keys'
201     );
202     $m->content_like(
203         qr/Selected key either is not trusted/i,
204         'problems with keys'
205     );
206
207     my @mail = RT::Test->fetch_caught_mails;
208     ok !@mail, 'there are no outgoing emails';
209 }
210
211 {
212     RT::Test->lsign_gnupg_key( $fpr1 );
213     my %res = RT::Crypt::GnuPG::GetKeysInfo('rt-test@example.com');
214     ok $res{'info'}[0]{'TrustLevel'} > 0, 'trusted key';
215     is $res{'info'}[1]{'TrustLevel'}, 0, 'is not trusted key';
216 }
217
218 diag "check that we see key selector even if only one key is trusted but there are more keys" if $ENV{TEST_VERBOSE};
219 {
220     RT::Test->clean_caught_mails;
221
222     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
223     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
224     $m->form_number(3);
225     $m->tick( Encrypt => 1 );
226     $m->field( UpdateCc => 'rt-test@example.com' );
227     $m->field( UpdateContent => 'Some content' );
228     $m->click('SubmitTicket');
229     $m->content_like(
230         qr/You are going to encrypt outgoing email messages/i,
231         'problems with keys'
232     );
233     $m->content_like(
234         qr/There are several keys suitable for encryption/i,
235         'problems with keys'
236     );
237
238     my $form = $m->form_number(3);
239     ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
240     is scalar $input->possible_values, 2, 'two options';
241
242     my @mail = RT::Test->fetch_caught_mails;
243     ok !@mail, 'there are no outgoing emails';
244 }
245
246 diag "check that key selector works and we can select trusted key" if $ENV{TEST_VERBOSE};
247 {
248     RT::Test->clean_caught_mails;
249
250     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
251     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
252     $m->form_number(3);
253     $m->tick( Encrypt => 1 );
254     $m->field( UpdateCc => 'rt-test@example.com' );
255     $m->field( UpdateContent => 'Some content' );
256     $m->click('SubmitTicket');
257     $m->content_like(
258         qr/You are going to encrypt outgoing email messages/i,
259         'problems with keys'
260     );
261     $m->content_like(
262         qr/There are several keys suitable for encryption/i,
263         'problems with keys'
264     );
265
266     my $form = $m->form_number(3);
267     ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
268     is scalar $input->possible_values, 2, 'two options';
269
270     $m->select( 'UseKey-rt-test@example.com' => $fpr1 );
271     $m->click('SubmitTicket');
272     $m->content_like( qr/Message recorded/i, 'Message recorded' );
273
274     my @mail = RT::Test->fetch_caught_mails;
275     ok @mail, 'there are some emails';
276     check_text_emails( { Encrypt => 1 }, @mail );
277 }
278
279 diag "check encrypting of attachments" if $ENV{TEST_VERBOSE};
280 {
281     RT::Test->clean_caught_mails;
282
283     ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
284     $m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
285     $m->form_number(3);
286     $m->tick( Encrypt => 1 );
287     $m->field( UpdateCc => 'rt-test@example.com' );
288     $m->field( UpdateContent => 'Some content' );
289     $m->field( Attach => $0 );
290     $m->click('SubmitTicket');
291     $m->content_like(
292         qr/You are going to encrypt outgoing email messages/i,
293         'problems with keys'
294     );
295     $m->content_like(
296         qr/There are several keys suitable for encryption/i,
297         'problems with keys'
298     );
299
300     my $form = $m->form_number(3);
301     ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
302     is scalar $input->possible_values, 2, 'two options';
303
304     $m->select( 'UseKey-rt-test@example.com' => $fpr1 );
305     $m->click('SubmitTicket');
306     $m->content_like( qr/Message recorded/i, 'Message recorded' );
307
308     my @mail = RT::Test->fetch_caught_mails;
309     ok @mail, 'there are some emails';
310     check_text_emails( { Encrypt => 1, Attachment => 1 }, @mail );
311 }
312
313 sub check_text_emails {
314     my %args = %{ shift @_ };
315     my @mail = @_;
316
317     ok scalar @mail, "got some mail";
318     for my $mail (@mail) {
319         for my $type ('email', 'attachment') {
320             next if $type eq 'attachment' && !$args{'Attachment'};
321
322             my $content = $type eq 'email'
323                         ? "Some content"
324                         : "Attachment content";
325
326             if ( $args{'Encrypt'} ) {
327                 unlike $mail, qr/$content/, "outgoing $type was encrypted";
328             } else {
329                 like $mail, qr/$content/, "outgoing $type was not encrypted";
330             } 
331
332             next unless $type eq 'email';
333
334             if ( $args{'Sign'} && $args{'Encrypt'} ) {
335                 like $mail, qr/BEGIN PGP MESSAGE/, 'outgoing email was signed';
336             } elsif ( $args{'Sign'} ) {
337                 like $mail, qr/SIGNATURE/, 'outgoing email was signed';
338             } else {
339                 unlike $mail, qr/SIGNATURE/, 'outgoing email was not signed';
340             }
341         }
342     }
343 }
344