package System::Introspector::Users;
use Moo;
-use IPC::Run qw( run );
+
+use System::Introspector::Util qw(
+ handle_from_command
+ transform_exceptions
+ output_from_file
+ output_from_command
+ files_from_dir
+ handle_from_file
+);
sub gather {
my ($self) = @_;
- my $fh = $self->_open_passwd_fh;
- my %user;
- while (defined( my $line = <$fh> )) {
- my $data = $self->_deparse_htpasswd_line($line);
- my $user = $data->{username};
- my $home = $data->{home};
- $data->{groups} = $self->_gather_user_groups($user);
- $data->{ssh}{keys} = $self->_gather_ssh_keys($user, $home);
- $data->{crontab} = $self->_gather_crontab($user);
- $user{ $data->{uid} } = $data;
- }
- return \%user;
+ return transform_exceptions {
+ my $fh = $self->_open_passwd_fh;
+ my %user;
+ while (defined( my $line = <$fh> )) {
+ my $data = $self->_deparse_htpasswd_line($line);
+ my $user = $data->{username};
+ my $home = $data->{home};
+ $data->{groups} = transform_exceptions {
+ $self->_gather_user_groups($user);
+ };
+ $data->{ssh}{keys} = transform_exceptions {
+ $self->_gather_ssh_keys($user, $home);
+ };
+ $data->{crontab} = transform_exceptions {
+ $self->_gather_crontab($user);
+ };
+ $user{ $data->{uid} } = $data;
+ }
+ return { users => \%user };
+ };
}
sub _gather_crontab {
my ($self, $user) = @_;
- my ($in, $out, $err) = (('') x 3);
- run(['crontab', '-u', $user, '-l'], \$in, \$out, \$err);
- if (length $err) {
+ my ($out, $err, $ok) = output_from_command
+ ['crontab', '-u', $user, '-l'];
+ unless ($ok) {
return {}
if $err =~ m{^no crontab}i;
return { error => $err };
my $ssh_dir = "$home/.ssh/";
return {}
unless -d $ssh_dir;
- my $dh;
- opendir $dh, $ssh_dir
- or return { error => $! };
my %key;
- while (defined( my $item = readdir $dh )) {
+ for my $item (files_from_dir $ssh_dir) {
next unless $item =~ m{\.pub$};
- my $item_path = "$ssh_dir/$item";
- open my $key_fh, '<', $item_path;
- if ($key_fh) {
- $key{ $item }{body} = do { local $/; <$key_fh> };
- }
- else {
- $key{ $item }{error} = $!;
- }
+ $key{ $item } = transform_exceptions {
+ return {
+ body => scalar output_from_file "$ssh_dir/$item",
+ };
+ };
}
return { files => \%key };
}
sub _gather_user_groups {
my ($self, $user) = @_;
- return [split m{\s+}, `groups $user`];
+ my $groups = output_from_command "groups $user";
+ return { list => [split m{\s+}, $groups] };
}
sub _deparse_htpasswd_line {
sub _open_passwd_fh {
my ($self) = @_;
- open my $fh, '<', '/etc/passwd'
- or die "Unable to open /etc/passwd: $!\n";
- return $fh;
+ return handle_from_file '/etc/passwd';
}
1;