File Coverage

blib/lib/Form/Processor/Field/TxtPassword.pm
Criterion Covered Total %
statement 31 31 100.0
branch 8 10 80.0
condition n/a
subroutine 11 11 100.0
pod 1 4 25.0
total 51 56 91.0


line stmt bran cond sub pod time code
1             package Form::Processor::Field::TxtPassword;
2             $Form::Processor::Field::TxtPassword::VERSION = '1.162360';
3 1     1   911 use strict;
  1         1  
  1         24  
4 1     1   2 use warnings;
  1         1  
  1         24  
5 1     1   2 use base 'Form::Processor::Field::EnterPassword';
  1         1  
  1         355  
6 1     1   456 use File::ShareDir;
  1         3878  
  1         42  
7 1     1   439 use Encode qw/ encode_utf8 is_utf8 /;
  1         6294  
  1         60  
8 1     1   381 use Data::Password::Entropy;
  1         7061  
  1         52  
9              
10             use Rose::Object::MakeMethods::Generic (
11 1         10 scalar => [
12             min_bytes => { interface => 'get_set_init' },
13             min_entropy => { interface => 'get_set_init' },
14             ],
15 1     1   5 );
  1         1  
16              
17 1     1 0 10 sub init_min_bytes { return 9 }
18 1     1 0 211 sub init_min_entropy { return 28 } # Arbitrary!
19              
20             # This is small because this is counting *characters*, not bytes.
21 1     1 0 7 sub init_min_length { return 4 }
22              
23             my %bad_pw_lookup;
24             {
25             my $pwd_list = File::ShareDir::dist_dir( 'Form-Processor' ) . '/passwords.txt';
26             open my $fh, '<:utf8', $pwd_list or die "Failed to open file [$pwd_list]: $!";
27             %bad_pw_lookup = map { chomp; $_ => 1 } <$fh>; ## no critic
28             close $fh;
29             }
30              
31              
32             sub validate {
33 4     4 1 4 my $self = shift;
34              
35 4 100       15 return unless $self->SUPER::validate;
36              
37 3         5 my $value = $self->input;
38              
39              
40             # Check length of password in bytes.
41 3 50       16 return $self->add_error( 'please enter a more secure password' )
    100          
42             if length( is_utf8( $value ) ? encode_utf8( $value ) : $value ) < $self->min_bytes;
43              
44              
45             return $self->add_error( 'please enter a more secure password' )
46 2 100       15 if exists $bad_pw_lookup{$value};
47              
48              
49              
50             # This is totally arbitrary. Plus, it can give away what what is considered
51             # a "good" password, limiting the patterns to attempt.
52              
53             # See also Data::Password, but that excludes ANY dictionary word with in the phrase
54 1 50       5 return $self->add_error( 'please enter a more secure password' )
55             if password_entropy( $value ) < $self->min_entropy;
56 1         4 return 1;
57              
58              
59             }
60              
61              
62              
63             # ABSTRACT: Input a password
64              
65              
66             1;
67              
68             __END__