File Coverage

blib/lib/Dancer/Plugin/Auth/Extensible/Provider/Base.pm
Criterion Covered Total %
statement 17 18 94.4
branch 3 4 75.0
condition n/a
subroutine 6 7 85.7
pod 0 3 0.0
total 26 32 81.2


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