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   17442 use Mojo::Base 'Mojolicious::Plugin';
  2         6243  
  2         10  
4 2     2   1209 use Mojo::ByteStream;
  2         39333  
  2         72  
5 2     2   971 use Authen::Simple::Password;
  2         3267  
  2         44  
6 2     2   737 use Authen::Simple::Passwd;
  2         28662  
  2         13  
7 2     2   855 use Authen::Simple::LDAP;
  2         180721  
  2         14  
8              
9             our $VERSION = '0.09';
10              
11             sub register {
12 1     1 1 44 my ( $plugin, $app ) = @_;
13              
14             $app->renderer->add_helper(
15             basic_auth => sub {
16 25     25   166694 my $self = shift;
17              
18             # Sent credentials
19 25   100     58 my $auth = $self->req->url->to_abs->userinfo || '';
20              
21             # Required credentials
22 25         5372 my ( $realm, $password, $username ) = $plugin->_expected_auth(@_);
23 25 100       56 my $callback = $password if ref $password eq 'CODE';
24 25 100       49 my $params = $password if ref $password eq 'HASH';
25              
26             # No credentials entered
27 25 100 66     52 return $plugin->_password_prompt( $self, $realm )
      66        
28             if !$auth
29             and !$callback
30             and !$params;
31              
32             # Hash for return data
33 24         22 my %data;
34 24 100       43 $data{username} = $username if $username;
35              
36             # Verification within callback
37 24 100 100     67 return (\%data, 1)
38             if $callback and $callback->( split /:/, $auth, 2 );
39              
40             # Verified with realm => username => password syntax
41 19 100 100     142 return (\%data, 1)
42             if $auth eq ( $username || '' ) . ":$password";
43              
44             # Verified via simple, passwd file, LDAP, or Active Directory.
45 13 100       29 if ($auth) {
46 11 100 66     58 if ( $params->{'username'} and $params->{'password'} ) {
    100          
    50          
47 5         12 $data{username} = $params->{'username'};
48 5 50       14 return (\%data, 1)
49             if $plugin->_check_simple( $self, $auth, $params );
50             }
51             elsif ( $params->{'path'} ) {
52 2 50       7 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         17 return $plugin->_password_prompt( $self, $realm );
63             }
64 1         7 );
65             }
66              
67             sub _expected_auth {
68 25     25   24 my $self = shift;
69 25         34 my $realm = shift;
70              
71 25 50       45 return @$realm{qw/ realm password username /} if ref $realm eq "HASH";
72              
73             # realm, pass, user || realm, pass, undef || realm, callback
74 25         52 return $realm, reverse @_;
75             }
76              
77             sub _password_prompt {
78 7     7   9 my ( $self, $c, $realm ) = @_;
79              
80 7         23 $c->res->headers->www_authenticate("Basic realm=\"$realm\"");
81 7         182 $c->res->code(401);
82 7         60 $c->rendered;
83              
84 7         896 return;
85             }
86              
87             sub _split_auth {
88 7     7   21 my ( $username, $password ) = split ':', $_[0];
89              
90 7 50       17 $username = '' unless defined $username;
91 7 50       9 $password = '' unless defined $password;
92              
93 7         19 return ( $username, $password );
94             }
95              
96             sub _check_simple {
97 5     5   8 my ( $self, $c, $auth, $params ) = @_;
98 5         12 my ( $username, $password ) = _split_auth($auth);
99              
100 5 50 33     38 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   3 my ( $self, $c, $auth, $params ) = @_;
118 2         6 my ( $username, $password ) = _split_auth($auth);
119              
120 2         23 my $passwd = Authen::Simple::Passwd->new(%$params);
121              
122 2 50       256 return 1 if $passwd->authenticate( $username, $password );
123             }
124              
125             1;
126              
127             __END__