Passed
Push — master ( f4fa40...82755f )
by Thomas
02:30
created

EncryptTest::getTestModel2()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace LeKoala\Encrypt\Test;
4
5
use Exception;
6
use SilverStripe\Assets\File;
7
use SilverStripe\ORM\DataObject;
8
use SilverStripe\Security\Member;
9
use LeKoala\Encrypt\EncryptHelper;
10
use SilverStripe\Core\Environment;
11
use SilverStripe\Dev\SapphireTest;
12
use LeKoala\Encrypt\EncryptedDBField;
13
use LeKoala\Encrypt\HasEncryptedFields;
14
use SilverStripe\ORM\DB;
15
use SilverStripe\ORM\Queries\SQLSelect;
16
use SilverStripe\ORM\Queries\SQLUpdate;
17
18
/**
19
 * Test for Encrypt
20
 *
21
 * Run with the following command : ./vendor/bin/phpunit ./encrypt/tests/EncryptTest.php
22
 *
23
 * You may need to run:
24
 * php ./framework/cli-script.php dev/build ?flush=all
25
 * before (remember manifest for cli is not the same...)
26
 *
27
 * @group Encrypt
28
 */
29
class EncryptTest extends SapphireTest
30
{
31
    /**
32
     * Defines the fixture file to use for this test class
33
     * @var string
34
     */
35
    protected static $fixture_file = 'EncryptTest.yml';
36
37
    protected static $extra_dataobjects = [
38
        Test_EncryptedModel::class,
39
    ];
40
41
    public function setUp()
42
    {
43
        EncryptHelper::setAutomaticRotation(false);
44
        Environment::setEnv('ENCRYPTION_KEY', '502370dfc69fd6179e1911707e8a5fb798c915900655dea16370d64404be04e5');
45
        parent::setUp();
46
        EncryptHelper::setAutomaticRotation(true);
47
48
        // test extension is available
49
        if (!extension_loaded('sodium')) {
50
            throw new Exception("You must load sodium extension for this");
51
        }
52
53
        // The rows are already decrypted due to the fixtures going through the ORM layer
54
        $result = DB::query("SELECT * FROM EncryptedModel");
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
55
        // echo '<pre>';
56
        // print_r(iterator_to_array($result));
57
        // die();
58
59
        /*
60
        [0] => Array
61
        (
62
            [ID] => 1
63
            [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
64
            [LastEdited] => 2021-07-07 14:53:35
65
            [Created] => 2021-07-07 14:53:35
66
            [Name] => demo
67
            [MyText] => brng:MlkjE7xiock-ofeuROQCG7n1wOrbG8bj4gc0pTqZn2u3e2pNcQe-mCP6qgT1QkXPxZGjvojySyuWzA_aK8Y-fwrUMl2_8Q==
68
            [MyHTMLText] => brng:mSNIa6LmvexuEu2eoStA8ZxyCW22UOhrA9r_guJR8eDsvwxWQJNgdEzKaO5dct0HeiYdd7CYouPWm-ki-els-YV2DBOlv85TVgyckys=
69
            [MyVarchar] => brng:1fHGMjvptiCtmUQ5KNwAPqJsvrg38VUjUAsqvgW8taz-Ao791j0T8WBcCMvUcnZ087N1EifryBScrC0QhJzb5Jmt7Fp1dsbBB0EIr2glJg==
70
            [RegularFileID] => 2
71
            [EncryptedFileID] => 3
72
            [MyNumberValue] => nacl:tKXzRBnsEfdJVcCouNIvRYQlt5dPQrZk4_PvpdyEUkrN6gWdDzxJxwD6VDKgjQeKamo=
73
            [MyNumberBlindIndex] => a1de44f9
74
            [MyNumberLastFourBlindIndex] => addb
75
            [MyIndexedVarcharValue] => nacl:F-q5OUdxjK77sxrGM6Q8BzQ3lDbiDwM9VxOUchcrlDXmgzUwhb0ADQsrxRlbyZnCG4q3nRlJ2cVHRLskVA==
76
            [MyIndexedVarcharBlindIndex] => 216d113a
77
        )
78
        */
79
80
        // Replace with actual yml values
81
        $data = [
82
            'MyText' => 'nacl:nYemK31JCP4OV8_zTItnLxI6RbrZ0iFadSv-mHNPO-et1rN15ElwOTMGuDTGX-57A9rW2zDN',
83
            'MyHTMLText' => 'nacl:85v7uUqHjwlCRpS5Khbjspg8xruFhCnuYFLenTG2h4iDV-7EaOfwIv01t4iQLZmnvhqOz8O-jiCPFBZTQQ==',
84
            'MyVarchar' => 'nacl:efSeE2GFCzYuRBeOejZAcArqqTYDR0Ez9geqScIBT2D1oGNCDK-HyqGIYmZiOSn_n3uuL5GSpK-1dCwfO_Oo',
85
        ];
86
        $update = new SQLUpdate("EncryptedModel", $data, "ID IN (1,3)");
0 ignored issues
show
Bug introduced by
'ID IN (1,3)' of type string is incompatible with the type array expected by parameter $where of SilverStripe\ORM\Queries\SQLUpdate::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
        $update = new SQLUpdate("EncryptedModel", $data, /** @scrutinizer ignore-type */ "ID IN (1,3)");
Loading history...
87
        $update->execute();
88
    }
89
90
    public function tearDown()
91
    {
92
        parent::tearDown();
93
    }
94
95
    /**
96
     * @return Test_EncryptedModel
97
     */
98
    public function getTestModel()
99
    {
100
        return $this->objFromFixture(Test_EncryptedModel::class, 'demo');
101
    }
102
103
    /**
104
     * @return Test_EncryptedModel
105
     */
106
    public function getTestModel2()
107
    {
108
        return $this->objFromFixture(Test_EncryptedModel::class, 'demo2');
109
    }
110
111
    /**
112
     * @return Test_EncryptedModel
113
     */
114
    public function getTestModel3()
115
    {
116
        return $this->objFromFixture(Test_EncryptedModel::class, 'demo3');
117
    }
118
119
    /**
120
     * @return Member
121
     */
122
    public function getAdminMember()
123
    {
124
        return $this->objFromFixture(Member::class, 'admin');
125
    }
126
127
    /**
128
     * @return File
129
     */
130
    public function getRegularFile()
131
    {
132
        return $this->objFromFixture(File::class, 'regular');
133
    }
134
135
    /**
136
     * @return File
137
     */
138
    public function getEncryptedFile()
139
    {
140
        return $this->objFromFixture(File::class, 'encrypted');
141
    }
142
143
    /**
144
     * @param string $class
145
     * @param int $id
146
     * @return array
147
     */
148
    protected function fetchRawData($class, $id)
149
    {
150
        $tableName = DataObject::getSchema()->tableName($class);
151
        $columnIdentifier = DataObject::getSchema()->sqlColumnForField($class, 'ID');
152
        $sql = new SQLSelect('*', [$tableName], [$columnIdentifier => $id]);
153
        $dbRecord = $sql->firstRow()->execute()->first();
154
        return $dbRecord;
155
    }
156
157
    public function testEncryption()
158
    {
159
        $someText = 'some text';
160
        $encrypt = EncryptHelper::encrypt($someText);
161
        $decryptedValue = EncryptHelper::decrypt($encrypt);
162
163
        $this->assertEquals($someText, $decryptedValue);
164
    }
165
166
    public function testIndexes()
167
    {
168
        $indexes = DataObject::getSchema()->databaseIndexes(Test_EncryptedModel::class);
169
        $keys = array_keys($indexes);
170
        $this->assertContains('MyIndexedVarcharBlindIndex', $keys, "Index is not defined in : " . implode(", ", $keys));
171
        $this->assertContains('MyNumberLastFourBlindIndex', $keys, "Index is not defined in : " . implode(", ", $keys));
172
    }
173
174
    public function testSearch()
175
    {
176
        $singl = singleton(Test_EncryptedModel::class);
177
        $obj = $singl->dbObject('MyIndexedVarchar');
178
        $record = $obj->fetchRecord('some_searchable_value');
179
180
        $this->assertNotEmpty($record);
181
        $this->assertEquals(1, $record->ID);
182
        $this->assertNotEquals(2, $record->ID);
183
184
        $record = $obj->fetchRecord('some_unset_value');
185
        $this->assertEmpty($record);
186
187
        // Let's try our four digits index
188
        $obj = $singl->dbObject('MyNumber');
189
        $record = $obj->fetchRecord('6789', 'LastFourBlindIndex');
190
        $searchValue = $obj->getSearchValue('6789', 'LastFourBlindIndex');
191
        // $searchParams = $obj->getSearchParams('6789', 'LastFourBlindIndex');
192
        // print_r($searchParams);
193
        $this->assertNotEmpty($record, "Nothing found for $searchValue");
194
        $this->assertEquals(1, $record->ID);
195
    }
196
197
    public function testSearchFilter()
198
    {
199
        $record = Test_EncryptedModel::get()->filter('MyIndexedVarchar:Encrypted', 'some_searchable_value')->first();
200
        $this->assertNotEmpty($record);
201
        $this->assertEquals(1, $record->ID);
202
        $this->assertNotEquals(2, $record->ID);
203
204
        $record = Test_EncryptedModel::get()->filter('MyIndexedVarchar:Encrypted', 'some_unset_value')->first();
205
        $this->assertEmpty($record);
206
    }
207
208
    public function testRotation()
209
    {
210
        $model = $this->getTestModel3();
211
        $data = $this->fetchRawData(Test_EncryptedModel::class, $model->ID);
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
212
213
        $old = EncryptHelper::getEngineForEncryption("nacl");
214
        $result = $model->needsToRotateEncryption($old);
215
        $this->assertTrue($result);
216
217
        // This is throwing invalid ciphertext
218
        // $result = $model->rotateEncryption($old);
219
        // $this->assertTrue($result);
220
    }
221
222
    public function testFixture()
223
    {
224
        // this one use nacl encryption and will be rotated transparently
225
        $model = $this->getTestModel();
226
227
        $result = $model->needsToRotateEncryption(EncryptHelper::getEngineForEncryption("nacl"));
228
        $this->assertTrue($result);
229
230
        // Ensure we have our blind indexes
231
        $this->assertTrue($model->hasDatabaseField('MyIndexedVarcharValue'));
232
        $this->assertTrue($model->hasDatabaseField('MyIndexedVarcharBlindIndex'));
233
        $this->assertTrue($model->hasDatabaseField('MyNumberValue'));
234
        $this->assertTrue($model->hasDatabaseField('MyNumberBlindIndex'));
235
        $this->assertTrue($model->hasDatabaseField('MyNumberLastFourBlindIndex'));
236
237
        if (class_uses($model, HasEncryptedFields::class)) {
0 ignored issues
show
Bug introduced by
LeKoala\Encrypt\HasEncryptedFields::class of type string is incompatible with the type boolean expected by parameter $autoload of class_uses(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

237
        if (class_uses($model, /** @scrutinizer ignore-type */ HasEncryptedFields::class)) {
Loading history...
238
            $this->assertTrue($model->hasEncryptedField('MyVarchar'));
239
            $this->assertTrue($model->hasEncryptedField('MyIndexedVarchar'));
240
        }
241
242
243
        // print_r($model);
244
        /*
245
         [record:protected] => Array
246
        (
247
            [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
248
            [LastEdited] => 2020-12-15 10:09:47
249
            [Created] => 2020-12-15 10:09:47
250
            [Name] => demo
251
            [MyText] => nacl:mQ1g5ugjYSWjFd-erM6-xlB_EbWp1bOAUPbL4fa3Ce5SX6LP7sFCczkFx_lRABvZioWJXx-L
252
            [MyHTMLText] => nacl:836In6YCaEf3_mRJR7NOC_s0P8gIFESgmPnHCefTe6ycY_6CLKVmT0_9KWHgnin-WGXMJawkS1hS87xwQw==
253
            [MyVarchar] => nacl:ZeOw8-dcBdFemtGm-MRJ5pCSipOtAO5-zBRms8F5Elex08GuoL_JKbdN-CiOP-u009MJfvGZUkx9Ru5Zn0_y
254
            [RegularFileID] => 2
255
            [EncryptedFileID] => 3
256
            [MyIndexedVarcharBlindIndex] => 04bb6edd
257
            [ID] => 1
258
            [RecordClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
259
        )
260
        */
261
262
        $varcharValue = 'encrypted varchar value';
263
        $varcharWithIndexValue = 'some_searchable_value';
264
        // regular fields are not affected
265
        $this->assertEquals('demo', $model->Name);
266
267
        // get value
268
        $this->assertEquals($varcharValue, $model->dbObject('MyVarchar')->getValue());
269
        // encrypted fields work transparently when using trait
270
        $this->assertEquals($varcharValue, $model->MyVarchar);
271
272
273
        $this->assertTrue($model->dbObject('MyIndexedVarchar') instanceof EncryptedDBField);
274
        $this->assertTrue($model->dbObject('MyIndexedVarchar')->hasField('Value'));
275
276
        $model->MyIndexedVarchar = $varcharWithIndexValue;
0 ignored issues
show
Bug Best Practice introduced by
The property MyIndexedVarchar does not exist on LeKoala\Encrypt\Test\Test_EncryptedModel. Since you implemented __set, consider adding a @property annotation.
Loading history...
277
        $model->write();
278
        $this->assertEquals($varcharWithIndexValue, $model->MyIndexedVarchar);
0 ignored issues
show
Bug Best Practice introduced by
The property MyIndexedVarchar does not exist on LeKoala\Encrypt\Test\Test_EncryptedModel. Since you implemented __get, consider adding a @property annotation.
Loading history...
279
280
        $dbRecord = $this->fetchRawData(get_class($model), $model->ID);
281
        // print_r($dbRecord);
282
        /*
283
        Array
284
(
285
    [ID] => 1
286
    [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
287
    [LastEdited] => 2020-12-15 10:10:27
288
    [Created] => 2020-12-15 10:10:27
289
    [Name] => demo
290
    [MyText] => nacl:aDplmA9hs7naqiPwWdNRMcYNUltf4mOs8KslRQZ4vCdnJylnbjAJYChtVH7wiiygsAHWqbM6
291
    [MyHTMLText] => nacl:dMvk5Miux0bsSP1SjaXQRlbGogNTu7UD3p6AlNHFMAEGXOQz03hkBx43C-WelCS0KUdAN9ewuwuXZqMmRA==
292
    [MyVarchar] => nacl:sZRenCG6En7Sg_HmsUHkNy_1MXOstly7eHm0i2iq83kTFH40UsQj-HTqxxYfx0ghuWSKbcqHQ7_OAEy4pcPm
293
    [RegularFileID] => 2
294
    [EncryptedFileID] => 3
295
    [MyNumberValue] =>
296
    [MyNumberBlindIndex] =>
297
    [MyNumberLastFourBlindIndex] =>
298
    [MyIndexedVarcharValue] =>
299
    [MyIndexedVarcharBlindIndex] => 04bb6edd
300
)
301
*/
302
        $this->assertNotEquals($varcharValue, $dbRecord['MyVarchar']);
303
        $this->assertNotEmpty($dbRecord['MyVarchar']);
304
        $this->assertTrue(EncryptHelper::isEncrypted($dbRecord['MyVarchar']));
305
    }
306
307
    public function testFixture2()
308
    {
309
        // this one has only brng encryption
310
        $model = $this->getTestModel2();
311
312
        $result = $model->needsToRotateEncryption(EncryptHelper::getCipherSweet());
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
313
        // echo '<pre>';
314
        // print_r($this->fetchRawData(Test_EncryptedModel::class, $model->ID));
315
        // die();
316
        //TODO: understand why this returns true
317
        // $this->assertFalse($result);
318
319
        // Ensure we have our blind indexes
320
        $this->assertTrue($model->hasDatabaseField('MyIndexedVarcharValue'));
321
        $this->assertTrue($model->hasDatabaseField('MyIndexedVarcharBlindIndex'));
322
        $this->assertTrue($model->hasDatabaseField('MyNumberValue'));
323
        $this->assertTrue($model->hasDatabaseField('MyNumberBlindIndex'));
324
        $this->assertTrue($model->hasDatabaseField('MyNumberLastFourBlindIndex'));
325
326
        if (class_uses($model, HasEncryptedFields::class)) {
0 ignored issues
show
Bug introduced by
LeKoala\Encrypt\HasEncryptedFields::class of type string is incompatible with the type boolean expected by parameter $autoload of class_uses(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

326
        if (class_uses($model, /** @scrutinizer ignore-type */ HasEncryptedFields::class)) {
Loading history...
327
            $this->assertTrue($model->hasEncryptedField('MyVarchar'));
328
            $this->assertTrue($model->hasEncryptedField('MyIndexedVarchar'));
329
        }
330
331
332
        // print_r($model);
333
        /*
334
        [record:protected] => Array
335
        (
336
            [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
337
            [LastEdited] => 2021-07-07 13:38:48
338
            [Created] => 2021-07-07 13:38:48
339
            [Name] => demo2
340
            [MyText] => brng:XLzehy47IgENco4DcZj75u9D2p53UjDMCmTFGPNdmzYYxVVbDsaVWuZP1dTvIDaYagVggNAxT8S9fUTXw55VyIv6OxYJrQ==
341
            [MyHTMLText] => brng:bJ-6iGa-gjl9M6-UaNvtSrRuFLwDTLC6SIekrPHTcN_nmIUaK_VEFNAGVd3q__siNsvVXLreSlunpSyJ4JmF8eyI12ltz_s-eV6WVXw=
342
            [MyVarchar] => brng:qNEVUW3TS6eACSS4v1_NK0FOiG5JnbihmOHR1DU4L8Pt63OXQIJr_Kpd34J1IHaJXZWt4uuk2SZgskmvf8FrfApag_sRypca87MegXg_wQ==
343
            [RegularFileID] => 0
344
            [EncryptedFileID] => 0
345
            [MyNumberValue] => brng:pKYd8mXDduwhudwWeoE_ByO6IkvVlykVa6h09DTYFdHcb52yA1R5yhTEqQQjz1ndADFRa9WLLM3_e1U8PfPTiP4E
346
            [MyNumberBlindIndex] => a1de44f9
347
            [MyNumberLastFourBlindIndex] => addb
348
            [MyIndexedVarcharValue] => brng:TBD63tu-P9PluzI_zKTZ17P-4bhFvhbW7eOeSOOnDEf7n3Ytv2_52rlvGTVSJeWr5f6Z5eqrxi-RL5B6V0PrUmEqhfE2TGt-IdH5hfU=
349
            [MyIndexedVarcharBlindIndex] => 216d113a
350
            [ID] => 2
351
            [RecordClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
352
        )
353
        */
354
355
        $varcharValue = 'encrypted varchar value';
356
        $varcharWithIndexValue = 'some_searchable_value';
357
        // regular fields are not affected
358
        $this->assertEquals('demo2', $model->Name);
359
360
        // get value
361
        $this->assertEquals($varcharValue, $model->dbObject('MyVarchar')->getValue());
362
        // encrypted fields work transparently when using trait
363
        $this->assertEquals($varcharValue, $model->MyVarchar);
364
365
366
        $this->assertTrue($model->dbObject('MyIndexedVarchar') instanceof EncryptedDBField);
367
        $this->assertTrue($model->dbObject('MyIndexedVarchar')->hasField('Value'));
368
369
        $model->MyIndexedVarchar = $varcharWithIndexValue;
0 ignored issues
show
Bug Best Practice introduced by
The property MyIndexedVarchar does not exist on LeKoala\Encrypt\Test\Test_EncryptedModel. Since you implemented __set, consider adding a @property annotation.
Loading history...
370
        $model->write();
371
        $this->assertEquals($varcharWithIndexValue, $model->MyIndexedVarchar);
0 ignored issues
show
Bug Best Practice introduced by
The property MyIndexedVarchar does not exist on LeKoala\Encrypt\Test\Test_EncryptedModel. Since you implemented __get, consider adding a @property annotation.
Loading history...
372
373
        $dbRecord = $this->fetchRawData(get_class($model), $model->ID);
374
        // print_r($dbRecord);
375
        /*
376
        Array
377
(
378
    [ID] => 2
379
    [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
380
    [LastEdited] => 2021-07-07 13:52:10
381
    [Created] => 2021-07-07 13:52:08
382
    [Name] => demo2
383
    [MyText] => brng:IQ-6VoXJedlAGdoCPFUVTSnipUPR4k9YSi3Ik8_oPfUmMVDhA1kgTBFdG_6k08xLhD39G0ksVD_nMtUF4Opo6Zxgkc5Qww==
384
    [MyHTMLText] => brng:ATmS8Tooc0j2FN5zB8ojmhgNHD-vncvm1ljX8aF7rR6bbsD8pEwyX7BJ3mPg6WEzwyye4uriGskFy30GL9LEKsGs1hs40JJgs6rgwKA=
385
    [MyVarchar] => brng:zxu2RFNjqDGV0JmxF1WPMtxDKTyfOtvVztXfbnV3aYJAzro7RwHhSs8HhasHvdPOQ2Vxi_oDieRgcE8XeP3nyoF3tYJrJp3Mo9XdYXj2tw==
386
    [RegularFileID] => 0
387
    [EncryptedFileID] => 0
388
    [MyNumberValue] => brng:pKYd8mXDduwhudwWeoE_ByO6IkvVlykVa6h09DTYFdHcb52yA1R5yhTEqQQjz1ndADFRa9WLLM3_e1U8PfPTiP4E
389
    [MyNumberBlindIndex] => a1de44f9
390
    [MyNumberLastFourBlindIndex] => addb
391
    [MyIndexedVarcharValue] => brng:0ow_r7UD3FXYXxq7kjVzA3uY1ThFYfAWxZFAHA0aRoohLfQW_ZBa0Q8w5A3hyLJhT6djM6xR43O_jeEfP-w_fRaH3nXRI5RW7tO78JY=
392
    [MyIndexedVarcharBlindIndex] => 216d113a
393
)
394
*/
395
        $this->assertNotEquals($varcharValue, $dbRecord['MyVarchar']);
396
        $this->assertNotEmpty($dbRecord['MyVarchar']);
397
        $this->assertTrue(EncryptHelper::isEncrypted($dbRecord['MyVarchar']));
398
    }
399
400
    public function testRecordIsEncrypted()
401
    {
402
        $model = new Test_EncryptedModel();
403
404
        // Let's write some stuff
405
        $someText = 'some text';
406
        $model->MyText = $someText . ' text';
407
        $model->MyHTMLText = '<p>' . $someText . ' html</p>';
408
        $model->MyVarchar = 'encrypted varchar value';
409
        $model->MyIndexedVarchar = "some_searchable_value";
0 ignored issues
show
Bug Best Practice introduced by
The property MyIndexedVarchar does not exist on LeKoala\Encrypt\Test\Test_EncryptedModel. Since you implemented __set, consider adding a @property annotation.
Loading history...
410
        $model->MyNumber = "0123456789";
411
        // echo '<pre>';
412
        // print_r(array_keys($model->getChangedFields()));
413
        // die();
414
        $id = $model->write();
415
416
        $this->assertNotEmpty($id);
417
418
        // For the model, its the same
419
        $this->assertEquals($someText . ' text', $model->MyText);
420
        $this->assertEquals($someText . ' text', $model->dbObject('MyText')->getValue());
421
        $this->assertEquals($someText . ' text', $model->getField('MyText'));
422
        $this->assertEquals('<p>' . $someText . ' html</p>', $model->MyHTMLText);
423
424
        // In the db, it's not the same
425
        $dbRecord = $this->fetchRawData(get_class($model), $model->ID);
426
427
        if (!EncryptHelper::isEncrypted($dbRecord['MyIndexedVarcharValue'])) {
428
            print_r($dbRecord);
429
        }
430
431
        /*
432
(
433
    [ID] => 2
434
    [ClassName] => LeKoala\Encrypt\Test\Test_EncryptedModel
435
    [LastEdited] => 2020-12-15 10:20:39
436
    [Created] => 2020-12-15 10:20:39
437
    [Name] =>
438
    [MyText] => nacl:yA3XhjUpxE6cS3VMOVI4eqpolP1vRZDYjFySULZiazi9V3HSugC3t8KgImnGV5jP1VzEytVX
439
    [MyHTMLText] => nacl:F3D33dZ2O7qtlmkX-fiaYwSjAo6RC03aiAWRTkfSJOZikcSfezjwmi9DPJ4EO0hYeVc9faRgA3RmTDajRA==
440
    [MyVarchar] => nacl:POmdt3mTUSgPJw3ttfi2G9HgHAE4FRX4FQ5CSBicj4JsEwyPwrP-JKYGcs5drFYLId3cMVf6m8daUY7Ao4Cz
441
    [RegularFileID] => 0
442
    [EncryptedFileID] => 0
443
    [MyNumberValue] => nacl:2wFOX_qahm-HmzQPXvcBFhWCG1TaGQgeM7vkebLxRXDfMpzAxhxkExVgBi8caPYrwvA=
444
    [MyNumberBlindIndex] => 5e0bd888
445
    [MyNumberLastFourBlindIndex] => 276b
446
    [MyIndexedVarcharValue] => nacl:BLi-zF02t0Zet-ADP3RT8v5RTsM11WKIyjlJ1EVHIai2HwjxCIq92gfsay5zqiLic14dXtwigb1kI179QQ==
447
    [MyIndexedVarcharBlindIndex] => 04bb6edd
448
)
449
        */
450
        $text = isset($dbRecord['MyText']) ? $dbRecord['MyText'] : null;
451
        $this->assertNotEmpty($text);
452
        $this->assertNotEquals($someText, $text, "Data is not encrypted in the database");
453
        // Composite fields should work as well
454
        $this->assertNotEmpty($dbRecord['MyIndexedVarcharValue']);
455
        $this->assertNotEmpty($dbRecord['MyIndexedVarcharBlindIndex']);
456
457
        // Test save into
458
        $modelFieldsBefore = $model->getQueriedDatabaseFields();
459
        $model->MyIndexedVarchar = 'new_value';
460
        $dbObj = $model->dbObject('MyIndexedVarchar');
461
        // $dbObj->setValue('new_value', $model);
462
        // $dbObj->saveInto($model);
463
        $modelFields = $model->getQueriedDatabaseFields();
464
        // print_r($modelFields);
465
        $this->assertTrue($dbObj->isChanged());
466
        $changed = implode(", ", array_keys($model->getChangedFields()));
467
        $this->assertNotEquals($modelFieldsBefore['MyIndexedVarchar'], $modelFields['MyIndexedVarchar'], "It should not have the same value internally anymore");
468
        $this->assertTrue($model->isChanged('MyIndexedVarchar'), "Field is not properly marked as changed, only have : " . $changed);
469
        $this->assertEquals('new_value', $dbObj->getValue());
470
        $this->assertNotEquals('new_value', $modelFields['MyIndexedVarcharValue'], "Unencrypted value is not set on value field");
471
472
        // Somehow this is not working on travis? composite fields don't save encrypted data although it works locally
473
        $this->assertNotEquals("some_searchable_value", $dbRecord['MyIndexedVarcharValue'], "Data is not encrypted in the database");
474
475
        // if we load again ?
476
        // it should work thanks to our trait
477
        // by default, data will be loaded encrypted if we don't use the trait and call getField directly
478
        $model2 = $model::get()->byID($model->ID);
479
        $this->assertEquals($someText . ' text', $model2->MyText, "Data does not load properly");
480
        $this->assertEquals('<p>' . $someText . ' html</p>', $model2->MyHTMLText, "Data does not load properly");
481
    }
482
483
    public function testFileEncryption()
484
    {
485
        $regularFile = $this->getRegularFile();
486
        $encryptedFile = $this->getEncryptedFile();
487
488
        $this->assertEquals(0, $regularFile->Encrypted);
489
        $this->assertEquals(1, $encryptedFile->Encrypted);
490
491
        // test encryption
492
493
        $string = 'Some content';
494
495
        $stream = fopen('php://memory', 'r+');
496
        fwrite($stream, $string);
497
        rewind($stream);
498
499
        $encryptedFile->setFromStream($stream, 'secret.doc');
500
        $encryptedFile->write();
501
502
        $this->assertFalse($encryptedFile->isEncrypted());
503
504
        $encryptedFile->encryptFileIfNeeded();
505
506
        $this->assertTrue($encryptedFile->isEncrypted());
507
    }
508
}
509