File Coverage

blib/lib/Net/AWS/SES/Signature4.pm
Criterion Covered Total %
statement 33 150 22.0
branch 0 42 0.0
condition 0 21 0.0
subroutine 11 32 34.3
pod 0 15 0.0
total 44 260 16.9


line stmt bran cond sub pod time code
1             package Net::AWS::SES::Signature4;
2              
3 1     1   69104 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         25  
5 1     1   4 use Carp ('croak');
  1         2  
  1         39  
6 1     1   495 use MIME::Base64;
  1         653  
  1         74  
7 1     1   553 use Time::Piece;
  1         12600  
  1         5  
8 1     1   599 use HTTP::Headers;
  1         4106  
  1         36  
9 1     1   737 use LWP::UserAgent;
  1         36183  
  1         35  
10 1     1   461 use Digest::HMAC_SHA1;
  1         4541  
  1         43  
11 1     1   536 use Net::AWS::SES::Response;
  1         10865  
  1         43  
12 1     1   546 use AWS::Signature4;
  1         17825  
  1         43  
13 1     1   516 use HTTP::Request::Common;
  1         2201  
  1         1653  
14              
15              
16             require Exporter;
17              
18             our @ISA = qw(Exporter);
19              
20             # Items to export into callers namespace by default. Note: do not export
21             # names by default without a very good reason. Use EXPORT_OK instead.
22             # Do not simply export all your public functions/methods/constants.
23              
24             # This allows declaration use Net::AWS::SES::Signature4 ':all';
25             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
26             # will save memory.
27             our %EXPORT_TAGS = ( 'all' => [ qw(
28              
29             ) ] );
30              
31             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
32              
33             our @EXPORT = qw(
34              
35             );
36              
37             our $VERSION = '0.08';
38              
39              
40             # Preloaded methods go here.
41              
42             sub __timestamp {
43 0     0     return localtime->datetime;
44             }
45            
46             sub __signature {
47 0     0     my $self = shift;
48 0           my ($date) = @_;
49 0 0         unless ($date) {
50 0           croak "signature(): usage error";
51             }
52 0           my $hmac = Digest::HMAC_SHA1->new( $self->secret_key );
53 0           $hmac->add($date);
54 0           return encode_base64( $hmac->digest );
55             }
56              
57             sub __user_agent {
58 0     0     my $self = shift;
59 0           my $ua = LWP::UserAgent->new(
60             agent => sprintf( "%s/%s", __PACKAGE__, $VERSION ),
61             default_headers => $self->__header
62             );
63 0           return $ua;
64             }
65              
66             sub __signer {
67 0     0     my $self = shift;
68 0           my $signer = AWS::Signature4->new(-access_key => $self->access_key, -secret_key => $self->secret_key);
69 0           return $signer;
70             }
71              
72             sub __header {
73 0     0     my $self = shift;
74 0           my $h = HTTP::Headers->new;
75 0           $h->date(time);
76 0           $h->header(
77             'Content-type' => 'application/x-www-form-urlencoded',
78             'X-Amzn-Authorization' => sprintf(
79             "AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA1,Signature=%s",
80             $self->access_key, $self->__signature( $h->header('Date') )
81             )
82             );
83 0           return $h;
84             }
85            
86             sub new {
87 0     0 0   my $class = shift;
88 0           my %data = (
89             access_key => '',
90             secret_key => '',
91             region => 'us-east-1',
92             from => '',
93             __user_agent => undef,
94             __response => undef,
95             __signer => undef,
96             @_
97             );
98 0 0 0       unless ( $data{access_key} && $data{secret_key} ) {
99 0           croak "new(): usage error";
100             }
101 0           return bless \%data, $class;
102             }
103            
104             sub DESTROY {
105 0     0     my $self = shift;
106 0           $self->{__response} = undef;
107             }
108              
109             sub response {
110 0     0 0   my $self = shift;
111 0           return $self->{__response};
112             }
113            
114             sub access_key {
115 0     0 0   my $self = shift;
116 0           my ($key) = @_;
117 0 0         return $self->{access_key} unless $key;
118 0           return $self->{access_key} = $key;
119             }
120            
121             sub secret_key {
122 0     0 0   my $self = shift;
123 0           my ($key) = @_;
124 0 0         return $self->{secret_key} unless $key;
125 0           return $self->{secret_key} = $key;
126             }
127            
128             sub region {
129 0     0 0   my $self = shift;
130 0           my ($key) = @_;
131 0 0         return $self->{region} unless $key;
132 0           return $self->{region} = $key;
133             }
134            
135             sub call {
136 0     0 0   my $self = shift;
137 0           my ( $action, $args, $responseClass ) = @_;
138 0 0         unless ($action) {
139 0           croak "call(): usage error";
140             }
141 0           $args->{AWSAccessKeyId} = $self->access_key;
142 0           $args->{Action} = $action;
143 0           $args->{Timestamp} = $self->__timestamp;
144 0           my $ua = LWP::UserAgent->new();
145 0           my $request = POST("https://email." . $self->region . ".amazonaws.com", [$args]);
146 0           my $signer = $self->__signer;
147 0           $signer->sign($request);
148 0           my $response = $ua->request($request);
149 0           return Net::AWS::SES::Response->new( $response, $action );
150             }
151            
152             sub send {
153 0     0 0   my $self = shift;
154 0 0         return $self->send_mime(@_) if ( @_ == 1 );
155 0           my (%args) = @_;
156 0 0         unless ( ref( $args{To} ) ) {
157 0           $args{To} = [ $args{To} ];
158             }
159 0   0       my $from = $args{From} || $self->{from};
160 0 0         unless ($from) {
161 0           croak "send(): usage error";
162             }
163 0 0 0       unless ( $from && ( $args{Body} || $args{Body_html} ) && $args{To} ) {
      0        
      0        
164 0           croak "Usage Error";
165             }
166             my %call_args = (
167             'Message.Subject.Data' => $args{Subject},
168 0           'Message.Subject.Charset' => 'UTF-8',
169             'Source' => $from
170             );
171 0 0         if ( $args{Body} ) {
172 0           $call_args{'Message.Body.Text.Data'} = $args{Body};
173 0           $call_args{'Message.Body.Text.Charset'} = 'UTF-8',;
174             }
175 0 0         if ( $args{Body_html} ) {
176 0           $call_args{'Message.Body.Html.Data'} = $args{Body_html};
177 0           $call_args{'Message.Body.Html.Charset'} = 'UTF-8';
178             }
179 0 0         if ( $args{ReturnPath} ) {
180 0           $call_args{'ReturnPath'} = $args{ReturnPath};
181             }
182 0           for ( my $i = 0 ; $i < @{ $args{To} } ; $i++ ) {
  0            
183 0           my $email = $args{To}->[$i];
184 0           $call_args{ sprintf( 'Destination.ToAddresses.member.%d', $i + 1 ) } =
185             $email;
186             }
187 0           my $r = $self->call( 'SendEmail', \%call_args );
188             } ## end sub send
189            
190             sub verify_email {
191 0     0 0   my ( $self, $email ) = @_;
192 0 0         unless ($email) {
193 0           croak "verify_email(): usage error";
194             }
195 0           return $self->call( 'VerifyEmailIdentity', { EmailAddress => $email } );
196             }
197             *delete_domain = \&delete_identity;
198             *delete_email = \&delete_identity;
199            
200             sub delete_identity {
201 0     0 0   my ( $self, $identity ) = @_;
202 0 0         unless ($identity) {
203 0           croak "delete_identity(): usage error";
204             }
205 0           return $self->call( 'DeleteIdentity', { Identity => $identity } );
206             }
207            
208             sub list_emails {
209 0     0 0   my $self = shift;
210 0           my %args = @_;
211 0           my %call_args = ( IdentityType => 'EmailAddress' );
212 0 0         if ( $args{limit} ) {
213 0           $call_args{MaxItems} = $args{limit};
214             }
215 0 0         if ( $args{offset} ) {
216 0           $call_args{NextToken} = $args{offset};
217             }
218 0           my $r = $self->call( 'ListIdentities', \%call_args );
219             }
220            
221             sub list_domains {
222 0     0 0   my $self = shift;
223 0           my %args = @_;
224 0           my %call_args = ( IdentityType => 'Domain' );
225 0 0         if ( $args{limit} ) {
226 0           $call_args{MaxItems} = $args{limit};
227             }
228 0 0         if ( $args{offset} ) {
229 0           $call_args{NextToken} = $args{offset};
230             }
231 0           my $r = $self->call( 'ListIdentities', \%call_args );
232             }
233            
234             sub get_quota {
235 0     0 0   my $self = shift;
236 0           return $self->call('GetSendQuota');
237             }
238            
239             sub get_statistics {
240 0     0 0   my $self = shift;
241 0           return $self->call('GetSendStatistics');
242             }
243            
244             sub send_mime {
245 0     0 0   my $self = shift;
246 0 0         my $msg = $_[0] if ( @_ == 1 );
247 0 0 0       if ( $msg && ref($msg) && $msg->isa("MIME::Entity") ) {
      0        
248 0           my $r = $self->call( 'SendRawEmail',
249             { 'RawMessage.Data' => encode_base64( $msg->stringify ) } );
250 0           return $r;
251             }
252             }
253            
254             sub get_dkim_attributes {
255 0     0 0   my $self = shift;
256 0           my @identities = @_;
257 0           my %call_args = ();
258 0           for ( my $i = 0 ; $i < @identities ; $i++ ) {
259 0           my $id = $identities[$i];
260 0           $call_args{ 'Identities.member.' . ( $i + 1 ) } = $id;
261             }
262 0           return $self->call( 'GetIdentityDkimAttributes', \%call_args );
263             }
264              
265             1;
266             __END__