File Coverage

blib/lib/Cookieville/Plugin/Authorize.pm
Criterion Covered Total %
statement 24 26 92.3
branch 8 10 80.0
condition 6 8 75.0
subroutine 3 3 100.0
pod 1 1 100.0
total 42 48 87.5


line stmt bran cond sub pod time code
1             package Cookieville::Plugin::Authorize;
2              
3             =head1 NAME
4              
5             Cookieville::Plugin::Authorize - Plugin for handling authorization
6              
7             =head1 DESCRIPTION
8              
9             L is a plugin for just allowing some clients
10             from doing read/write/update. The clients are identified by the
11             C HTTP header. These headers should be long to prevent
12             brute force entry.
13              
14             =head1 SYNOPSIS
15              
16             This L explains how to enable this plugin in the L server.
17              
18             Example C file:
19              
20             {
21             access_rules => {
22             "Some-Long-Auth-Id-12b34acf274" => {
23             Artist => [qw( GET PATCH )],
24             CD => [qw( GET PATCH PUT )],
25             },
26             },
27             }
28              
29             The presense of "access_rules" in C file will load this plugin
30             with the given set of rules.
31              
32             The rules above will allow a client with the C header
33             set to "Some-Long-Auth-Id-12b34acf274" to "GET" and "PATCH" data to the
34             "Artist" source. The same client can also "GET", "PATCH" and "PUT" data to the "CD"
35             source.
36              
37             Any client can access "/".
38              
39             Any client with a valid C can access "/sources".
40              
41             Any other request will result in HTTP status code "401" and an error message.
42              
43             You can have as many C keys under "access_rules"
44             as you want.
45              
46             =cut
47              
48 1     1   777 use Mojo::Base 'Mojolicious::Plugin';
  1         1  
  1         6  
49              
50             =head1 METHODS
51              
52             =head2 register
53              
54             This plugin will register a route with the name "cookieville_authorizer" in
55             the main app. This route is then used for any request in the main app,
56             except "/".
57              
58             =cut
59              
60             sub register {
61 1     1 1 31 my ($self, $app, $rules) = @_;
62 1         18 my $r = $app->routes->route('/')->under;
63              
64 1         484 $r->name('cookieville_authorizer');
65             $r->to(
66             cb => sub {
67 14     14   31869 my $c = shift;
68 14         55 my $method = $c->req->method;
69 14   100     848 my $id = $c->req->headers->header('X-Cookieville-Auth-Id') || '';
70 14         1145 my @path = @{$c->req->url->path};
  14         67  
71              
72 14         1758 $c->stash(auth_id => $id);
73              
74 14 100 66     295 if (!$id or !$rules->{$id}) {
75 5         25 $c->render('not_authorized', status => 401);
76 5         11015 return undef;
77             }
78 9 100 66     74 if (!@path or $path[0] eq 'sources') {
79 1         8 return 1;
80             }
81 8 50       43 if (!$rules->{$id}{$path[0]}) {
82 0         0 $c->render('not_authorized', message => "No access to $path[0].", status => 401);
83 0         0 return undef;
84             }
85              
86 8 50       16 for my $m (@{$rules->{$id}{$path[0]} || []}) {
  8         42  
87 17 100       78 return 1 if $m eq $method;
88             }
89              
90 2         14 $c->render('not_authorized', message => "Cannot $method $path[0].", status => 401);
91 2         2361 return undef;
92             },
93 1         11 );
94             }
95              
96             =head1 AUTHOR
97              
98             Jan Henning Thorsen - C
99              
100             =cut
101              
102             1;