/
Groups.pm
161 lines (106 loc) · 3.64 KB
/
Groups.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
use v6.c;
=begin pod
=head1 NAME
Unix::Groups - access to details from C</etc/group>
=head1 SYNOPSIS
=begin code
use Unix::Groups;
my $groups = Unix::Groups.new;
say "The logged in user is member of these groups:";
for $groups.groups-for-user($*USER.Str) -> $group {
say $group.name;
}
=end code
=head1 DESCRIPTION
This module provides access to the group details from C</etc/group>, with
similar to C<getgrent()>, C<getgrnam> and C<getgrgid> in the Unix standard
C library.
The methods either return a L<Unix::Groups::Group|#Unix::Groups::Group> object
or an array of those objects.
Because this module goes directly to the group file, if your system is
configured to retrieve its group information from e.g. C<NIS> or C<LDAP>
it may not necessarily reflect all the groups present, just the local ones.
=head1 METHODS
=head2 method groups
method groups() returns Array[User::Groups::Group]
Returns the full list of groups, sorted in order of group id.
=head2 method group-by-name
method group-by-name(Str $name) returns User::Groups::Group
Returns the group specified by C<$name> or the type object if none exists.
=head2 method group-by-id
method group-by-id(Int $id) returns User::Groups::Group
Returns the group specified by the integer group id of the type object if
none exists.
=head2 method groups-for-user
method groups-for-user(Str() $user) returns Array[User::Groups::Group]
This returns a list of the groups that the specified user is a member of
or an empty list if the user isn't in any groups.
=head1 Unix::Groups::Group
This is the class that represents the groups returned by the above methods.
It stringifies to the group name and numifies to the group id.
It has attributes that reflect the fields in C</etc/group>
=head2 gid
The L<Int> id of the group.
=head2 name
The name of the group.
=head2 password
The password for the group if set, most modern systems place this in a
shadow file so this may be empty or some other meaningless value.
=head2 users
This is a list of the names of the users that are members of the group.
=end pod
class Unix::Groups:ver<0.0.3>:auth<github:jonathanstowe> {
constant GROUPFILE = '/etc/group';
class Group {
has Int $.gid;
has Str $.name;
has Str $.password;
has Str @.users;
multi submethod BUILD(Str :$line!) {
my ( $name, $pass, $id, $users ) = $line.split(':');
$!gid = $id.Int;
$!name = $name;
$!password = $pass;
@!users = $users.split(',');
}
method Str() returns Str {
$!name;
}
method Numeric() returns Numeric {
$!gid;
}
}
has IO::Handle $!handle handles <lines>;
has Group @.groups;
has Group %!group-by-id;
has Group %!group-by-name;
submethod BUILD() {
$!handle = GROUPFILE.IO.open();
}
method groups() returns Array[Group] {
if !?@!groups.elems {
for self.lines.map({Group.new(line => $_)}).sort({$^a.gid}) -> $g {
@!groups.push($g);
%!group-by-id{$g.gid} = $g;
%!group-by-name{$g.name} = $g;
}
}
@!groups;
}
method group-by-name(Str $name) returns Group {
%!group-by-name{$name};
}
method group-by-id(Int $id) returns Group {
%!group-by-id{$id};
}
method groups-for-user(Str() $user) returns Array[Group] {
my Group @groups;
for self.groups -> $group {
if ?$group.users.grep($user) {
@groups.push($group);
}
}
@groups;
}
}
# vim: expandtab shiftwidth=4 ft=perl6