Passed
Branch wip_sessions (2e0cc8)
by Nils
04:59
created

recursive()   D

Complexity

Conditions 21
Paths 6

Size

Total Lines 74
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 45
c 1
b 0
f 0
nc 6
nop 4
dl 0
loc 74
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Teampass - a collaborative passwords manager.
7
 * ---
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 * ---
12
 * @project   Teampass
13
 * @file      import.queries.php
14
 * ---
15
 * @author    Nils Laumaillé ([email protected])
16
 * @copyright 2009-2023 Teampass.net
17
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
18
 * ---
19
 * @see       https://www.teampass.net
20
 */
21
22
23
use Goodby\CSV\Import\Standard\Lexer;
24
use Goodby\CSV\Import\Standard\Interpreter;
25
use Goodby\CSV\Import\Standard\LexerConfig;
26
use voku\helper\AntiXSS;
27
use TeampassClasses\NestedTree\NestedTree;
28
use TeampassClasses\SessionManager\SessionManager;
29
use TeampassClasses\Language\Language;
30
use TeampassClasses\PerformChecks\PerformChecks;
31
32
// Load functions
33
require_once 'main.functions.php';
34
35
// init
36
loadClasses('DB');
37
$session = SessionManager::getSession();
38
$lang = new Language(); 
39
40
// Load config if $SETTINGS not defined
41
try {
42
    include_once __DIR__.'/../includes/config/tp.config.php';
43
} catch (Exception $e) {
44
    throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
45
}
46
47
// Do checks
48
// Instantiate the class with posted data
49
$checkUserAccess = new PerformChecks(
50
    dataSanitizer(
51
        [
52
            'type' => isset($_POST['type']) === true ? htmlspecialchars($_POST['type']) : '',
53
        ],
54
        [
55
            'type' => 'trim|escape',
56
        ],
57
    ),
58
    [
59
        'user_id' => returnIfSet($session->get('user-id'), null),
60
        'user_key' => returnIfSet($session->get('key'), null),
61
    ]
62
);
63
// Handle the case
64
echo $checkUserAccess->caseHandler();
65
if (
66
    $checkUserAccess->userAccessPage('import') === false ||
67
    $checkUserAccess->checkSession() === false
68
) {
69
    // Not allowed page
70
    $session->set('system-error_code', ERR_NOT_ALLOWED);
71
    include $SETTINGS['cpassman_dir'] . '/error.php';
72
    exit;
73
}
74
75
// Define Timezone
76
date_default_timezone_set(isset($SETTINGS['timezone']) === true ? $SETTINGS['timezone'] : 'UTC');
77
78
// Set header properties
79
header('Content-type: text/html; charset=utf-8');
80
header('Cache-Control: no-cache, no-store, must-revalidate');
81
error_reporting(E_ERROR);
82
set_time_limit(0);
83
84
// --------------------------------- //
85
86
// Set some constants for program readability
87
define('KP_PATH', 0);
88
define('KP_GROUP', 1);
89
define('KP_TITLE', 2);
90
define('KP_PASSWORD', 3);
91
define('KP_USERNAME', 4);
92
define('KP_URL', 5);
93
define('KP_UUID', 6);
94
define('KP_NOTES', 7);
95
96
97
$tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
98
99
// POST Varaibles
100
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
101
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
102
103
// Build query
104
switch (filter_input(INPUT_POST, 'type', FILTER_SANITIZE_FULL_SPECIAL_CHARS)) {
105
    //Check if import CSV file format is what expected
106
    case 'import_file_format_csv':
107
        // Check KEY and rights
108
        if ($post_key !== $session->get('key')) {
109
            echo prepareExchangedData(
110
                array(
111
                    'error' => true,
112
                    'message' => $lang->get('key_is_not_correct'),
113
                ),
114
                'encode'
115
            );
116
            break;
117
        }
118
119
        //load full tree
120
        $tree->rebuild();
121
        $tree = $tree->getDescendants();
122
123
        // Init post variable
124
        $post_operation_id = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_NUMBER_INT);
125
126
        // Get filename from database
127
        $data = DB::queryFirstRow(
128
            'SELECT valeur
129
            FROM '.prefixTable('misc').'
130
            WHERE increment_id = %i AND type = "temp_file"',
131
            $post_operation_id
132
        );
133
        
134
        // Delete operation id
135
        DB::delete(
136
            prefixTable('misc'),
137
            "increment_id = %i AND type = 'temp_file'",
138
            $post_operation_id
139
        );
140
141
        // do some initializations
142
        $file = $SETTINGS['path_to_files_folder'].'/'.$data['valeur'];
143
        $importation_possible = true;
144
        $itemsArray = array();
145
        $line_number = 0;
146
        $account = $text = '';
147
        $continue_on_next_line = false;
148
149
        // Open file
150
        if ($fp = fopen($file, 'r')) {
151
            // data from CSV
152
            $valuesToImport = array();
153
154
            // Lexer configuration
155
            $config = new LexerConfig();
156
            $lexer = new Lexer($config);
157
            $config->setIgnoreHeaderLine('true');
158
            $interpreter = new Interpreter();
159
            $interpreter->addObserver(function (array $row) use (&$valuesToImport) {
160
                $valuesToImport[] = array(
161
                    'Label' => $row[0],
162
                    'Login' => $row[1],
163
                    'Password' => $row[2],
164
                    'url' => $row[3],
165
                    'Comments' => $row[4],
166
                );
167
            });
168
            $lexer->parse($file, $interpreter);
169
170
            // extract one line
171
            foreach ($valuesToImport as $key => $row) {
172
                //increment number of lines found
173
                ++$line_number;
174
175
                //Check number of fields. MUST be 5. if not stop importation
176
                if (count($row) != 5) {
177
                    $importation_possible = false;
178
                    //Stop if file has not expected structure
179
                    if ($importation_possible === false) {
180
                        echo '[{"error":"bad_structure"}]';
181
                        break;
182
                    }
183
                }
184
185
                //If any comment is on several lines, then replace 'lf' character
186
                $row['Comments'] = str_replace(array("\r\n", "\n", "\r"), '<br>', $row['Comments']);
187
188
                // Check if current line contains a "<br>" character in order to identify an ITEM on several CSV lines
189
                if (substr_count($row['Comments'], '<br>') > 0 || substr_count($row['Label'], '<br>') > 0) {
190
                    $continue_on_next_line = true;
191
                    $comment .= addslashes($row['Label']);
192
                } else {
193
                    // Store in variable values from previous line
194
                    if (empty($account) === false) {
195
                        if ($continue_on_next_line === false) {
196
                            // Prepare listing that will be shown to user
197
                            array_push(
198
                                $itemsArray,
199
                                array(
200
                                    'label' => $account,
201
                                    'login' => $login,
202
                                    'pwd' => $pwd,
203
                                    'url' => $url,
204
                                    'comment' => $comment,
205
                                )
206
                            );
207
208
                            // Initialize this variable in order to restart from scratch
209
                            $account = '';
210
                        }
211
                    }
212
                }
213
214
                // Get values of current line
215
                if ($account === '' && $continue_on_next_line === false) {
216
                    $account = trim(htmlspecialchars($row['Label'], ENT_QUOTES, 'UTF-8'));
217
                    $login = trim(htmlspecialchars($row['Login'], ENT_QUOTES, 'UTF-8'));
218
                    $pwd = trim(str_replace('"', '&quot;', $row['Password']));
219
                    $url = trim($row['url']);
220
                    $to_find = array('"', "'");
221
                    $to_ins = array('&quot', '&#39;');
222
                    $comment = htmlentities(
223
                        addslashes(str_replace($to_find, $to_ins, $row['Comments'])),
224
                        ENT_QUOTES,
225
                        'UTF-8'
226
                    );
227
228
                    $continue_on_next_line = false;
229
                }
230
            }
231
            // close file
232
            fclose($fp);
233
        } else {
234
            echo prepareExchangedData(
235
                array(
236
                    'error' => true,
237
                    'message' => $lang->get('cannot_open_file'),
238
                ),
239
                'encode'
240
            );
241
242
            //delete file
243
            unlink($file);
244
            break;
245
        }
246
247
        if ($line_number > 0) {
248
            array_push(
249
                $itemsArray,
250
                array(
251
                    'label' => $account,
252
                    'login' => $login,
253
                    'pwd' => $pwd,
254
                    'url' => $url,
255
                    'comment' => $comment,
256
                )
257
            );
258
259
            // Show results to user.
260
            echo prepareExchangedData(
261
                array(
262
                    'error' => false,
263
                    'message' => '',
264
                    'output' => $itemsArray,
265
                    'number' => $line_number++,
266
                ),
267
                'encode'
268
            );
269
        }
270
271
        //delete file
272
        unlink($file);
273
274
        break;
275
276
    //Insert into DB the items the user has selected
277
    case 'import_items':
278
        // Check KEY and rights
279
        if ($post_key !== $session->get('key')) {
280
            echo prepareExchangedData(
281
                array(
282
                    'error' => true,
283
                    'message' => $lang->get('key_is_not_correct'),
284
                ),
285
                'encode'
286
            );
287
            break;
288
        }
289
290
        // Init
291
        $list = [];
292
293
        // Decrypt and retreive data in JSON format
294
        $dataReceived = prepareExchangedData(
295
            $post_data,
296
            'decode'
297
        );
298
        
299
        // Init post variable
300
        $post_folder = filter_var($dataReceived['folder-id'], FILTER_SANITIZE_NUMBER_INT);
301
        $post_items = filter_var_array(
302
            $dataReceived['items'],
303
            FILTER_SANITIZE_FULL_SPECIAL_CHARS
304
        );
305
        $post_edit_role = filter_var($dataReceived['edit-role'], FILTER_SANITIZE_NUMBER_INT);
306
        $post_edit_all = filter_var($dataReceived['edit-all'], FILTER_SANITIZE_NUMBER_INT);
307
308
        // Get title for this folder
309
        $data_fld = DB::queryFirstRow(
310
            'SELECT title
311
            FROM '.prefixTable('nested_tree').'
312
            WHERE id = %i',
313
            $post_folder
314
        );
315
316
        //Get some info about personal folder
317
        if (in_array($post_folder, $session->get('user-personal_folders')) === true) {
318
            $personalFolder = 1;
319
        } else {
320
            $personalFolder = 0;
321
        }
322
323
        //Prepare variables
324
        //$listItems = json_decode($post_items, true);
325
326
        // Clean each array entry
327
        if (is_array($post_items) === true) {
328
            array_walk_recursive($post_items, 'cleanOutput');
329
        }
330
        //print_r($post_items);
331
        // Loop on array
332
        foreach ($post_items as $item) {
333
            //For each item, insert into DB
334
335
            // Handle case where pw is empty
336
            // if not allowed then warn user
337
            if ((null !== $session->get('user-create_item_without_password')
338
                && (int) $session->get('user-create_item_without_password') !== 1
339
                ) ||
340
                empty($item['pwd']) === false
341
            ) {
342
                // NEW ENCRYPTION
343
                $cryptedStuff = doDataEncryption($item['pwd']);
344
            } else {
345
                $cryptedStuff['encrypted'] = '';
346
            }
347
            $post_password = $cryptedStuff['encrypted'];
348
349
            // Insert new item in table ITEMS
350
            DB::insert(
351
                prefixTable('items'),
352
                array(
353
                    'label' => substr($item['label'], 0, 500),
354
                    'description' => empty($item['comment']) === true ? '' : $item['comment'],
355
                    'pw' => $post_password,
356
                    'pw_iv' => '',
357
                    'url' => empty($item['url']) === true ? '' : substr($item['url'], 0, 500),
358
                    'id_tree' => $post_folder,
359
                    'login' => empty($item['login']) === true ? '' : substr($item['login'], 0, 200),
360
                    'anyone_can_modify' => $post_edit_all,
361
                    'encryption_type' => 'teampass_aes',
362
                )
363
            );
364
            $newId = DB::insertId();
365
366
            // Create sharekeys for users
367
            storeUsersShareKey(
368
                prefixTable('sharekeys_items'),
369
                (int) $personalFolder,
370
                (int) $post_folder,
371
                (int) $newId,
372
                $cryptedStuff['objectKey'],
373
                $SETTINGS
374
            );
375
376
            //if asked, anyone in role can modify
377
            if ((int) $post_edit_role === 1) {
378
                foreach ($session->get('system-array_roles') as $role) {
379
                    DB::insert(
380
                        prefixTable('restriction_to_roles'),
381
                        array(
382
                            'role_id' => $role['id'],
383
                            'item_id' => $newId,
384
                        )
385
                    );
386
                }
387
            }
388
389
            // Insert new item in table LOGS_ITEMS
390
            DB::insert(
391
                prefixTable('log_items'),
392
                array(
393
                    'id_item' => $newId,
394
                    'date' => time(),
395
                    'id_user' => $session->get('user-id'),
396
                    'action' => 'at_creation',
397
                )
398
            );
399
400
            array_push($list, $item['row']);
401
402
            //Add entry to cache table
403
            DB::insert(
404
                prefixTable('cache'),
405
                array(
406
                    'id' => $newId,
407
                    'label' => substr($item['label'], 0, 500),
408
                    'description' => empty($item['comment']) ? '' : $item['comment'],
409
                    'id_tree' => $post_folder,
410
                    'url' => '0',
411
                    'perso' => $personalFolder === 0 ? 0 : 1,
412
                    'login' => empty($item['login']) ? '' : substr($item['login'], 0, 500),
413
                    'folder' => $data_fld['title'],
414
                    'author' => $session->get('user-id'),
415
                    'timestamp' => time(),
416
                    'tags' => '',
417
                    'restricted_to' => '0',
418
                    'renewal_period' => '0',
419
                    'timestamp' => time(),
420
                )
421
            );
422
        }
423
424
        echo prepareExchangedData(
425
            array(
426
                'error' => false,
427
                'message' => '',
428
                'items' => $list,
429
            ),
430
            'encode'
431
        );
432
        break;
433
434
    //Check if import KEEPASS file format is what expected
435
    case 'import_file_format_keepass':
436
        // Check KEY and rights
437
        if ($post_key !== $session->get('key')) {
438
            echo prepareExchangedData(
439
                array(
440
                    'error' => true,
441
                    'message' => $lang->get('key_is_not_correct'),
442
                ),
443
                'encode'
444
            );
445
            break;
446
        }
447
448
        // Decrypt and retreive data in JSON format
449
        $receivedParameters = prepareExchangedData(
450
            $post_data,
451
            'decode'
452
        );
453
        $post_operation_id = filter_var($receivedParameters['file'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
454
        $post_folder_id = filter_var($receivedParameters['folder-id'], FILTER_SANITIZE_NUMBER_INT);
455
456
        // Get filename from database
457
        $data = DB::queryFirstRow(
458
            'SELECT valeur
459
            FROM '.prefixTable('misc').'
460
            WHERE increment_id = %i AND type = "temp_file"',
461
            $post_operation_id
462
        );
463
464
        // Delete operation id
465
        DB::delete(
466
            prefixTable('misc'),
467
            'increment_id = %i AND type = "temp_file"',
468
            $post_operation_id
469
        );
470
471
        // do some initializations
472
        $file = $data['valeur'];
473
474
        //read xml file
475
        if (file_exists($SETTINGS['path_to_files_folder'].'/'.$file)) {
476
            $xml = simplexml_load_file(
477
                $SETTINGS['path_to_files_folder'].'/'.$file
478
            );
479
        }
480
481
        // Convert XML to associative array
482
        $xmlfile = file_get_contents($SETTINGS['path_to_files_folder'].'/'.$file);
483
        $new = simplexml_load_string($xmlfile);
484
        $con = json_encode($new);
485
        $newArr = json_decode($con, true);
486
        
487
        /**
488
         * Undocumented function
489
         *
490
         * @param array $array
491
         * @param integer $previousFolder
492
         * @param array $newItemsToAdd
493
         * @param integer $level
494
         * @return array
495
         */
496
        function recursive($array, $previousFolder, $newItemsToAdd, $level) : array
497
        {
498
            // Manage entries
499
            if (isset($array['Entry']) === true) {
500
                foreach($array['Entry'] as $key => $value) {
501
                    if (isset($value['String']) === true) {
502
                        $itemDefinition = [];
503
                        $c = count($value['String']);
504
                        for ($i = 0; $i < $c; $i++) {
505
                            $itemDefinition[$value['String'][$i]['Key']] = is_array($value['String'][$i]['Value']) === false ? $value['String'][$i]['Value'] : '';
506
                        }
507
                        $itemDefinition['parentFolderId'] = $previousFolder;
508
                        isset($itemDefinition['Notes']) === false ? $itemDefinition['Notes'] = '' : '';
509
                        isset($itemDefinition['URL']) === false ? $itemDefinition['URL'] = '' : '';
510
                        isset($itemDefinition['Password']) === false ? $itemDefinition['Password'] = '' : '';
511
                        array_push(
512
                            $newItemsToAdd['items'],
513
                            $itemDefinition
514
                        );
515
                        continue;
516
                    }
517
                    
518
                    if ($key === "String") {
519
                        array_push(
520
                            $newItemsToAdd['items'],
521
                            [
522
                                'Notes' => is_array($value[0]['Value']) === false ? $value[0]['Value'] : '',
523
                                'Title' => is_array($value[2]['Value']) === false ? $value[2]['Value'] : '',
524
                                'Password' => is_array($value[1]['Value']) === false ? $value[1]['Value'] : '',
525
                                'URL' => is_array($value[3]['Value']) === false ? $value[3]['Value'] : '',
526
                                'UserName' => is_array($value[4]['Value']) === false ? $value[4]['Value'] : '',
527
                                'parentFolderId' => $previousFolder,
528
                            ]
529
                        );
530
                    }
531
                }
532
            }
533
534
            // Manage GROUPS
535
            if (isset($array['Group']) === true && is_array($array['Group'])=== true) {
536
                $currentFolderId = $previousFolder;
537
                if (isset($array['Group']['UUID']) === true) {
538
                    // build expect array format
539
                    $array['Group'] = [$array['Group']];
540
                }
541
                foreach($array['Group'] as $key => $value){
542
                    // Add this new folder
543
                    array_push(
544
                        $newItemsToAdd['folders'],
545
                        [
546
                            'folderName' => $value['Name'],
547
                            'uuid' => $value['UUID'],
548
                            'parentFolderId' => $previousFolder,
549
                            'level' => $level,
550
                        ]
551
                    );
552
                    $previousFolder = $value['UUID'];
553
                    
554
                    // recursive inside this entry
555
                    $newItemsToAdd = recursive(
556
                        array_merge(
557
                            ['Entry' => isset($value['Entry']) === true ? $value['Entry'] : ''],
558
                            ['Group' => isset($value['Group']) === true ? $value['Group'] : ''],
559
                        ),
560
                        $previousFolder,
561
                        $newItemsToAdd,
562
                        $level + 1
563
                    );
564
565
                    $previousFolder = $currentFolderId;
566
                }
567
            }
568
            
569
            return $newItemsToAdd;
570
        }
571
        
572
        $ret = recursive(
573
            array_merge(
574
                ['Entry' => $newArr['Root']['Group']['Entry']],
575
                ['Group' => $newArr['Root']['Group']['Group']],
576
            ),
577
            $post_folder_id,
578
            [
579
                'folders' => [],
580
                'items' => []
581
            ],
582
            1,
583
        );
584
585
        
586
        echo prepareExchangedData(
587
            array(
588
                'error' => false,
589
                'message' => '',
590
                'data' => $ret,
591
            ),
592
            'encode'
593
        );
594
595
        break;
596
597
    // KEEPASS - CREATE FOLDERS
598
    case 'keepass_create_folders':
599
        // Check KEY and rights
600
        if ($post_key !== $session->get('key')) {
601
            echo prepareExchangedData(
602
                array(
603
                    'error' => true,
604
                    'message' => $lang->get('key_is_not_correct'),
605
                ),
606
                'encode'
607
            );
608
            break;
609
        }
610
611
        // Decrypt and retreive data in JSON format
612
        $receivedParameters = prepareExchangedData(
613
            $post_data,
614
            'decode'
615
        );
616
617
        $post_folder_id = filter_var($receivedParameters['folder-id'], FILTER_SANITIZE_NUMBER_INT);
618
        $post_edit_all = filter_var($receivedParameters['edit-all'], FILTER_SANITIZE_NUMBER_INT);
619
        $post_edit_role = filter_var($receivedParameters['edit-role'], FILTER_SANITIZE_NUMBER_INT);
620
        $post_folders = filter_var_array(
621
            $receivedParameters['folders'],
622
            FILTER_SANITIZE_FULL_SPECIAL_CHARS
623
        );
624
625
        // get destination folder informations
626
        $destinationFolderInfos = getFolderComplexity($post_folder_id, $session->get('user-personal_folders'));
627
        $arrFolders[$post_folder_id] = [
628
            'id' => (int) $post_folder_id,
629
            'level' => 1,
630
            'isPF' => false,
631
        ];
632
        $startPathLevel = 1;
633
634
        foreach($post_folders as $folder) {
635
            // get parent id
636
            $parentId = $arrFolders[$folder['parentFolderId']];
637
638
            // create folder in DB
639
            $folderId = createFolder(
640
                $folder['folderName'],
641
                $parentId['id'],
642
                $folder['level'],
643
                $startPathLevel,
644
                $destinationFolderInfos['levelPwComplexity']
645
            );
646
647
            // manage parent
648
            $arrFolders[$folder['uuid']] = [
649
                'id' => (int) $folderId,
650
                'level' => (int) ($folder['level'] + $startPathLevel),
651
                'isPF' => $destinationFolderInfos['importPF'],
652
            ];
653
        }
654
        //rebuild full tree
655
        $tree->rebuild();
656
657
658
        echo prepareExchangedData(
659
            array(
660
                'error' => false,
661
                'message' => '',
662
                'folders' => $arrFolders,
663
            ),
664
            'encode'
665
        );
666
667
        break;
668
669
    // KEEPASS - CREATE ITEMS
670
    case 'keepass_create_items':
671
        // Check KEY and rights
672
        if ($post_key !== $session->get('key')) {
673
            echo prepareExchangedData(
674
                array(
675
                    'error' => true,
676
                    'message' => $lang->get('key_is_not_correct'),
677
                ),
678
                'encode'
679
            );
680
            break;
681
        }
682
683
        // Decrypt and retreive data in JSON format
684
        $receivedParameters = prepareExchangedData(
685
            $post_data,
686
            'decode'
687
        );
688
689
        $post_edit_all = filter_var($receivedParameters['edit-all'], FILTER_SANITIZE_NUMBER_INT);
690
        $post_edit_role = filter_var($receivedParameters['edit-role'], FILTER_SANITIZE_NUMBER_INT);
691
        $post_folders = filter_var_array(
692
            $receivedParameters['folders'],
693
            FILTER_SANITIZE_FULL_SPECIAL_CHARS
694
        );
695
        $item = filter_var_array(
696
            $receivedParameters['items'],
697
            FILTER_SANITIZE_FULL_SPECIAL_CHARS
698
        );
699
        $ret = '';
700
701
        //foreach($post_items as $item) {
702
            // get info about this folder
703
            $destinationFolderMore = DB::queryFirstRow(
704
                'SELECT title FROM '.prefixTable('nested_tree').' WHERE id = %i',
705
                (int) $post_folders[$item['parentFolderId']]['id']
706
            );
707
708
            // Handle case where pw is empty
709
            // if not allowed then warn user
710
            if ((null !== $session->get('user-create_item_without_password')
711
                && (int) $session->get('user-create_item_without_password') !== 1
712
                ) ||
713
                empty($item['Password']) === false
714
            ) {
715
                // NEW ENCRYPTION
716
                $cryptedStuff = doDataEncryption($item['Password']);
717
            } else {
718
                $cryptedStuff['encrypted'] = '';
719
                $cryptedStuff['objectKey'] = '';
720
            }
721
            $post_password = $cryptedStuff['encrypted'];
722
723
            //ADD item
724
            DB::insert(
725
                prefixTable('items'),
726
                array(
727
                    'label' => substr($item['Title'], 0, 500),
728
                    'description' => $item['Notes'],
729
                    'pw' => $cryptedStuff['encrypted'],
730
                    'pw_iv' => '',
731
                    'url' => substr($item['URL'], 0, 500),
732
                    'id_tree' => $post_folders[$item['parentFolderId']]['id'],
733
                    'login' => substr($item['UserName'], 0, 500),
734
                    'anyone_can_modify' => $post_edit_all,
735
                    'encryption_type' => 'teampass_aes',
736
                    'inactif' => 0,
737
                    'restricted_to' => '',
738
                    'perso' => $post_folders[$item['parentFolderId']]['isPF'] === true ? 1 : 0,
739
                )
740
            );
741
            $newId = DB::insertId();
742
743
            // Create sharekeys for users
744
            storeUsersShareKey(
745
                prefixTable('sharekeys_items'),
746
                $post_folders[$item['parentFolderId']]['isPF'] === true ? 1 : 0,
747
                (int) $post_folders[$item['parentFolderId']]['id'],
748
                (int) $newId,
749
                $cryptedStuff['objectKey'],
750
                $SETTINGS
751
            );
752
753
            //if asked, anyone in role can modify
754
            if ($post_edit_role === 1) {
755
                foreach ($session->get('system-array_roles') as $role) {
756
                    DB::insert(
757
                        prefixTable('restriction_to_roles'),
758
                        array(
759
                            'role_id' => $role['id'],
760
                            'item_id' => $newId,
761
                        )
762
                    );
763
                }
764
            }
765
766
            //Add log
767
            DB::insert(
768
                prefixTable('log_items'),
769
                array(
770
                    'id_item' => $newId,
771
                    'date' => time(),
772
                    'id_user' => $session->get('user-id'),
773
                    'action' => 'at_creation',
774
                    'raison' => 'at_import',
775
                )
776
            );
777
778
            //Add entry to cache table
779
            DB::insert(
780
                prefixTable('cache'),
781
                array(
782
                    'id' => $newId,
783
                    'label' => substr(stripslashes($item['Title']), 0, 500),
784
                    'description' => stripslashes($item['Notes']),
785
                    'url' => substr(stripslashes($item['URL']), 0, 500),
786
                    'tags' => '',
787
                    'id_tree' => $post_folders[$item['parentFolderId']]['id'],
788
                    'perso' => $post_folders[$item['parentFolderId']]['isPF'] === 0 ? 0 : 1,
789
                    'login' => substr(stripslashes($item['UserName']), 0, 500),
790
                    'restricted_to' => '0',
791
                    'folder' => $destinationFolderMore['title'],
792
                    'author' => $session->get('user-id'),
793
                    'renewal_period' => '0',
794
                    'timestamp' => time(),
795
                )
796
            );
797
798
            // prepare return
799
            $ret .= "<li>".substr(stripslashes($item['Title']), 0, 500)." [".$destinationFolderMore['title']."]</li>";
800
        //}
801
802
803
        echo prepareExchangedData(
804
            array(
805
                'error' => false,
806
                'message' => '',
807
                'info' => "<ul>".$ret."</ul>",
808
            ),
809
            'encode'
810
        );
811
812
        break;
813
    }
814
815
816
817
/**
818
 * Create folders during importation
819
 *
820
 * @param string $folderTitle
821
 * @param integer $parentId
822
 * @param integer $folderLevel
823
 * @param integer $startPathLevel
824
 * @param integer $levelPwComplexity
825
 * @return integer
826
 */
827
function createFolder($folderTitle, $parentId, $folderLevel, $startPathLevel, $levelPwComplexity)
828
{
829
    $session = SessionManager::getSession();
830
    //create folder - if not exists at the same level
831
    DB::query(
832
        'SELECT * FROM '.prefixTable('nested_tree').'
833
        WHERE nlevel = %i AND title = %s AND parent_id = %i LIMIT 1',
834
        intval($folderLevel + $startPathLevel),
835
        $folderTitle,
836
        $parentId
837
    );
838
    if (DB::count() === 0) {
839
        //do query
840
        DB::insert(
841
            prefixTable('nested_tree'),
842
            array(
843
                'parent_id' => $parentId,
844
                'title' => stripslashes($folderTitle),
845
                'nlevel' => $folderLevel,
846
                'categories' => '',
847
            )
848
        );
849
        $id = DB::insertId();
850
        //Add complexity level => level is set to "medium" by default.
851
        DB::insert(
852
            prefixTable('misc'),
853
            array(
854
                'type' => 'complex',
855
                'intitule' => $id,
856
                'valeur' => $levelPwComplexity,
857
            )
858
        );
859
860
        // Indicate that a change has been done to force tree user reload
861
        DB::update(
862
            prefixTable('misc'),
863
            array(
864
                'valeur' => time(),
865
            ),
866
            'type = %s AND intitule = %s',
867
            'timestamp',
868
            'last_folder_change'
869
        );
870
871
        //For each role to which the user depends on, add the folder just created.
872
        foreach ($session->get('system-array_roles') as $role) {
873
            DB::insert(
874
                prefixTable('roles_values'),
875
                array(
876
                    'role_id' => $role['id'],
877
                    'folder_id' => $id,
878
                    'type' => 'W',
879
                )
880
            );
881
        }
882
883
        //Add this new folder to the list of visible folders for the user.
884
        $session->set('user-accessible_folders', $id);
885
886
        return $id;
887
    }
888
    
889
    //get folder actual ID
890
    $data = DB::queryFirstRow(
891
        'SELECT id FROM '.prefixTable('nested_tree').'
892
        WHERE nlevel = %i AND title = %s AND parent_id = %i',
893
        intval($folderLevel + $startPathLevel),
894
        $folderTitle,
895
        $parentId
896
    );
897
    return $data['id'];
898
}
899
900
/** 
901
 * getFolderComplexity
902
 * 
903
 * @param int $folderId
904
 * @param boolean $isFolderPF
905
 * 
906
 * @return array
907
*/
908
function getFolderComplexity($folderId, $isFolderPF)
909
{
910
    // If destination is not ROOT then get the complexity level
911
    if ($isFolderPF === true) {
912
        return [
913
            'levelPwComplexity' => 50,
914
            'startPathLevel' => 1,
915
            'importPF' => true
916
        ];
917
    } elseif ($folderId > 0) {
918
        $data = DB::queryFirstRow(
919
            'SELECT m.valeur as value, t.nlevel as nlevel
920
            FROM '.prefixTable('misc').' as m
921
            INNER JOIN '.prefixTable('nested_tree').' as t ON (m.intitule = t.id)
922
            WHERE m.type = %s AND m.intitule = %s',
923
            'complex',
924
            $folderId
925
        );
926
        return [
927
            'levelPwComplexity' => $data['value'],
928
            'startPathLevel' => $data['nlevel'],
929
            'importPF' => false
930
        ];
931
    }
932
    return [
933
        'levelPwComplexity' => 50,
934
        'startPathLevel' => 0,
935
        'importPF' => false
936
    ];
937
}
938
939
spl_autoload_register(function ($class) {
940
    $prefix = 'League\\Csv\\';
941
    $base_dir = __DIR__.'/src/';
942
    $len = strlen($prefix);
943
    if (strncmp($prefix, $class, $len) !== 0) {
944
        // no, move to the next registered autoloader
945
        return;
946
    }
947
    $relative_class = substr($class, $len);
948
    $file = $base_dir.str_replace('\\', '/', $relative_class).'.php';
949
    if (file_exists($file)) {
950
        require $file;
951
    }
952
});
953
954
/**
955
 * Used to format the string ready for insertion in to the database.
956
 *
957
 * @param string $str             String to clean
958
 * @param string $crLFReplacement Replacement
959
 *
960
 * @return string
961
 */
962
function sanitiseString($str, $crLFReplacement)
963
{
964
    $str = preg_replace('#[\r\n]#', $crLFReplacement, (string) $str);
965
    $str = str_replace('\\', '&#92;', $str);
966
    $str = str_replace('"', '&quot;', $str);
967
    if (!empty($str)) {
968
        addslashes($str);
969
    }
970
971
    return $str;
972
}
973
974
/**
975
 * Clean array values.
976
 *
977
 * @param string $value String to clean
978
 *
979
 * @return string
980
 */
981
function cleanOutput(&$value)
982
{
983
    return htmlspecialchars_decode($value);
984
}
985