File Coverage

blib/lib/System/Introspector/Probe/Users.pm
Criterion Covered Total %
statement 50 52 96.1
branch 6 10 60.0
condition n/a
subroutine 11 11 100.0
pod 0 1 0.0
total 67 74 90.5


line stmt bran cond sub pod time code
1             package System::Introspector::Probe::Users;
2 1     1   27375 use Moo;
  1         16165  
  1         7  
3              
4 1         1049 use System::Introspector::Util qw(
5             handle_from_command
6             transform_exceptions
7             output_from_file
8             output_from_command
9             files_from_dir
10             handle_from_file
11 1     1   2380 );
  1         4  
12              
13             has passwd_file => (is => 'ro', default => sub { '/etc/passwd' });
14              
15             sub gather {
16 1     1 0 1549 my ($self) = @_;
17             return transform_exceptions {
18 1     1   6 my $fh = $self->_open_passwd_fh;
19 1         2 my %user;
20 1         16 while (defined( my $line = <$fh> )) {
21 2         16 my $data = $self->_deparse_htpasswd_line($line);
22 2         21 my $user = $data->{username};
23 2         5 my $home = $data->{home};
24             $data->{groups} = transform_exceptions {
25 2         7 $self->_gather_user_groups($user);
26 2         20 };
27             $data->{ssh}{keys} = transform_exceptions {
28 2         18 $self->_gather_ssh_keys($user, $home);
29 2         85 };
30             $data->{crontab} = transform_exceptions {
31 2         29 $self->_gather_crontab($user);
32 2         84 };
33 2         105 $user{ $data->{username} } = $data;
34             }
35 1         54 return { users => \%user };
36 1         14 };
37             }
38              
39             sub _gather_crontab {
40 2     2   179 my ($self, $user) = @_;
41 2         33 my ($out, $err, $ok) = output_from_command
42             ['crontab', '-u', $user, '-l'];
43 2 50       77 unless ($ok) {
44             return {}
45 0 0       0 if $err =~ m{^no crontab}i;
46 0         0 return { __error__ => $err };
47             }
48 2         49 return { body => $out };
49             }
50              
51             sub _gather_ssh_keys {
52 2     2   8 my ($self, $user, $home) = @_;
53 2         11 my $ssh_dir = "$home/.ssh";
54 2         9 my $ssh_authkeys = "$ssh_dir/authorized_keys";
55             return {
56 2 100       152 files => {},
57             authorized => { file_name => $ssh_authkeys, body => '' }
58             } unless -d $ssh_dir;
59 1         2 my %key;
60 1         8 for my $item (files_from_dir $ssh_dir) {
61 2 100       20 next unless $item =~ m{\.pub$};
62             $key{ $item } = transform_exceptions {
63             return {
64 1     1   14 file_name => "$ssh_dir/$item",
65             body => scalar output_from_file "$ssh_dir/$item",
66             };
67 1         27 };
68             }
69             my $auth_keys = (-e $ssh_authkeys) ? (transform_exceptions {
70             return {
71 1     1   6 file_name => $ssh_authkeys,
72             body => scalar output_from_file $ssh_authkeys,
73             };
74 1 50       96 }) : { file_name => $ssh_authkeys, body => '' };
75 1         21 return { files => \%key, authorized => $auth_keys };
76             }
77              
78             sub _gather_user_groups {
79 2     2   3 my ($self, $user) = @_;
80 2         11 my $groups = output_from_command [groups => $user];
81 2         165 chomp $groups;
82 2         32 $groups =~ s{^ .* : \s* }{}x;
83 2         63 return [split m{\s+}, $groups];
84             }
85              
86             sub _deparse_htpasswd_line {
87 2     2   6 my ($self, $line) = @_;
88 2         6 chomp $line;
89 2         4 my %value;
90 2         29 @value{qw( username uid gid comment home shell )}
91             = (split m{:}, $line)[0, 2..6];
92 2         11 return \%value;
93             }
94              
95             sub _open_passwd_fh {
96 1     1   3 my ($self) = @_;
97 1         12 return handle_from_file $self->passwd_file;
98             }
99              
100             1;
101              
102             __END__