File Coverage

blib/lib/Net/OAuth2/Scheme/Mixin/Current_Secret.pm
Criterion Covered Total %
statement 13 13 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 18 100.0


line stmt bran cond sub pod time code
1 1     1   612 use warnings;
  1         2  
  1         23  
2 1     1   5 use strict;
  1         2  
  1         41  
3              
4             package Net::OAuth2::Scheme::Mixin::Current_Secret;
5             BEGIN {
6 1     1   21 $Net::OAuth2::Scheme::Mixin::Current_Secret::VERSION = '0.03';
7             }
8             # ABSTRACT: the 'current_secret' option group
9              
10 1     1   4 use Net::OAuth2::Scheme::Option::Defines;
  1         2  
  1         44  
11 1     1   615 use Net::OAuth2::Scheme::Random;
  1         3  
  1         8  
12              
13             # INTERFACE current_secret
14             # DEFINES
15             # current_secret => [v_id, secret, expiration, @secret_payload]
16             # current_secret_rekey_check => now -> ; (generate new secret if necessary)
17             # SUMMARY
18             # maintain a current secret for use by format_bearer_signed
19             #
20             Define_Group current_secret => 'simple',
21             qw(current_secret current_secret_rekey_check);
22              
23             Default_Value current_secret_rekey_interval => 86400*7; # 7 days
24             Default_Value current_secret_payload => [];
25              
26             # IMPLEMENTATION current_secret_simple FOR current_secret
27             # (current_secret_)rekey_interval
28             # (current_secret_)length
29             # (current_secret_)payload
30             # SUMMARY
31             # secret lifetime = 2*rekey_interval;
32             # change the secret whenever we are within rekey_interval of expiration;
33             # prior secrets remain available from the cache until they expire
34             # REQUIRES
35             # v_id_next
36             # vtable_insert
37             # random
38             #
39             # rekey_interval should be set to be at least as long as the
40             # longest anticipated lifetime for tokens generated using this secret
41             # as needed, there will generally be 2 secret keys active,
42             # and, for every token issued from a given key, the secret for it
43             # will remain available for at least rekey_interval seconds after issuance, so as long as
44             # is longer the token lifetime, the token will never be prematurely
45             # expired.
46             # Note that for reliable repudiation of secrets, you need to be using
47             # a shared-cache vtable
48             sub pkg_current_secret_simple {
49             my __PACKAGE__ $self = shift;
50             $self->parameter_prefix(current_secret_ => @_);
51             my ( $random, $vtable_insert,
52             $rekey_interval, $length, $payload)
53             = $self->uses_all
54             (qw(random vtable_insert
55             current_secret_rekey_interval
56             current_secret_length
57             current_secret_payload));
58              
59             my @stashed = (undef, undef, 0, @$payload);
60              
61             my $v_id_next = $self->uses('v_id_next');
62              
63             $self->install( current_secret => \@stashed );
64             $self->install( current_secret_rekey_check => sub {
65             my ($now) = @_;
66             my (undef, undef, $expiration) = @stashed;
67             if ($expiration < $now + $rekey_interval) {
68             my ($v_id, $new_secret, $new_expiration) =
69             @stashed = ($v_id_next->(),
70             $random->($length),
71             $now + 2 * $rekey_interval,
72             @$payload);
73             $vtable_insert->($v_id,
74             $new_expiration, $now, $new_secret,
75             @$payload);
76             }
77             });
78             return $self;
79             }
80              
81              
82             1;
83              
84              
85             __END__