File Coverage

blib/lib/Dancer2/Plugin/CryptPassphrase.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             package Dancer2::Plugin::CryptPassphrase;
2 1     1   59172 use strict;
  1         3  
  1         27  
3 1     1   5 use warnings;
  1         1  
  1         41  
4              
5             our $VERSION = '0.001';
6             $VERSION = eval $VERSION;
7              
8 1     1   475 use Dancer2::Plugin;
  1         248167  
  1         13  
9 1     1   42784 use Crypt::Passphrase;
  1         27176  
  1         57  
10 1         22 use Types::Standard qw(
11             ArrayRef
12             HashRef
13             InstanceOf
14             Str
15 1     1   14 );
  1         2  
16              
17             # CONFIG
18              
19             has encoder => (
20             is => 'ro',
21             isa => HashRef | Str,
22             from_config => sub {'Argon2'},
23             );
24              
25             has validators => (
26             is => 'ro',
27             isa => ArrayRef [ HashRef | Str ],
28             from_config => sub { [] },
29             );
30              
31             # KEYWORDS
32              
33             has crypt_passphrase => (
34             is => 'ro',
35             isa => InstanceOf ['Crypt::Passphrase'],
36             lazy => 1,
37             default => sub {
38             my $plugin = shift;
39             return Crypt::Passphrase->new(
40             encoder => $plugin->encoder,
41             validators => $plugin->validators,
42             );
43             },
44             handles => {
45             hash_password => 'hash_password',
46             password_needs_rehash => 'needs_rehash',
47             verify_password => 'verify_password',
48             },
49             );
50              
51             plugin_keywords qw(
52             crypt_passphrase
53             hash_password
54             password_needs_rehash
55             verify_password
56             );
57              
58             1;
59              
60             =head1 NAME
61              
62             Dancer2::Plugin::CryptPassphrase - use Crypt::Passphrase with Dancer2
63              
64             =head1 SYNOPSIS
65              
66             package My::App;
67             use Dancer2;
68             use Dancer2::Plugin::CryptPassphrase;
69              
70             post '/login' => sub {
71             my $username = body_parameters->get('username');
72             my $password = body_parameters->get('password');
73             my $hash = my_get_hash_function($username);
74              
75             if ( verify_password( $password, $hash ) ) {
76             # login success
77              
78             if ( password_needs_rehash($hash) ) {
79             # upgrade hash in storage
80             my_update_hash_function( $username, hash_password($pasword) );
81             }
82              
83             # ... do stuff
84             }
85             else {
86             # login failed
87              
88             # ... do stuff
89             }
90             };
91              
92             =head1 DESCRIPTION
93              
94             This plugin integrates L<Crypt::Passphrase> with your L<Dancer2> app,
95              
96             See L<Prometheus::Tiny> for more details of the kind of metrics supported.
97              
98             =head1 KEYWORDS
99              
100             =head2 crypt_passphrase
101              
102             Returns the C<Crypt::Passphrase> instance.
103              
104             =head2 hash_password $password
105              
106             Returns a new hash for the given C<$password>.
107              
108             See also L<Crypt::Password/hash_password>.
109              
110             =head2 password_needs_rehash $hash
111              
112             Returns a true value if C<$hash> should be upgraded to use the current
113             L</encoder>.
114              
115             See also L<Crypt::Password/needs_rehash>.
116              
117             =head2 verify_password $password, $hash
118              
119             Returns a true value if the C<$password> matches the given C<$hash>,
120             otherwise returns a false value.
121              
122             See also L<Crypt::Password/verify_password>.
123              
124             =head1 CONFIGURATION
125              
126             Example:
127              
128             plugins:
129             CryptPassphrase:
130             encoder:
131             module: Argon2
132             parallelism: 2
133             validators:
134             - +My::Old::Passphrase::Module
135             - Bcrypt
136              
137             Configuration options are used as the arguments for L<Crypt::Passphrase/new>,
138             as follows:
139              
140             =head2 encoder
141              
142             Default: C<Argon2> with defaults from L<Crypt::Passphrase::Argon2>.
143              
144             This can be one of two different things:
145              
146             =over
147              
148             =item * A simple string
149              
150             The name of the encoder class. If the value starts with a C<+>, the C<+> will
151             be removed and the remainder will be taken as a fully-qualified package name.
152             Otherwise, C<Crypt::Passphrase::> will be prepended to the value.
153              
154             The class will be loaded, and constructed without arguments.
155              
156             =item * A hash
157              
158             The C<module> entry will be used to load a new L<Crypt::Passphrase> module as
159             described above, the other arguments will be passed to the constructor. This
160             is the recommended option, as it gives you full control over the password
161             parameters.
162              
163             =back
164              
165             B<NOTE:> If you wish to use an encoder other than C<Argon2>, then you
166             need to install the appropriate C<Crypt::Passphrase::> module.
167              
168             =head2 validators
169              
170             Defaults to an empty list.
171              
172             This is a list of additional validators for passwords. These values can each
173             be the same an L/<encoder> value.
174              
175             The L</encoder> is always considered as a validator and thus doesn't need to be
176             explicitly specified.
177              
178             =head1 SEE ALSO
179              
180             L<Crypt::Passphrase>, L<Crypt::Passphrase::Argon2>.
181              
182             =head1 AUTHOR
183              
184             Peter Mottram (SysPete) <peter@sysnix.com>
185              
186             =head1 CONTRIBUTORS
187              
188             None yet.
189              
190             =head1 COPYRIGHT
191              
192             Copyright (c) 2022 the Catalyst::Plugin::CryptPassphrase L</AUTHOR>
193             and L</CONTRIBUTORS> as listed above.
194              
195             The initial L</CONFIGURATION> documentation was taken from L<Crypt::Passphrase>
196             which is copyright (c) 2021 by Leon Timmermans <leont@cpan.org>.
197              
198             =head1 LICENSE
199            
200             This is free software; you can redistribute it and/or modify it under
201             the same terms as the Perl 5 programming language system itself.