File Coverage

blib/lib/PlugAuth/Plugin/Audit.pm
Criterion Covered Total %
statement 85 89 95.5
branch 6 12 50.0
condition 3 8 37.5
subroutine 16 17 94.1
pod 0 2 0.0
total 110 128 85.9


line stmt bran cond sub pod time code
1             package PlugAuth::Plugin::Audit;
2              
3 2     2   30847 use strict;
  2         5  
  2         75  
4 2     2   11 use warnings;
  2         3  
  2         62  
5 2     2   29 use v5.10;
  2         5  
  2         92  
6 2     2   1704 use Role::Tiny::With;
  2         6211  
  2         114  
7 2     2   989 use Path::Class::Dir;
  2         52158  
  2         56  
8 2     2   12 use Path::Class::File;
  2         3  
  2         39  
9 2     2   921 use File::HomeDir;
  2         6320  
  2         128  
10 2     2   773 use YAML::XS qw( Dump LoadFile );
  2         3258  
  2         112  
11 2     2   2579 use DateTime;
  2         339069  
  2         2377  
12              
13             with 'PlugAuth::Role::Plugin';
14              
15             # ABSTRACT: Audit log for authentication/authorization
16             our $VERSION = '0.05'; # VERSION
17              
18              
19             with 'PlugAuth::Role::Plugin';
20              
21             sub init
22             {
23 1     1 0 2172 my($self) = @_;
24            
25             $self->app->routes->route('/audit')->name('audit_check')->get(sub {
26 1     1   187333 my($c) = @_;
27 1         51 my ($day,$month,$year) = (localtime(time))[3,4,5];
28 1         4 $year+=1900;
29 1         2 $month++;
30 1   50     20 $c->stash->{autodata} = {
31             today => join('-', $year, sprintf("%02d", $month), sprintf("%02d", $day)),
32             version => $PlugAuth::Plugin::Audit::VERSION // 'dev',
33             };
34 1         4 });
35            
36             $self->app->routes->route('/audit/today')->name('audit_today')->get(sub {
37 1     1   26375 my($c) = @_;
38 1         40 my ($day,$month,$year) = (localtime(time))[3,4,5];
39 1         2 $year+=1900;
40 1         2 $month++;
41 1         17 $c->redirect_to($c->url_for('audit', year => $year, month => sprintf("%02d", $month), day => sprintf("%02d", $day)));
42 1         1015 });
43            
44             # FIXME: provide an interface for this
45             # in Clustericious
46             my $auth = sub {
47 2     2   61595 my $c = shift;
48 2         17 my $plugin = $self->_self_auth_plugin;
49 2 50       33 return 1 unless defined $plugin;
50 0 0       0 return 0 unless $plugin->authenticate($c, 'ACPS');
51 0 0       0 return 0 unless $plugin->authorize($c, 'accounts', $c->req->url->path);
52 0         0 return 1;
53 1         744 };
54            
55 0     0   0 my $authz = sub {
56 1         4 };
57            
58             $self->app->routes->bridge->to({ cb => $auth })->route('/audit/:year/:month/:day')->name('audit')->get(sub {
59 2     2   520 my($c) = @_;
60 2         7 my $year = $c->stash('year');
61 2         22 my $month = $c->stash('month');
62 2         20 my $day = $c->stash('day');
63 2 50 33     49 return $c->render_message('not ok', 404)
      33        
64             unless $year =~ /^\d\d\d\d$/
65             && $month =~ /^\d\d?$/
66             && $day =~ /^\d\d?$/;
67 2         14 my $filename = $self->log_filename({ year => $year, month => $month, day => $day });
68 2 100       16 return $c->render_message('not ok', 404)
69             unless -r $filename;
70 1         175 my(@events) = map {
71 1         70 my $event = $_;
72 1         13 my $dt = DateTime->from_epoch( epoch => $event->{time} );
73 1         398 $dt->set_time_zone('local');
74 1         7603 $event->{time_epoch} = delete $event->{time};
75 1         7 $event->{time_human} = $dt->strftime("%a, %d %b %Y %H:%M:%S %z");
76 1         228 $event->{time_computer} = $dt->strftime("%Y-%m-%dT%H:%M:%S%z");
77 1         107 $event;
78             } LoadFile($filename->stringify);
79 1         14 $c->stash->{autodata} = \@events;
80 1         4 });
81            
82 1         1256 my @event_names = qw(
83             create_user
84             delete_user
85             create_group
86             delete_group
87             update_group
88             grant
89             revoke
90             change_password
91             );
92            
93 1         4 foreach my $event_name (@event_names)
94             {
95             $self->app->on($event_name => sub {
96 1     1   50562 my($app, $args) = @_;
97            
98 1         6 my %info = %$args;
99 1         5 $info{time} = time;
100 1         3 $info{event} = $event_name;
101 1         7 my $filename = $self->log_filename($info{time});
102 1         11 open(my $fh, '>>', $filename->stringify);
103 1         237 print $fh Dump(\%info);
104 1         53 close $fh;
105 8         135 });
106             }
107             }
108              
109             sub log_filename
110             {
111 3     3 0 7 my($self, $time) = @_;
112            
113 3         4 my($day, $month, $year);
114            
115 3 100       12 if(ref $time)
116             {
117 2         3 $day = $time->{day};
118 2         5 $month = $time->{month};
119 2         12 $year = $time->{year};
120             }
121             else
122             {
123 1         23 ($day,$month,$year) = (localtime($time))[3,4,5];
124 1         4 $year += 1900;
125 1         2 $month++;
126             }
127            
128 3         33 my $filename = Path::Class::File->new(
129             File::HomeDir->my_home,
130             '.plugauth_plugin_audit',
131             sprintf("%04d", $year),
132             sprintf("%02d", $month),
133             sprintf("%02d", $day),
134             'audit.log',
135             );
136 3         603 $filename->dir->mkpath(0,0700);
137 3         1296 $filename;
138             }
139              
140             1;
141              
142             __END__