File Coverage

blib/lib/Azure/SAS/Timestamp.pm
Criterion Covered Total %
statement 17 22 77.2
branch 1 4 25.0
condition n/a
subroutine 6 7 85.7
pod 0 3 0.0
total 24 36 66.6


line stmt bran cond sub pod time code
1             package Azure::SAS::Timestamp;
2 3     3   207016 use Moo;
  3         35372  
  3         14  
3 3     3   6316 use Types::Standard qw(Int Str InstanceOf);
  3         231733  
  3         30  
4 3     3   4857 use Time::Piece;
  3         32022  
  3         14  
5 3     3   1831 use Regexp::Common 'time';
  3         8249  
  3         15  
6              
7             our $VERSION = '0.0.3';
8              
9             has time_piece => (
10             is => 'rw',
11             isa => InstanceOf['Time::Piece']
12             );
13              
14             sub sas_time {
15             ## Azure SAS requires time in UTC, but the timestamp must be "Z", not "UTC"
16 6     6 0 3343 my $self = shift;
17 6         146 return $self->time_piece->strftime( '%Y-%m-%dT%TZ' );
18             }
19              
20             sub epoch {
21 0     0 0 0 my $self = shift;
22 0         0 return $self->time_piece->epoch;
23             }
24              
25             around BUILDARGS => sub {
26             my ( $orig, $class, @args ) = @_;
27              
28             my $arg = $args[0];
29              
30             my $time_piece;
31             my $int_check = Int;
32             my $str_check = Str;
33             my $tp_check = InstanceOf['Time::Piece'];
34             my $dt_check = InstanceOf['DateTime'];
35              
36             ## If the argument is an integer, assume it's an epoch stamp.
37             if ( $int_check->check( $arg ) ) {
38             $time_piece = Time::Piece->strptime( $arg, '%s');
39             }
40             elsif ( $str_check->check( $arg ) ) {
41             $time_piece = parse_timestamp_str( $arg );
42             }
43             elsif ( $tp_check->check( $arg ) ) { ## If $arg is a Time::Piece object
44             $time_piece = $arg;
45             }
46             elsif ( $dt_check->check( $arg ) ) {
47             $time_piece = Time::Piece->strptime( $arg->epoch, '%s' );
48             }
49             else {
50             die "Couldn't parse argument to Time::Piece";
51             }
52            
53             return { time_piece => $time_piece }
54              
55             };
56              
57              
58              
59             sub parse_timestamp_str {
60 3     3 0 7 my $str = shift;
61            
62             ## NOTE: It looks like Time::Piece strptime will not support timezone by
63             ## name, so we can't support arguments where the zone is expressed this
64             ## way (for example 2020-05-10T10:00:00CST). It (maybe?) can parse an
65             ## offset. Also, DateTime could (of course) handle this. Of course,
66             ## DateTime will not handle parsing the string as well. For now, we won't
67             ## support alternate time zones.
68 3 50       24 if ( $str =~ /^
69             (?<timestamp> # Start capture $1
70             \d{4} - \d{2} - \d{2} T \d{2}:\d{2} # Matches YYYY-MM-DDTHH:mm
71             (:\d{2})? # Optionally matches :SS
72             )
73             (?<timezone> Z|\w{3})? ## Could have timezone or literal "Z"
74             $/x
75             ) {
76 3         13 return Time::Piece->strptime( $1, '%Y-%m-%dT%T' );
77             }
78              
79 0 0         if ( $str =~ /^\d{4} - \d{2} - \d{2}$/) { ## Matches YYYY-MM-DD
80 0           return Time::Piece->strptime( $str, '%Y-%m-%d' );
81            
82             }
83              
84             else {
85 0           die("$str does not look like an iso8601 datetime");
86             }
87              
88             }
89              
90              
91             1;
92              
93             __END__
94              
95             =head1 NAME
96              
97             Azure::SAS::Timestamp - Creating timestamps for Azure Shared Access Signatures.
98              
99              
100             =head1 SYNOPSIS
101              
102             use Azure::SAS::Timestamp;
103            
104             my $ast;
105              
106             # Using an epoch time stamp
107             $ast = Azure::SAS::Timestamp->new( 1589119719 );
108             print $ast->sas_time; # 2020-05-10T14:08:39Z
109            
110            
111             # Using a DateTime object:
112             use DateTime;
113             $dt = DateTime->new(
114             year => 2020,
115             month => 5,
116             day => 10,
117             hour => 13,
118             minute => 12,
119             second => 0
120             );
121             $ast = Azure::SAS::Timestamp->new( $dt );
122             print $ast->sas_time; # 2020-05-10T13:12:00Z
123            
124             # Using Time::Piece
125             use Time::Piece;
126             my $tp = Time::Piece->strptime( '2020-05-10T13:12:00', '%FT%T');
127             $ast = Azure::SAS::Timestamp->new( $tp );
128             print $ast->sas_time; # 2020-05-10T13:12:00Z
129              
130              
131             =head1 DESCRIPTION
132              
133             Azure::SAS::Timestamp can be used to generate validly formated timestamps to
134             be used when creating an Azure SAS (Shared Access Signature).
135             Azure::SAS::Timestamp supports input as seconds from epoch, L<DateTime> objects
136             and L<Time::Piece> objects.
137              
138             There is only one method, `sas_time`, which is an ISO 8601 format with a 'Z'
139             at the end.
140              
141             The general idea is simply to allow a bit of sugar to avoid having to look up
142             the format to use and the object methods of conversion.
143              
144             =head1 SEE ALSO
145              
146             L<Documentation for Shared Access Signatures
147             |https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas>
148              
149             =head1 LICENSE
150              
151             Copyright (C) Ben Kaufman.
152              
153             This library is free software; you can redistribute it and/or modify it under
154             the same terms as Perl itself.
155              
156             =head1 AUTHOR
157              
158             Ben Kaufman (WHOSGONNA) ben.whosgonna.com@gmail.com
159              
160              
161