use more reusable utils for I/O operations, better error handling, have a top-level...
Robert 'phaylon' Sedlacek [Wed, 9 May 2012 23:13:09 +0000 (23:13 +0000)]
lib/System/Introspector/Users.pm

index b9c477b..4510c6c 100644 (file)
@@ -1,28 +1,44 @@
 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 };
@@ -35,27 +51,22 @@ sub _gather_ssh_keys {
     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 {
@@ -69,9 +80,7 @@ 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;