1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
|
#!/usr/bin/perl
#
# Tests for the basic object implementation.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2007-2008, 2011, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
# SPDX-License-Identifier: MIT
use strict;
use warnings;
use POSIX qw(strftime);
use Test::More tests => 139;
use Wallet::ACL;
use Wallet::Admin;
use Wallet::Config;
use Wallet::Object::Base;
use lib 't/lib';
use Util;
# Some global defaults to use.
my $user = 'admin@EXAMPLE.COM';
my $host = 'localhost';
my @trace = ($user, $host, time);
my $princ = 'service/test@EXAMPLE.COM';
# Use Wallet::Admin to set up the database.
db_setup;
my $admin = eval { Wallet::Admin->new };
is ($@, '', 'Database connection succeeded');
is ($admin->reinitialize ($user), 1, 'Database initialization succeeded');
my $schema = $admin->schema;
# 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 $object = eval {
Wallet::Object::Base->create ('keytab', $princ, $schema, @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, $schema, @trace)
};
like ($@, qr/^cannot create object \Qkeytab:$princ: /, 'Repeating fails');
$other = eval { Wallet::Object::Base->create ('', $princ, $schema, @trace) };
is ($@, "invalid object type\n", 'Using an empty type fails');
$other = eval { Wallet::Object::Base->create ('keytab', '', $schema, @trace) };
is ($@, "invalid object name\n", ' as does an empty name');
$object = eval { Wallet::Object::Base->new ('keytab', "a$princ", $schema) };
is ($@, "cannot find keytab:a$princ\n", 'Searching for unknown object fails');
$object = eval { Wallet::Object::Base->new ('keytab', $princ, $schema) };
is ($@, '', 'Object new did not die');
ok ($object->isa ('Wallet::Object::Base'), ' and returned the right class');
# Simple accessor tests.
is ($object->type, 'keytab', 'Type accessor works');
is ($object->name, $princ, 'Name accessor works');
# We'll use this for later tests.
my $acl = Wallet::ACL->new ('ADMIN', $schema);
# Owner.
is ($object->owner, undef, 'Owner is not set to start');
if ($object->owner ('ADMIN', @trace)) {
ok (1, ' and setting it to ADMIN works');
} else {
is ($object->error, '', ' and setting it to ADMIN works');
}
is ($object->owner, $acl->name, ' at which point it is ADMIN');
ok (! $object->owner ('unknown', @trace),
' but setting it to something bogus fails');
is ($object->error, 'ACL unknown not found', ' with the right error');
if ($object->owner ('', @trace)) {
ok (1, ' and clearing it works');
} else {
is ($object->error, '', ' and clearing it works');
}
is ($object->owner, undef, ' at which point it is cleared');
is ($object->owner ('ADMIN', @trace), 1, ' and setting it again works');
# Expires.
is ($object->expires, undef, 'Expires is not set to start');
my $now = strftime ('%Y-%m-%d %T', localtime time);
if ($object->expires ($now, @trace)) {
ok (1, ' and setting it works');
} else {
is ($object->error, '', ' and setting it works');
}
is ($object->expires, $now, ' at which point it matches');
ok (! $object->expires ('13/13/13 13:13:13', @trace),
' but setting it to something bogus fails');
is ($object->error, 'malformed expiration time 13/13/13 13:13:13',
' with the right error');
if ($object->expires ('', @trace)) {
ok (1, ' and clearing it works');
} else {
is ($object->error, '', ' and clearing it works');
}
is ($object->expires, undef, ' at which point it is cleared');
is ($object->expires ($now, @trace), 1, ' and setting it again works');
# Comment.
is ($object->comment, undef, 'Comment is not set to start');
if ($object->comment ('this is a comment', @trace)) {
ok (1, ' and setting it works');
} else {
is ($object->error, '', ' and setting it works');
}
is ($object->comment, 'this is a comment', ' at which point it matches');
if ($object->comment ('', @trace)) {
ok (1, ' and clearing it works');
} else {
is ($object->error, '', ' and clearing it works');
}
is ($object->comment, undef, ' at which point it is cleared');
is ($object->comment (join (' ', ('this is a comment') x 5), @trace), 1,
' and setting it again works');
# ACLs.
for my $type (qw/get store show destroy flags/) {
is ($object->acl ($type), undef, "ACL $type is not set to start");
if ($object->acl ($type, $acl->id, @trace)) {
ok (1, ' and setting it to ADMIN (numeric) works');
} else {
is ($object->error, '', ' and setting it to ADMIN (numeric) works');
}
is ($object->acl ($type), $acl->name, ' at which point it is ADMIN');
ok (! $object->acl ($type, 22, @trace),
' but setting it to something bogus fails');
is ($object->error, 'ACL 22 not found', ' with the right error');
if ($object->acl ($type, '', @trace)) {
ok (1, ' and clearing it works');
} else {
is ($object->error, '', ' and clearing it works');
}
is ($object->acl ($type), undef, ' at which point it is cleared');
is ($object->acl ($type, $acl->name, @trace), 1,
' and setting it again by name works');
}
# Flags.
my @flags = $object->flag_list;
is (scalar (@flags), 0, 'No flags set to start');
is ($object->flag_check ('locked'), 0, ' and locked is not set');
is ($object->flag_set ('locked', @trace), 1, ' and setting locked works');
is ($object->flag_check ('locked'), 1, ' and now locked is set');
@flags = $object->flag_list;
is (scalar (@flags), 1, ' and there is one flag');
is ($flags[0], 'locked', ' which is locked');
is ($object->flag_set ('locked', @trace), undef, 'Setting locked again fails');
is ($object->error,
"cannot set flag locked on keytab:$princ: flag already set",
' with the right error');
is ($object->flag_set ('unchanging', @trace), 1,
' but setting unchanging works');
is ($object->flag_check ('unchanging'), 1, ' and unchanging is now set');
@flags = $object->flag_list;
is (scalar (@flags), 2, ' and there are two flags');
is ($flags[0], 'locked', ' which are locked');
is ($flags[1], 'unchanging', ' and unchanging');
is ($object->flag_clear ('locked', @trace), 1, 'Clearing locked works');
is ($object->flag_check ('locked'), 0, ' and now it is not set');
is ($object->flag_check ('unchanging'), 1, ' but unchanging still is');
is ($object->flag_clear ('locked', @trace), undef,
' and clearing it again fails');
is ($object->error,
"cannot clear flag locked on keytab:$princ: flag not set",
' with the right error');
if ($object->flag_set ('locked', @trace)) {
ok (1, ' and setting it again works');
} else {
is ($object->error, '', ' and setting it again works');
}
# Attributes. Very boring.
is ($object->attr ('foo'), undef, 'Retrieving an attribute fails');
is ($object->error, 'unknown attribute foo', ' with the right error');
is ($object->attr ('foo', [ 'foo' ], @trace), undef, ' and setting fails');
is ($object->error, 'unknown attribute foo', ' with the right error');
# Test stub methods and locked status.
is ($object->store ("Some data", @trace), undef, 'Store fails');
is ($object->error, "cannot store keytab:${princ}: object is locked",
' because the object is locked');
is ($object->owner ('', @trace), undef, ' and setting owner fails');
is ($object->error, "cannot modify keytab:${princ}: object is locked",
' for the same reason');
is ($object->owner, 'ADMIN', ' but retrieving the owner works');
is ($object->expires ('', @trace), undef, ' and setting expires fails');
is ($object->error, "cannot modify keytab:${princ}: object is locked",
' for the same reason');
is ($object->expires, $now, ' but retrieving expires works');
for my $acl (qw/get store show destroy flags/) {
is ($object->acl ($acl, '', @trace), undef, " and setting $acl ACL fails");
is ($object->error, "cannot modify keytab:${princ}: object is locked",
' for the same reason');
is ($object->acl ($acl), 'ADMIN', " but retrieving $acl ACL works");
}
is ($object->flag_check ('locked'), 1, ' and checking flags works');
@flags = $object->flag_list;
is (scalar (@flags), 2, ' and listing flags works');
is ("@flags", 'locked unchanging', ' and returns the right data');
is ($object->flag_clear ('locked', @trace), 1, 'Clearing locked succeeds');
eval { $object->get (@trace) };
is ($@, "Do not instantiate Wallet::Object::Base directly\n",
'Get fails with the right error');
ok (!$object->update (@trace), 'Update fails');
is ($object->error, 'update is not supported for this type, use get instead',
' with the right error');
ok (! $object->store ("Some data", @trace), 'Store fails');
is ($object->error, "cannot store keytab:$princ: object type is immutable",
' with the right error');
# Test show.
my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]);
my $output = <<"EOO";
Type: keytab
Name: $princ
Owner: ADMIN
Get ACL: ADMIN
Store ACL: ADMIN
Show ACL: ADMIN
Destroy ACL: ADMIN
Flags ACL: ADMIN
Expires: $now
Comment: this is a comment this is a comment this is a comment this is
a comment this is a comment
Flags: unchanging
Created by: $user
Created from: $host
Created on: $date
Members of ACL ADMIN (id: 1) are:
krb5 $user
EOO
is ($object->show, $output, 'Show output is correct');
is ($object->flag_set ('locked', @trace), 1, ' and setting locked works');
$output = <<"EOO";
Type: keytab
Name: $princ
Owner: ADMIN
Get ACL: ADMIN
Store ACL: ADMIN
Show ACL: ADMIN
Destroy ACL: ADMIN
Flags ACL: ADMIN
Expires: $now
Comment: this is a comment this is a comment this is a comment this is
a comment this is a comment
Flags: locked unchanging
Created by: $user
Created from: $host
Created on: $date
Members of ACL ADMIN (id: 1) are:
krb5 $user
EOO
is ($object->show, $output, ' and show still works and is correct');
# Test destroy.
is ($object->destroy (@trace), undef, 'Destroy fails');
is ($object->error, "cannot destroy keytab:${princ}: object is locked",
' because of the locked status');
is ($object->flag_clear ('locked', @trace), 1,
' and clearing locked status works');
if ($object->destroy (@trace)) {
ok (1, 'Destroy is successful');
} else {
is ($object->error, '', 'Destroy is successful');
}
$object = eval { Wallet::Object::Base->new ('keytab', $princ, $schema) };
is ($@, "cannot find keytab:$princ\n", ' and object is all gone');
# Test history.
$object = eval {
Wallet::Object::Base->create ('keytab', $princ, $schema, @trace)
};
ok (defined ($object), 'Recreating the object succeeds');
$output = <<"EOO";
$date create
by $user from $host
$date set owner to ADMIN (1)
by $user from $host
$date unset owner (was ADMIN (1))
by $user from $host
$date set owner to ADMIN (1)
by $user from $host
$date set expires to $now
by $user from $host
$date unset expires (was $now)
by $user from $host
$date set expires to $now
by $user from $host
$date set comment to this is a comment
by $user from $host
$date unset comment (was this is a comment)
by $user from $host
$date set comment to this is a comment this is a comment this is a comment this is a comment this is a comment
by $user from $host
$date set acl_get to ADMIN (1)
by $user from $host
$date unset acl_get (was ADMIN (1))
by $user from $host
$date set acl_get to ADMIN (1)
by $user from $host
$date set acl_store to ADMIN (1)
by $user from $host
$date unset acl_store (was ADMIN (1))
by $user from $host
$date set acl_store to ADMIN (1)
by $user from $host
$date set acl_show to ADMIN (1)
by $user from $host
$date unset acl_show (was ADMIN (1))
by $user from $host
$date set acl_show to ADMIN (1)
by $user from $host
$date set acl_destroy to ADMIN (1)
by $user from $host
$date unset acl_destroy (was ADMIN (1))
by $user from $host
$date set acl_destroy to ADMIN (1)
by $user from $host
$date set acl_flags to ADMIN (1)
by $user from $host
$date unset acl_flags (was ADMIN (1))
by $user from $host
$date set acl_flags to ADMIN (1)
by $user from $host
$date set flag locked
by $user from $host
$date set flag unchanging
by $user from $host
$date clear flag locked
by $user from $host
$date set flag locked
by $user from $host
$date clear flag locked
by $user from $host
$date set flag locked
by $user from $host
$date clear flag locked
by $user from $host
$date destroy
by $user from $host
$date create
by $user from $host
EOO
is ($object->history, $output, ' and the history is correct');
# Clean up.
$admin->destroy;
END {
unlink 'wallet-db';
}
|