diff options
author | Russ Allbery <rra@stanford.edu> | 2007-11-20 02:16:25 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2007-11-20 02:16:25 +0000 |
commit | cad3cc7993bb8f21fb6aac27fabbb973c5438773 (patch) | |
tree | eed169e35ba00fabeb84459780e32b2a306a8951 /perl | |
parent | 66da128c39971f9a40553af9351b489f1ad186e1 (diff) |
Attempt to create the object with a default owner on get and store
when the object doesn't exist.
Diffstat (limited to 'perl')
-rw-r--r-- | perl/Wallet/Server.pm | 17 | ||||
-rwxr-xr-x | perl/t/server.t | 63 |
2 files changed, 74 insertions, 6 deletions
diff --git a/perl/Wallet/Server.pm b/perl/Wallet/Server.pm index bb1a90c..429b3fb 100644 --- a/perl/Wallet/Server.pm +++ b/perl/Wallet/Server.pm @@ -401,10 +401,16 @@ sub owner { # Retrieve the information associated with an object, or returns undef and # sets the internal error if the retrieval fails or if the user isn't -# authorized. +# authorized. If the object doesn't exist, attempts dynamic creation of the +# object using the default ACL mappings (if any). sub get { my ($self, $type, $name) = @_; my $object = $self->retrieve ($type, $name); + if (not defined $object and $self->error =~ /^cannot find/) { + if ($self->create ($type, $name)) { + $object = $self->retrieve ($type, $name); + } + } return undef unless defined $object; return undef unless $self->acl_check ($object, 'get'); my $result = $object->get ($self->{user}, $self->{host}); @@ -414,10 +420,17 @@ sub get { # Store new data in an object, or returns undef and sets the internal error if # the object can't be found or if the user isn't authorized. Also don't -# permit storing undef, although storing the empty string is fine. +# permit storing undef, although storing the empty string is fine. If the +# object doesn't exist, attempts dynamic creation of the object using the +# default ACL mappings (if any). sub store { my ($self, $type, $name, $data) = @_; my $object = $self->retrieve ($type, $name); + if (not defined $object and $self->error =~ /^cannot find/) { + if ($self->create ($type, $name)) { + $object = $self->retrieve ($type, $name); + } + } return undef unless defined $object; return undef unless $self->acl_check ($object, 'store'); if (not defined ($data)) { diff --git a/perl/t/server.t b/perl/t/server.t index d709492..b0c196b 100755 --- a/perl/t/server.t +++ b/perl/t/server.t @@ -8,7 +8,7 @@ # # See LICENSE for licensing terms. -use Test::More tests => 311; +use Test::More tests => 321; use Wallet::Config; use Wallet::Server; @@ -734,10 +734,12 @@ is ($server->attr ('base', 'service/both', 'foo', 'foo'), undef, is ($server->error, 'unknown attribute foo', ' but calls the method'); is ($server->destroy ('base', 'service/both'), 1, ' and we can destroy it'); is ($server->get ('base', 'service/both'), undef, ' and now cannot get it'); -is ($server->error, 'cannot find base:service/both', ' because it is gone'); +is ($server->error, "$user2 not authorized to create base:service/both", + ' because it is gone'); is ($server->store ('base', 'service/both', 'stuff'), undef, ' or store it'); -is ($server->error, 'cannot find base:service/both', ' because it is gone'); +is ($server->error, "$user2 not authorized to create base:service/both", + ' because it is gone'); # Test default ACLs on object creation. # @@ -747,6 +749,9 @@ is ($server->error, 'cannot find base:service/both', ' because it is gone'); # definition than the existing ACL), and $user2 to create service/default-2 # with a default owner of user2 (with the same definition as the existing # ACL). +# +# Also add service/default-get and service/default-store to test auto-creation +# on get and store. package Wallet::Config; sub default_owner { my ($type, $name) = @_; @@ -756,6 +761,10 @@ sub default_owner { return ('both', [ 'krb5', $user1 ]); } elsif ($type eq 'base' and $name eq 'service/default-2') { return ('user2', [ 'krb5', $user2 ]); + } elsif ($type eq 'base' and $name eq 'service/default-get') { + return ('user2', [ 'krb5', $user2 ]); + } elsif ($type eq 'base' and $name eq 'service/default-store') { + return ('user2', [ 'krb5', $user2 ]); } else { return; } @@ -789,7 +798,7 @@ EOO is ($server->error, undef, ' and the created object and ACL are correct'); } -# Try the other cases in default_acl. +# Try the other basic cases in default_acl. is ($server->create ('base', 'service/default-both'), undef, 'Creating an object with an ACL mismatch fails'); is ($server->error, "ACL both exists and doesn't match default", @@ -811,6 +820,52 @@ Members of ACL user2 (id: 3) are: EOO is ($show, $expected, ' and the created object and ACL are correct'); +# Test auto-creation on get and store. +$result = eval { $server->get ('base', 'service/default-get') }; +is ($result, undef, 'Auto-creation on get...'); +is ($@, "Do not instantiate Wallet::Object::Base directly\n", ' ...works'); +$show = $server->show ('base', 'service/default-get'); +$show =~ s/(Created on:) \d+$/$1 0/m; +$expected = <<"EOO"; + Type: base + Name: service/default-get + Owner: user2 + Created by: $user2 + Created from: $host + Created on: 0 + +Members of ACL user2 (id: 3) are: + krb5 $user2 +EOO +is ($show, $expected, ' and the created object and ACL are correct'); +is ($server->get ('base', 'service/foo'), undef, + ' but auto-creation of something else fails'); +is ($server->error, "$user2 not authorized to create base:service/foo", + ' with the right error'); +is ($server->store ('base', 'service/default-store', 'stuff'), undef, + 'Auto-creation on store...'); +is ($server->error, + "cannot store base:service/default-store: object type is immutable", + ' ...works'); +$show = $server->show ('base', 'service/default-store'); +$show =~ s/(Created on:) \d+$/$1 0/m; +$expected = <<"EOO"; + Type: base + Name: service/default-store + Owner: user2 + Created by: $user2 + Created from: $host + Created on: 0 + +Members of ACL user2 (id: 3) are: + krb5 $user2 +EOO +is ($show, $expected, ' and the created object and ACL are correct'); +is ($server->store ('base', 'service/foo', 'stuff'), undef, + ' but auto-creation of something else fails'); +is ($server->error, "$user2 not authorized to create base:service/foo", + ' with the right error'); + # Now test handling of some configuration errors. undef $Wallet::Config::DB_DRIVER; $server = eval { Wallet::Server->new ($user2, $host) }; |