File Coverage

blib/lib/Authen/PAAS/Subject.pm
Criterion Covered Total %
statement 72 72 100.0
branch 14 16 87.5
condition 1 3 33.3
subroutine 13 13 100.0
pod 11 11 100.0
total 111 115 96.5


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Authen::PAAS::Subject by Daniel Berrange
4             #
5             # Copyright (C) 2004-2006 Dan Berrange
6             #
7             # This program is free software; you can redistribute it and/or modify
8             # it under the terms of the GNU General Public License as published by
9             # the Free Software Foundation; either version 2 of the License, or
10             # (at your option) any later version.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             # GNU General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License
18             # along with this program; if not, write to the Free Software
19             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20             #
21             # $Id: Subject.pm,v 1.5 2005/08/21 10:57:06 dan Exp $
22              
23             =pod
24              
25             =head1 NAME
26              
27             Authen::PAAS::Subject - represents an authenticated party
28              
29             =head1 SYNOPSIS
30              
31             use Authen::PAAS::Subject;
32              
33             ####### Creating a populating a subject..
34              
35             # Create a new anonymous subject with no credentials
36             my $subject = Authen::PAAS::Subject->new();
37              
38             # Add a principal eg a UNIX username, or a Kerberos
39             # principal, or some such
40             my $prin = SomePrincipal->new();
41             $subject->add_principal($prin)
42              
43             # Add a credential. eg some form of magic token
44             # representing a previously added principal
45             my $cred = SomeCredential->new($principal)
46             $subject->add_credential($cred);
47              
48              
49             ######## Fetching and querying a subject
50              
51             # Create a context module for performing auth
52             my $context = Context->new($config, "myapp");
53              
54             # Attempt to login
55             my $subject = $context->login($callbacks);
56              
57             if ($subject) {
58             # Retrieve set of all principals
59             my @princs = $subject->principals;
60              
61             # Or only get principal of particular class
62             my $princ = $subject->principal("SomePrincipal");
63              
64             # Retrieve set of all credentials
65             my @cred = $subject->credentials;
66              
67             # Or only get credential of particular class
68             my $cred = $subject->credential("SomeCredential");
69             } else {
70             die "login failed";
71             }
72              
73             =head1 DESCRIPTION
74              
75             The C module provides a representation
76             of an authenticated party, be they a human user, or a independantly
77             operating computing service. An authenticated subject will have
78             one of more principals associated with them, which can be thought
79             of as their set of C. These are represented by the
80             L module. Some authentication mechanisms
81             will also associate some form of security related token with a
82             subject, thus an authenticated subject may also have zero or more
83             credentials. These are represented by the L
84             module.
85              
86             An authenticated subject is typically obtained via the C
87             method on the L module. This creates an
88             anonymous subject, and invokes a set of login modules
89             (L), which in turn populate the
90             subject with principals and credentials.
91              
92             =head1 METHODS
93              
94             =over 4
95              
96             =cut
97              
98             package Authen::PAAS::Subject;
99              
100              
101 3     3   26161 use strict;
  3         5  
  3         92  
102 3     3   17 use warnings;
  3         3  
  3         2338  
103              
104             our $VERSION = '1.0.0';
105              
106              
107             =item my $subject = Authen::PAAS::Subject->new();
108              
109             Create a new subject, with no initial principals
110             or credentials.
111              
112             =cut
113              
114             sub new {
115 12     12 1 3217 my $proto = shift;
116 12   33     77 my $class = ref($proto) || $proto;
117 12         26 my $self = {};
118 12         32 my %params = @_;
119              
120 12         34 $self->{principals} = {};
121 12         31 $self->{credentials} = {};
122              
123 12         32 bless $self, $class;
124              
125 12         38 return $self;
126             }
127              
128              
129             =item $subject->add_principal($owner, $principal)
130              
131             Adds a principal to the subject. The C<$owner> parameter
132             should be the class name of the login module owning the
133             principal. The principal parameter must be a subclass of
134             the L class.
135              
136             =cut
137              
138             sub add_principal {
139 6     6 1 24 my $self = shift;
140 6         9 my $owner = shift;
141 6         8 my $principal = shift;
142              
143 6         10 my $type = ref($principal);
144 6 100       646 $self->{principals}->{$owner} = {} unless exists $self->{principals}->{$owner};
145 6         25 $self->{principals}->{$owner}->{$type} = $principal;
146             }
147              
148              
149             =item $subject->remove_principal($owner[, $type]);
150              
151             Removes a previously added principal from the subject. The
152             C<$id> parameter is the index of the principal previously
153             added via the C method.
154              
155             =cut
156              
157             sub remove_principal {
158 3     3 1 1641 my $self = shift;
159 3         7 my $owner = shift;
160 3         7 my $type = shift;
161              
162 3 50       16 return unless exists $self->{principals}->{$owner};
163 3 100       13 if ($type) {
164 2         10 delete $self->{principals}->{$owner}->{$type};
165             } else {
166 1         5 delete $self->{principals}->{$owner};
167             }
168             }
169              
170              
171             =item my @principals = $subject->principals_by_owner($owner);
172              
173             Retrieves a list of all the principals for the subject associated
174             with the owner specified in the C<$owner> parameter. The
175             value of the C<$owner> parameter is the class name of a login
176             module
177              
178             =cut
179              
180             sub principals_by_owner {
181 10     10 1 35197 my $self = shift;
182              
183 10         21 my $owner = shift;
184 10 100       54 return () unless exists $self->{principals}->{$owner};
185 7         10 return values %{$self->{principals}->{$owner}};
  7         47  
186             }
187              
188             =item my @principals = $subject->principals_by_type($type);
189              
190             Retrieves the first matching principal of a given type. The
191             C<$type> parameter should be the Perl module name of the
192             principal implementation.
193              
194             =cut
195              
196             sub principals_by_type {
197 8     8 1 8347 my $self = shift;
198 8         16 my $type = shift;
199              
200 8         21 return grep { $_->isa($type) } $self->principals;
  15         95  
201             }
202              
203             =item my @principals = $subject->principals;
204              
205             Retrieves a list of all the principals for the subject.
206              
207             =cut
208              
209             sub principals {
210 17     17 1 66 my $self = shift;
211              
212 17         24 my @principals;
213 17         24 foreach my $owner (keys %{$self->{principals}}) {
  17         72  
214 22         24 push @principals, values %{$self->{principals}->{$owner}};
  22         70  
215             }
216 17         69 return @principals;
217             }
218              
219              
220             =item $subject->add_credential($owner, $credential)
221              
222             Adds a credential to the subject. The C<$owner> parameter
223             should be the class name of the login module owning the
224             credential. The credential parameter must be a subclass of
225             the L class.
226              
227             =cut
228              
229             sub add_credential {
230 3     3 1 11 my $self = shift;
231 3         4 my $owner = shift;
232 3         3 my $credential = shift;
233              
234 3         4 my $type = ref($credential);
235 3 100       14 $self->{credentials}->{$owner} = {} unless exists $self->{credentials}->{$owner};
236 3         10 $self->{credentials}->{$owner}->{$type} = $credential;
237             }
238              
239             =item $subject->remove_credential($owner[, $type]);
240              
241             Removes a previously added credential from the subject. The
242             C<$id> parameter is the index of the credential previously
243             added via the C method.
244              
245             =cut
246              
247             sub remove_credential {
248 2     2 1 1628 my $self = shift;
249 2         5 my $owner = shift;
250 2         4 my $type = shift;
251              
252 2 50       10 return unless exists $self->{credentials}->{$owner};
253 2 100       7 if ($type) {
254 1         4 delete $self->{credentials}->{$owner}->{$type};
255             } else {
256 1         5 delete $self->{credentials}->{$owner};
257             }
258             }
259              
260             =item my @credentials = $subject->credentials_by_owner($owner);
261              
262             Retrieves a list of all the credentials for the subject associated
263             with the owner specified in the C<$owner> parameter. The
264             value of the C<$owner> parameter is the class name of a login
265             module
266              
267             =cut
268              
269             sub credentials_by_owner {
270 5     5 1 4977 my $self = shift;
271              
272 5         13 my $owner = shift;
273 5 100       35 return () unless exists $self->{credentials}->{$owner};
274 2         3 return values %{$self->{credentials}->{$owner}};
  2         14  
275             }
276              
277             =item my @credentials = $subject->credentials_by_type($type);
278              
279             Retrieves the first matching credential of a given type. The
280             C<$type> parameter should be the Perl module name of the
281             credential implementation.
282              
283             =cut
284              
285             sub credentials_by_type {
286 5     5 1 3994 my $self = shift;
287 5         10 my $type = shift;
288              
289 5         16 return grep { $_->isa($type) } $self->credentials;
  9         60  
290             }
291              
292             =item my @credentials = $subject->credentials;
293              
294             Retrieves a list of all the credentials for the subject.
295              
296             =cut
297              
298             sub credentials {
299 9     9 1 648 my $self = shift;
300              
301 9         14 my @credentials;
302 9         13 foreach my $owner (keys %{$self->{credentials}}) {
  9         33  
303 12         17 push @credentials, values %{$self->{credentials}->{$owner}};
  12         34  
304             }
305 9         37 return @credentials;
306             }
307              
308             1 # So that the require or use succeeds.
309              
310             __END__