Amazon-CloudFront-SignedURL
view release on metacpan or search on metacpan
lib/Amazon/CloudFront/SignedURL.pm view on Meta::CPAN
package Amazon::CloudFront::SignedURL;
use strict;
use warnings;
use Carp;
use Crypt::OpenSSL::RSA;
use Data::Validator;
use MIME::Base64;
use Mouse;
use URI;
our $VERSION = "0.03";
my $validator = Data::Validator->new(
resource => { isa => 'Str', },
expires => {
isa => 'Int',
xor => [qw(policy)],
},
policy => { isa => 'Str', },
);
has private_key_string => (
is => 'rw',
isa => 'Str',
required => 1,
trigger => sub {
$_[0]->clear_private_key;
},
);
has private_key => (
is => 'ro',
isa => 'Crypt::OpenSSL::RSA',
lazy_build => 1,
);
has key_pair_id => (
is => 'rw',
isa => 'Str',
required => 1,
);
sub _build_private_key {
my $private_key;
eval { $private_key = Crypt::OpenSSL::RSA->new_private_key( $_[0]->private_key_string() ); };
if ($@) {
croak "Private Key Error: Maybe your key is invalid. ($@)";
}
$private_key->use_sha1_hash();
return $private_key;
}
sub generate {
my $self = shift;
my $args = $validator->validate(@_);
my $resource = $args->{resource};
my $policy = exists $args->{policy} ? $args->{policy} : undef;
my $expires = exists $args->{expires} ? $args->{expires} : undef;
if ($policy) {
$policy =~ s/ //g;
}
else {
$policy = sprintf( qq/{"Statement":[{"Resource":"%s","Condition":{"DateLessThan":{"AWS:EpochTime":%d}}}]}/,
$resource, $expires );
}
my $encoded_policy = $self->_encode_url_safe_base64($policy);
my $signature = $self->_sign($policy);
return $self->_create_url( $resource, $expires, $encoded_policy, $signature );
}
sub _encode_url_safe_base64 {
my ( $self, $str ) = @_;
my $encoded = encode_base64($str);
$encoded =~ s/\r|\n//g;
$encoded =~ tr|+=/|-_~|;
return $encoded;
}
sub _sign {
my ( $self, $str ) = @_;
my $signature = $self->_encode_url_safe_base64( $self->private_key->sign($str) );
return $signature;
}
sub _create_url {
my ( $self, $resource, $expires, $policy, $signature ) = @_;
my $uri = URI->new($resource);
if ($expires) {
$uri->query_form(
'Expires' => $expires,
'Signature' => $signature,
'Key-Pair-Id' => $self->key_pair_id(),
);
}
else {
$uri->query_form(
'Policy' => $policy,
'Signature' => $signature,
'Key-Pair-Id' => $self->key_pair_id(),
);
}
return $uri->as_string;
}
no Mouse;
__PACKAGE__->meta->make_immutable;
1;
__END__
=encoding utf-8
( run in 1.418 second using v1.01-cache-2.11-cpan-d8267643d1d )