File Coverage

blib/lib/Plack/Middleware/Auth/Htpasswd.pm
Criterion Covered Total %
statement 48 48 100.0
branch 9 10 90.0
condition 4 6 66.6
subroutine 13 13 100.0
pod 1 2 50.0
total 75 79 94.9


line stmt bran cond sub pod time code
1             package Plack::Middleware::Auth::Htpasswd;
2             BEGIN {
3 2     2   3199 $Plack::Middleware::Auth::Htpasswd::VERSION = '0.02';
4             }
5 2     2   19 use strict;
  2         4  
  2         74  
6 2     2   12 use warnings;
  2         3  
  2         74  
7 2     2   12 use base 'Plack::Middleware::Auth::Basic';
  2         4  
  2         1910  
8 2     2   5174 use Plack::Util::Accessor qw(file file_root);
  2         4  
  2         20  
9 2     2   2188 use Plack::Request;
  2         54946  
  2         73  
10              
11 2     2   1716 use Authen::Htpasswd;
  2         41635  
  2         12  
12 2     2   86 use MIME::Base64;
  2         5  
  2         122  
13 2     2   11 use Path::Class ();
  2         5  
  2         832  
14              
15             # ABSTRACT: http basic authentication through apache-style .htpasswd files
16              
17              
18             sub prepare_app {
19 5     5 1 36347 my $self = shift;
20 5     13   47 $self->authenticator(sub { $self->authenticate(@_) });
  13         568100  
21 5 50 66     305 die "must specify either file or file_root"
22             unless defined $self->file || $self->file_root;
23 5         132 return $self->SUPER::prepare_app;
24             }
25              
26             sub _check_password {
27 12     12   59 my $self = shift;
28 12         27 my ($file, $user, $pass) = @_;
29 12         105 my $htpasswd = Authen::Htpasswd->new($file);
30 12         299076 my $htpasswd_user = $htpasswd->lookup_user($user);
31 12 100       6246 return unless $htpasswd_user;
32 9         93 return $htpasswd_user->check_password($pass);
33             }
34              
35             sub authenticate {
36 13     13 0 29 my $self = shift;
37 13         26 my ($user, $pass, $env) = @_;
38              
39 13 100       56 return $self->_check_password($self->file, $user, $pass)
40             if defined $self->file;
41              
42 10         151 my $path = Plack::Request->new($env)->path;
43 10         228 my $dir = Path::Class::Dir->new($self->file_root);
44 24         2372 my @htpasswd = $path ne '/'
45             ? reverse
46 24         876 map { $_->file('.htpasswd')->stringify }
47 10 100       942 map { $dir = $dir->subdir($_) }
48             split m{/}, $path
49             : ($dir->file('.htpasswd')->stringify);
50              
51 10         1170 for my $htpasswd (@htpasswd) {
52 18 100 66     668 next unless -f $htpasswd && -r _;
53 9         36 return $self->_check_password($htpasswd, $user, $pass);
54             }
55              
56 1         5 return;
57             }
58              
59              
60             1;
61              
62             __END__