File Coverage

blib/lib/Mojolicious/Plugin/BasicAuthPlus.pm
Criterion Covered Total %
statement 53 59 89.8
branch 26 40 65.0
condition 14 19 73.6
subroutine 12 13 92.3
pod 1 1 100.0
total 106 132 80.3


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::BasicAuthPlus;
2              
3 2     2   15332 use Mojo::Base 'Mojolicious::Plugin';
  2         6294  
  2         10  
4 2     2   1262 use Mojo::ByteStream;
  2         36344  
  2         81  
5 2     2   930 use Authen::Simple::Password;
  2         3089  
  2         46  
6 2     2   716 use Authen::Simple::Passwd;
  2         28859  
  2         15  
7 2     2   830 use Authen::Simple::LDAP;
  2         175328  
  2         16  
8              
9             our $VERSION = '0.10';
10              
11             sub register {
12 1     1 1 47 my ( $plugin, $app ) = @_;
13              
14             $app->renderer->add_helper(
15             basic_auth => sub {
16 25     25   178895 my $self = shift;
17              
18             # Sent credentials
19 25   100     77 my $auth = $self->req->url->to_abs->userinfo || '';
20              
21             # Required credentials
22 25         5444 my ( $realm, $password, $username ) = $plugin->_expected_auth(@_);
23 25 100       73 my $callback = $password if ref $password eq 'CODE';
24 25 100       67 my $params = $password if ref $password eq 'HASH';
25              
26             # No credentials entered
27 25 100 66     51 return $plugin->_password_prompt( $self, $realm )
      66        
28             if !$auth
29             and !$callback
30             and !$params;
31              
32             # Hash for return data
33 24         40 my %data;
34 24 100       72 $data{username} = $username if $username;
35              
36             # Verification within callback
37 24 100 100     91 return (\%data, 1)
38             if $callback and $callback->( split /:/, $auth, 2 );
39              
40             # Verified with realm => username => password syntax
41 19 100 100     140 return (\%data, 1)
42             if $auth eq ( $username || '' ) . ":$password";
43              
44             # Verified via simple, passwd file, LDAP, or Active Directory.
45 13 100       26 if ($auth) {
46 11         24 $data{username} = $params->{'username'};
47 11 100 66     69 if ( $params->{'username'} and $params->{'password'} ) {
    100          
    50          
48 5 50       17 return (\%data, 1)
49             if $plugin->_check_simple( $self, $auth, $params );
50             }
51             elsif ( $params->{'path'} ) {
52 2 50       6 return (\%data, 1)
53             if $plugin->_check_passwd( $self, $auth, $params );
54             }
55             elsif ( $params->{'host'} ) {
56 0 0       0 return (\%data, 1)
57             if $plugin->_check_ldap( $self, $auth, $params );
58             }
59             }
60              
61             # Not verified
62 6         18 return $plugin->_password_prompt( $self, $realm );
63             }
64 1         7 );
65             }
66              
67             sub _expected_auth {
68 25     25   38 my $self = shift;
69 25         44 my $realm = shift;
70              
71 25 50       89 return @$realm{qw/ realm password username /} if ref $realm eq "HASH";
72              
73             # realm, pass, user || realm, pass, undef || realm, callback
74 25         71 return $realm, reverse @_;
75             }
76              
77             sub _password_prompt {
78 7     7   7 my ( $self, $c, $realm ) = @_;
79              
80 7         28 $c->res->headers->www_authenticate("Basic realm=\"$realm\"");
81 7         180 $c->res->code(401);
82 7         62 $c->rendered;
83              
84 7         984 return;
85             }
86              
87             sub _split_auth {
88 7     7   24 my ( $username, $password ) = split ':', $_[0];
89              
90 7 50       20 $username = '' unless defined $username;
91 7 50       23 $password = '' unless defined $password;
92              
93 7         16 return ( $username, $password );
94             }
95              
96             sub _check_simple {
97 5     5   11 my ( $self, $c, $auth, $params ) = @_;
98 5         13 my ( $username, $password ) = _split_auth($auth);
99              
100 5 50 33     44 return 1
101             if $username eq $params->{'username'}
102             and Authen::Simple::Password->check( $password,
103             $params->{'password'} );
104             }
105              
106             sub _check_ldap {
107 0     0   0 my ( $self, $c, $auth, $params ) = @_;
108 0         0 my ( $username, $password ) = _split_auth($auth);
109              
110 0 0       0 return 0 unless defined $password;
111 0         0 my $ldap = Authen::Simple::LDAP->new(%$params);
112              
113 0 0       0 return 1 if $ldap->authenticate( $username, $password );
114             }
115              
116             sub _check_passwd {
117 2     2   5 my ( $self, $c, $auth, $params ) = @_;
118 2         8 my ( $username, $password ) = _split_auth($auth);
119              
120 2         25 my $passwd = Authen::Simple::Passwd->new(%$params);
121              
122 2 50       275 return 1 if $passwd->authenticate( $username, $password );
123             }
124              
125             1;
126              
127             __END__