File Coverage

blib/lib/Mojolicious/Plugin/HttpBasicAuth.pm
Criterion Covered Total %
statement 38 39 97.4
branch 6 6 100.0
condition 12 19 63.1
subroutine 8 9 88.8
pod 1 1 100.0
total 65 74 87.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::HttpBasicAuth;
2              
3 1     1   1178 use Mojo::Base 'Mojolicious::Plugin';
  1         2  
  1         9  
4 1     1   221 use Mojo::ByteStream;
  1         3  
  1         48  
5 1     1   14 use Mojo::Util qw{b64_encode b64_decode};
  1         2  
  1         742  
6              
7             our $VERSION = '0.11';
8              
9             sub register {
10 1     1 1 45 my ($plugin, $app, $user_defaults) = @_;
11              
12 1         1 push @{ $app->renderer->classes }, __PACKAGE__;
  1         24  
13              
14 1         39 my %defaults = %$user_defaults;
15 1   50     8 $defaults{realm} //= 'WWW';
16             $defaults{validate} //= sub {
17 0     0   0 die('please define a validate callback');
18 1   50     5 };
19             $defaults{invalid} //= sub {
20 14     14   28 my $controller = shift;
21             return (
22 14         188 json => { json => { error => 'HTTP 401: Unauthorized' } },
23             html => { template => 'auth/basic' },
24             any => { data => 'HTTP 401: Unauthorized' }
25             );
26 1   50     10 };
27              
28             $app->renderer->add_helper(
29             basic_auth => sub {
30 18     18   469703 my $controller = shift;
31 18   50     155 my $params = shift // {};
32 18         153 my %options = (%defaults, %$params);
33              
34             # Sent credentials
35 18   100     93 my $auth = b64_decode($plugin->_auth_header($controller) || '');
36              
37             # No credentials entered
38 18 100       141 return $plugin->_unauthorized($controller, $options{realm}, $options{invalid}) unless ($auth);
39              
40             # Verification within callback
41 16 100 66     128 return 1 if $options{validate} and $options{validate}->($controller, split(/:/, $auth, 2), $options{realm});
42              
43             # Not verified
44 12         193 return $plugin->_unauthorized($controller, $options{realm}, $options{invalid});
45             }
46 1         25 );
47             }
48              
49             sub _auth_header {
50 18     18   28 my $plugin = shift;
51 18         31 my $controller = shift;
52 18   66     63 my $auth = $controller->req->headers->authorization || $controller->req->env->{'X_HTTP_AUTHORIZATION'} || $controller->req->env->{'HTTP_AUTHORIZATION'};
53              
54 18 100 66     2483 if ($auth && $auth =~ m/Basic (.*)/) {
55 16         45 $auth = $1;
56             }
57              
58 18         117 return $auth;
59             }
60              
61             sub _unauthorized {
62 14     14   30 my ($plugin, $controller, $realm, $callback) = @_;
63              
64 14         57 $controller->res->headers->www_authenticate("Basic realm=\"$realm\"");
65 14         1809 $controller->respond_to($callback->($controller));
66 14         39376 $controller->res->code(401);
67 14         1034 $controller->rendered;
68              
69 14         1920 return;
70             }
71              
72             1;
73             __DATA__