File Coverage

blib/lib/Armadito/Agent/HTTP/Client/ArmaditoAV.pm
Criterion Covered Total %
statement 51 115 44.3
branch 0 28 0.0
condition 0 12 0.0
subroutine 17 29 58.6
pod 3 6 50.0
total 71 190 37.3


line stmt bran cond sub pod time code
1             package Armadito::Agent::HTTP::Client::ArmaditoAV;
2              
3 3     3   11566767 use strict;
  3         7  
  3         86  
4 3     3   12 use warnings;
  3         4  
  3         105  
5 3     3   21 use base 'Armadito::Agent::HTTP::Client';
  3         25  
  3         853  
6              
7 3     3   14 use English qw(-no_match_vars);
  3         3  
  3         15  
8 3     3   1041 use HTTP::Request;
  3         5  
  3         30  
9 3     3   1172 use HTTP::Request::Common qw{ POST };
  3         3843  
  3         126  
10 3     3   13 use UNIVERSAL::require;
  3         4  
  3         15  
11 3     3   51 use URI;
  3         17  
  3         19  
12 3     3   1035 use Encode;
  3         15726  
  3         216  
13 3     3   1382 use Data::Dumper;
  3         10695  
  3         157  
14 3     3   15 use URI::Escape;
  3         4  
  3         160  
15 3     3   13 use JSON;
  3         7  
  3         52  
16              
17 3     3   1739 use Armadito::Agent::HTTP::Client::ArmaditoAV::Event;
  3         4  
  3         32  
18 3     3   1383 use Armadito::Agent::HTTP::Client::ArmaditoAV::Event::DetectionEvent;
  3         5  
  3         18  
19 3     3   1367 use Armadito::Agent::HTTP::Client::ArmaditoAV::Event::OnDemandCompletedEvent;
  3         4  
  3         41  
20 3     3   1449 use Armadito::Agent::HTTP::Client::ArmaditoAV::Event::OnDemandProgressEvent;
  3         5  
  3         20  
21 3     3   1387 use Armadito::Agent::HTTP::Client::ArmaditoAV::Event::StatusEvent;
  3         6  
  3         18  
22              
23             my @supported_events = ( "DetectionEvent", "OnDemandCompletedEvent", "OnDemandProgressEvent", "StatusEvent" );
24              
25             sub new {
26 0     0 1   my ( $class, %params ) = @_;
27 0           my $self = $class->SUPER::new(%params);
28              
29 0           $self->{taskobj} = $params{taskobj};
30 0           $self->{server_url} = "http://localhost:8888";
31              
32 0           return $self;
33             }
34              
35             sub _prepareURL {
36 0     0     my ( $self, %params ) = @_;
37              
38 0 0         my $url = ref $params{url} eq 'URI' ? $params{url} : URI->new( $params{url} );
39              
40 0           return $url;
41             }
42              
43             sub sendRequest {
44 0     0 1   my ( $self, %params ) = @_;
45              
46 0           my $url = $self->_prepareURL(%params);
47              
48 0 0         $self->{logger}->debug2($url) if $self->{logger};
49              
50 0           my $headers = HTTP::Headers->new(
51             'User-Agent' => 'armadito-agent',
52             'Referer' => $url
53             );
54              
55 0 0         $headers->header( 'Content-Type' => 'application/json' ) if ( $params{method} eq 'POST' );
56 0 0         $headers->header( 'X-Armadito-Token' => $self->{token} ) if ( defined( $self->{token} ) );
57              
58             my $request = HTTP::Request->new(
59 0           $params{method} => $url,
60             $headers
61             );
62              
63 0 0 0       if ( $params{message} && $params{method} eq 'POST' ) {
64 0           $request->content( encode( 'UTF-8', $params{message} ) );
65             }
66              
67 0           return $self->request($request);
68             }
69              
70             sub _handleRegisterResponse() {
71 0     0     my ( $self, $response ) = @_;
72              
73 0           $self->{logger}->info( $response->content() );
74 0           my $obj = from_json( $response->content(), { utf8 => 1 } );
75              
76             # Update armadito agent_id
77 0 0         if ( defined( $obj->{token} ) ) {
78 0           $self->{token} = $obj->{token};
79 0           $self->{logger}->info( "ArmaditAV Registration successful, session token : " . $obj->{token} );
80             }
81             else {
82 0           $self->{logger}->error("Invalid token from ArmaditAV registration.");
83             }
84             }
85              
86             sub register {
87 0     0 1   my ($self) = @_;
88              
89             my $response = $self->sendRequest(
90 0           "url" => $self->{server_url} . "/api/register",
91             method => "GET"
92             );
93              
94 0 0 0       die "Unable to register to ArmaditoAV api." if ( !$response->is_success() || !$response->content() =~ /^\s*\{/ms );
95 0           $self->_handleRegisterResponse($response);
96 0           return $self;
97             }
98              
99             sub unregister {
100 0     0 0   my ($self) = @_;
101              
102             my $response = $self->sendRequest(
103 0           "url" => $self->{server_url} . "/api/unregister",
104             method => "GET"
105             );
106              
107 0 0         die "Unable to unregister to ArmaditoAV api." if ( !$response->is_success() );
108 0           return $self;
109             }
110              
111             sub _handleJsonResponse() {
112 0     0     my ( $self, $response ) = @_;
113              
114 0           $self->{logger}->debug( $response->content() );
115              
116 0           return from_json( $response->content(), { utf8 => 1 } );
117             }
118              
119             sub pollEvents {
120 0     0 0   my ($self) = @_;
121 0           while (1) {
122 0           my $event = $self->_getEvent();
123 0 0         if ( defined( $event->{"event_type"} ) ) {
124 0 0         last if $self->_handleEvent($event); # return endpolling flag
125             }
126             }
127             }
128              
129             sub _getEvent {
130 0     0     my ($self) = @_;
131              
132             my $response = $self->sendRequest(
133 0           "url" => $self->{server_url} . "/api/event",
134             method => "GET"
135             );
136              
137 0 0 0       die "Unable to get event with ArmaditoAV api."
138             if ( !$response->is_success() || !$response->content() =~ /^\s*\{/ms );
139 0           return $self->_handleJsonResponse($response);
140             }
141              
142             sub getAntivirusVersion {
143 0     0 0   my ($self) = @_;
144              
145             my $response = $self->sendRequest(
146 0           "url" => $self->{server_url} . "/api/version",
147             method => "GET"
148             );
149              
150 0 0 0       die "Unable to get Armadito version with ArmaditoAV api."
151             if ( !$response->is_success() || !$response->content() =~ /^\s*\{/ms );
152 0           return $self->_handleJsonResponse($response);
153             }
154              
155             sub _isEventSupported {
156 0     0     my ( $self, $event ) = @_;
157 0           foreach (@supported_events) {
158 0 0         if ( $event eq $_ ) {
159 0           return 1;
160             }
161             }
162 0           return 0;
163             }
164              
165             sub _handleEvent {
166 0     0     my ( $self, $event_jobj ) = @_;
167              
168 0 0         if ( !$self->_isEventSupported( $event_jobj->{"event_type"} ) ) {
169 0           $self->{logger}->info("Unknown ArmaditoAV api event.");
170 0           return 0;
171             }
172              
173 0           my $class = "Armadito::Agent::HTTP::Client::ArmaditoAV::Event::$event_jobj->{'event_type'}";
174 0           $class->require();
175 0           my $event = $class->new( jobj => $event_jobj, taskobj => $self->{taskobj} );
176 0           $event->run();
177              
178 0           return $event->{"end_polling"};
179             }
180              
181             1;
182             __END__
183              
184             =head1 NAME
185              
186             Armadito::Agent::HTTP::Client::ArmaditoAV - HTTP Client for armadito AV RESTful API.
187              
188             =head1 DESCRIPTION
189              
190             This is the class used by Armadito agent to communicate with armadito antivirus locally.
191              
192             =head1 METHODS
193              
194             =head2 $client->register()
195              
196             Register to Armadito Antivirus API And set token after parsing AV json response.
197              
198             =head2 $client->sendRequest(%params)
199              
200             Send a request according to params given. If this is a GET request, params are formatted into URL with _prepareURL method. If this is a POST request, a message must be given in params. This should be a valid JSON message.
201              
202             The following parameters are allowed, as keys of the %params hash :
203              
204             =over
205              
206             =item I<url>
207              
208             the url to send the message to (mandatory)
209              
210             =item I<method>
211              
212             the method used: GET or POST. (mandatory)
213              
214             =item I<message>
215              
216             the message to send (mandatory if method is POST)
217              
218             =back
219              
220             The return value is a response object. See L<HTTP::Request> and L<HTTP::Response> for a description of the interface provided by these classes.