aboutsummaryrefslogtreecommitdiff
path: root/perl
diff options
context:
space:
mode:
Diffstat (limited to 'perl')
-rw-r--r--perl/Wallet/Object/Base.pm64
-rwxr-xr-xperl/t/object.t92
2 files changed, 146 insertions, 10 deletions
diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm
index 527a146..7320dd6 100644
--- a/perl/Wallet/Object/Base.pm
+++ b/perl/Wallet/Object/Base.pm
@@ -17,12 +17,13 @@ use strict;
use vars qw($VERSION);
use DBI;
+use POSIX qw(strftime);
use Wallet::ACL;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# Constructors
@@ -440,6 +441,59 @@ sub flag_set {
}
##############################################################################
+# History
+##############################################################################
+
+# Return the formatted history for a given object or undef on error.
+# Currently always returns the complete history, but eventually will need to
+# provide some way of showing only recent entries.
+sub history {
+ my ($self) = @_;
+ my $output = '';
+ eval {
+ my $sql = 'select oh_action, oh_field, oh_type_field, oh_old, oh_new,
+ oh_by, oh_from, oh_on from object_history where oh_type = ? and
+ oh_name = ? order by oh_on';
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute ($self->{type}, $self->{name});
+ my @data;
+ while (@data = $sth->fetchrow_array) {
+ my $time = strftime ('%Y-%m-%d %H:%M:%S', localtime $data[7]);
+ $output .= "$time ";
+ if ($data[0] eq 'set' and $data[1] eq 'flags') {
+ if (defined ($data[4])) {
+ $output .= "set flag $data[4]";
+ } elsif (defined ($data[3])) {
+ $output .= "clear flag $data[3]";
+ }
+ } elsif ($data[0] eq 'set') {
+ my $field = $data[1];
+ if ($field eq 'type_data') {
+ $field = $data[2];
+ }
+ my ($old, $new) = @data[3..4];
+ if (defined ($old) and defined ($new)) {
+ $output .= "set $field to $new (was $old)";
+ } elsif (defined ($new)) {
+ $output .= "set $field to $new";
+ } elsif (defined ($old)) {
+ $output .= "unset $field";
+ }
+ } else {
+ $output .= $data[0];
+ }
+ $output .= "\n by $data[5] from $data[6]\n";
+ }
+ };
+ if ($@) {
+ my $id = $self->{type} . ':' . $self->{name};
+ $self->error ("cannot read history for $id: $@");
+ return undef;
+ }
+ return $output;
+}
+
+##############################################################################
# Object manipulation
##############################################################################
@@ -745,6 +799,14 @@ either the data of the object or undef on some error, using the provided
arguments to update history information. The Wallet::Object::Base
implementation just throws an exception.
+=item history()
+
+Returns the formatted history for the object. There will be two lines for
+each action on the object. The first line has the timestamp of the action
+and the action, and the second line gives the user who performed the
+action and the host from which they performed it (based on the trace
+information passed into the other object methods).
+
=item name()
Returns the object's name.
diff --git a/perl/t/object.t b/perl/t/object.t
index e2ae5ca..d67bd40 100755
--- a/perl/t/object.t
+++ b/perl/t/object.t
@@ -8,7 +8,8 @@
#
# See LICENSE for licensing terms.
-use Test::More tests => 129;
+use POSIX qw(strftime);
+use Test::More tests => 131;
use Wallet::ACL;
use Wallet::Config;
@@ -23,7 +24,7 @@ unlink 'wallet-db';
# Some global defaults to use.
my $user = 'admin@EXAMPLE.COM';
my $host = 'localhost';
-my @trace = ($user, $host);
+my @trace = ($user, $host, time);
my $princ = 'service/test@EXAMPLE.COM';
# Use Wallet::Server to set up the database.
@@ -34,13 +35,14 @@ my $dbh = $server->dbh;
# Okay, now we have a database. Test create and new. We make believe this is
# a keytab object; it won't matter for what we're doing.
-my $created = time;
-my $object = eval { Wallet::Object::Base->create ('keytab', $princ, $dbh,
- @trace, $created) };
+my $object = eval {
+ Wallet::Object::Base->create ('keytab', $princ, $dbh, @trace)
+ };
is ($@, '', 'Object creation did not die');
ok ($object->isa ('Wallet::Object::Base'), ' and returned the right class');
-my $other =
- eval { Wallet::Object::Base->create ('keytab', $princ, $dbh, @trace) };
+my $other = eval {
+ Wallet::Object::Base->create ('keytab', $princ, $dbh, @trace)
+ };
like ($@, qr/^cannot create object \Qkeytab:$princ: /, 'Repeating fails');
$other = eval { Wallet::Object::Base->create ('', $princ, $dbh, @trace) };
is ($@, "invalid object type\n", 'Using an empty type fails');
@@ -205,7 +207,7 @@ my $output = <<"EOO";
Flags: unchanging
Created by: $user
Created from: $host
- Created on: $created
+ Created on: $trace[2]
Members of ACL ADMIN (id: 1) are:
krb5 $user
@@ -225,7 +227,7 @@ $output = <<"EOO";
Flags: locked unchanging
Created by: $user
Created from: $host
- Created on: $created
+ Created on: $trace[2]
Members of ACL ADMIN (id: 1) are:
krb5 $user
@@ -246,5 +248,77 @@ if ($object->destroy (@trace)) {
$object = eval { Wallet::Object::Base->new ('keytab', $princ, $dbh) };
is ($@, "cannot find keytab:$princ\n", ' and object is all gone');
+# Test history.
+$object = eval {
+ Wallet::Object::Base->create ('keytab', $princ, $dbh, @trace)
+ };
+ok (defined ($object), 'Recreating the object succeeds');
+my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]);
+$output = <<"EOO";
+$date create
+ by admin\@EXAMPLE.COM from localhost
+$date set owner to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset owner
+ by admin\@EXAMPLE.COM from localhost
+$date set owner to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set expires to $now
+ by admin\@EXAMPLE.COM from localhost
+$date unset expires
+ by admin\@EXAMPLE.COM from localhost
+$date set expires to $now
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_get to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset acl_get
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_get to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_store to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset acl_store
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_store to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_show to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset acl_show
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_show to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_destroy to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset acl_destroy
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_destroy to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_flags to 1
+ by admin\@EXAMPLE.COM from localhost
+$date unset acl_flags
+ by admin\@EXAMPLE.COM from localhost
+$date set acl_flags to 1
+ by admin\@EXAMPLE.COM from localhost
+$date set flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date set flag unchanging
+ by admin\@EXAMPLE.COM from localhost
+$date clear flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date set flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date clear flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date set flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date clear flag locked
+ by admin\@EXAMPLE.COM from localhost
+$date destroy
+ by admin\@EXAMPLE.COM from localhost
+$date create
+ by admin\@EXAMPLE.COM from localhost
+EOO
+is ($object->history, $output, ' and the history is correct');
+
# Clean up.
unlink 'wallet-db';