File Coverage

blib/lib/Net/Azure/Authorization/SAS.pm
Criterion Covered Total %
statement 51 51 100.0
branch 6 6 100.0
condition 1 3 33.3
subroutine 13 13 100.0
pod 2 2 100.0
total 73 75 97.3


line stmt bran cond sub pod time code
1             package Net::Azure::Authorization::SAS;
2 2     2   96370 use 5.008001;
  2         21  
3 2     2   14 use strict;
  2         5  
  2         53  
4 2     2   12 use warnings;
  2         6  
  2         120  
5              
6             our $VERSION = "0.03";
7             our $DEFAULT_TOKEN_EXPIRE = 3600;
8              
9 2     2   27 use Carp;
  2         6  
  2         145  
10 2     2   1266 use URI;
  2         15559  
  2         79  
11 2     2   17 use URI::Escape 'uri_escape';
  2         6  
  2         128  
12 2     2   1255 use Digest::SHA 'hmac_sha256';
  2         8054  
  2         203  
13 2     2   1106 use MIME::Base64 'encode_base64';
  2         1515  
  2         137  
14 2     2   1041 use String::CamelCase 'decamelize';
  2         1306  
  2         166  
15             use Class::Accessor::Lite (
16 2         18 new => 0,
17             ro => [qw[
18             connection_string
19             endpoint
20             shared_access_key_name
21             shared_access_key
22             entity_path
23             expire
24             ]],
25 2     2   1165 );
  2         3867  
26              
27             sub new {
28 3     3 1 9486 my ($class, %param) = @_;
29 3   33     26 $param{expire} ||= $DEFAULT_TOKEN_EXPIRE;
30 3 100       13 if (defined($param{connection_string})) {
31 1         8 %param = (%param, $class->_parse_connection_string($param{connection_string}));
32             }
33 3         74 for my $key (qw(endpoint shared_access_key_name shared_access_key)) {
34 7 100       54 if (!defined($param{$key})) {
35 1         23 croak "$key was not specified. Please specify $key or connection_string.";
36             }
37             }
38 2         18 bless {%param}, $class;
39             }
40              
41             sub _parse_connection_string {
42 1     1   4 my ($class, $string) = @_;
43 1         7 my %parsed = (map {split '=', $_, 2} split(';', $string));
  4         18  
44 1         6 ( map {(decamelize($_) => $parsed{$_})} keys %parsed );
  4         181  
45             }
46              
47             sub token {
48 2     2 1 10202 my ($self, $url) = @_;
49 2 100       23 croak 'An url for token is required' if !defined $url;
50 1         9 my $uri = URI->new($url);
51 1         11207 my $target_uri = lc(uri_escape(lc(sprintf("%s://%s%s", $uri->scheme, $uri->host, $uri->path))));
52 1         311 my $expire_time = time + $self->expire;
53 1         23 my $to_sign = "$target_uri\n$expire_time";
54 1         6 my $signature = encode_base64(hmac_sha256($to_sign, $self->shared_access_key));
55 1         43 chomp $signature;
56 1         4 sprintf 'SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s', $target_uri, uri_escape($signature), $expire_time, $self->shared_access_key_name;
57             }
58              
59             1;
60             __END__