Passed
Push — master ( b28c40...f61e74 )
by Petr
08:06
created

FilesTest::testGroupManipulation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 19
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 32
rs 9.6333
1
<?php
2
3
namespace SourcesTests\Files\Storage;
4
5
6
use CommonTestClass;
7
use kalanis\kw_auth\AuthException;
8
use kalanis\kw_auth\Data\FileCertUser;
9
use kalanis\kw_auth\Data\FileGroup;
10
use kalanis\kw_auth\Interfaces\IFile;
11
use kalanis\kw_auth\Sources\Files\Storage\Files;
12
use kalanis\kw_auth\Statuses\Always;
13
use kalanis\kw_locks\LockException;
14
use kalanis\kw_storage\Storage\Key\DefaultKey;
15
use kalanis\kw_storage\Storage\Storage;
16
use kalanis\kw_storage\Storage\Target\Memory;
17
use kalanis\kw_storage\StorageException;
18
19
20
class FilesTest extends CommonTestClass
21
{
22
    protected $sourcePath = 'data';
23
24
    /**
25
     * @throws AuthException
26
     * @throws LockException
27
     */
28
    public function testNotExistsData(): void
29
    {
30
        $lib = $this->emptyFileSources();
31
        $this->assertNull($lib->getDataOnly('does not exist'));
32
        $this->assertNull($lib->getCertData('does not exist'));
33
        $this->assertNull($lib->authenticate('does not exist', ['password' => 'not need']));
34
    }
35
36
    /**
37
     * @throws AuthException
38
     * @throws LockException
39
     * @throws StorageException
40
     */
41
    public function testDataOnly(): void
42
    {
43
        $lib = $this->fileSources();
44
        $this->assertEmpty($lib->getDataOnly('does not exist'));
45
        $user = $lib->getDataOnly('manager');
46
        $this->assertNotEmpty($user);
47
        $this->assertEquals('Manage', $user->getDisplayName());
48
    }
49
50
    /**
51
     * @throws AuthException
52
     * @throws LockException
53
     * @throws StorageException
54
     */
55
    public function testAuthenticate(): void
56
    {
57
        $lib = $this->fileSources();
58
        $this->assertEmpty($lib->authenticate('manager', ['password' => 'thisisnotreal']));
59
        $user = $lib->authenticate('manager', ['password' => 'valid']);
60
        $this->assertNotEmpty($user);
61
        $this->assertEquals('Manage', $user->getDisplayName());
62
    }
63
64
    /**
65
     * @throws AuthException
66
     * @throws LockException
67
     * @throws StorageException
68
     */
69
    public function testAuthenticateNoPass(): void
70
    {
71
        $lib = $this->fileSources();
72
        $this->expectException(AuthException::class);
73
        $lib->authenticate('manager', []);
74
    }
75
76
    /**
77
     * @throws AuthException
78
     * @throws LockException
79
     */
80
    public function testCreateAccountOnEmptyInstance(): void
81
    {
82
        $lib = $this->emptyFileSources();
83
        $user = $this->wantedUser();
84
85
        // create
86
        $lib->createAccount($user, 'here to set');
87
88
        // check data
89
        $saved = $lib->getDataOnly($user->getAuthName());
90
        $this->assertEquals('Testing another', $saved->getDisplayName());
91
        $this->assertEquals('why_here', $saved->getDir());
92
        $this->assertEquals(3, $saved->getClass());
93
    }
94
95
    /**
96
     * @throws AuthException
97
     * @throws LockException
98
     */
99
    public function testUpdateAccountOnEmptyInstance(): void
100
    {
101
        $lib = $this->emptyFileSources();
102
        $user = $this->wantedUser();
103
104
        $this->expectException(AuthException::class);
105
        $lib->updateAccount($user);
106
    }
107
108
    /**
109
     * @throws AuthException
110
     * @throws LockException
111
     */
112
    public function testUpdatePasswordOnEmptyInstance(): void
113
    {
114
        $lib = $this->emptyFileSources();
115
116
        $this->expectException(AuthException::class);
117
        $lib->updatePassword('someone', 'not important');
118
    }
119
120
    /**
121
     * @throws AuthException
122
     * @throws LockException
123
     */
124
    public function testUpdateCertsOnEmptyInstance(): void
125
    {
126
        $lib = $this->emptyFileSources();
127
128
        $this->expectException(AuthException::class);
129
        $lib->updateCertKeys('someone', 'can be empty in this case', 'not important');
130
    }
131
132
    /**
133
     * @throws AuthException
134
     * @throws LockException
135
     */
136
    public function testDeleteAccountOnEmptyInstance(): void
137
    {
138
        $lib = $this->emptyFileSources();
139
        $user = $this->wantedUser();
140
141
        $this->expectException(AuthException::class);
142
        $lib->deleteAccount($user->getAuthName());
143
    }
144
145
    /**
146
     * @throws AuthException
147
     * @throws LockException
148
     * @throws StorageException
149
     */
150
    public function testDeleteAccountOnPartialInstance(): void
151
    {
152
        $lib = $this->partialFileSources();
153
        $user = $this->wantedUser();
154
155
        $this->expectException(AuthException::class);
156
        $lib->deleteAccount($user->getAuthName());
157
    }
158
159
    /**
160
     * @throws AuthException
161
     * @throws LockException
162
     * @throws StorageException
163
     */
164
    public function testAccountManipulation(): void
165
    {
166
        $lib = $this->fileSources();
167
        $user = $this->wantedUser();
168
169
        // create
170
        $lib->createAccount($user, 'here to set');
171
        // check data
172
        $saved = $lib->getDataOnly($user->getAuthName());
173
        $this->assertEquals('Testing another', $saved->getDisplayName());
174
        $this->assertEquals('why_here', $saved->getDir());
175
        $this->assertEquals(3, $saved->getClass());
176
177
        // check login
178
        $this->assertNotEmpty($lib->authenticate($user->getAuthName(), ['password' => 'here to set']));
179
180
        // update
181
        $user->setData(
182
            $user->getAuthId(),
183
            $user->getAuthName(),
184
            $user->getGroup(),
185
            2,
186
            3,
187
            'WheĐn yoĐu dđo nođt knđow',
188
            $user->getDir()
189
        );
190
        $user->addCertInfo('==public key for accessing that content==', 'hidden salt');
191
        $lib->updateAccount($user);
192
        $lib->updateCertKeys($user->getAuthName(), $user->getPubKey(), $user->getPubSalt());
193
194
        // update name
195
        $user->setData(
196
            $user->getAuthId(),
197
            'changed name',
198
            $user->getGroup(),
199
            $user->getClass(),
200
            $user->getStatus(),
201
            $user->getDisplayName(),
202
            $user->getDir()
203
        );
204
        $lib->updateAccount($user);
205
206
        // check data - again with new values
207
        $saved = $lib->getCertData($user->getAuthName());
208
        $this->assertEquals('When you do not know', $saved->getDisplayName());
209
        $this->assertEquals(2, $saved->getClass());
210
        $this->assertEquals($user->getPubKey(), $saved->getPubKey());
211
        $this->assertEquals($user->getPubSalt(), $saved->getPubSalt());
212
213
214
        // update password
215
        $lib->updatePassword($user->getAuthName(), 'another pass');
216
        // check login
217
        $this->assertEmpty($lib->authenticate($user->getAuthName(), ['password' => 'here to set']));
218
        $this->assertNotEmpty($lib->authenticate($user->getAuthName(), ['password' => 'another pass']));
219
220
        // remove
221
        $lib->deleteAccount($user->getAuthName());
222
        // check for existence
223
        $this->assertEmpty($lib->getDataOnly($user->getAuthName()));
224
    }
225
226
    /**
227
     * @throws AuthException
228
     * @throws LockException
229
     * @throws StorageException
230
     * AuthId is not correct but auth name is
231
     */
232
    public function testAccountUpdateFail(): void
233
    {
234
        $lib = $this->fileSources();
235
        $user = new FileCertUser();
236
        $user->setData(600, 'worker', 0, 0, 2, 'Die on set', 'so_here');
237
238
        $this->expectException(AuthException::class);
239
        $lib->updateAccount($user);
240
    }
241
242
    /**
243
     * @throws AuthException
244
     * @throws LockException
245
     * @throws StorageException
246
     */
247
    public function testCreateFail(): void
248
    {
249
        $lib = $this->fileSources();
250
        $user = $this->wantedUser();
251
        $this->expectException(AuthException::class);
252
        $lib->createAccount($user, '');
253
    }
254
255
    /**
256
     * @throws AuthException
257
     * @throws LockException
258
     * @throws StorageException
259
     */
260
    public function testAllUsers(): void
261
    {
262
        $lib = $this->fileSources();
263
        $data = $lib->readAccounts();
264
        $this->assertEquals(1, $data[0]->getClass());
265
        $this->assertEquals('manager', $data[1]->getAuthName());
266
    }
267
268
    /**
269
     * Contains a full comedy/tragedy of work with locks
270
     * @throws LockException
271
     * @throws StorageException
272
     * @return Files
273
     */
274
    protected function fileSources(): Files
275
    {
276
        $storage = new Storage(new DefaultKey(), new Memory());
277
        $storage->write($this->sourcePath . DIRECTORY_SEPARATOR . IFile::PASS_FILE,
278
            'owner:1000:0:1:1:Owner:/data/:' . "\r\n"
279
            . 'manager:1001:1:2:1:Manage:/data/:' . "\r\n"
280
            . '# commented out' . "\r\n"
281
            . 'worker:1002:1:3:1:Worker:/data/:' . "\r\n"
282
            // last line is intentionally empty one
283
        );
284
        $storage->write($this->sourcePath . DIRECTORY_SEPARATOR . IFile::SHADE_FILE,
285
            'owner:M2FjMjZhMjc3MGY4MzUxYjYyN2YzMzI1NjRkNTVlYmM4N2U5N2Y3ODI2NDAwMjY0MTZmMTI0NTliOTFlMTUxZQ==:0:9999999999:7:x:' . "\r\n"
286
            . 'manager:ZWZmNzQwODIxZDhjNzRkMjZlZTIzYjQ2ODBiNDA1YTA5MWY0ZjdkNWVhNzk2NDAxZTZkODY3NDhmMjg0MzE4Yw==:0:9999999999:salt_hash:x:' . "\r\n"
287
            . '# commented out' . "\r\n"
288
            . 'worker:M2FjMjZhMjc3MGY4MzUxYjYyN2YzMzI1NjRkNTVlYmM4N2U5N2Y3ODI2NDAwMjY0MTZmMTI0NTliOTFlMTUxZQ==:0:9999999999:salt_key:x:' . "\r\n"
289
            // last line is intentionally empty one
290
        );
291
        $storage->write($this->sourcePath . DIRECTORY_SEPARATOR . IFile::GROUP_FILE,
292
            '0:root:1000:Maintainers:1:' . "\r\n"
293
            . '1:admin:1000:Administrators:1:' . "\r\n"
294
            . '# commented out' . "\r\n"
295
            . '2:user:1000:All users:1:' . "\r\n"
296
            // last line is intentionally empty one
297
        );
298
        return new Files(
299
            $storage,
300
            new \MockModes(),
301
            new Always(),
302
            $this->getLockPath(),
303
            $this->sourcePath
304
        );
305
    }
306
307
    /**
308
     * Contains a partial files - no groups or shadow files
309
     * @throws LockException
310
     * @throws StorageException
311
     * @return Files
312
     */
313
    protected function partialFileSources(): Files
314
    {
315
        $storage = new Storage(new DefaultKey(), new Memory());
316
        $storage->write($this->sourcePath . DIRECTORY_SEPARATOR . IFile::PASS_FILE,
317
            'owner:1000:0:1:1:Owner:/data/:' . "\r\n"
318
            . 'manager:1001:1:2:1:Manage:/data/:' . "\r\n"
319
            . '# commented out' . "\r\n"
320
            . 'worker:1002:1:3:1:Worker:/data/:' . "\r\n"
321
            // last line is intentionally empty one
322
        );
323
        return new Files(
324
            $storage,
325
            new \MockModes(),
326
            new Always(),
327
            $this->getLockPath(),
328
            $this->sourcePath
329
        );
330
    }
331
332
    /**
333
     * Contains a full comedy/tragedy of work with locks
334
     * @throws LockException
335
     * @return Files
336
     */
337
    protected function emptyFileSources(): Files
338
    {
339
        $storage = new Storage(new DefaultKey(), new Memory());
340
        return new Files(
341
            $storage,
342
            new \MockModes(),
343
            new Always(),
344
            $this->getLockPath(),
345
            $this->sourcePath
346
        );
347
    }
348
349
    protected function wantedUser(): FileCertUser
350
    {
351
        $user = new FileCertUser();
352
        $user->setData(1003, 'another', 0, 0, 1, 'Testing another', 'why_here');
353
        return $user;
354
    }
355
356
    /**
357
     * @throws AuthException
358
     * @throws LockException
359
     * @throws StorageException
360
     */
361
    public function testGroupManipulation(): void
362
    {
363
        $lib = $this->fileSources();
364
        $group = $this->wantedGroup();
365
366
        // create
367
        $lib->createGroup($group);
368
        // check data
369
        $saved = $lib->getGroupDataOnly($group->getGroupId());
370
        $this->assertEquals('another', $saved->getGroupName());
371
        $this->assertEquals('Testing group', $saved->getGroupDesc());
372
        $this->assertEquals(1001, $saved->getGroupAuthorId());
373
374
        // update
375
        $group->setData(
376
            $group->getGroupId(),
377
            $group->getGroupName(),
378
            1002,
379
            'WheĐn yoĐu dđo nođt knđow',
380
            888
381
        );
382
        $lib->updateGroup($group);
383
384
        // check data - again with new values
385
        $saved = $lib->getGroupDataOnly($group->getGroupId());
386
        $this->assertEquals('When you do not know', $saved->getGroupDesc()); // overwrite this
387
        $this->assertEquals(1001, $saved->getGroupAuthorId()); // cannot overwrite this
388
389
        // remove
390
        $lib->deleteGroup($group->getGroupId());
391
        // check for existence
392
        $this->assertEmpty($lib->getGroupDataOnly($group->getGroupId()));
393
    }
394
395
    /**
396
     * @throws AuthException
397
     * @throws LockException
398
     * @throws StorageException
399
     */
400
    public function testCreateGroupFail(): void
401
    {
402
        $lib = $this->fileSources();
403
        $group = $this->wantedGroup('');
404
        $this->expectException(AuthException::class);
405
        $lib->createGroup($group);
406
    }
407
408
    /**
409
     * @throws AuthException
410
     * @throws LockException
411
     * @throws StorageException
412
     */
413
    public function testDeleteGroupFail(): void
414
    {
415
        $lib = $this->fileSources();
416
        $this->expectException(AuthException::class);
417
        $lib->deleteGroup(1);
418
    }
419
420
    /**
421
     * @throws AuthException
422
     * @throws LockException
423
     * @throws StorageException
424
     */
425
    public function testAllGroups(): void
426
    {
427
        $lib = $this->fileSources();
428
        $data = $lib->readGroup();
429
        $this->assertEquals('Maintainers', $data[0]->getGroupDesc());
430
        $this->assertEquals(1000, $data[1]->getGroupAuthorId());
431
    }
432
433
    protected function wantedGroup($name = 'another'): FileGroup
434
    {
435
        $user = new FileGroup();
436
        $user->setData(3, $name, 1001, 'Testing group', 999);
437
        return $user;
438
    }
439
}
440