lol
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v206 291 lines 9.9 kB view raw
1commit 4afa16864ac8ae23a450abf95db023b0c8bea698 2Author: Shea Levy <shea@shealevy.com> 3Date: Thu Aug 29 07:09:34 2013 -0400 4 5 Use CredentialsProviders à la the Java API 6 7 Signed-off-by: Shea Levy <shea@shealevy.com> 8 9diff --git a/lib/Net/Amazon/Auth/CredentialsProvider.pm b/lib/Net/Amazon/Auth/CredentialsProvider.pm 10new file mode 100755 11index 0000000..527acae 12--- /dev/null 13+++ b/lib/Net/Amazon/Auth/CredentialsProvider.pm 14@@ -0,0 +1,9 @@ 15+package Net::Amazon::Auth::CredentialsProvider; 16+ 17+use Moose::Role 0.85; 18+ 19+requires 'get_credentials'; 20+ 21+sub refresh { } 22+ 23+1; 24diff --git a/lib/Net/Amazon/Auth/CredentialsProviderChain.pm b/lib/Net/Amazon/Auth/CredentialsProviderChain.pm 25new file mode 100755 26index 0000000..85cd8e0 27--- /dev/null 28+++ b/lib/Net/Amazon/Auth/CredentialsProviderChain.pm 29@@ -0,0 +1,41 @@ 30+package Net::Amazon::Auth::CredentialsProviderChain; 31+ 32+use Moose 0.85; 33+use MooseX::StrictConstructor 0.16; 34+use Net::Amazon::Auth::EnvironmentVariableCredentialsProvider; 35+use Net::Amazon::Auth::InstanceProfileCredentialsProvider; 36+ 37+with 'Net::Amazon::Auth::CredentialsProvider'; 38+ 39+has 'providers' => ( is => 'ro', isa => 'ArrayRef[Net::Amazon::Auth::CredentialsProvider]', required => 1 ); 40+ 41+sub refresh { 42+ my $self = shift; 43+ 44+ map { $_->refresh } @{$self->providers}; 45+} 46+ 47+sub get_credentials { 48+ my $self = shift; 49+ 50+ foreach my $provider (@{$self->providers}) { 51+ my $res = $provider->get_credentials; 52+ if (defined $res->{access_key_id}) { 53+ return $res; 54+ } 55+ } 56+ 57+ return {}; 58+} 59+ 60+sub default_chain { 61+ my $class = shift; 62+ return $class->new(providers => [ 63+ Net::Amazon::Auth::EnvironmentVariableCredentialsProvider->new, 64+ Net::Amazon::Auth::InstanceProfileCredentialsProvider->new 65+ ]); 66+} 67+ 68+__PACKAGE__->meta->make_immutable; 69+ 70+1; 71diff --git a/lib/Net/Amazon/Auth/EnvironmentVariableCredentialsProvider.pm b/lib/Net/Amazon/Auth/EnvironmentVariableCredentialsProvider.pm 72new file mode 100755 73index 0000000..ac38a84 74--- /dev/null 75+++ b/lib/Net/Amazon/Auth/EnvironmentVariableCredentialsProvider.pm 76@@ -0,0 +1,26 @@ 77+package Net::Amazon::Auth::EnvironmentVariableCredentialsProvider; 78+ 79+use Moose 0.85; 80+use MooseX::StrictConstructor 0.16; 81+ 82+extends 'Net::Amazon::Auth::FixedCredentialsProvider'; 83+ 84+around BUILDARGS => sub { 85+ my $orig = shift; 86+ my $class = shift; 87+ 88+ my %args = ( 89+ access_key_id => $ENV{AWS_ACCESS_KEY_ID}, 90+ secret_access_key => $ENV{AWS_SECRET_ACCESS_KEY} 91+ ); 92+ 93+ if (exists $ENV{AWS_SESSION_TOKEN}) { 94+ $args{session_token} = $ENV{AWS_SESSION_TOKEN}; 95+ } 96+ 97+ return $class->$orig(\%args); 98+}; 99+ 100+__PACKAGE__->meta->make_immutable; 101+ 102+1; 103diff --git a/lib/Net/Amazon/Auth/FixedCredentialsProvider.pm b/lib/Net/Amazon/Auth/FixedCredentialsProvider.pm 104new file mode 100755 105index 0000000..21d56c7 106--- /dev/null 107+++ b/lib/Net/Amazon/Auth/FixedCredentialsProvider.pm 108@@ -0,0 +1,23 @@ 109+package Net::Amazon::Auth::FixedCredentialsProvider; 110+ 111+use Moose 0.85; 112+use MooseX::StrictConstructor 0.16; 113+ 114+with 'Net::Amazon::Auth::CredentialsProvider'; 115+ 116+has 'access_key_id' => ( is => 'ro', isa => 'Maybe[Str]', required => 1 ); 117+has 'secret_access_key' => ( is => 'ro', isa => 'Maybe[Str]', required => 1 ); 118+has 'session_token' => ( is => 'ro', isa => 'Maybe[Str]', required => 0 ); 119+ 120+sub get_credentials { 121+ my $self = shift; 122+ return { 123+ access_key_id => $self->access_key_id, 124+ secret_access_key => $self->secret_access_key, 125+ session_token => $self->session_token 126+ }; 127+} 128+ 129+__PACKAGE__->meta->make_immutable; 130+ 131+1; 132diff --git a/lib/Net/Amazon/Auth/InstanceProfileCredentialsProvider.pm b/lib/Net/Amazon/Auth/InstanceProfileCredentialsProvider.pm 133new file mode 100755 134index 0000000..b9f826a 135--- /dev/null 136+++ b/lib/Net/Amazon/Auth/InstanceProfileCredentialsProvider.pm 137@@ -0,0 +1,57 @@ 138+package Net::Amazon::Auth::InstanceProfileCredentialsProvider; 139+ 140+use Moose 0.85; 141+use MooseX::StrictConstructor 0.16; 142+use HTTP::Date; 143+use JSON; 144+ 145+with 'Net::Amazon::Auth::CredentialsProvider'; 146+ 147+has '_ua' => ( is => 'rw', isa => 'LWP::UserAgent', required => 0 ); 148+has '_access_key_id' => ( is => 'rw', isa => 'Str', required => 0 ); 149+has '_secret_access_key' => ( is => 'rw', isa => 'Str', required => 0 ); 150+has '_session_token' => ( is => 'rw', isa => 'Str', required => 0 ); 151+has '_expiration_date' => ( is => 'rw', isa => 'Int', required => 0, default => 0 ); 152+ 153+sub BUILD { 154+ my $self = shift; 155+ my $ua = LWP::UserAgent->new; 156+ $ua->timeout(10); 157+ $self->_ua($ua); 158+} 159+ 160+sub refresh { 161+ my $self = shift; 162+ 163+ my $role_name_response = 164+ $self->_ua->get("http://169.254.169.254/latest/meta-data/iam/security-credentials/"); 165+ if ($role_name_response->code == 200) { 166+ my $credentials_response = $self->_ua->get("http://169.254.169.254/latest/meta-data/iam/security-credentials/" . $role_name_response->content); 167+ 168+ if ($credentials_response->code == 200) { 169+ my $credentials = decode_json($credentials_response->content); 170+ $self->_expiration_date(str2time($credentials->{Expiration})); 171+ $self->_access_key_id($credentials->{AccessKeyId}); 172+ $self->_secret_access_key($credentials->{SecretAccessKey}); 173+ $self->_session_token($credentials->{Token}); 174+ } 175+ } 176+} 177+ 178+sub get_credentials { 179+ my $self = shift; 180+ 181+ if (time() - $self->_expiration_date > -5 * 60) { #Credentials available 5 minutes before expiry 182+ $self->refresh; 183+ } 184+ 185+ return { 186+ access_key_id => $self->_access_key_id, 187+ secret_access_key => $self->_secret_access_key, 188+ session_token => $self->_session_token 189+ }; 190+} 191+ 192+__PACKAGE__->meta->make_immutable; 193+ 194+1; 195diff --git a/lib/Net/Amazon/S3.pm b/lib/Net/Amazon/S3.pm 196index 907113e..a369e4b 100755 197--- a/lib/Net/Amazon/S3.pm 198+++ b/lib/Net/Amazon/S3.pm 199@@ -133,9 +133,10 @@ use LWP::UserAgent::Determined; 200 use URI::Escape qw(uri_escape_utf8); 201 use XML::LibXML; 202 use XML::LibXML::XPathContext; 203+use Net::Amazon::Auth::FixedCredentialsProvider; 204+use Net::Amazon::Auth::CredentialsProviderChain; 205 206-has 'aws_access_key_id' => ( is => 'ro', isa => 'Str', required => 1 ); 207-has 'aws_secret_access_key' => ( is => 'ro', isa => 'Str', required => 1 ); 208+has 'credentials_provider' => ( is => 'ro', isa => 'Net::Amazon::Auth::CredentialsProvider', required => 0, default => sub { return Net::Amazon::Auth::CredentialsProviderChain->default_chain; } ); 209 has 'secure' => ( is => 'ro', isa => 'Bool', required => 0, default => 0 ); 210 has 'timeout' => ( is => 'ro', isa => 'Num', required => 0, default => 30 ); 211 has 'retry' => ( is => 'ro', isa => 'Bool', required => 0, default => 0 ); 212@@ -144,7 +145,23 @@ has 'libxml' => ( is => 'rw', isa => 'XML::LibXML', required => 0 ); 213 has 'ua' => ( is => 'rw', isa => 'LWP::UserAgent', required => 0 ); 214 has 'err' => ( is => 'rw', isa => 'Maybe[Str]', required => 0 ); 215 has 'errstr' => ( is => 'rw', isa => 'Maybe[Str]', required => 0 ); 216-has 'aws_session_token' => ( is => 'ro', isa => 'Str', required => 0 ); 217+ 218+around BUILDARGS => sub { 219+ my $orig = shift; 220+ my $class = shift; 221+ 222+ my $args = $class->$orig(@_); 223+ 224+ if (exists $args->{aws_access_key_id}) { 225+ $args->{credentials_provider} = Net::Amazon::Auth::FixedCredentialsProvider->new({ 226+ access_key_id => $args->{aws_access_key_id}, 227+ secret_access_key => $args->{aws_secret_access_key}, 228+ session_token => $args->{aws_session_token} 229+ }); 230+ delete @{$args}{qw(aws_access_key_id aws_secret_access_key aws_session_token)}; 231+ } 232+ return $args; 233+}; 234 235 __PACKAGE__->meta->make_immutable; 236 237@@ -223,6 +240,24 @@ sub BUILD { 238 239 $self->ua($ua); 240 $self->libxml( XML::LibXML->new ); 241+ 242+ die "No AWS credentials found!" unless defined $self->credentials_provider->get_credentials->{access_key_id}; 243+} 244+ 245+# Backwards compatibility 246+sub aws_access_key_id { 247+ my $self = shift; 248+ return $self->credentials_provider->get_credentials->{access_key_id}; 249+} 250+ 251+sub aws_secret_access_key { 252+ my $self = shift; 253+ return $self->credentials_provider->get_credentials->{secret_access_key}; 254+} 255+ 256+sub aws_session_token { 257+ my $self = shift; 258+ return $self->credentials_provider->get_credentials->{session_token}; 259 } 260 261 =head2 buckets 262diff --git a/lib/Net/Amazon/S3/HTTPRequest.pm b/lib/Net/Amazon/S3/HTTPRequest.pm 263index 69c6327..d49e95b 100755 264--- a/lib/Net/Amazon/S3/HTTPRequest.pm 265+++ b/lib/Net/Amazon/S3/HTTPRequest.pm 266@@ -63,8 +63,9 @@ sub query_string_authentication_uri { 267 my $path = $self->path; 268 my $headers = $self->headers; 269 270- my $aws_access_key_id = $self->s3->aws_access_key_id; 271- my $aws_secret_access_key = $self->s3->aws_secret_access_key; 272+ my $creds = $self->s3->credentials_provider->get_credentials; 273+ my $aws_access_key_id = $creds->{access_key_id}; 274+ my $aws_secret_access_key = $creds->{secret_access_key}; 275 my $canonical_string 276 = $self->_canonical_string( $method, $path, $headers, $expires ); 277 my $encoded_canonical 278@@ -86,9 +87,10 @@ sub query_string_authentication_uri { 279 280 sub _add_auth_header { 281 my ( $self, $headers, $method, $path ) = @_; 282- my $aws_access_key_id = $self->s3->aws_access_key_id; 283- my $aws_secret_access_key = $self->s3->aws_secret_access_key; 284- my $aws_session_token = $self->s3->aws_session_token; 285+ my $creds = $self->s3->credentials_provider->get_credentials; 286+ my $aws_access_key_id = $creds->{access_key_id}; 287+ my $aws_secret_access_key = $creds->{secret_access_key}; 288+ my $aws_session_token = $creds->{session_token}; 289 290 if ( not $headers->header('Date') ) { 291 $headers->header( Date => time2str(time) );