summaryrefslogtreecommitdiff
path: root/libpiny/lib/Piny/Group.pm
diff options
context:
space:
mode:
Diffstat (limited to 'libpiny/lib/Piny/Group.pm')
-rw-r--r--libpiny/lib/Piny/Group.pm136
1 files changed, 136 insertions, 0 deletions
diff --git a/libpiny/lib/Piny/Group.pm b/libpiny/lib/Piny/Group.pm
new file mode 100644
index 0000000..86a6d95
--- /dev/null
+++ b/libpiny/lib/Piny/Group.pm
@@ -0,0 +1,136 @@
+# Copyright © 2010 Julian Blake Kongslie <jblake@omgwallhack.org>
+# Licensed under the BSD 3-clause license.
+
+use strict;
+use warnings;
+
+package Piny::Group;
+
+use Moose;
+use MooseX::StrictConstructor;
+
+use Piny::User;
+
+# Attributes
+
+has 'gid' =>
+ ( is => 'ro'
+ , isa => 'Int'
+ , lazy_build => 1
+ );
+
+has 'name' =>
+ ( is => 'ro'
+ , isa => 'Str'
+ , lazy_build => 1
+ );
+
+has 'grent' =>
+ ( is => 'ro'
+ , isa => 'ArrayRef'
+ , lazy_build => 1
+ , init_arg => undef
+ );
+
+has 'members' =>
+ ( is => 'ro'
+ , isa => 'ArrayRef[Piny::User]'
+ , lazy_build => 1
+ , init_arg => undef
+ );
+
+# Public methods
+
+sub add_member {
+ my ( $s, @users ) = @_;
+
+ foreach my $user ( @users ) {
+ system( "/usr/sbin/adduser", $user->name( ), $s->name( ) );
+ $user->clear_groups( );
+ };
+
+ $s->clear_members( );
+};
+
+sub remove_member {
+ my ( $s, @users ) = @_;
+
+ foreach my $user ( @users ) {
+ system( "/usr/sbin/deluser", $user->name( ), $s->name( ) );
+ $user->clear_groups( );
+ };
+
+ $s->clear_members( );
+};
+
+# Builder methods
+
+# If constructed with just one argument, then
+# * If that argument is numeric, treat it as a GID.
+# * Otherwise, treat it as a name.
+around BUILDARGS => sub {
+ my ( $orig, $class ) = ( shift, shift );
+
+ if ( @_ == 1 && ! ref $_[0] ) {
+ if ( $_[0] =~ m/^\d+$/ ) {
+ return $class->$orig( gid => $_[0] );
+ } else {
+ return $class->$orig( name => $_[0] );
+ };
+ } else {
+ return $class->$orig( @_ );
+ };
+};
+
+sub BUILD {
+ my ( $s ) = @_;
+
+ if ( not ( $s->has_gid( ) or $s->has_name( ) ) ) {
+ die "You must provide either GID or name!";
+ };
+
+ if ( $s->has_gid( ) and $s->has_name( ) ) {
+ die "You must not provide both GID and name!";
+ };
+};
+
+sub _build_gid {
+ my ( $s ) = @_;
+
+ return $s->grent( )->[2];
+};
+
+sub _build_name {
+ my ( $s ) = @_;
+
+ return $s->grent( )->[0];
+};
+
+sub _build_grent {
+ my ( $s ) = @_;
+
+ if ( $s->has_gid( ) ) {
+ my @res = getgrgid( $s->gid( ) );
+ die "getgrgid( " . $s->gid( ) . " ) failed: $!" unless @res;
+ return \@res;
+ } elsif ( $s->has_name( ) ) {
+ my @res = getgrnam( $s->name( ) );
+ die "getgrnam( " . $s->name( ) . " ) failed: $!" unless @res;
+ return \@res;
+ } else {
+ die "Not enough information provided to lookup group!";
+ };
+};
+
+sub _build_members {
+ my ( $s ) = @_;
+
+ return [ ] if ( $s->grent( )->[3] eq "" );
+ return [ map { Piny::User->new( name => $_ ) } split( /:/, $s->grent( )->[3] ) ];
+};
+
+# Moose boilerplate
+
+__PACKAGE__->meta->make_immutable;
+
+1;