File Coverage

blib/lib/DBIx/Class/CryptColumn.pm
Criterion Covered Total %
statement 70 70 100.0
branch 12 20 60.0
condition 1 3 33.3
subroutine 17 17 100.0
pod 4 4 100.0
total 104 114 91.2


line stmt bran cond sub pod time code
1             package DBIx::Class::CryptColumn;
2             $DBIx::Class::CryptColumn::VERSION = '0.009';
3 2     2   582230 use strict;
  2         4  
  2         82  
4 2     2   10 use warnings;
  2         5  
  2         146  
5              
6 2     2   2871 use Crypt::Passphrase 0.019;
  2         30551  
  2         16  
7 2     2   727 use Sub::Util 1.40 'set_subname';
  2         421  
  2         187  
8 2     2   655 use namespace::clean;
  2         64319  
  2         23  
9              
10 2     2   633 use parent 'DBIx::Class';
  2         4  
  2         19  
11              
12             __PACKAGE__->load_components(qw(InflateColumn::Crypt::Passphrase));
13              
14             sub new {
15 1     1 1 440909 my ($self, $attr, @rest) = @_;
16              
17 1         4 for my $col (grep { !/^-/ } keys %{ $attr }) {
  2         10  
  1         4  
18 1 50       141 next unless my $inflate = $self->column_info($col)->{inflate_passphrase};
19 1         127 $attr->{$col} = $inflate->hash_password($attr->{$col});
20             }
21              
22 1         161 return $self->next::method($attr, @rest);
23             }
24              
25             sub _export_sub {
26 4     4   15 my ($self, $name, $sub) = @_;
27 4         168 my $full_name = $self->result_class . "::$name";
28 2     2   70188 no strict 'refs';
  2         7  
  2         1733  
29 4         1282 *$full_name = set_subname $full_name => $sub;
30             }
31              
32             sub register_column {
33 2     2 1 2602 my ($self, $column, $info, @rest) = @_;
34              
35 2 100       9 if (my $args = $info->{inflate_passphrase}) {
36 1 50       4 $self->throw_exception(q['inflate_passphrase' must be a hash reference]) unless ref $args eq 'HASH';
37              
38 1         3 my $crypt_passphrase = Crypt::Passphrase->new(%{$args});
  1         8  
39              
40 1 50       12472 if (defined(my $name = $args->{verify_method})) {
41             $self->_export_sub($name, sub {
42 7     7   12331 my ($row, $password) = @_;
        7      
43 7         38 return $crypt_passphrase->verify_password($password, $row->get_column($column));
44 1         20 });
45             }
46              
47 1 50       7 if (defined(my $name = $args->{rehash_method})) {
48             $self->_export_sub($name, sub {
49 4     4   10319 my $row = shift;
50 4         22 return $crypt_passphrase->needs_rehash($row->get_column($column));
51 1         9 });
52             }
53              
54 1 50       7 if (defined(my $name = $args->{verify_and_rehash_method})) {
55             $self->_export_sub($name, sub {
56 1     5   497 my ($row, $password) = @_;
57              
58 1         6 my $hash = $row->get_column($column);
59 1         14 my $result = $crypt_passphrase->verify_password($password, $hash);
60 1 50 33     123 if ($result && $crypt_passphrase->needs_rehash($hash)) {
61 1         20 $row->update({ $column => $password })->discard_changes;
62             }
63              
64 1         5989 return $result;
65 1         36 });
66             }
67              
68 1 50       6 if (defined(my $name = $args->{recode_hash_method})) {
69             $self->_export_sub($name, sub {
70 1     2   582 my $row = shift;
71 1         7 my $old_hash = $row->get_column($column);
72 1         14 my $new_hash = $crypt_passphrase->recode_hash($old_hash);
73              
74 1 50       41 if ($new_hash ne $old_hash) {
75 1         38 local $self->column_info($column)->{inflate_passphrase};
76 1         77 $row->update({ $column => $new_hash })->discard_changes;
77             }
78              
79 1         5973 return $new_hash;
80 1         7 });
81             }
82              
83 1         4 $info->{inflate_passphrase} = $crypt_passphrase;
84             }
85              
86 2         13 $self->next::method($column, $info, @rest);
87             }
88              
89             sub set_column {
90 4     5 1 1300 my ($self, $col, $val, @rest) = @_;
91              
92 4         158 my $inflate = $self->column_info($col)->{inflate_passphrase};
93 4 100       327 $val = $inflate->hash_password($val) if $inflate;
94              
95 4         168 return $self->next::method($col, $val, @rest);
96             }
97              
98             sub set_inflated_column {
99 1     1 1 3100 my ($self, $col, $val, @rest) = @_;
100 1         38 local $self->column_info($col)->{inflate_passphrase};
101 1         74 $self->next::method($col, $val, @rest);
102             }
103              
104             1;
105              
106             # ABSTRACT: Automatically hash password/passphrase columns
107              
108             __END__