RT 4.0.22
[freeside.git] / rt / t / customfields / iprangev6.t
1
2 use strict;
3 use warnings;
4
5 use RT::Test tests => 158;
6
7 my ($baseurl, $agent) =RT::Test->started_ok;
8 ok( $agent->login, 'log in' );
9
10 my $q = RT::Queue->new($RT::SystemUser);
11 $q->Load('General');
12 my $ip_cf = RT::CustomField->new($RT::SystemUser);
13
14 my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
15 ok($val,$msg);
16 my $cf_id = $val;
17 $ip_cf->AddToObject($q);
18 use_ok('RT');
19
20 my $cf;
21 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
22 {
23     my $cfs = RT::CustomFields->new( $RT::SystemUser );
24     $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
25     is( $cfs->Count, 1, "found one CF with name 'IP'" );
26
27     $cf = $cfs->First;
28     is( $cf->Type, 'IPAddressRange', 'type check' );
29     is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
30     ok( !$cf->MaxValues, "unlimited number of values" );
31     ok( !$cf->Disabled, "not disabled" );
32 }
33
34 diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
35 {
36     my $cfs = $q->TicketCustomFields;
37     $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
38     is( $cfs->Count, 1, 'field applies to queue' );
39 }
40
41 my %valid = (
42     'abcd:' x 7 . 'abcd' => 'abcd:' x 7 . 'abcd',
43     '034:' x 7 . '034'   => '0034:' x 7 . '0034',
44     'abcd::'             => 'abcd:' . '0000:' x 6 . '0000',
45     '::abcd'             => '0000:' x 7 . 'abcd',
46     'abcd::034'          => 'abcd:' . '0000:' x 6 . '0034',
47     'abcd::192.168.1.1'  => 'abcd:' . '0000:' x 5 . 'c0a8:0101',
48     '::192.168.1.1'      => '0000:' x 6 . 'c0a8:0101',
49     '::'                 => '0000:' x 7 . '0000',
50 );
51
52 diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
53 {
54     for my $ip ( keys %valid ) {
55         ok $agent->goto_create_ticket($q), "go to create ticket";
56         my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
57         $agent->submit_form(
58             form_name => 'TicketCreate',
59             fields    => {
60                 Subject   => 'test ip',
61                 $cf_field => $ip,
62             }
63         );
64
65         $agent->content_like( qr/$valid{$ip}/, "IP on the page" );
66         my ($id) = $agent->content =~ /Ticket (\d+) created/;
67         ok( $id, "created ticket $id" );
68
69         my $ticket = RT::Ticket->new($RT::SystemUser);
70         $ticket->Load($id);
71         ok( $ticket->id, 'loaded ticket' );
72         is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip},
73             'correct value' );
74     }
75 }
76
77 diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
78 {
79     my $val = 'abcd:034::/31';
80     ok $agent->goto_create_ticket($q), "go to create ticket";
81     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
82     $agent->submit_form(
83         form_name => 'TicketCreate',
84         fields    => {
85             Subject                                       => 'test ip',
86             $cf_field => $val,
87         }
88     );
89
90     my ($id) = $agent->content =~ /Ticket (\d+) created/;
91     ok( $id, "created ticket $id" );
92
93     my $ticket = RT::Ticket->new($RT::SystemUser);
94     $ticket->Load($id);
95     ok( $ticket->id, 'loaded ticket' );
96     is(
97         $ticket->FirstCustomFieldValue('IP'),
98 'abcd:0034:0000:0000:0000:0000:0000:0000-abcd:0035:ffff:ffff:ffff:ffff:ffff:ffff',
99         'correct value'
100     );
101 }
102
103 diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
104 {
105     my $val = 'abcd' . ':abcd' x 7;
106     ok $agent->goto_create_ticket($q), "go to create ticket";
107     $agent->submit_form(
108         form_name => 'TicketCreate',
109         fields    => { Subject => 'test ip', }
110     );
111
112     my ($id) = $agent->content =~ /Ticket (\d+) created/;
113     ok( $id, "created ticket $id" );
114     my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
115
116     $agent->follow_link_ok( { text => 'Basics', n => "1" },
117         "Followed 'Basics' link" );
118     $agent->form_name('TicketModify');
119
120     is( $agent->value($cf_field), '', 'IP is empty' );
121     $agent->field( $cf_field => $val );
122     $agent->click('SubmitTicket');
123
124     $agent->content_contains( $val, "IP on the page" );
125
126     my $ticket = RT::Ticket->new($RT::SystemUser);
127     $ticket->Load($id);
128     ok( $ticket->id, 'loaded ticket' );
129     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
130
131     diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
132     $agent->follow_link_ok( { text => 'Basics', n => "1" },
133         "Followed 'Basics' link" );
134     $agent->form_name('TicketModify');
135     is( $agent->value($cf_field), $val, 'IP is in input box' );
136     $val = 'bbcd' . ':abcd' x 7;
137     $agent->field( $cf_field => "   $val   " );
138     $agent->click('SubmitTicket');
139
140     $agent->content_contains( $val, "IP on the page" );
141
142     $ticket = RT::Ticket->new($RT::SystemUser);
143     $ticket->Load($id);
144     ok( $ticket->id, 'loaded ticket' );
145     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
146
147     diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
148     $agent->follow_link_ok( { text => 'Basics', n => "1" },
149         "Followed 'Basics' link" );
150     $agent->form_name('TicketModify');
151     is( $agent->value($cf_field), $val, 'IP is in input box' );
152     $val = 'abcd' . ':0000' x 7 . '-' . 'abcd' . ':ffff' x 7;
153     $agent->field( $cf_field => 'abcd::/16' );
154     $agent->click('SubmitTicket');
155
156     $agent->content_contains( $val, "IP on the page" );
157
158     $ticket = RT::Ticket->new($RT::SystemUser);
159     $ticket->Load($id);
160     ok( $ticket->id, 'loaded ticket' );
161     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
162
163     diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
164     $agent->follow_link_ok( { text => 'Basics', n => "1" },
165         "Followed 'Basics' link" );
166     $agent->form_name('TicketModify');
167     is( $agent->value($cf_field), $val, 'IP is in input box' );
168     $val = 'bb00' . ':0000' x 7 . '-' . 'bbff' . ':ffff' x 7;
169     $agent->field( $cf_field => $val );
170     $agent->click('SubmitTicket');
171
172     $agent->content_contains( $val, "IP on the page" );
173
174     $ticket = RT::Ticket->new($RT::SystemUser);
175     $ticket->Load($id);
176     ok( $ticket->id, 'loaded ticket' );
177     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
178 }
179
180 diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
181 {
182
183     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
184     my @invalid =
185       ( 'abcd:', 'efgh', 'abcd:' x 8 . 'abcd', 'abcd::abcd::abcd' );
186     for my $invalid (@invalid) {
187         ok $agent->goto_create_ticket($q), "go to create ticket";
188         $agent->submit_form(
189             form_name => 'TicketCreate',
190             fields    => {
191                 Subject   => 'test ip',
192                 $cf_field => $invalid,
193             }
194         );
195
196         $agent->content_like( qr/is not a valid IP address range/,
197             'ticket fails to create' );
198     }
199
200 }
201
202 diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
203 {
204     my $val = 'abcd::/16';
205     ok $agent->goto_create_ticket($q), "go to create ticket";
206     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
207     $agent->submit_form(
208         form_name => 'TicketCreate',
209         fields    => {
210             Subject   => 'test ip',
211             $cf_field => $val,
212         }
213     );
214
215     my ($id) = $agent->content =~ /Ticket (\d+) created/;
216     ok( $id, "created ticket $id" );
217
218     my $ticket = RT::Ticket->new($RT::SystemUser);
219     $ticket->Load($id);
220     ok( $ticket->id, 'loaded ticket' );
221
222     my $tickets = RT::Tickets->new($RT::SystemUser);
223     $tickets->FromSQL("id = $id AND CF.{IP} = 'abcd::/16'");
224     ok( $tickets->Count, "found tickets" );
225     is(
226         $ticket->FirstCustomFieldValue('IP'),
227 'abcd:0000:0000:0000:0000:0000:0000:0000-abcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
228         'correct value'
229     );
230 }
231
232 diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
233 {
234     my $val = 'abcd:ef00::/24';
235     ok $agent->goto_create_ticket($q), "go to create ticket";
236     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
237     $agent->submit_form(
238         form_name => 'TicketCreate',
239         fields    => {
240             Subject   => 'test ip',
241             $cf_field => $val,
242         }
243     );
244
245     my ($id) = $agent->content =~ /Ticket (\d+) created/;
246     ok( $id, "created ticket $id" );
247
248     my $ticket = RT::Ticket->new($RT::SystemUser);
249     $ticket->Load($id);
250     ok( $ticket->id, 'loaded ticket' );
251
252     my $tickets = RT::Tickets->new( $RT::SystemUser );
253     $tickets->FromSQL("id = $id AND CF.{IP} =
254             'abcd:ef::-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff'");
255     ok( $tickets->Count, "found tickets" );
256
257     is(
258         $ticket->FirstCustomFieldValue('IP'),
259 'abcd:ef00:0000:0000:0000:0000:0000:0000-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff',
260         'correct value'
261     );
262 }
263
264 diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
265 {
266     ok $agent->goto_create_ticket($q), "go to create ticket";
267     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
268     my $first_ip = 'cbcd' . ':0000' x 7;
269     my $second_ip = 'cbdd' . ':0000' x 7;
270     $agent->submit_form(
271         form_name => 'TicketCreate',
272         fields    => {
273             Subject   => 'test ip',
274             $cf_field => $first_ip,
275         }
276     );
277
278     my ($id1) = $agent->content =~ /Ticket (\d+) created/;
279     ok( $id1, "created first ticket $id1" );
280
281     ok $agent->goto_create_ticket($q), "go to create ticket";
282     $agent->submit_form(
283         form_name => 'TicketCreate',
284         fields    => {
285             Subject   => 'test ip',
286             $cf_field => $second_ip,
287         }
288     );
289
290     my ($id2) = $agent->content =~ /Ticket (\d+) created/;
291     ok( $id2, "created second ticket $id2" );
292
293     my $tickets = RT::Tickets->new( $RT::SystemUser );
294     $tickets->FromSQL("id = $id1 OR id = $id2");
295     is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
296
297     # IP
298     $tickets = RT::Tickets->new( $RT::SystemUser );
299     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip'");
300     is( $tickets->Count, 1, "found one ticket" );
301     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
302     $tickets = RT::Tickets->new( $RT::SystemUser );
303     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip'");
304     is( $tickets->Count, 1, "found one ticket" );
305     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
306
307     # IP/32 - one address
308     $tickets = RT::Tickets->new( $RT::SystemUser );
309     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/16'");
310     is( $tickets->Count, 1, "found one ticket" );
311     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
312     $tickets = RT::Tickets->new( $RT::SystemUser );
313     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/16'");
314     is( $tickets->Count, 1, "found one ticket" );
315     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
316
317     # IP range
318     $tickets = RT::Tickets->new( $RT::SystemUser );
319     $tickets->FromSQL(
320         "(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip-cbcf::'"
321     );
322     is( $tickets->Count, 1, "found one ticket" );
323     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
324     $tickets = RT::Tickets->new( $RT::SystemUser );
325     $tickets->FromSQL(
326         "(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip-cbdf::'");
327     is( $tickets->Count, 1, "found one ticket" );
328     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
329
330     # IP range, with start IP greater than end
331     $tickets = RT::Tickets->new( $RT::SystemUser );
332     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} =
333             'cbcf::-$first_ip'");
334     is( $tickets->Count, 1, "found one ticket" );
335     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip,, "correct value" );
336     $tickets = RT::Tickets->new( $RT::SystemUser );
337     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdf::-$second_ip'");
338     is( $tickets->Count, 1, "found one ticket" );
339     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
340
341     # CIDR/12
342     $tickets = RT::Tickets->new( $RT::SystemUser );
343     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/12'");
344     is( $tickets->Count, 1, "found one ticket" );
345     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
346     $tickets = RT::Tickets->new( $RT::SystemUser );
347     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/12'");
348     is( $tickets->Count, 1, "found one ticket" );
349     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
350
351     # IP is not in CIDR/24
352     $tickets = RT::Tickets->new( $RT::SystemUser );
353     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbcd::/12'");
354     is( $tickets->Count, 1, "found one ticket" );
355     is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip,, "correct value" );
356     $tickets = RT::Tickets->new( $RT::SystemUser );
357     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbdd::/12'");
358     is( $tickets->Count, 1, "found one ticket" );
359     is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
360
361     # CIDR or CIDR
362     $tickets = RT::Tickets->new( $RT::SystemUser );
363     $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
364         ."(CF.{IP} = 'cbcd::/12' OR CF.{IP} = 'cbdd::/12')");
365     is( $tickets->Count, 2, "found both tickets" );
366 }
367
368 diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
369 {
370     ok $agent->goto_create_ticket($q), "go to create ticket";
371     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
372     $agent->submit_form(
373         form_name => 'TicketCreate',
374         fields    => {
375             Subject   => 'test ip',
376             $cf_field => 'ddcd::/16',
377         }
378     );
379
380     my ($id1) = $agent->content =~ /Ticket (\d+) created/;
381     ok( $id1, "created first ticket $id1" );
382
383     ok $agent->goto_create_ticket($q), "go to create ticket";
384     $agent->submit_form(
385         form_name => 'TicketCreate',
386         fields    => {
387             Subject   => 'test ip',
388             $cf_field => 'edcd::/16',
389         }
390     );
391
392     my ($id2) = $agent->content =~ /Ticket (\d+) created/;
393     ok( $id2, "created ticket $id2" );
394
395     my $tickets = RT::Tickets->new( $RT::SystemUser );
396     $tickets->FromSQL("id = $id1 OR id = $id2");
397     is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
398
399     # IP
400     $tickets = RT::Tickets->new( $RT::SystemUser );
401     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::'");
402     is( $tickets->Count, 1, "found one ticket" );
403     is( $tickets->First->id, $id1, "correct value" );
404     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:abcd::'");
405     is( $tickets->Count, 1, "found one ticket" );
406     is( $tickets->First->id, $id1, "correct value" );
407     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ffff::'");
408     is( $tickets->Count, 1, "found one ticket" );
409     is( $tickets->First->id, $id1, "correct value" );
410     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::abcd'");
411     is( $tickets->Count, 1, "found one ticket" );
412     is( $tickets->First->id, $id2, "correct value" );
413     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::ffff'");
414     is( $tickets->Count, 1, "found one ticket" );
415     is( $tickets->First->id, $id2, "correct value" );
416     $tickets->FromSQL(
417 "(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
418     );
419     is( $tickets->Count, 1, "found one ticket" );
420     is( $tickets->First->id, $id2, "correct value" );
421
422     # IP/32 - one address
423     $tickets = RT::Tickets->new( $RT::SystemUser );
424     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/32'");
425     is( $tickets->Count, 1, "found one ticket" );
426     is( $tickets->First->id, $id1, "correct value" );
427     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::/32'");
428     is( $tickets->Count, 1, "found one ticket" );
429     is( $tickets->First->id, $id2, "correct value" );
430
431     # IP range, lower than both
432     $tickets = RT::Tickets->new( $RT::SystemUser );
433     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'abcd::/32'");
434     is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
435
436     # IP range, intersect with the first range
437     $tickets->FromSQL(
438         "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-ddcd:ab::'"
439     );
440     is( $tickets->Count, 1, "found one ticket" );
441     is( $tickets->First->id, $id1, "correct value" );
442
443     # IP range, equal to the first range
444     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/16'");
445     is( $tickets->Count, 1, "found one ticket" );
446     is( $tickets->First->id, $id1, "correct value" );
447
448     # IP range, lay inside the first range
449     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ab::'");
450     is( $tickets->Count, 1, "found one ticket" );
451     is( $tickets->First->id, $id1, "correct value" );
452
453     # IP range, intersect with the ranges
454     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-edcd:ab::'");
455     is( $tickets->Count, 2, "found both tickets" );
456
457     # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
458     $tickets->FromSQL(
459         "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::-edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
460     );
461     is( $tickets->Count, 2, "found both tickets" );
462
463     # IP range, has the both ranges inside it
464     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'd000::/2'");
465     is( $tickets->Count, 2, "found both tickets" );
466
467     # IP range, greater than both
468     $tickets = RT::Tickets->new( $RT::SystemUser );
469     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ffff::/16'");
470     is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;
471 }
472
473