File Coverage

blib/lib/Mojolicious/Plugin/BasicAuthPlus.pm
Criterion Covered Total %
statement 52 58 89.6
branch 24 38 63.1
condition 14 19 73.6
subroutine 12 13 92.3
pod 1 1 100.0
total 103 129 79.8


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