File Coverage

File:/home/mik/work/module/Tivoli/AccessManager/Admin/SSO/Cred.pm
Coverage:100.0%

linestmtbrancondsubpodtimecode
1package Tivoli::AccessManager::Admin::SSO::Cred;
2
15
15
15
144
77
213
use strict;
3
15
15
15
203
59
212
use warnings;
4
15
15
15
201
71
273
use Carp;
5
15
15
15
228
65
262
use Tivoli::AccessManager::Admin::Response;
6
15
15
15
201
50
249
use Tivoli::AccessManager::Admin::SSO::Web;
7
15
15
15
209
60
199
use Tivoli::AccessManager::Admin::SSO::Group;
8
15
15
15
180
72
337
use Data::Dumper;
9
10#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
11# $Id$
12#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
13$Tivoli::AccessManager::Admin::SSO::Cred::VERSION = '0.04';
14
15
230
use Inline(C => 'DATA',
15                INC => '-I/opt/PolicyDirector/include',
16                LIBS => ' -lpthread -lpdadminapi -lstdc++',
17                CCFLAGS => '-Wall',
18# VERSION => '0.04',
19                NAME => 'Tivoli::AccessManager::Admin::SSO::Cred',
20
15
15
213
62
           );
21
22sub _get_credtype {
23
7
60
    my ($tam,$cred) = @_;
24
7
56
    my $resp;
25
26
7
170
    my $test = Tivoli::AccessManager::Admin::SSO::Web->new( $tam, name => $cred );
27
7
462
    if ($test->exist) {
28
5
81
        return 'web';
29    }
30    else {
31
2
70
        $test = Tivoli::AccessManager::Admin::SSO::Group->new( $tam, name => $cred );
32
2
30
        if ($test->exist) {
33
1
19
            return 'group';
34        }
35    }
36
37
1
8
    return '';
38}
39
40sub new {
41
23
1
374
    my $class = shift;
42
23
236
    my $cont = shift;
43
23
1200
    unless ( defined($cont) and UNIVERSAL::isa($cont,'Tivoli::AccessManager::Admin::Context' ) ) {
44
4
248
        warn "Incorrect syntax -- did you forget the context?\n";
45
4
109
        return undef;
46    }
47
48
19
471
    my $self = bless {}, $class;
49
19
345
    if ( @_ % 2 ) {
50
2
110
        warn "Incorrent syntax -- I really need a hash\n";
51
2
41
        return undef;
52    }
53
17
449
    my %opts = @_;
54
55
17
263
    $self->{context} = $cont;
56
17
287
    $self->{resource} = $opts{resource} || '';
57
17
321
    $self->{uid} = $opts{uid} || '';
58
17
249
    $self->{ssouid} = $opts{ssouid} || '';
59
17
277
    $self->{ssopwd} = $opts{ssopwd} || '';
60
17
305
    $self->{type} = $opts{type} || '';
61
62
63
17
455
    if ( $self->{resource} and not $self->{type} ) {
64
7
98
        $self->{type} = _get_credtype($cont,$self->{resource}) || 'web';
65    }
66
67
17
907
    $self->_ssocred_stash();
68
69
17
494
    if ( $self->{resource} && $self->{uid} ) {
70
13
336
        my $resp = Tivoli::AccessManager::Admin::Response->new();
71
13
910128
        my $rc = $self->ssocred_get($resp);
72
13
402
        $self->{exist} = $rc;
73    }
74    else {
75
4
61
        $self->{exist} = 0;
76    }
77
17
1058
    return $self;
78}
79
80sub create {
81
16
1
295
    my $self = shift;
82
83
16
287
    unless ( ref $self ) {
84
9
121
        my $pd = shift;
85
9
182
        $self = new( $self, $pd, @_ );
86    }
87
88
16
477
    my $resp = Tivoli::AccessManager::Admin::Response->new();
89
90
16
312
    if ( @_ % 2 ) {
91
1
25
        $resp->set_message("Incorrent syntax -- I really need a hash");
92
1
26
        $resp->set_isok(0);
93
1
20
        return $resp;
94    }
95
15
347
    my %opts = @_;
96
97
15
427
    $self->{resource} = $opts{resource} || $self->{resource} || '';
98
15
327
    $self->{uid} = $opts{uid} || $self->{uid} || '';
99
15
412
    $self->{type} = $opts{type} || $self->{type} || '';
100
15
393
    $self->{ssouid} = $opts{ssouid} || $self->{ssouid} || '';
101
15
320
    $self->{ssopwd} = $opts{ssopwd} || $self->{ssopwd} || '';
102
103
15
412
    unless ( $self->{uid} and $self->{ssouid} ) {
104
2
65
        $resp->set_message("You must define both the UID and the SSO UID");
105
2
58
        $resp->set_isok(0);
106
2
52
        return $resp;
107    }
108
109
13
163
    unless ( $self->{ssopwd} ) {
110
1
44
        $resp->set_message("You must define the SSO password");
111
1
38
        $resp->set_isok(0);
112
1
21
        return $resp;
113    }
114
115
12
149
    unless ( $self->{resource} ) {
116
1
40
        $resp->set_message("You must define the SSO resource");
117
1
36
        $resp->set_isok(0);
118
1
30
        return $resp;
119    }
120
121
11
1136810
    my $rc = $self->ssocred_create($resp);
122
11
556
    if ( $resp->isok ) {
123
10
689545
        $rc = $self->ssocred_get($resp);
124
10
446
        $self->{exist} = $rc;
125    }
126
11
429
    $resp->set_value($self);
127
128
11
325
    return $resp;
129}
130
131# This must be a read only call. The documentation implies you can change the
132# resource id via the ssocred_set call. I do not think you really can.
133sub resource {
134
2
1
37
    my $self = shift;
135
2
58
    my $resp = Tivoli::AccessManager::Admin::Response->new();
136
137
2
171
    my $rc = $self->ssocred_getid;
138
2
35
    $self->{resource} = $rc;
139
2
41
    $resp->set_value( $rc );
140
2
84
    return $resp;
141}
142
143sub ssopwd {
144
6
1
84
    my $self = shift;
145
6
183
    my $resp = Tivoli::AccessManager::Admin::Response->new();
146
6
53
    my ($ssopwd,$rc);
147
148
6
165
    if ( @_ == 1 ) {
149
2
23
        $ssopwd = shift;
150    }
151    elsif ( @_ % 2 ) {
152
1
30
        $resp->set_message("Invalid syntax");
153
1
26
        $resp->set_isok(0);
154
1
25
        return $resp;
155    }
156    elsif (@_) {
157
2
46
        my %opts = @_;
158
2
100
        $ssopwd = $opts{ssopwd} || '';
159    }
160
161
5
77
    if ( defined( $ssopwd ) ) {
162
4
47
        $self->{ssopwd} = $ssopwd;
163
4
287005
        $self->ssocred_set($resp);
164
4
261857
        $rc = $self->ssocred_get($resp);
165    }
166
167
5
215
    if ( $resp->isok ) {
168
4
230
        $rc = $self->ssocred_getssopassword;
169
4
74
        $self->{ssopwd} = $rc;
170
4
95
        $resp->set_value( $rc );
171    }
172
5
135
    return $resp;
173}
174
175sub ssouid {
176
6
1
84
    my $self = shift;
177
6
151
    my $resp = Tivoli::AccessManager::Admin::Response->new();
178
6
55
    my ($ssouid,$rc);
179
180
6
139
    if ( @_ == 1 ) {
181
2
26
        $ssouid = shift;
182    }
183    elsif ( @_ % 2 ) {
184
1
30
        $resp->set_message("Invalid syntax");
185
1
31
        $resp->set_isok(0);
186
1
25
        return $resp;
187    }
188    elsif (@_) {
189
2
42
        my %opts = @_;
190
2
94
        $ssouid = $opts{ssouid} || '';
191    }
192
193
5
86
    if ( $ssouid ) {
194
3
25
        $self->{ssouid} = $ssouid;
195
3
202732
        $self->ssocred_set($resp);
196
3
182091
        $rc = $self->ssocred_get($resp);
197    }
198
199
5
670
    if ( $resp->isok ) {
200
4
221
        $rc = $self->ssocred_getssouser;
201
4
64
        $self->{ssopwd} = $rc;
202
4
90
        $resp->set_value( $rc );
203    }
204
5
94
    return $resp;
205}
206
207# This too must be a read only method.
208sub type {
209
2
1
61
    my $self = shift;
210
2
51
    my $resp = Tivoli::AccessManager::Admin::Response->new();
211
2
25
    my ($type,$rc);
212
213
2
211
    $rc = $self->ssocred_getssotype;
214
2
36
    $self->{type} = $rc;
215
2
53
    $resp->set_value( $rc );
216
217
2
46
    return $resp;
218}
219
220sub user {
221
2
1
33
    my $self = shift;
222
2
52
    my $resp = Tivoli::AccessManager::Admin::Response->new();
223
2
24
    my ($uid,$rc);
224
225
2
165
    $rc = $self->ssocred_getuser;
226
2
32
    $self->{uid} = $rc;
227
2
55
    $resp->set_value( $rc );
228
229
2
35
    return $resp;
230}
231
232sub list {
233
9
1
149
    my $class = shift;
234
9
168
    my $pd = ref($class) ? $class->{context} : shift;
235
9
254
    my $resp = Tivoli::AccessManager::Admin::Response->new();
236
9
112
    my ($uid,@rc);
237
238
9
273
    if ( @_ == 1 ) {
239
1
15
        $uid = shift;
240    }
241    elsif ( @_ % 2 ) {
242
1
35
        $resp->set_message("Invalid syntax");
243
1
36
        $resp->set_isok(0);
244
1
31
        return $resp;
245    }
246    elsif (@_) {
247
3
72
        my %opts = @_;
248
3
102
        $uid = $opts{uid} || '';
249    }
250    elsif ( ref($class) ) {
251
1
16
        $resp = $class->user;
252
1
16
        $uid = $resp->value;
253    }
254
255
8
401
    unless ( defined($pd) and UNIVERSAL::isa($pd,'Tivoli::AccessManager::Admin::Context' ) ) {
256
2
56
        $resp->set_message("Incorrect syntax -- did you forget the context?");
257
2
46
        $resp->set_isok(0);
258
2
45
        return $resp;
259    }
260
6
166
    unless ( defined($uid) and $uid ) {
261
2
45
        $resp->set_message("Invalid syntax -- please provide the userid");
262
2
45
        $resp->set_isok(0);
263
2
43
        return $resp;
264    }
265
266
4
266818
    my @hrefs = ssocred_list($pd,$resp,$uid);
267
4
289
    if ( $resp->isok ) {
268
3
63
        for ( @hrefs ) {
269
3
3
38
195
            push @rc,Tivoli::AccessManager::Admin::SSO::Cred->new($pd, %{$_});
270        }
271
3
106
        $resp->set_value(\@rc);
272    }
273
4
167
    return $resp;
274}
275
276sub delete {
277
12
1
179
    my $self = shift;
278
12
268
    my $resp = Tivoli::AccessManager::Admin::Response->new();
279
280
12
167
    unless ( $self->exist ) {
281
1
26
        $resp->set_message("The SSO Cred " . $self->resource . " does not exist");
282
1
14
        $resp->set_iswarning(1);
283
1
15
        return $resp;
284    }
285
286
11
859645
    my $rc = $self->ssocred_delete($resp);
287
11
495
    $resp->set_value($rc);
288
11
180
    $self->{exist} = 0 if $resp->isok;
289
11
185
    return $resp;
290}
291
292
13
1
241
sub exist { return $_[0]->{exist}; }
293
294sub DESTROY {
295
19
238
    my $self = shift;
296
297
19
519
    $self->_ssocredfree;
298}
299
3001;
301
302 - 603
=head1 NAME

Tivoli::AccessManager::Admin::SSO::Cred

=head1 SYNOPSIS

    use Tivoli::AccessManager::Admin;

    my $pd = Tivoli::AccessManager::Admin->new( password => 'N3ew0nk' );
    my $sso = Tivoli::AccessManager::Admin::SSO::Cred->new( $pd,
					resource => 'fred',
					uid  => 'mik',
					ssouid => 'mikfire',
					ssopwd => 'pa$$w0rd',
				      ); 
    unless ( $sso->exist ) {
	$resp = $sso->create;
    }

    $resp = $sso->resource();

    $resp = $sso->ssopwd('derf');

    $resp = $sso->ssopwd();

    # SSOUID
    $resp = $sso->ssouid('derf');

    $resp = $sso->ssouid();

    # TYPE
    $resp = $sso->type();

    # USER
    $resp = $sso->user();

    $resp = $sso->list();
    for ( $resp->value ) {
	isa_ok($_, "Tivoli::AccessManager::Admin::SSO::Cred");
    }

=head1 DESCRIPTION

L<Tivoli::AccessManager::Admin::SSO::Cred> provides the interface to create and modify GSO
credentials.

=head1 CONSTRUCTOR

=head2 new(PDADMIN[,resource =E<gt> NAME, uid =E<gt> UID, ssouid =E<gt> GSO User ID, ssopwd =E<gt> GSO password, type =E<gt> E<lt>web|groupE<gt>])

Creates a blessed L<Tivoli::AccessManager::Admin::SSO::Cred> object.  

=head3 Parameters

=over 4

=item PDADMIN

An initialized L<Tivoli::AccessManager::Admin::Context> object.  As with every other class, the
only way to change the context is to destroy the L<Tivoli::AccessManager::Admin::SSO::Cred>
object and recreate it with the new context.  This parameter is required.

=item resource =E<gt> NAME

The name of the GSO resource.  This resource must already exist or an error
will be generated.  This parameter is optional but can only be provided to
L</"new"> or L</"create">.  Most other methods will not work without the
resource name.

=item uid =E<gt> UID

The user's ID in TAM.  As with resource, this parameter is optional, but can
only be given to L</"new"> or L</"create">.  Most of the methods will not work
without it.

=item ssouid =E<gt> GSO User ID

The user ID to presented to the back end.  This parameter is optional and can
be provided/changed at any time.

=item ssopwd =E<gt> GSO password

The password to be presented to the back end.  This parameter is optional and
can be changed/provided when ever.  I should make the observation that this
password is stored in plain text in the L<Tivoli::AccessManager::Admin::SSO::Cred> object.  This
means it may be readable in a core dump or something similar.  Caveat emptor.

=item type =E<gt> E<lt>web|groupE<gt>

Defines the resource as a web or group resource.  This is optional.  If not
provided, I will try to figure it out.  If I cannot figure out, it defaults to
"web".

=back

=head3 Returns

A fully blessed L<Tivoli::AccessManager::Admin::SSO::Cred> object under normal circumstances,
undef otherwise.  Since no TAM API calls are made by this method, "other" can
loosely be defined as "syntax error".

=head2 create(PDADMIN,resource =E<gt> NAME, uid =E<gt> UID, ssouid =E<gt> GSO User ID, ssopwd =E<gt> GSO password[, type =E<gt> E<lt>web|groupE<gt>])

Initializes the L<Tivoli::AccessManager::Admin::SSO::Cred> and creates it in TAM as well.

=head3 Parameters

See the parameter list for L</"new">.  The only difference is that all of the
parameters except type are now required.

=head3 Returns

A L<Tivoli::AccessManager::Admin::Response> object indicating the success or failure of the
create operation.  If it could be created, the new L<Tivoli::AccessManager::Admin::SSO::Cred>
object will be embedded in the response object as well.

=head1 CLASS METHODS

=head2 list(PDADMIN, 'uid')

Lists all GSO credentials for the provided uid.

=head3 Parameters

=over 4

=item PDADMIN

An initialized L<Tivoli::AccessManager::Admin::Context> object.  

=item uid =E<gt> UID

The user's ID in TAM.  

=back

=head3 Returns

A list of initialized L<Tivoli::AccessManager::Admin::SSO::Cred> objects, one for each GSO
credential the user has.  This list may be empty.  Please do note that this is
different from every other list method in Tivoli::AccessManager::Admin.

This list is, of course, embedded in a L<Tivoli::AccessManager::Admin::Response> object.

=head1 METHODS

The standard disclaimer.  All the methods will return a
L<Tivoli::AccessManager::Admin::Response> object unless specifically stated otherwise.  See the
documentation for that module on how to coax the values out.

The methods also follow the same basic pattern.  If an optional parameter is
provided, it will have the affect of setting the attribute.  All method calls
will embed the results of a 'get' in the L<Tivoli::AccessManager::Admin::Response> object.

=head2 create( [resource =E<gt> NAME, uid =E<gt> UID, ssouid =E<gt> GSO User ID, ssopwd =E<gt> GSO password, type =E<gt> E<lt>web|groupE<gt>])

As you might expect, create can also be used as a method call.

=head3 Parameters

See L</"new"> for a full description.  Only those parameters not provided to
L</"new"> need to be sent to L</"create">.  However, all of them need to be
provided to one method or the other (except type) for the create call to work.

=head3 Returns

The success or failure of the operation.

=head2 delete

Deletes the user's GSO cred.

=head3 Parameters

None.

=head3 Returns

The success or failure of the operation.

=head2 ssopwd('password')

Gets/sets the GSO password for this resource.

=head3 Parameters

=over 4

=item 'password'

The new GSO password.

=back

=head3 Returns

The GSO password.  Need I repeat the warnings about plain text passwords in
memory?

=head2 ssouid('UID')

Gets/sets teh GSO user ID.

=head3 Parameters

=over 4

=item 'UID'

The new GSO user ID.

=back

=head3 Returns

The GSO user ID.  

The following methods are all read only.  The documentation for the underlying
API calls implies otherwise, but I was not able to make it work.  Rather than
cause problems, I thought it better to make them read only.

=head2 resource

Returns the name of the GSO resource to which the cred belongs.  

=head3 Parameters

None.

=head3 Returns

The name of the GSO resource.

=head2 type

Returns the type of the GSO resource 

=head3 Parameters

None.

=head3 Returns

'web' or 'group'

=head2 user

Returns the TAM user ID associated with the resource

=head3 Parameters

None.

=head3 Returns

The TAM user ID

=head2 exist

Determines of the GSO cred exists or not.

=head3 Parameters

None.

=head3 Returns

1 if the object exists, 0 otherwise.

=head1 ACKNOWLEDGEMENTS

See L<Tivoli::AccessManager::Admin> for the list.  This was not possible without the help of a
bunch of people smarter than I.

=head1 BUGS

None known.

=head1 TODO

I need to figure out if the three read only methods can be made read/write.

I need to make the create and new methods smarter.  I would really like them
to be able to figure out if the resource is a web or group resource.  I would
also like a force option that will create the GSO resource if:
   o it does not already exist and
   o the type was provided in the method call

=head1 AUTHOR

Mik Firestone E<lt>mikfire@gmail.comE<gt>

=head1 COPYRIGHT

Copyright (c) 2006-2013 Mik Firestone.  All rights reserved.  This program is
free software; you can redistibute it and/or modify it under the same terms as
Perl itself.

All references to TAM, Tivoli Access Manager, etc are copyrighted, trademarked
and otherwise patented by IBM.

=cut
604