File Coverage

blib/lib/App/Spoor/ParsedEntryWriter.pm
Criterion Covered Total %
statement 35 35 100.0
branch 3 4 75.0
condition 36 36 100.0
subroutine 7 7 100.0
pod 1 1 100.0
total 82 83 98.8


line stmt bran cond sub pod time code
1             package App::Spoor::ParsedEntryWriter;
2              
3 1     1   187707 use v5.10;
  1         6  
4 1     1   5 use strict;
  1         2  
  1         20  
5 1     1   7 use warnings;
  1         2  
  1         23  
6 1     1   6 use utf8;
  1         2  
  1         6  
7              
8 1     1   21 use JSON;
  1         2  
  1         5  
9 1     1   522 use File::Touch;
  1         17354  
  1         301  
10              
11             =head1 NAME
12              
13             App::Spoor::ParsedEntryWriter
14              
15             =head1 VERSION
16              
17             Version 0.01
18              
19             =cut
20              
21             our $VERSION = '0.01';
22              
23             =head1 SYNOPSIS
24              
25             Writes a parsed log entry as json to a file in /var/lib/spoor/parsed.
26              
27             =head1 SUBROUTINES/METHODS
28              
29             =head2 write_parsed_entry
30              
31             For parsed entries that meet the criteria, this subroutine writes the entry as JSON to a file located in /var/lib/spoor/parsed.
32              
33             Currently the criteria only allows for parsed entries with the following characteristics to be written:
34              
35             =over 2
36              
37             =item * A successful login event with a mailbox context.
38              
39             =item * A successful forward added partial entry (IP) with a mailbox context.
40              
41             =item * A successful forward added partial entry (Recipient) with a mailbox context, that is forwarding to a email address.
42              
43             =item * A successful forward removed entry with a mailbox context.
44              
45             =back
46              
47             The created filenames adhere to the pattern "type.timestamp.random_element.json", where 'type' would be the type of log
48             that produced the entry ('login', 'access', 'error'), 'timestamp' is the unix timestamp at the time of file creation and
49             the random element is a random integer between 1000000 and 1999999 (inclusive).
50              
51             my $entry = '[2018-09-19 16:02:36 +0000] info [webmaild] 10.10.10.10 ' .
52             '- rorymckinley@blah.capefox.co (possessor: blahuser) - SUCCESS LOGIN webmaild';
53              
54             $parsed_entry_ref = App::Spoor::LoginEntryParser::parse($entry);
55              
56             App::Spoor::ParsedEntryWriter::write_parsed_entry($parsed_entry_ref, App::Spoor::Config::get_application_config());
57              
58             The subroutine does not return anything of significance.
59              
60             =cut
61              
62             sub write_parsed_entry {
63 14     14 1 36073 my $contents_ref = shift;
64 14         33 my $path = (shift)->{'parsed_entries_path'};
65 14         27 my $type = $contents_ref->{type};
66 14         24 my $context = $contents_ref->{context};
67 14         26 my $status = $contents_ref->{status};
68 14         17 my $event = $contents_ref->{event};
69 14         27 my $forward_type = $contents_ref->{forward_type};
70              
71 14 100 100     187 if (
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
72             ($event eq 'login' && $status eq 'success' && $context eq 'mailbox') ||
73             ($event eq 'forward_added_partial_ip' && $status eq 'success' && $context eq 'mailbox') ||
74             (
75             $event eq 'forward_added_partial_recipient' && $status eq 'success' && $forward_type eq 'email' &&
76             $context eq 'mailbox'
77             ) ||
78             ($event eq 'forward_removed' && $status eq 'success' && $context eq 'mailbox')
79             ) {
80 4         13 my $timestamp = time();
81 4         39 my $random_element = int(rand(1000000)) + 1000000;
82 4         51 my $filepath = File::Spec->catdir($path, "$type.$timestamp.$random_element.json");
83 4         19 touch($filepath);
84 4         670 chmod(0600, $filepath);
85              
86 4 50       182 open(my $file_handle, '>', $filepath) or die "Couldn't open: $!";
87 4         120 print $file_handle JSON->new->encode($contents_ref);
88 4         285 close $file_handle;
89              
90 4         54 return $filepath;
91             } else {
92 10         69 return;
93             }
94             }
95              
96             =head1 AUTHOR
97              
98             Rory McKinley, C<< <rorymckinley at capefox.co> >>
99              
100             =head1 BUGS
101              
102             Please report any bugs or feature requests to C<bug-. at rt.cpan.org>, or through
103             the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=.>. I will be notified, and then you'll
104             automatically be notified of progress on your bug as I make changes.
105              
106              
107             =head1 SUPPORT
108              
109             You can find documentation for this module with the perldoc command.
110              
111             perldoc App::Spoor::ParsedEntryWriter
112              
113              
114             You can also look for information at:
115              
116             =over 4
117              
118             =item * RT: CPAN's request tracker (report bugs here)
119              
120             L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=.>
121              
122             =item * AnnoCPAN: Annotated CPAN documentation
123              
124             L<http://annocpan.org/dist/.>
125              
126             =item * CPAN Ratings
127              
128             L<https://cpanratings.perl.org/d/.>
129              
130             =item * Search CPAN
131              
132             L<https://metacpan.org/release/.>
133              
134             =back
135              
136             =head1 LICENSE AND COPYRIGHT
137              
138             Copyright 2019 Rory McKinley.
139              
140             This program is free software; you can redistribute it and/or modify it
141             under the terms of the the Artistic License (2.0). You may obtain a
142             copy of the full license at:
143              
144             L<http://www.perlfoundation.org/artistic_license_2_0>
145              
146             Any use, modification, and distribution of the Standard or Modified
147             Versions is governed by this Artistic License. By using, modifying or
148             distributing the Package, you accept this license. Do not use, modify,
149             or distribute the Package, if you do not accept this license.
150              
151             If your Modified Version has been derived from a Modified Version made
152             by someone other than you, you are nevertheless required to ensure that
153             your Modified Version complies with the requirements of this license.
154              
155             This license does not grant you the right to use any trademark, service
156             mark, tradename, or logo of the Copyright Holder.
157              
158             This license includes the non-exclusive, worldwide, free-of-charge
159             patent license to make, have made, use, offer to sell, sell, import and
160             otherwise transfer the Package with respect to any patent claims
161             licensable by the Copyright Holder that are necessarily infringed by the
162             Package. If you institute patent litigation (including a cross-claim or
163             counterclaim) against any party alleging that the Package constitutes
164             direct or contributory patent infringement, then this Artistic License
165             to you shall terminate on the date that such litigation is filed.
166              
167             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
168             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
169             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
170             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
171             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
172             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
173             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
174             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
175              
176              
177             =cut
178              
179             1; # End of App::Spoor::ParsedEntryWriter