File Coverage

blib/lib/Mojolicious/Plugin/PlugAuthLite.pm
Criterion Covered Total %
statement 48 50 96.0
branch 10 14 71.4
condition 10 13 76.9
subroutine 9 10 90.0
pod 1 1 100.0
total 78 88 88.6


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::PlugAuthLite;
2              
3 10     10   4356 use Mojo::Base qw( Mojolicious::Plugin );
  10         29  
  10         77  
4 10     10   2273 use Mojo::ByteStream qw( b );
  10         44  
  10         573  
5 10     10   215 use 5.010001;
  10         42  
6              
7             # ABSTRACT: Add a minimal PlugAuth server to your Mojolicious application.
8             our $VERSION = '0.37'; # VERSION
9              
10              
11             sub register
12             {
13 9     9 1 436 my($self, $app, $conf) = @_;
14            
15 9   100 2   55 my $cb_auth = $conf->{auth} // sub { 0 };
  2         11  
16 9   100 1   51 my $cb_authz = $conf->{authz} // sub { 1 };
  1         6  
17 9   100 0   55 my $cb_host = $conf->{host} // sub { 0 };
  0         0  
18 9   50     112 my $realm = $conf->{realm} // 'PlugAuthLite';
19 9   66     117 my $base_url = $conf->{url} // $conf->{uri} // '';
      50        
20              
21             $app->routes->get("$base_url/auth" => sub {
22 14     14   545614 my $self = shift;
23 14         45 eval {
24 14         86 my $auth_header = $self->req->headers->authorization;
25 14 100       478 unless($auth_header)
26             {
27 5         29 $self->res->headers->www_authenticate("Basic \"$realm\"");
28 5         179 $self->render(text => 'please authenticate', status => 401);
29 5         2551 return;
30             }
31 9         57 my ($method,$str) = split / /,$auth_header;
32 9         66 my ($user,$pw) = split /:/, b($str)->b64_decode;
33 9 100       347 if($cb_auth->($user, $pw))
34             {
35 4         68 $self->render(text => 'ok', status => 200);
36             }
37             else
38             {
39 5         53 $self->render(text => 'not ok', status => 403);
40             }
41             };
42 14 50       5002 $self->render(text => 'not ok', status => 503) if $@;
43 9         71 })->name('plugauth_auth');
44            
45             $app->routes->get("$base_url/authz/user/#user/#action/(*resource)" => { resource => '/' } => sub {
46 6     6   272017 my $self = shift;
47 6         19 eval {
48 6         21 my($user, $resource, $action) = map { $self->stash($_) } qw( user resource action );
  18         176  
49 6         92 $resource =~ s{^/?}{/};
50 6 100       39 if($cb_authz->($user, $action, $resource))
51             {
52 4         3292 $self->render(text => 'ok', status => 200);
53             }
54             else
55             {
56 2         2360 $self->render(text => 'not ok', status => 403);
57             }
58             };
59 6 50       2936 $self->render(text => 'not ok', status => 503) if $@;
60 9         4030 })->name('plugauth_authz');
61            
62             $app->routes->get("$base_url/host/#host/:tag" => sub {
63 2     2   81443 my $self = shift;
64 2         7 eval {
65 2         16 my ($host,$tag) = map $self->stash($_), qw/host tag/;
66 2 50       69 if ($cb_host->($host,$tag)) {
67 0         0 return $self->render(text => 'ok', status => 200);
68             }
69 2         14 return $self->render(text => 'not ok', status => 403);
70             };
71 2 50       1504 $self->render(text => 'not ok', status => 503) if $@;
72 9         4186 })->name('plugauth_host');
73            
74 9         3149 return;
75             }
76              
77             1;
78              
79             __END__
80              
81             =pod
82              
83             =encoding UTF-8
84              
85             =head1 NAME
86              
87             Mojolicious::Plugin::PlugAuthLite - Add a minimal PlugAuth server to your Mojolicious application.
88              
89             =head1 VERSION
90              
91             version 0.37
92              
93             =head1 SYNOPSIS
94              
95             use Mojolicious::Lite
96            
97             plugin 'plug_auth_lite',
98             auth => sub {
99             my($user, $pass) = @_;
100             if($user eq 'optimus' && $pass eq 'matrix')
101             { return 1; }
102             else
103             { return 0; }
104             },
105             authz => sub {
106             my($user, $action, $resource) = @_;
107             if($user eq 'optimus && $action eq 'open' && $resource =~ m{^/matrix})
108             { return 1 }
109             else
110             { return 0 }
111             };
112              
113             =head1 DESCRIPTION
114              
115             This plugin provides a very minimal but customizable L<PlugAuth> server which can
116             be included with your L<Mojolicious> application for L<Clustericious> applications
117             to authenticate against. If you do not need specialized plugins for LDAP or DBI,
118             and if you do not need the user/group/resource management provided by a the full
119             featured L<PlugAuth> server then this plugin may be for you.
120              
121             The script L<plugauthlite> included with this distribution provides PlugAuth
122             style authentication (but not authorization) using a simple Apache style password
123             file.
124              
125             =head1 CONFIGURATION
126              
127             =head2 auth
128              
129             Subroutine which checks the authentication of a user. It is passed two arguments,
130             the username and the password. If they are authentic this call back should return
131             1. Otherwise it should return 0.
132              
133             =head2 authz
134              
135             Subroutine which checks the authorization of a user. It is passwd three arguments,
136             the username, action (usually a verb) and resource (usually the path part of a URL).
137             If the user is authorized for the action on that resource the call back should return
138             1. Otherwise it should return 0.
139              
140             =head2 url
141              
142             The prefix to prepend to the standard PlugAuth API routes. Usually the authentication
143             route is /auth and the authorization route is /authz, but if the PlugAuth.conf client
144             configuration is set to http://example.com/foo the client expects the authentication
145             route to be /foo/auth and the authorization route to be /foo/authz. In this case you
146             would set this configuration item to '/foo'.
147              
148             =head2 realm
149              
150             The realm to use for HTTP Basic authentication. The default is PlugAuthLite.
151              
152             =head1 ROUTES
153              
154             =head2 GET /auth
155              
156             =over 4
157              
158             =item * if username and password provided using BASIC authentication and are correct
159              
160             Return 200 ok
161              
162             =item * if username and password provided using BASIC authentication but are not correct
163              
164             Return 403 not ok
165              
166             =item * if username and password are not provided using BASIC authentication
167              
168             Return 401 please authenticate
169              
170             =back
171              
172             =head2 GET /authz/user/#user/#action/(*resource)
173              
174             =over 4
175              
176             =item * if the given user (#user) is permitted to perform the given action (#action) on the given resource (*resource)
177              
178             Return 200 ok
179              
180             =item * otherwise
181              
182             return 403 not ok
183              
184             =back
185              
186             =head1 METHODS
187              
188             =head2 register
189              
190             This method adds the routes to your application required to implement the PlugAuth
191             API.
192              
193             =head1 LIMITATIONS
194              
195             This implementation of the PlugAuth protocol does not support these features provided
196             by the full fledged L<PlugAuth> server:
197              
198             =over 4
199              
200             =item *
201              
202             Groups
203              
204             =item *
205              
206             Management API for creating/removing/modifying users/groups/resources
207              
208             =item *
209              
210             Standard Clustericious routes like "/version" and "/status"
211              
212             =item *
213              
214             Clustericious configuration file (~/etc/PlugAuth.conf)
215              
216             =item *
217              
218             Support for L<PlugAuth> plugins (L<PlugAuth::Plugin>).
219              
220             =item *
221              
222             Probably many others.
223              
224             =back
225              
226             =head1 SEE ALSO
227              
228             L<plugauthlite>,
229             L<PlugAuth::Lite>,
230             L<PlugAuth>
231              
232             =head1 AUTHOR
233              
234             Graham Ollis <plicease@cpan.org>
235              
236             =head1 COPYRIGHT AND LICENSE
237              
238             This software is copyright (c) 2013 by Graham Ollis.
239              
240             This is free software; you can redistribute it and/or modify it under
241             the same terms as the Perl 5 programming language system itself.
242              
243             =cut