File Coverage

blib/lib/Net/AWS/SES/Signature4.pm
Criterion Covered Total %
statement 35 152 23.0
branch 0 42 0.0
condition 0 21 0.0
subroutine 12 33 36.3
pod 0 15 0.0
total 47 263 17.8


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