File Coverage

blib/lib/Dancer/Plugin/Auth/Extensible/Provider/Base.pm
Criterion Covered Total %
statement 20 21 95.2
branch 3 4 75.0
condition n/a
subroutine 7 8 87.5
pod 0 3 0.0
total 30 36 83.3


line stmt bran cond sub pod time code
1             package Dancer::Plugin::Auth::Extensible::Provider::Base;
2              
3 1     1   4 use strict;
  1         2  
  1         21  
4 1     1   3 use warnings;
  1         1  
  1         18  
5              
6 1     1   411 use Crypt::SaltedHash;
  1         2668  
  1         148  
7              
8             =head1 NAME
9              
10             Dancer::Plugin::Auth::Extensible::Provider::Base - base class for authentication providers
11              
12             =head1 DESCRIPTION
13              
14             Base class for authentication providers. Provides a constructor which handles
15             receiving the realm settings and returning an instance of the provider.
16              
17             Also provides secure password matching which automatically handles crypted
18             passwords via Crypt::SaltedHash.
19              
20             Finally, provides the methods which providers must override with their
21             implementation, which will die if they are not overridden.
22              
23             =cut
24              
25             sub new {
26 2     2 0 2 my ($class, $realm_settings) = @_;
27 2         5 my $self = {
28             realm_settings => $realm_settings,
29             };
30 2         8 return bless $self => $class;
31             }
32              
33 34 50   34 0 147 sub realm_settings { shift->{realm_settings} || {} }
34              
35              
36            
37             sub match_password {
38 4     4 0 8 my ($self, $given, $correct) = @_;
39              
40             # TODO: perhaps we should accept a configuration option to state whether
41             # passwords are crypted or not, rather than guessing by looking for the
42             # {...} tag at the start.
43             # I wanted to let it try straightforward comparison first, then try
44             # Crypt::SaltedHash->validate, but that has a weakness: if a list of hashed
45             # passwords got leaked, you could use the hashed password *as it is* to log
46             # in, rather than cracking it first. That's obviously Not Fucking Good.
47             # TODO: think about this more. This shit is important. I'm thinking a
48             # config option to indicate whether passwords are crypted - yes, no, auto
49             # (where auto would do the current guesswork, and yes/no would just do as
50             # told.)
51 4 100       19 if ($correct =~ /^{.+}/) {
52             # Looks like a crypted password starting with the scheme, so try to
53             # validate it with Crypt::SaltedHash:
54 1         8 return Crypt::SaltedHash->validate($correct, $given);
55             } else {
56             # Straightforward comparison, then:
57 3         11 return $given eq $correct;
58             }
59             }
60              
61              
62             # Install basic method placeholders which will blow up if the provider module
63             # did not implement their own version.
64             {
65 1     1   6 no strict 'refs';
  1         2  
  1         103  
66             for my $method (qw(
67             authenticate_user
68             get_user_details
69             get_user_roles
70             ))
71             {
72             *$method = sub {
73 0     0     die "$method was not implemented by provider " . __PACKAGE__;
74             };
75             }
76             }
77              
78              
79              
80              
81             1;
82