File Coverage

blib/lib/Mojolicious/Plugin/AutoSecrets.pm
Criterion Covered Total %
statement 44 46 95.6
branch 4 10 40.0
condition 10 25 40.0
subroutine 8 8 100.0
pod 2 2 100.0
total 68 91 74.7


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::AutoSecrets;
2             # ABSTRACT: Automatic, Rotating Mojolicious Secrets
3              
4              
5 1     1   2000 use Mojo::Base 'Mojolicious::Plugin';
  1         2  
  1         7  
6 1     1   303 use Mojo::Util qw(sha1_sum);
  1         4  
  1         98  
7 1     1   18 use Mojo::JSON qw(encode_json decode_json);
  1         4  
  1         81  
8 1     1   10 use Carp qw(croak);
  1         3  
  1         77  
9 1     1   9 use Fcntl qw(:DEFAULT :flock);
  1         4  
  1         716  
10 1     1   910 use autodie;
  1         16439  
  1         5  
11              
12             our $VERSION = '0.01';
13              
14              
15             sub register {
16 1     1 1 66 my ($self, $app, $config) = @_;
17 1   50     7 $config //= {};
18              
19 1   33     4 my $path = $config->{path} // $app->home->rel_file('.mojo-secrets');
20 1   50     8 my $mode = $config->{mode} // 0600;
21 1   50     5 my $expire_days = $config->{expire_days} // 60;
22 1   50     6 my $prune = $config->{prune} // 3;
23 1   50     5 my $generator = $config->{generator} // \&generator;
24              
25 1         2 my @secrets;
26              
27 1         5 sysopen my $fh, $path, O_RDWR | O_CREAT, $mode;
28 1         1828 flock $fh, LOCK_EX;
29              
30 1         319 my $rv;
31 1         3 my $disk = '';
32 1         12 while ($rv = $fh->sysread(my $buf, 4096, 0)) { $disk .= $buf }
  0         0  
33 1 50       27 croak "Can't read from $path: $!"
34             if !defined $rv;
35              
36 1   33     5 my $disk_secrets = $disk && decode_json($disk);
37              
38 1 50       4 unshift @secrets, @$disk_secrets
39             if $disk_secrets;
40              
41 1 0 33     5 if (!@secrets || -z $path || -M _ > $expire_days) {
      33        
42 1         3 unshift @secrets, $generator->();
43              
44 1 50 33     9 @secrets = @secrets[0 .. $prune - 1]
45             if $prune && @secrets > $prune;
46              
47 1         14 $fh->seek(0, 0);
48 1         17 $fh->syswrite(my $j = encode_json(\@secrets));
49             }
50 1         308 flock $fh, LOCK_UN;
51 1         48 $fh->close;
52              
53 0         0 push @secrets, @{$app->{secrets}}
54 1 50       17 if $app->{secrets};
55              
56 1         11 $app->secrets(\@secrets);
57             }
58              
59              
60             sub generator {
61 1     1 1 85 sha1_sum(join '', rand(1000) x 2, $$, localtime)
62             }
63              
64              
65              
66             1;
67              
68             __END__