| File: | /home/mik/work/module/Tivoli/AccessManager/Admin/Action.pm |
| Coverage: | 99.6% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package Tivoli::AccessManager::Admin::Action; | ||||||
| 2 | 15 15 15 | 157 54 319 | use Carp; | ||||
| 3 | 15 15 15 | 212 63 211 | use strict; | ||||
| 4 | 15 15 15 | 200 63 216 | use warnings; | ||||
| 5 | 15 15 15 | 201 52 275 | use Data::Dumper; | ||||
| 6 | |||||||
| 7 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
| 8 | # $Id: Action.pm 305 2006-09-28 19:18:01Z mik $ | ||||||
| 9 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||||
| 10 | |||||||
| 11 | $Tivoli::AccessManager::Admin::Action::VERSION = '0.04'; | ||||||
| 12 | 15 | 208 | use Inline(C => 'DATA', | ||||
| 13 | INC => '-I/opt/PolicyDirector/include', | ||||||
| 14 | LIBS => ' -lpthread -lpdadminapi -lstdc++', | ||||||
| 15 | CCFLAGS => '-Wall', | ||||||
| 16 | # VERSION => '0.04', | ||||||
| 17 | NAME => 'Tivoli::AccessManager::Admin::Action', | ||||||
| 18 | 15 15 | 214 52 | ); | ||||
| 19 | 15 15 15 | 220 50 260 | use Tivoli::AccessManager::Admin::Response; | ||||
| 20 | |||||||
| 21 | sub new { | ||||||
| 22 | 12 | 1 | 94 | my $class = shift; | |||
| 23 | 12 | 45 | my $cont = shift; | ||||
| 24 | |||||||
| 25 | 12 | 190 | unless ( defined($cont) and UNIVERSAL::isa($cont,'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
| 26 | 2 | 39 | warn "Incorrect syntax -- did you forget the context?\n"; | ||||
| 27 | 2 | 17 | return undef; | ||||
| 28 | } | ||||||
| 29 | |||||||
| 30 | 10 | 61 | if ( @_ % 2 ) { | ||||
| 31 | 1 | 19 | warn "Invalid syntax -- you did not send a hash\n"; | ||||
| 32 | 1 | 9 | return undef; | ||||
| 33 | } | ||||||
| 34 | 9 | 95 | my %opts = @_; | ||||
| 35 | |||||||
| 36 | 9 | 70 | my $self = bless {}, $class; | ||||
| 37 | 9 | 84 | $self->{actionid} = $opts{actionid} || ''; | ||||
| 38 | 9 | 64 | $self->{description} = $opts{description} || ''; | ||||
| 39 | 9 | 60 | $self->{type} = $opts{type} || ''; | ||||
| 40 | 9 | 40 | $self->{context} = $cont; | ||||
| 41 | |||||||
| 42 | 9 | 86 | return $self; | ||||
| 43 | } | ||||||
| 44 | |||||||
| 45 | sub create { | ||||||
| 46 | 13 | 1 | 226 | my $self = shift; | |||
| 47 | 13 | 36 | my $rc; | ||||
| 48 | 13 | 129 | my $resp = Tivoli::AccessManager::Admin::Response->new; | ||||
| 49 | |||||||
| 50 | 13 | 81 | unless ( ref $self ) { | ||||
| 51 | 5 | 20 | my $pd = shift; | ||||
| 52 | 5 | 67 | unless ( UNIVERSAL::isa($pd, 'Tivoli::AccessManager::Admin::Context') ) { | ||||
| 53 | 1 | 11 | $resp->set_message('syntax error - no context'); | ||||
| 54 | 1 | 9 | $resp->set_isok(0); | ||||
| 55 | 1 | 9 | return $resp; | ||||
| 56 | } | ||||||
| 57 | 4 | 35 | $self = $self->new( $pd, @_ ); | ||||
| 58 | } | ||||||
| 59 | |||||||
| 60 | 12 | 65 | if ( @_ % 2 ) { | ||||
| 61 | 1 | 11 | $resp->set_message("Invalid syntax"); | ||||
| 62 | 1 | 5 | $resp->set_isok(0); | ||||
| 63 | 1 | 6 | return $resp; | ||||
| 64 | } | ||||||
| 65 | 11 | 76 | my %opts = @_; | ||||
| 66 | |||||||
| 67 | 11 | 62 | unless ( $self->{actionid} ) { | ||||
| 68 | 2 | 28 | $self->{actionid} = $opts{actionid} || ''; | ||||
| 69 | } | ||||||
| 70 | |||||||
| 71 | 11 | 55 | unless ( $self->{description} ) { | ||||
| 72 | 2 | 29 | $self->{description} = $opts{description} || ''; | ||||
| 73 | } | ||||||
| 74 | |||||||
| 75 | 11 | 60 | unless ( $self->{type} ) { | ||||
| 76 | 2 | 28 | $self->{type} = $opts{type} || ''; | ||||
| 77 | } | ||||||
| 78 | |||||||
| 79 | 11 | 160 | unless ( $self->{actionid} and $self->{description} and $self->{type} ) { | ||||
| 80 | 3 | 31 | $resp->set_isok(0); | ||||
| 81 | 3 | 24 | $resp->set_message("actionid, description and type must be defined" ); | ||||
| 82 | 3 | 25 | return $resp; | ||||
| 83 | } | ||||||
| 84 | |||||||
| 85 | 8 | 41 | if ( defined $opts{group} ) { | ||||
| 86 | 2 | 89407 | $rc = $self->action_create_in_group($resp, $opts{group}); | ||||
| 87 | } | ||||||
| 88 | else { | ||||||
| 89 | 6 | 276311 | $rc = $self->action_create($resp); | ||||
| 90 | } | ||||||
| 91 | |||||||
| 92 | 8 | 169 | $resp->isok and $resp->set_value( $self ); | ||||
| 93 | 8 | 112 | return $resp; | ||||
| 94 | } | ||||||
| 95 | |||||||
| 96 | sub delete { | ||||||
| 97 | 8 | 1 | 35 | my $self = shift; | |||
| 98 | 8 | 75 | my $resp = Tivoli::AccessManager::Admin::Response->new; | ||||
| 99 | 8 | 30 | my $rc; | ||||
| 100 | |||||||
| 101 | 8 | 50 | if ( @_ % 2 ) { | ||||
| 102 | 1 | 6 | $resp->set_message("Invalid syntax"); | ||||
| 103 | 1 | 7 | $resp->set_isok(0); | ||||
| 104 | 1 | 18 | return $resp; | ||||
| 105 | } | ||||||
| 106 | 7 | 38 | my %opts = @_; | ||||
| 107 | |||||||
| 108 | 7 | 35 | if ( defined $opts{group} ) { | ||||
| 109 | 1 | 50202 | $rc = $self->action_delete_from_group($resp, $opts{group}); | ||||
| 110 | } | ||||||
| 111 | else { | ||||||
| 112 | 6 | 324961 | $rc = $self->action_delete($resp); | ||||
| 113 | } | ||||||
| 114 | # Because we need to rely on the information held in the perl code's | ||||||
| 115 | # cache, I want to make certain we zero it all out if the delete | ||||||
| 116 | # worked. | ||||||
| 117 | 7 | 144 | if ( $resp->isok ) { | ||||
| 118 | 6 | 34 | $self->{actionid} = undef; | ||||
| 119 | 6 | 28 | $self->{description} = undef; | ||||
| 120 | 6 | 47 | $self->{type} = undef; | ||||
| 121 | } | ||||||
| 122 | 7 | 85 | return $resp; | ||||
| 123 | } | ||||||
| 124 | |||||||
| 125 | sub group { | ||||||
| 126 | 12 | 1 | 77 | my $self = shift; | |||
| 127 | 12 | 118 | my $resp = Tivoli::AccessManager::Admin::Response->new; | ||||
| 128 | 12 | 38 | my $pd; | ||||
| 129 | |||||||
| 130 | 12 | 56 | if ( ref $self ) { | ||||
| 131 | 2 | 9 | $pd = $self->{context}; | ||||
| 132 | } | ||||||
| 133 | else { | ||||||
| 134 | 10 | 38 | $pd = shift; | ||||
| 135 | 10 | 138 | unless ( UNIVERSAL::isa($pd, 'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
| 136 | 1 | 13 | $resp->set_message( 'syntax error -- no context object' ); | ||||
| 137 | 1 | 11 | $resp->set_isok(0); | ||||
| 138 | 1 | 11 | return $resp; | ||||
| 139 | } | ||||||
| 140 | } | ||||||
| 141 | |||||||
| 142 | 11 | 64 | if ( @_ % 2 ) { | ||||
| 143 | 1 | 8 | $resp->set_message("Invalid syntax"); | ||||
| 144 | 1 | 7 | $resp->set_isok(0); | ||||
| 145 | 1 | 4 | return $resp; | ||||
| 146 | } | ||||||
| 147 | 10 | 63 | my %opts = @_; | ||||
| 148 | 10 | 79 | my %dispatch = ( create => \&action_group_create, | ||||
| 149 | remove => \&action_group_delete | ||||||
| 150 | ); | ||||||
| 151 | 10 | 28 | my $rc; | ||||
| 152 | |||||||
| 153 | DISPATCH: | ||||||
| 154 | 10 | 38 | for my $com ( qw/remove create/ ) { | ||||
| 155 | 18 | 103 | next unless defined $opts{$com}; | ||||
| 156 | |||||||
| 157 | 8 | 53 | if ( ref $opts{$com} eq 'ARRAY' ) { | ||||
| 158 | 4 4 | 8 15 | for my $grp ( @{$opts{$com}} ) { | ||||
| 159 | 8 | 358351 | $rc = $dispatch{$com}->( $pd, $resp, $grp ); | ||||
| 160 | 8 | 172 | last DISPATCH unless $resp->isok; | ||||
| 161 | } | ||||||
| 162 | } | ||||||
| 163 | else { | ||||||
| 164 | 4 | 187127 | $rc =$dispatch{$com}->( $pd, $resp, $opts{$com} ); | ||||
| 165 | 4 | 94 | last DISPATCH unless $resp->isok; | ||||
| 166 | } | ||||||
| 167 | } | ||||||
| 168 | |||||||
| 169 | 10 | 98 | if ( $resp->isok ) { | ||||
| 170 | 6 | 272068 | my @list = action_group_list( $pd, $resp ); | ||||
| 171 | 6 | 140 | $resp->isok and $resp->set_value(\@list); | ||||
| 172 | } | ||||||
| 173 | |||||||
| 174 | 10 | 155 | return $resp; | ||||
| 175 | } | ||||||
| 176 | |||||||
| 177 | sub list { | ||||||
| 178 | 5 | 1 | 26 | my $self = shift; | |||
| 179 | 5 | 14 | my ($pd,$class); | ||||
| 180 | 5 | 44 | my $resp = Tivoli::AccessManager::Admin::Response->new; | ||||
| 181 | |||||||
| 182 | 5 | 30 | if ( ref $self ) { | ||||
| 183 | 2 | 11 | $pd = $self->{context}; | ||||
| 184 | 2 | 7 | $class = ref $self; | ||||
| 185 | } | ||||||
| 186 | else { | ||||||
| 187 | 3 | 10 | $pd = shift; | ||||
| 188 | 3 | 38 | unless ( UNIVERSAL::isa($pd, 'Tivoli::AccessManager::Admin::Context' ) ) { | ||||
| 189 | 1 | 11 | $resp->set_message( 'syntax error -- no context object' ); | ||||
| 190 | 1 | 12 | $resp->set_isok(0); | ||||
| 191 | 1 | 8 | return $resp; | ||||
| 192 | } | ||||||
| 193 | 2 | 13 | $class = $self; | ||||
| 194 | } | ||||||
| 195 | |||||||
| 196 | 4 | 26 | if ( @_ % 2 ) { | ||||
| 197 | 1 | 7 | $resp->set_message("Invalid syntax"); | ||||
| 198 | 1 | 6 | $resp->set_isok(0); | ||||
| 199 | 1 | 5 | return $resp; | ||||
| 200 | } | ||||||
| 201 | 3 | 21 | my %opts = @_; | ||||
| 202 | 3 | 8 | my (@rc,@objs); | ||||
| 203 | |||||||
| 204 | 3 | 16 | if ( defined $opts{group} ) { | ||||
| 205 | 2 | 88027 | @rc = action_list_in_group( $pd, $resp, $opts{group} ); | ||||
| 206 | } | ||||||
| 207 | else { | ||||||
| 208 | 1 | 51905 | @rc = action_list( $pd, $resp ); | ||||
| 209 | } | ||||||
| 210 | |||||||
| 211 | 3 | 65 | if ( $resp->isok ) { | ||||
| 212 | 2 | 9 | for ( @rc ) { | ||||
| 213 | 20 | 67 | bless $_, $class; | ||||
| 214 | 20 | 57 | $_->{context} = $pd; | ||||
| 215 | } | ||||||
| 216 | 2 | 21 | $resp->set_value(\@rc); | ||||
| 217 | } | ||||||
| 218 | 3 | 33 | return $resp; | ||||
| 219 | } | ||||||
| 220 | |||||||
| 221 | 2 | 1 | 24 | sub description { return $_[0]->{description} } | |||
| 222 | 1 | 1 | 14 | sub id { return $_[0]->{actionid} } | |||
| 223 | 1 | 1 | 16 | sub type { return $_[0]->{type} } | |||
| 224 | |||||||
| 225 | 1; | ||||||
| 226 | |||||||
| 227 - 517 | =head1 NAME
Tivoli::AccessManager::Admin::Action
=head1 SYNOPSIS
use Tivoli::AccessManager::Admin;
my $pd = Tivoli::AccessManager::Admin->new( password => 'N3ew0nk' );
my ( @acts, $resp, @lists, @grps, @gnames );
# Create an action via new and create
$acts[0] = Tivoli::AccessManager::Admin::Action->new( $pd,
actionid => 'Z',
description => 'Action Z!',
type => 'This is action Z'
);
$resp = $acts[0]->create;
# Or, create an action through create alone
$resp = Tivoli::AccessManager::Admin::Action->create( $pd,
actionid => 'X',
description => 'Action X!',
type => 'This is action X'
);
$acts[1] = $resp->value if $resp->isok;
# Print the description, the type and the action id out
for my $act ( @acts ) {
print "Action ID : " . $act->id . "\n";
print "Description: " . $act->description . "\n";
print "Type : " . $act->type . "\n\n";
}
@gnames = qw/ateam dirty12 ratpack/;
# Create some action groups.
for my $name ( @gnames ) {
$resp = Tivoli::AccessManager::Admin::Action->group( $pd, create => $name );
push( @grps, $name ) if $resp->isok;
}
# Delete the groups
for my $name ( @gnames ) {
$resp = Tivoli::AccessManager::Admin::Action->group( $pd, delete => $name );
push( @grps, $name ) if $resp->isok;
}
# Create them another way, just for fun
$resp = Tivoli::AccessManager::Admin::Action->group( $pd, create => \@gnames );
@grps = @gnames if $resp->isok;
# Create a new actions in a group
$resp = Tivoli::AccessManager::Admin::Action->create( $pd,
actionid => 'T',
description => 'Pity the fool',
type => 'Mr T action',
group => 'ateam',
);
# Get the list of all the groups
$resp = Tivoli::AccessManager::Admin::Action->group;
# list the default actions
$resp = Tivoli::AccessManager::Admin::Action->list;
for my $obj ( @{$resp->value} ) {
printf "Found action %s -- %s\n",
$obj->id, $obj->description;
}
# list the actions in a group
$resp = Tivoli::AccessManager::Admin::Action->list( group => 'ateam' );
=head1 DESCRIPTION
Tivoli::AccessManager::Admin::Action implements the interface to the action portion of the API.
I will warn you -- the underlying API is somewhat half baked.
=head1 CONSTRUCTORS
=head2 new( PDADMIN[, actionid =E<gt> ID, description =E<gt> DESC, type =E<gt> TYPE, group =E<gt> GROUP] )
Creates a blessed L<Tivoli::AccessManager::Admin::Action> object. You will need to destroy this
object if you wish to change the context.
=head3 Parameters
=over 4
=item PDADMIN
An initialized L<Tivoli::AccessManager::Admin::Context> object. This is the only required
parameter.
=item actionid =E<gt> ID
The action id to create. This is currently limitted by the C API to one
character.
=item description =E<gt> DESC
A description of the action.
=item type =E<gt> TYPE
The action's type. This is usually a one word description thst is displayed
by the WPM.
=item group =E<gt> GROUP
If provided, name the action group in which the action will be created.
=back
=head3 Returns
A blessed L<Tivoli::AccessManager::Admin::Action> object.
=head2 create( PDADMIN, actionid =E<gt> ID, description =E<gt> DESC, type =E<gt> TYPE[, group =E<gt> GROUP] )
Instantiates a L<Tivoli::AccessManager::Admin::Context> object and creates the action in the
policy database if used as a class method.
=head3 Parameters
The parameters are identical to those for L</"new">. Unlike L</"new">, they
are all required, except for the group name.
=head3 Returns
A blessed L<Tivoli::AccessManager::Admin::Action> object, buried in a L<Tivoli::AccessManager::Admin::Response>
object.
=head2 list(PDADMIN[, group =E<gt> GROUP] )
Lists all the defined actions. The return is a list of L<Tivoli::AccessManager::Admin::Action>
objects, buried in a L<Tivoli::AccessManager::Admin::Response> object.
=head3 Parameters
=over 4
=item PDADMIN
An initialized L<Tivoli::AccessManager::Admin::Context> object. This is the only required
arameter.
=item group =E<gt> GROUP
If provided, the return will be the list of actions within the named group.
It will otherwise search the default group.
=back
=head3 Returns
A list of blessed L<Tivoli::AccessManager::Admin::Action> objects.
=head1 CLASS METHODS
=head2 group(PDADMIN[, create =E<gt> name, remove =E<gt> name ] )
Lists, creates and/or deletes action groups. If none of the optional
parameters are provided, L</"group"> will return a list of all the action
groups.
=head3 Parameters
=over 4
=item PDADMIN
An initialized L<Tivoli::AccessManager::Admin::Context> object. This is the only required
parameter.
=item create =E<gt> name
The name of an action group to create. This can also be a reference to an
array of group names.
=item remove =E<gt> name
The name of an action group to remove. This can also be a reference to an
array of group names. If create and remove are both specified, removes are
done first.
=back
=head3 Returns
Regardless of the operation performed, a list of action group names will be
returned.
=head1 METHODS
=head2 create( [actionid =E<gt> ID, description =E<gt> DESC, type =E<gt> TYPE, group =E<gt> GROUP] )
Yes, this can called as an instance method if you want. Notice the different
signature -- the context object is no longer required.
=head3 Parameters
See L</"new">. Any parameter yiu did not provide to L</"new"> must be
provided to L</"create">.
=head3 Returns
The results if the create operation
=head2 delete([group =E<gt> GROUP])
Deletes the action.
=head3 Parameters
=over 4
=item group =E<gt> GROUP
If provided, the action will be deleted from the named group.
=back
=head3 Returns
The results of the delete call.
=head2 id
Returns the action id. This is a read-only method.
=head3 Parameters
None
=head3 Returns
The action id.
=head2 description
Returns the description. This is a read-only method.
=head3 Parameters
None
=head3 Returns
The description.
=head2 type
Returns the type. This is a read-only method.
=head3 Parameters
None
=head3 Returns
The type.
=head1 ACKNOWLEDGEMENTS
See L<Tivoli::AccessManager::Admin> for the list. This was not possible without the help of a
bunch of people smarter than me.
=head1 BUGS
The underlying C API is very different from the other portions -- there is no
way to get an ivadmin_action struct w/o doing a list. I have worked around
this in the perl code. This is surely a bug.
There is no way to change the description or type w/o deleting the action and
recreating it.
=head1 AUTHOR
Mik Firestone E<lt>mikfire@gmail.comE<gt>
=head1 COPYRIGHT
Copyright (c) 2004-2011 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 | ||||||
| 518 | |||||||