File Coverage

blib/lib/WWW/Postini.pm
Criterion Covered Total %
statement 323 359 89.9
branch 89 158 56.3
condition 43 105 40.9
subroutine 29 29 100.0
pod 10 10 100.0
total 494 661 74.7


line stmt bran cond sub pod time code
1             package WWW::Postini;
2            
3 1     1   18060 use strict;
  1         2  
  1         33  
4 1     1   6 use warnings;
  1         2  
  1         29  
5            
6 1     1   560 use WWW::Postini::Assert;
  1         4  
  1         54  
7 1     1   669 use WWW::Postini::Exception::LoginFailure;
  1         3  
  1         28  
8 1     1   598 use WWW::Postini::Exception::InvalidParameter;
  1         3  
  1         28  
9 1     1   554 use WWW::Postini::Exception::UnexpectedResponse;
  1         3  
  1         26  
10 1     1   494 use WWW::Postini::UserAgent;
  1         3  
  1         28  
11 1     1   582 use WWW::Postini::Constants ':all';
  1         3  
  1         170  
12            
13 1     1   896 use HTML::TokeParser;
  1         51472  
  1         54  
14 1     1   11 use HTTP::Request;
  1         2  
  1         33  
15 1     1   7 use HTTP::Status;
  1         2  
  1         506  
16            
17 1     1   8 use vars '$VERSION';
  1         3  
  1         51  
18            
19 1     1   6 use constant DEFAULT_LOGIN_HOST => 'login.postini.com';
  1         3  
  1         90  
20            
21 1     1   5 use constant QUARANTINE_PAGE_SIZE => 1000;
  1         3  
  1         47  
22            
23 1     1   6 use constant LOG_IN_TITLE => 'Log in';
  1         1  
  1         50  
24 1     1   7 use constant CHOOSE_SESSION_TITLE => 'Choose Session Type';
  1         2  
  1         42  
25 1     1   6 use constant ADMIN_TITLE => 'System Administration';
  1         10  
  1         5979  
26            
27             $VERSION = '0.01';
28            
29             #################
30             ## constructor ##
31             #################
32            
33             sub new {
34            
35 2     2 1 36 my $class = shift;
36 2         5 my $self = bless {}, $class;
37 2         10 $self->_init(@_);
38 2         6 $self;
39            
40             }
41            
42             #################
43             ## initializer ##
44             #################
45            
46             sub _init {
47            
48 2     2   4 my $self = shift;
49            
50 2 100       7 if (@_) {
51            
52 1         5 $self->login_host(shift);
53            
54             } else {
55            
56 1         8 $self->{'_login_host'} = DEFAULT_LOGIN_HOST;
57            
58             }
59            
60 2         20 $self->{'_user_agent'} = new WWW::Postini::UserAgent();
61 2         6659 return;
62            
63             }
64            
65             ######################
66             ## accessor methods ##
67             ######################
68            
69             # user agent
70            
71             sub user_agent {
72            
73 1     1 1 3 my $self = shift;
74            
75 1 50       7 if (@_) {
76            
77 0         0 $self->{'_user_agent'} = shift;
78            
79             }
80            
81 1 50       13 return $self->{'_user_agent'} if defined wantarray;
82            
83             }
84            
85             # login host
86            
87             sub login_host {
88            
89 4     4 1 347 my $self = shift;
90            
91 4 100       10 if (@_) {
92            
93 2         5 $self->{'_login_host'} = shift;
94            
95             }
96            
97 4 100       19 return $self->{'_login_host'} if defined wantarray;
98            
99             }
100            
101             # admin host
102            
103             sub admin_host {
104            
105 1     1 1 300 my $self = shift;
106            
107 1 50       4 if (@_) {
108            
109 0         0 $self->{'_admin_host'} = shift;
110            
111             }
112            
113 1 50       7 return $self->{'_admin_host'} if defined wantarray;
114            
115             }
116            
117             #####################
118             ## utility methods ##
119             #####################
120            
121             # login
122            
123             sub login {
124            
125 2     2 1 390 my $self = shift;
126            
127 2 50 33     29 throw WWW::Postini::Exception::InvalidParameter('Email address not specified')
128             unless defined $_[0] && length $_[0]
129             ;
130 2 50 33     16 throw WWW::Postini::Exception::InvalidParameter('Password not specified')
131             unless defined $_[1] && length $_[1]
132             ;
133            
134 2         5 my $email_address = shift;
135 2         3 my $password = shift;
136 2         3 my $response;
137            
138             # try
139            
140 2         4 eval {
141            
142             # attempt to log in
143            
144 2         32 $response = $self->{'_user_agent'}->get(
145             "https://$self->{'_login_host'}/exec/login?"
146             ."email=$email_address"
147             ."&pword=$password"
148             ."&action=login"
149             );
150            
151 2         10 assert($response, 'Response returned');
152            
153 2         6 my $code = $response->code();
154 2         22 assert($code == RC_OK, 'Response code is '.RC_OK);
155            
156 2         12 my $content = $response->content();
157 2         29 my $p = new HTML::TokeParser(\$content);
158            
159             # determine title
160            
161 2         345 my $tag = $p->get_tag('title');
162 2         307 assert($tag, 'Title tag exists');
163            
164 2         6 my $token = $p->get_token();
165 2         18 assert($token, 'Token exists');
166 2         7 assert($token->[0] eq 'T', 'Token is text');
167 2   66     15 assert(
168             $token->[1] eq LOG_IN_TITLE || $token->[1] eq CHOOSE_SESSION_TITLE,
169             'Title recognized'
170             );
171            
172             # log in
173            
174 2 100       10 if ($token->[1] eq LOG_IN_TITLE) {
    50          
175            
176 1         12 $tag = $p->get_tag('br');
177 1         81 assert($tag, 'Break tag exists');
178            
179 1         3 $tag = $p->get_tag('b');
180 1         22 assert($tag, 'Bold tag exists');
181            
182 1         5 my $text = $p->get_trimmed_text();
183 1         57 assert($text, 'Bold has text');
184            
185 1         18 throw WWW::Postini::Exception::LoginFailure($text);
186            
187             # choose session (transfer phase)
188            
189             } elsif ($token->[1] eq CHOOSE_SESSION_TITLE) {
190            
191 1         6 $tag = $p->get_tag('a');
192 1         97 assert($tag, 'Administration link exists');
193 1         6 assert($tag->[1]->{'href'}, 'Administration URL defined');
194            
195             # make certain user is administrator
196            
197 1         5 my $text = $p->get_trimmed_text();
198 1         61 assert($text eq ADMIN_TITLE, 'User is administrator');
199            
200             # determine administration host
201            
202 1         3 my $url = $tag->[1]->{'href'};
203 1         7 my ($admin_host) = $url =~ m!^https?://(.+?)/!;
204 1         169 assert($admin_host, 'Administration site determined');
205 1         3 $self->{'_admin_host'} = $admin_host;
206            
207             # send transfer code
208            
209 1         6 $response = $self->{'_user_agent'}->get($url);
210            
211 1         12 assert($response, 'Response returned');
212            
213 1         4 $code = $response->code();
214 1         14 assert($code == RC_OK, 'Response code is '.RC_OK);
215            
216             }
217            
218             };
219            
220             # catch
221            
222 2 100 66     649 if (defined $@ && (length $@ || ref $@)) {
      33        
223            
224 1 50       681 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::LoginFailure')) {
225            
226 1         8 $@->rethrow();
227            
228             } else {
229            
230 0         0 throw WWW::Postini::Exception::UnexpectedResponse($@);
231            
232             }
233            
234             }
235            
236 1         4 return 1;
237            
238             }
239            
240             # get user id
241            
242             sub get_user_id {
243            
244 2     2 1 291 my $self = shift;
245            
246 2 50 33     20 throw WWW::Postini::Exception::InvalidParameter('Email address not specified')
247             unless defined $_[0] && length $_[0]
248             ;
249            
250 2         4 my $email_address = shift;
251 2         3 my ($response, $user_id);
252            
253             # try
254            
255 2         2 eval {
256            
257             # avoid automatic redirect so user id can be ascertained
258            
259 2         14 $response = $self->{'_user_agent'}->simple_request(new HTTP::Request (
260             GET =>
261             'https://'
262             .$self->{'_admin_host'}
263             .'/exec/adminstart?'
264             .'action=user_shortcut'
265             ."&targetAddress=$email_address"
266             .'&next_action=Quarantine'
267             ));
268            
269 2         8 assert($response, 'Response returned');
270            
271 2         15 my $code = $response->code();
272 2         21 assert($code == RC_FOUND, 'Response code is '.RC_FOUND);
273            
274 1         4 my $location = $response->headers->header('location');
275 1         61 assert($location, 'Location defined');
276            
277 1         6 ($user_id) = $location =~ /targetuserid=(\d+)/;
278 1         5 assert($user_id, 'User ID defined');
279            
280             };
281            
282             # catch
283            
284 2 100 66     547 if (defined $@ && (length $@ || ref $@)) {
      33        
285            
286 1 50       585 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::UnexpectedResponse')) {
287            
288 0         0 $@->rethrow();
289            
290             } else {
291            
292 1         9 throw WWW::Postini::Exception::UnexpectedResponse($@);
293            
294             }
295            
296             }
297            
298 1         4 $user_id;
299            
300             }
301            
302             # list messages messages from quarantine
303            
304             sub list_messages {
305            
306 9     9 1 13904 my $self = shift;
307 9         17 my %args;
308            
309             # handle arguments
310            
311 9 50       38 if (@_) {
312            
313             # hash reference
314            
315 9 50 33     117 if (defined $_[0] && UNIVERSAL::isa($_[0], 'HASH')) {
    50          
316            
317 0         0 %args = %{$_[0]};
  0         0  
318            
319             # single parameter (user id)
320            
321             } elsif (@_ == 1) {
322            
323 0         0 $args{'user_id'} = shift;
324            
325             # array of key/value pairs
326            
327             } else {
328            
329 9         41 %args = @_;
330            
331             }
332            
333             }
334            
335             # require user id parameter
336            
337 9 50 33     56 throw WWW::Postini::Exception::InvalidParameter ('User ID not specified')
338             unless defined $args{'user_id'} && length $args{'user_id'}
339             ;
340            
341             # set argument defaults
342            
343 9 100       29 $args{'show'} = SHOW_ALL unless defined $args{'show'};
344 9 50       42 $args{'sort'} = SORT_NONE unless defined $args{'sort'};
345            
346             # define which messages will be shown
347            
348 9         15 my $show;
349            
350 9 100       35 if ($args{'show'} == SHOW_ALL) {
    100          
    100          
    50          
351            
352 5         9 $show = 'all';
353            
354             } elsif ($args{'show'} == SHOW_QUARANTINED) {
355            
356 1         3 $show = 'visible';
357            
358             } elsif ($args{'show'} == SHOW_DELIVERED) {
359            
360 2         5 $show = 'delivered';
361            
362             } elsif ($args{'show'} == SHOW_DELETED) {
363            
364 1         2 $show = 'deleted';
365            
366             } else {
367            
368 0         0 throw WWW::Postini::Exception::InvalidParameter(
369             'Invalid "show" parameter specified'
370             );
371            
372             }
373            
374             # define sort method
375            
376 9         14 my $sort;
377            
378 9 50       21 if ($args{'sort'} == SORT_NONE) {
    0          
    0          
    0          
    0          
379            
380 9         13 $sort = '';
381            
382             } elsif ($args{'sort'} == SORT_RECIPIENT) {
383            
384 0         0 $sort = 'recip';
385            
386             } elsif ($args{'sort'} == SORT_SENDER) {
387            
388 0         0 $sort = 'sender';
389            
390             } elsif ($args{'sort'} == SORT_SUBJECT) {
391            
392 0         0 $sort = 'subject';
393            
394             } elsif ($args{'sort'} == SORT_FILTER) {
395            
396 0         0 $sort = 'block';
397            
398             } else {
399            
400 0         0 throw WWW::Postini::Exception::InvalidParameter(
401             'Invalid "sort" parameter specified'
402             );
403            
404             }
405            
406 9         43 my $base_url = "https://$self->{'_admin_host'}/exec/admin_users?"
407             ."targetuserid=$args{'user_id'}"
408             .'&action=display_Quarantine'
409             ;
410            
411 9         48 my %url_params = (
412             pagesize => QUARANTINE_PAGE_SIZE,
413             msgtype => $show,
414             msgsort => $sort
415             );
416            
417             # search for recipient
418            
419 9 100       28 $url_params{'filterRecip'} = $args{'recipient'}
420             if defined $args{'recipient'}
421             ;
422            
423             # search for sender
424            
425 9 100       22 $url_params{'filterSender'} = $args{'sender'}
426             if defined $args{'sender'}
427             ;
428            
429             # search for subject
430            
431 9 100       26 $url_params{'filterSubject'} = $args{'subject'}
432             if defined $args{'subject'}
433             ;
434            
435             # limit to specified filter
436            
437 9 100       26 $url_params{'filterBlock'} = $args{'filter'}
438             if defined $args{'filter'}
439             ;
440            
441 9         12 my $page_number = 1;
442 9         12 my @messages;
443            
444             # try
445            
446 9         13 eval {
447            
448 9         9 my $response;
449            
450 9         15 while (1) {
451            
452             # retrieve current page
453            
454 9         95 $response = $self->{'_user_agent'}->post(
455             $base_url, [
456             %url_params,
457             firstmsg => (($page_number - 1) * QUARANTINE_PAGE_SIZE)
458             ]
459             );
460            
461 9         54 assert($response, 'Response returned');
462            
463 9         29 my $code = $response->code();
464 9         98 assert($code == RC_OK, 'Response code is '.RC_OK);
465            
466 9         28 my $content = $response->content();
467 9         116 my $p = new HTML::TokeParser(\$content);
468            
469 9         2320 my ($tag, $start_range, $end_range, $total_messages);
470            
471 9         39 while (defined ($tag = $p->get_tag('td'))) {
472            
473 18 50 66     4288 last if defined $tag->[1]->{'width'}
      66        
      33        
474             && defined $tag->[1]->{'align'}
475             && $tag->[1]->{'width'} eq '100%'
476             && $tag->[1]->{'align'} eq 'right'
477             ;
478            
479             }
480            
481 9         29 $tag = $p->get_tag('font');
482 9         263 assert($tag, 'Font tag exists');
483            
484 9         17 my $token;
485            
486 9         32 while (defined ($token = $p->get_token())) {
487            
488 45 50 66     501 last if $token->[0] eq 'E' && $token->[1] eq 'font';
489            
490 45 100       115 if ($token->[0] eq 'T') {
491            
492 27 100       132 next unless $token->[1] =~ /\d+ - \d+ of \d+/s;
493            
494 9         57 ($start_range, $end_range, $total_messages) = $token->[1] =~ /
495             (\d+) \s - \s (\d+)
496             \s of \s
497             (\d+)
498             /x;
499 9         19 last;
500            
501             }
502            
503             }
504            
505 9         35 assert(defined ($total_messages), 'Total messages defined');
506 9         22 assert(defined ($start_range), 'Start range defined');
507 9         35 assert($start_range <= $total_messages, 'Valid start range');
508            
509 9         31 $tag = $p->get_tag('form');
510 9         1343 assert($tag, 'Form tag exists');
511            
512 9         28 $tag = $p->get_tag('tr');
513 9         411 assert($tag, 'TR tag exists');
514            
515 9         29 while($tag = $p->get_tag('tr')) {
516            
517 31 50 66     2778 next unless defined $tag->[1]->{'bgcolor'} && (
      33        
518             $tag->[1]->{'bgcolor'} eq '#EEEEEE'
519             || $tag->[1]->{'bgcolor'} eq '#FFFFFF'
520             );
521 31 50       93 last unless defined $p->get_tag('font');
522            
523 31         2434 my ($date, $recipient, $sender) = (
524             $self->_get_message_field($p),
525             $self->_get_message_field($p),
526             $self->_get_message_field($p)
527             );
528            
529 31         1414 assert($date, 'Date defined');
530 31         67 assert($recipient, 'Recipient defined');
531 31         62 assert($sender, 'Sender defined');
532            
533 31         86 $tag = $p->get_tag('font');
534 31         2638 assert($tag, 'Font tag exists');
535            
536 31         78 $tag = $p->get_tag('a');
537 31         1213 assert($tag, 'Link exists');
538            
539 31         63 my $url = $tag->[1]->{'href'};
540 31         70 assert($url, 'URL defined');
541            
542 31         81 my $subject = $p->get_trimmed_text();
543 31         1499 assert($subject, 'Subject defined');
544            
545 31         207 my $uri = (split m!\?!, $url)[1];
546 31         80 assert($uri, 'URI defined');
547            
548 31         31 my %params;
549            
550 31         91 foreach my $pair (split /&/, $uri) {
551            
552 93         182 my ($key, $value) = split /=/, $pair;
553 93         348 $params{$key} = $value;
554            
555             }
556            
557 31         106 $tag = $p->get_tag('font');
558 31         4614 assert($tag, 'Font tag exists');
559            
560 31         82 my $filter = $p->get_trimmed_text();
561 31         1419 assert($filter, 'Filter defined');
562            
563 31         338 push @messages, {
564             sender => $sender,
565             recipient => $recipient,
566             subject => $subject,
567             date => $date,
568             filter => $filter,
569             id => $params{'msgid'},
570             uid => $args{'user_id'}
571             };
572            
573             }
574            
575 9 50       1770 last if $end_range >= $total_messages;
576 0         0 $page_number++;
577            
578             }
579            
580             };
581            
582             # catch
583            
584 9 50 33     82 if (defined $@ && (length $@ || ref $@)) {
      33        
585            
586 0 0       0 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::UnexpectedResponse')) {
587            
588 0         0 $@->rethrow();
589            
590             } else {
591            
592 0         0 throw WWW::Postini::Exception::UnexpectedResponse($@);
593            
594             }
595            
596             }
597            
598 9         71 \@messages;
599            
600             }
601            
602             # get message info
603            
604             sub get_message_info {
605            
606 1     1 1 945 my $self = shift;
607            
608 1 50 33     10 throw WWW::Postini::Exception::InvalidParameter('User ID not specified')
609             unless defined $_[0] && length $_[0]
610             ;
611 1 50 33     7 throw WWW::Postini::Exception::InvalidParameter('Message ID not specified')
612             unless defined $_[1] && length $_[1]
613             ;
614            
615 1         2 my $user_id = shift;
616 1         2 my $message_id = shift;
617 1         1 my ($headers, $body, @attachments);
618            
619 1         2 eval {
620            
621 1         11 my $response = $self->{'_user_agent'}->get(
622             "https://$self->{'_admin_host'}/exec/admin_users?"
623             ."targetuserid=$user_id"
624             .'&action=display_Message'
625             ."&msgid=$message_id"
626             .'&showheader=1'
627             );
628            
629 1         5 assert($response, 'Response returned');
630            
631 1         4 my $code = $response->code();
632 1         10 assert($code == RC_OK, 'Response code is '.RC_OK);
633            
634 1         3 my $content = $response->content();
635 1         11 my $p = new HTML::TokeParser(\$content);
636            
637 1         115 my $tag = $p->get_tag('pre');
638 1         201 assert($tag, 'PRE tag exists');
639            
640 1         4 $headers = $p->get_text();
641 1         43 assert($headers, 'Headers exist');
642            
643 1         137 $headers =~ s/\s+$//gs;
644            
645 1         5 $tag = $p->get_tag('xmp');
646 1         47 assert($tag, 'XMP tag exists');
647            
648 1         1 my $token;
649            
650 1         4 while (defined ($token = $p->get_token())) {
651            
652             # start tag
653            
654 2 50 33     26 if ($token->[0] eq 'S') {
    100 33        
    50          
    0          
655            
656 0         0 $body .= $token->[4];
657            
658             # end tag
659            
660             } elsif ($token->[0] eq 'E') {
661            
662 1 50       3 last if $token->[1] eq 'xmp';
663 0         0 $body .= $token->[2];
664            
665             # text, comment, or declaration
666            
667             } elsif ($token->[0] eq 'T'
668             || $token->[0] eq 'C'
669             || $token->[0] eq 'D'
670             ) {
671            
672 1         3 $body .= $token->[1];
673            
674             # processing instruction
675            
676             } elsif ($token->[0] eq 'PI') {
677            
678 0         0 $body .= $token->[2];
679            
680             }
681            
682             }
683            
684 1         5 $body =~ s/\s+$//sg;
685            
686 1         2 my ($text, $file);
687            
688 1         3 while (defined ($token = $p->get_token())) {
689            
690 8 100 66     67 last if $token->[0] eq 'E' && $token->[1] eq 'font';
691 7 100       15 next unless $token->[0] eq 'T';
692            
693 4 100       25 if (($file) = $token->[1] =~ /name=\"?([^";]+?)\s*(?:"|\;|$)/s) {
694            
695 2         6 push @attachments, $file;
696            
697             }
698            
699             }
700            
701             };
702            
703             # catch
704            
705 1 50 33     10 if (defined $@ && (length $@ || ref $@)) {
      33        
706            
707 0 0       0 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::UnexpectedResponse')) {
708            
709 0         0 $@->rethrow();
710            
711             } else {
712            
713 0         0 throw WWW::Postini::Exception::UnexpectedResponse($@);
714            
715             }
716            
717             }
718            
719             return {
720 1         7 headers => $headers,
721             body => $body,
722             attachments => \@attachments
723             };
724            
725             }
726            
727             # delete specified messages
728            
729             sub delete_messages {
730            
731 1     1 1 2995 my $self = shift;
732 1         2 my @message_ids;
733            
734 1 50 33     8 throw WWW::Postini::Exception::InvalidParameter('User ID not specified')
735             unless defined $_[0] && length $_[0]
736             ;
737            
738 1         2 my $user_id = shift;
739            
740             # handle arguments
741            
742 1 50       3 if (@_) {
743            
744             # array reference
745            
746 1 50 33     11 if (defined $_[0] && UNIVERSAL::isa($_[0], 'ARRAY')) {
747            
748 0         0 @message_ids = @{$_[0]};
  0         0  
749            
750             # list of values
751            
752             } else {
753            
754 1         2 @message_ids = @_;
755            
756             }
757            
758             }
759            
760 1 50       5 throw WWW::Postini::Exception::InvalidParameter('No messages specified')
761             unless scalar @message_ids
762             ;
763            
764 1         1 my $message_count;
765            
766             # try
767            
768 1         6 eval {
769            
770 1         4 my @args = (
771             action => 'processQuarantine',
772             targetuserid => $user_id,
773             submit => 'Delete'
774             );
775            
776 1         2 foreach my $id (@message_ids) {
777            
778 1         4 push @args, ('msgid', $id);
779            
780             }
781            
782 1         10 my $response = $self->{'_user_agent'}->post(
783             "https://$self->{'_admin_host'}/exec/admin_users",
784             \@args
785             );
786            
787 1         4 assert($response, 'Response returned');
788            
789 1         4 my $code = $response->code();
790 1         9 assert($code == RC_OK, 'Response code is '.RC_OK);
791            
792 1         3 my $content = $response->content();
793 1         13 my $p = new HTML::TokeParser(\$content);
794 1         126 my ($tag, $text);
795            
796 1         5 while (defined ($tag = $p->get_tag('b'))) {
797            
798 1         221 my $text = $p->get_trimmed_text();
799 1 50 33     60 last if defined $text && $text eq 'Message Results';
800            
801             }
802            
803 1         4 $tag = $p->get_tag('font');
804 1         37 assert($tag, 'Font tag exists');
805            
806 1         3 $text = $p->get_trimmed_text();
807 1         53 assert(
808             $text =~ /^\d+ message\(s\) marked as deleted\./,
809             'Message text recognized'
810             );
811            
812 1         13 ($message_count) = $text =~ /^(\d+)/;
813            
814             };
815            
816             # catch
817            
818 1 50 33     15 if (defined $@ && (length $@ || ref $@)) {
      33        
819            
820 0 0       0 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::UnexpectedResponse')) {
821            
822 0         0 $@->rethrow();
823            
824             } else {
825            
826 0         0 throw WWW::Postini::Exception::UnexpectedResponse($@);
827            
828             }
829            
830             }
831            
832 1         4 $message_count;
833            
834             }
835            
836             # process quarantined messages
837            
838             sub process_messages {
839            
840 1     1 1 740 my $self = shift;
841 1         2 my %args;
842            
843             # handle arguments
844            
845 1 50       3 if (@_) {
846            
847             # array reference
848            
849 1 50 33     9 if (defined $_[0] && UNIVERSAL::isa ($_[0], 'HASH')) {
850            
851 0         0 %args = %{$_[0]};
  0         0  
852            
853             # list of values
854            
855             } else {
856            
857 1         7 %args = @_;
858            
859             }
860            
861             }
862            
863 1 50 33     7 throw WWW::Postini::Exception::InvalidParameter('User ID not specified')
864             unless defined $args{'user_id'} && length $args{'user_id'}
865             ;
866            
867             # set default parameters
868            
869 1 50       3 $args{'recipient'} = RECIPIENT_USER unless defined $args{'recipient'};
870 1 50       3 $args{'mark'} = 1 unless defined $args{'mark'};
871 1 50       5 $args{'clean'} = 1 unless defined $args{'clean'};
872            
873             # handle recipient parameter
874            
875 1         2 my $recipient;
876            
877 1 50       4 if ($args{'recipient'} == RECIPIENT_USER) {
    0          
878            
879 1         2 $recipient = 'user';
880            
881             } elsif ($args{'recipient'} == RECIPIENT_ADMIN) {
882            
883 0         0 $recipient = 'admin';
884            
885             } else {
886            
887 0         0 throw WWW::Postini::Exception::InvalidParameter(
888             'Invalid "recipient" parameter specified'
889             );
890            
891             }
892            
893             # handle messages parameter
894            
895 1         2 my @message_ids;
896            
897 1 50       12 if (defined $args{'messages'}) {
898            
899 1 50       6 if (UNIVERSAL::isa ($args{'messages'}, 'ARRAY')) {
900            
901 1         1 @message_ids = @{$args{'messages'}};
  1         4  
902            
903             } else {
904            
905 0         0 @message_ids = $args{'messages'};
906            
907             }
908            
909             }
910            
911             # no messages passed
912            
913 1 50       4 throw WWW::Postini::Exception::InvalidParameter('No messages specified')
914             unless scalar @message_ids
915             ;
916            
917 1         2 my $message_count;
918            
919             # try
920            
921 1         2 eval {
922            
923 1 50       9 my @args = (
    50          
924             action => 'processQuarantine',
925             targetuserid => $args{'user_id'},
926             submit => 'Process',
927             markdeliver => ($args{'mark'} ? 1 : 0),
928             preclean => ($args{'clean'} ? 1 : 0),
929             deliv_rcpt => $recipient
930             );
931            
932 1         3 foreach my $id (@message_ids) {
933            
934 1         2 push @args, ('msgid', $id);
935            
936             }
937            
938 1         7 my $response = $self->{'_user_agent'}->post(
939             "https://$self->{'_admin_host'}/exec/admin_users",
940             \@args
941             );
942            
943 1         5 assert($response, 'Response returned');
944            
945 1         3 my $code = $response->code();
946 1         10 assert($code == RC_OK, 'Response code is '.RC_OK);
947            
948 1         3 my $content = $response->content();
949 1         12 my $p = new HTML::TokeParser(\$content);
950 1         101 my ($tag, $text);
951            
952 1         4 while (defined ($tag = $p->get_tag('b'))) {
953            
954 1         179 my $text = $p->get_trimmed_text();
955 1 50 33     66 last if defined $text && $text eq 'Message Results';
956            
957             }
958            
959 1         5 $tag = $p->get_tag('font');
960 1         46 assert($tag, 'Font tag exists');
961            
962 1         5 $text = $p->get_trimmed_text();
963 1         59 assert(
964             $text =~ /^\d+ message\(s\) queued for delivery/,
965             'Message text recognized'
966             );
967            
968 1         13 ($message_count) = $text =~ /^(\d+)/;
969            
970             };
971            
972             # catch
973            
974 1 50 33     12 if (defined $@ && (length $@ || ref $@)) {
      33        
975            
976             # unexpected response
977            
978 0 0       0 if (UNIVERSAL::isa($@, 'WWW::Postini::Exception::UnexpectedResponse')) {
979            
980 0         0 $@->rethrow;
981            
982             # all other exceptions
983            
984             } else {
985            
986 0         0 throw WWW::Postini::Exception::UnexpectedResponse($@);
987            
988             }
989            
990             }
991            
992 1         6 $message_count;
993            
994             }
995            
996             # get message field
997            
998             sub _get_message_field {
999            
1000 93     93   3193 my $self = shift;
1001 93         112 my $p = shift;
1002 93         243 my $tag = $p->get_tag ('font');
1003 93         7329 assert ($tag, 'Font tag exists');
1004 93         241 $p->get_trimmed_text;
1005            
1006             }
1007            
1008             1;
1009            
1010             __END__