summaryrefslogtreecommitdiff
path: root/perl/t/object.t
blob: 5eb69417b0fb50adaff9b083f5a992651be9bba5 (plain)
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
#!/usr/bin/perl -w
#
# Tests for the basic object implementation.
#
# Written by Russ Allbery <rra@stanford.edu>
# Copyright 2007, 2008, 2011
#     The Board of Trustees of the Leland Stanford Junior University
#
# See LICENSE for licensing terms.

use POSIX qw(strftime);
use Test::More tests => 137;

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->id, ' 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->id, ' 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->id, @trace), 1,
        ' and setting it again 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, 1, ' 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), 1, " 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->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;
unlink 'wallet-db';