Passed
Push — master ( 5a3ed5...a919c1 )
by Nils
06:37 queued 14s
created

nameFromEmail()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Teampass - a collaborative passwords manager.
7
 * ---
8
 * This file is part of the TeamPass project.
9
 * 
10
 * TeamPass is free software: you can redistribute it and/or modify it
11
 * under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, version 3 of the License.
13
 * 
14
 * TeamPass is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU General Public License for more details.
18
 * 
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 * 
22
 * Certain components of this file may be under different licenses. For
23
 * details, see the `licenses` directory or individual file headers.
24
 * ---
25
 * @file      users.queries.php
26
 * @author    Nils Laumaillé ([email protected])
27
 * @copyright 2009-2025 Teampass.net
28
 * @license   GPL-3.0
29
 * @see       https://www.teampass.net
30
 */
31
32
use LdapRecord\Connection;
33
use TeampassClasses\NestedTree\NestedTree;
34
use TeampassClasses\SessionManager\SessionManager;
35
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
36
use TeampassClasses\Language\Language;
37
use TeampassClasses\PerformChecks\PerformChecks;
38
use TeampassClasses\ConfigManager\ConfigManager;
39
use TeampassClasses\PasswordManager\PasswordManager;
40
use TeampassClasses\EmailService\EmailService;
41
use TeampassClasses\EmailService\EmailSettings;
42
use TeampassClasses\OAuth2Controller\OAuth2Controller;
43
44
// Load functions
45
require_once 'main.functions.php';
46
47
// init
48
loadClasses('DB');
49
$session = SessionManager::getSession();
50
$request = SymfonyRequest::createFromGlobals();
51
$lang = new Language($session->get('user-language') ?? 'english');
52
53
// Load config
54
$configManager = new ConfigManager();
55
$SETTINGS = $configManager->getAllSettings();
56
57
// Do checks
58
$checkUserAccess = new PerformChecks(
59
    dataSanitizer(
60
        [
61
            'type' => htmlspecialchars($request->request->get('type', ''), ENT_QUOTES, 'UTF-8'),
62
        ],
63
        [
64
            'type' => 'trim|escape',
65
        ],
66
    ),
67
    [
68
        'user_id' => returnIfSet($session->get('user-id'), null),
69
        'user_key' => returnIfSet($session->get('key'), null),
70
    ]
71
);
72
// Handle the case
73
echo $checkUserAccess->caseHandler();
74
if ($checkUserAccess->checkSession() === false || $checkUserAccess->userAccessPage('profile') === false) {
75
    // Not allowed page
76
    $session->set('system-error_code', ERR_NOT_ALLOWED);
77
    include $SETTINGS['cpassman_dir'] . '/error.php';
78
    exit;
79
}
80
81
// Define Timezone
82
date_default_timezone_set($SETTINGS['timezone'] ?? 'UTC');
83
84
// Set header properties
85
header('Content-type: text/html; charset=utf-8');
86
header('Cache-Control: no-cache, no-store, must-revalidate');
87
88
// --------------------------------- //
89
90
// Prepare post variables
91
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
92
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
93
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
94
$isprofileupdate = filter_input(INPUT_POST, 'isprofileupdate', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
95
$password_do_not_change = 'do_not_change';
96
97
98
//Load Tree
99
$tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
100
101
if (null !== $post_type) {
102
103
    // List of post types allowed to all users
104
    $all_users_can_access = [
105
        'get_generate_keys_progress',
106
        'user_profile_update',
107
        'save_user_change',
108
    ];
109
110
    // decrypt and retrieve data in JSON format
111
    $dataReceived = [];
112
    if (!empty($post_data)) {
113
        $dataReceived = prepareExchangedData(
114
            $post_data,
115
            'decode'
116
        );
117
    }
118
119
    // Non-manager user
120
    if ((int) $session->get('user-admin') !== 1 &&
121
        (int) $session->get('user-manager') !== 1 &&
122
        (int) $session->get('user-can_manage_all_users') !== 1) {
123
124
        // Administrative type requested -> deny
125
        if (!in_array($post_type, $all_users_can_access)) {
126
            echo prepareExchangedData(
127
                array(
128
                    'error' => true,
129
                    'message' => $lang->get('error_not_allowed_to'),
130
                ),
131
                'encode'
132
            );
133
            exit;
134
        } else if (isset($dataReceived['user_id'])) {
135
            // If user isn't manager, he can't change user_id
136
            $dataReceived['user_id'] = (int) $session->get('user-id');
137
        }
138
    }
139
140
    // For administrative types only, do additional check whether user is manager 
141
    // and $dataReceived['user_id'] is defined to ensure that this manager can
142
    // modify this user account.
143
    if (!in_array($post_type, $all_users_can_access) &&
144
        (int) $session->get('user-admin') !== 1 && !empty($dataReceived['user_id'])) {
145
146
        // Get info about user to modify
147
        $targetUserInfos = DB::queryFirstRow(
148
            'SELECT admin, gestionnaire, can_manage_all_users, isAdministratedByRole FROM ' . prefixTable('users') . '
149
            WHERE id = %i',
150
            (int) $dataReceived['user_id']
151
        );
152
153
        // User not exists
154
        if (DB::count() === 0) {
155
            echo prepareExchangedData(
156
                array(
157
                    'error' => true,
158
                    'message' => $lang->get('error_not_allowed_to'),
159
                ),
160
                'encode'
161
            );
162
            exit;
163
        }
164
165
        // Managers can't edit administrator or other manager
166
        if ((int) $targetUserInfos['admin'] === 1 ||
167
            (int) $targetUserInfos['can_manage_all_users'] === 1 ||
168
            (int) $targetUserInfos['gestionnaire'] === 1) {
169
170
                echo prepareExchangedData(
171
                    array(
172
                        'error' => true,
173
                        'message' => $lang->get('error_not_allowed_to'),
174
                    ),
175
                    'encode'
176
                );
177
                exit;
178
            }
179
180
        // Manager of basic/ro users in this role
181
        if ((int) $session->get('user-manager') === 1
182
            && !in_array($targetUserInfos['isAdministratedByRole'], $session->get('user-roles_array'))) {
183
184
            echo prepareExchangedData(
185
                array(
186
                    'error' => true,
187
                    'message' => $lang->get('error_not_allowed_to'),
188
                ),
189
                'encode'
190
            );
191
            exit;
192
        }
193
    }
194
195
    switch ($post_type) {
196
        /*
197
         * ADD NEW USER
198
         */
199
        case 'add_new_user':
200
            // Check KEY
201
            if ($post_key !== $session->get('key')) {
202
                echo prepareExchangedData(
203
                    array(
204
                        'error' => true,
205
                        'message' => $lang->get('key_is_not_correct'),
206
                    ),
207
                    'encode'
208
                );
209
                break;
210
            } elseif ($session->get('user-read_only') === 1) {
211
                echo prepareExchangedData(
212
                    array(
213
                        'error' => true,
214
                        'message' => $lang->get('error_not_allowed_to'),
215
                    ),
216
                    'encode'
217
                );
218
                break;
219
            }
220
221
            // Check if current user can add a new user
222
            if ((int) $session->get('user-admin') === 0 && (int) $session->get('user-can_manage_all_users') === 0 && (int) $session->get('user-manager') === 0) {
223
                echo prepareExchangedData(
224
                    array(
225
                        'error' => true,
226
                        'message' => $lang->get('error_not_allowed_to'),
227
                    ),
228
                    'encode'
229
                );
230
                break;
231
            }
232
233
            // Prepare variables
234
            $login = filter_var($dataReceived['login'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
235
            $email = filter_var($dataReceived['email'], FILTER_SANITIZE_EMAIL);
236
            $lastname = filter_var($dataReceived['lastname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
237
            $name = filter_var($dataReceived['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
238
            $is_admin = filter_var($dataReceived['admin'], FILTER_SANITIZE_NUMBER_INT);
239
            $is_manager = filter_var($dataReceived['manager'], FILTER_SANITIZE_NUMBER_INT);
240
            $is_hr = filter_var($dataReceived['hr'], FILTER_SANITIZE_NUMBER_INT);
241
            $is_read_only = filter_var($dataReceived['read_only'], FILTER_SANITIZE_NUMBER_INT) || 0;
242
            $has_personal_folder = filter_var($dataReceived['personal_folder'], FILTER_SANITIZE_NUMBER_INT);
243
            $new_folder_role_domain = filter_var($dataReceived['new_folder_role_domain'], FILTER_SANITIZE_NUMBER_INT);
244
            $domain = filter_var($dataReceived['domain'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
245
            $is_administrated_by = filter_var($dataReceived['isAdministratedByRole'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
246
            $groups = filter_var_array($dataReceived['groups'], FILTER_SANITIZE_NUMBER_INT);
247
            $allowed_flds = filter_var_array($dataReceived['allowed_flds'], FILTER_SANITIZE_NUMBER_INT);
248
            $forbidden_flds = filter_var_array($dataReceived['forbidden_flds'], FILTER_SANITIZE_NUMBER_INT);
249
            $post_root_level = filter_var($dataReceived['form-create-root-folder'], FILTER_SANITIZE_NUMBER_INT);
250
            $mfa_enabled = filter_var($dataReceived['mfa_enabled'], FILTER_SANITIZE_NUMBER_INT);
251
252
            // Only administrators can create managers or administrators accounts.
253
            if ((int) $session->get('user-admin') !== 1 
254
                && ((int) $is_admin === 1 || (int) $is_manager === 1 || (int) $is_hr === 1)) {
255
256
                echo prepareExchangedData(
257
                    array(
258
                        'error' => true,
259
                        'message' => $lang->get('error_not_allowed_to'),
260
                    ),
261
                    'encode'
262
                );
263
                break;
264
            }
265
266
            // Empty user
267
            if (empty($login) === true) {
268
                echo prepareExchangedData(
269
                    array(
270
                        'error' => true,
271
                        'message' => $lang->get('error_empty_data'),
272
                    ),
273
                    'encode'
274
                );
275
                break;
276
            }
277
            // Check if user already exists
278
            $data = DB::query(
279
                'SELECT id, fonction_id, groupes_interdits, groupes_visibles
280
                FROM ' . prefixTable('users') . '
281
                WHERE login = %s
282
                AND deleted_at IS NULL',
283
                $login
284
            );
285
286
            if (DB::count() === 0) {
287
                // Generate pwd
288
                $password = generateQuickPassword();
289
290
                // GEnerate new keys
291
                $userKeys = generateUserKeys($password);
292
293
                // load password library
294
                $passwordManager = new PasswordManager();
295
296
                // Prepare variables
297
                $hashedPassword = $passwordManager->hashPassword($password);
298
                if ($passwordManager->verifyPassword($hashedPassword, $password) === false) {
299
                    echo prepareExchangedData(
300
                        array(
301
                            'error' => true,
302
                            'message' => $lang->get('pw_hash_not_correct'),
303
                        ),
304
                        'encode'
305
                    );
306
                    break;
307
                }
308
309
                // Add user in DB
310
                DB::insert(
311
                    prefixTable('users'),
312
                    array(
313
                        'login' => $login,
314
                        'name' => $name,
315
                        'lastname' => $lastname,
316
                        'pw' => $hashedPassword,
317
                        'email' => $email,
318
                        'admin' => empty($is_admin) === true ? 0 : $is_admin,
319
                        'can_manage_all_users' => empty($is_hr) === true ? 0 : $is_hr,
320
                        'gestionnaire' => empty($is_manager) === true ? 0 : $is_manager,
321
                        'read_only' => empty($is_read_only) === true ? 0 : $is_read_only,
322
                        'personal_folder' => empty($has_personal_folder) === true ? 0 : $has_personal_folder,
323
                        'user_language' => $SETTINGS['default_language'],
324
                        'fonction_id' => is_null($groups) === true ? '' : implode(';', $groups),
325
                        'groupes_interdits' => is_null($forbidden_flds) === true ? '' : implode(';', $forbidden_flds),
326
                        'groupes_visibles' => is_null($allowed_flds) === true ? '' : implode(';', $allowed_flds),
327
                        'isAdministratedByRole' => $is_administrated_by,
328
                        'encrypted_psk' => '',
329
                        'last_pw_change' => time(),
330
                        'public_key' => $userKeys['public_key'],
331
                        'private_key' => $userKeys['private_key'],
332
                        'special' => 'auth-pwd-change',
333
                        'is_ready_for_usage' => 0,
334
                        'otp_provided' => 0,
335
                        'can_create_root_folder' => empty($post_root_level) === true ? 0 : $post_root_level,
336
                        'mfa_enabled' => empty($mfa_enabled) === true ? 0 : $mfa_enabled,
337
                        'created_at' => time(),
338
                    )
339
                );
340
                $new_user_id = DB::insertId();
341
                // Create personnal folder
342
                if ($has_personal_folder === 1) {
343
                    DB::insert(
344
                        prefixTable('nested_tree'),
345
                        array(
346
                            'parent_id' => '0',
347
                            'title' => $new_user_id,
348
                            'bloquer_creation' => '0',
349
                            'bloquer_modification' => '0',
350
                            'personal_folder' => '1',
351
                            'categories' => '',
352
                        )
353
                    );
354
                    $tree->rebuild();
355
                }
356
                // Create folder and role for domain
357
                if ($new_folder_role_domain === 1) {
358
                    // create folder
359
                    DB::insert(
360
                        prefixTable('nested_tree'),
361
                        array(
362
                            'parent_id' => 0,
363
                            'title' => $domain,
364
                            'personal_folder' => 0,
365
                            'renewal_period' => 0,
366
                            'bloquer_creation' => '0',
367
                            'bloquer_modification' => '0',
368
                        )
369
                    );
370
                    $new_folder_id = DB::insertId();
371
                    // Add complexity
372
                    DB::insert(
373
                        prefixTable('misc'),
374
                        array(
375
                            'type' => 'complex',
376
                            'intitule' => $new_folder_id,
377
                            'valeur' => 50,
378
                            'created_at' => time(),
379
                        )
380
                    );
381
                    // Create role
382
                    DB::insert(
383
                        prefixTable('roles_title'),
384
                        array(
385
                            'title' => $domain,
386
                        )
387
                    );
388
                    $new_role_id = DB::insertId();
389
                    // Associate new role to new folder
390
                    DB::insert(
391
                        prefixTable('roles_values'),
392
                        array(
393
                            'folder_id' => $new_folder_id,
394
                            'role_id' => $new_role_id,
395
                        )
396
                    );
397
                    // Add the new user to this role
398
                    DB::update(
399
                        prefixTable('users'),
400
                        array(
401
                            'fonction_id' => is_int($new_role_id),
402
                        ),
403
                        'id=%i',
404
                        $new_user_id
405
                    );
406
                    // rebuild tree
407
                    $tree->rebuild();
408
                }
409
410
                // Create the API key
411
                DB::insert(
412
                    prefixTable('api'),
413
                    array(
414
                        'type' => 'user',
415
                        'user_id' => $new_user_id,
416
                        'value' => encryptUserObjectKey(base64_encode(base64_encode(uniqidReal(39))), $userKeys['public_key']),
417
                        'timestamp' => time(),
418
                    )
419
                );
420
421
                // get links url
422
                if (empty($SETTINGS['email_server_url']) === true) {
423
                    $SETTINGS['email_server_url'] = $SETTINGS['cpassman_url'];
424
                }
425
426
                // Launch process for user keys creation
427
                // No OTP is provided here, no need.
428
                handleUserKeys(
429
                    (int) $new_user_id,
430
                    (string) $password,
431
                    (int) isset($SETTINGS['maximum_number_of_items_to_treat']) === true ? $SETTINGS['maximum_number_of_items_to_treat'] : NUMBER_ITEMS_IN_BATCH,
432
                    "",
433
                    true,
434
                    true,
435
                    true,
436
                    false,
437
                    (string) $lang->get('email_body_user_config_6'),
438
                );
439
440
                // update LOG
441
                logEvents(
442
                    $SETTINGS,
443
                    'user_mngt',
444
                    'at_user_added',
445
                    (string) $session->get('user-id'),
446
                    $session->get('user-login'),
447
                    (string) $new_user_id
448
                );
449
450
                echo prepareExchangedData(
451
                    array(
452
                        'error' => false,
453
                        'user_id' => $new_user_id,
454
                        'message' => '',
455
                    ),
456
                    'encode'
457
                );
458
            } else {
459
                echo prepareExchangedData(
460
                    array(
461
                        'error' => true,
462
                        'message' => $lang->get('error_user_exists'),
463
                    ),
464
                    'encode'
465
                );
466
            }
467
            break;
468
469
            /*
470
         * Delete the user
471
         */
472
        case 'delete_user':
473
            // Check KEY
474
            if ($post_key !== $session->get('key')) {
475
                echo prepareExchangedData(
476
                    array(
477
                        'error' => true,
478
                        'message' => $lang->get('key_is_not_correct'),
479
                    ),
480
                    'encode'
481
                );
482
                break;
483
            } elseif ($session->get('user-read_only') === 1) {
484
                echo prepareExchangedData(
485
                    array(
486
                        'error' => true,
487
                        'message' => $lang->get('error_not_allowed_to'),
488
                    ),
489
                    'encode'
490
                );
491
                break;
492
            }
493
494
            // Prepare variables
495
            $post_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
496
497
            // Get info about user to delete
498
            $data_user = DB::queryFirstRow(
499
                'SELECT login, admin, isAdministratedByRole FROM ' . prefixTable('users') . '
500
                WHERE id = %i',
501
                $post_id
502
            );
503
504
            // Is this user allowed to do this?
505
            if (
506
                (int) $session->get('user-admin') === 1
507
                || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
508
                || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
509
            ) {
510
                // delete user in database
511
                /*DB::delete(
512
                    prefixTable('users'),
513
                    'id = %i',
514
                    $post_id
515
                );*/
516
                DB::update(
517
                    prefixTable('users'),
518
                    array(
519
                        'login' => $data_user['login'].'_deleted_'.time(),
520
                        'deleted_at' => time(),
521
                    ),
522
                    'id = %i',
523
                    $post_id
524
                );
525
                // delete user api
526
                DB::delete(
527
                    prefixTable('api'),
528
                    'user_id = %i',
529
                    $post_id
530
                );
531
                // delete personal folder and subfolders
532
                $data = DB::queryFirstRow(
533
                    'SELECT id FROM ' . prefixTable('nested_tree') . '
534
                    WHERE title = %s AND personal_folder = %i',
535
                    $post_id,
536
                    '1'
537
                );
538
                // Get through each subfolder
539
                if (!empty($data['id'])) {
540
                    $folders = $tree->getDescendants($data['id'], true);
541
                    foreach ($folders as $folder) {
542
                        // delete folder
543
                        DB::delete(prefixTable('nested_tree'), 'id = %i AND personal_folder = %i', $folder->id, '1');
544
                        // delete items & logs
545
                        $items = DB::query(
546
                            'SELECT id FROM ' . prefixTable('items') . '
547
                            WHERE id_tree=%i AND perso = %i',
548
                            $folder->id,
549
                            '1'
550
                        );
551
                        foreach ($items as $item) {
552
                            // Delete item
553
                            DB::delete(prefixTable('items'), 'id = %i', $item['id']);
554
                            // log
555
                            DB::delete(prefixTable('log_items'), 'id_item = %i', $item['id']);
556
                        }
557
                    }
558
                    // rebuild tree
559
                    $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
560
                    $tree->rebuild();
561
                }
562
563
                // Delete objects keys
564
                deleteUserObjetsKeys((int) $post_id, $SETTINGS);
565
566
567
                // Delete any process related to user
568
                $processes = DB::query(
569
                    'SELECT increment_id
570
                    FROM ' . prefixTable('background_tasks') . '
571
                    WHERE JSON_EXTRACT(arguments, "$.new_user_id") = %i',
572
                    $post_id
573
                );
574
                $process_id = -1;
575
                foreach ($processes as $process) {
576
                    // Delete task
577
                    DB::delete(
578
                        prefixTable('background_subtasks'),
579
                        'task_id = %i',
580
                        $process['increment_id']
581
                    );
582
                    $process_id = $process['increment_id'];
583
                }
584
                // Delete main process
585
                if ($process_id > -1) {
586
                    DB::delete(
587
                        prefixTable('background_tasks'),
588
                        'increment_id = %i',
589
                        $process_id
590
                    );
591
                }
592
                
593
                // update LOG
594
                logEvents($SETTINGS, 'user_mngt', 'at_user_deleted', (string) $session->get('user-id'), $session->get('user-login'), $post_id);
595
596
                //Send back
597
                echo prepareExchangedData(
598
                    array(
599
                        'error' => false,
600
                        'message' => '',
601
                    ),
602
                    'encode'
603
                );
604
            } else {
605
                //Send back
606
                echo prepareExchangedData(
607
                    array(
608
                        'error' => false,
609
                        'message' => $lang->get('error_not_allowed_to'),
610
                    ),
611
                    'encode'
612
                );
613
            }
614
            break;
615
616
        /*
617
         * Check the domain
618
         */
619
        case 'check_domain':
620
            $return = array();
621
            // Check if folder exists
622
            $data = DB::query(
623
                'SELECT * FROM ' . prefixTable('nested_tree') . '
624
                WHERE title = %s AND parent_id = %i',
625
                filter_input(INPUT_POST, 'domain', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
626
                '0'
627
            );
628
            $counter = DB::count();
629
            if ($counter != 0) {
630
                $return['folder'] = 'exists';
631
            } else {
632
                $return['folder'] = 'not_exists';
633
            }
634
            // Check if role exists
635
            $data = DB::query(
636
                'SELECT * FROM ' . prefixTable('roles_title') . '
637
                WHERE title = %s',
638
                filter_input(INPUT_POST, 'domain', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
639
            );
640
            $counter = DB::count();
641
            if ($counter != 0) {
642
                $return['role'] = 'exists';
643
            } else {
644
                $return['role'] = 'not_exists';
645
            }
646
647
            echo json_encode($return);
648
            break;
649
650
        /*
651
         * delete the timestamp value for specified user => disconnect
652
         */
653
        case 'disconnect_user':
654
            // Check KEY
655
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS) !== filter_var($session->get('key'), FILTER_SANITIZE_FULL_SPECIAL_CHARS)) {
656
                echo '[ { "error" : "key_not_conform" } ]';
657
                break;
658
            }
659
660
            $post_user_id = filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT);
661
662
            // Get info about user to delete
663
            $data_user = DB::queryFirstRow(
664
                'SELECT admin, isAdministratedByRole, gestionnaire
665
                FROM ' . prefixTable('users') . '
666
                WHERE id = %i',
667
                $post_user_id
668
            );
669
670
            // Is this user allowed to do this?
671
            if (
672
                (int) $session->get('user-admin') === 1
673
                || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
674
                || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
675
            ) {
676
                // Do
677
                DB::update(
678
                    prefixTable('users'),
679
                    array(
680
                        'timestamp' => '',
681
                        'key_tempo' => '',
682
                        'session_end' => '',
683
                    ),
684
                    'id = %i',
685
                    $post_user_id
686
                );
687
            }
688
            break;
689
690
        /*
691
         * Get user info
692
         */
693
        case 'get_user_info':
694
            // Check KEY
695
            if ($post_key !== $session->get('key')) {
696
                echo prepareExchangedData(
697
                    array(
698
                        'error' => true,
699
                        'message' => $lang->get('key_is_not_correct'),
700
                    ),
701
                    'encode'
702
                );
703
                break;
704
            } elseif ($session->get('user-read_only') === 1) {
705
                echo prepareExchangedData(
706
                    array(
707
                        'error' => true,
708
                        'message' => $lang->get('error_not_allowed_to'),
709
                    ),
710
                    'encode'
711
                );
712
                break;
713
            }
714
            
715
            // Prepare variables
716
            $post_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
717
718
            // Get info about user
719
            $rowUser = DB::queryFirstRow(
720
                'SELECT *
721
                FROM ' . prefixTable('users') . '
722
                WHERE id = %i',
723
                $post_id
724
            );
725
726
            // Is this user allowed to do this?
727
            if (
728
                (int) $session->get('user-admin') === 1
729
                || (in_array($rowUser['isAdministratedByRole'], $session->get('user-roles_array')) === true)
730
                || ((int) $session->get('user-can_manage_all_users') === 1 && $rowUser['admin'] !== '1')
731
            ) {
732
                $arrData = array();
733
                $arrFunction = array();
734
                $arrMngBy = array();
735
                $arrFldForbidden = array();
736
                $arrFldAllowed = array();
737
738
                //Build tree
739
                $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
740
741
                // get FUNCTIONS
742
                $functionsList = array();
743
                $selected = '';
744
                $users_functions = array_filter(array_unique(explode(';', empty($rowUser['fonction_id'].';'.$rowUser['roles_from_ad_groups']) === true ? '' : $rowUser['fonction_id'].';'.$rowUser['roles_from_ad_groups'])));
745
746
                $rows = DB::query('SELECT id,title,creator_id FROM ' . prefixTable('roles_title'));
747
                foreach ($rows as $record) {
748
                    if (
749
                        (int) $session->get('user-admin') === 1
750
                        || (((int) $session->get('user-manager') === 1 || (int) $session->get('user-can_manage_all_users') === 1))
751
                    ) {
752
                        if (in_array($record['id'], $users_functions)) {
753
                            $selected = 'selected';
754
755
                            array_push(
756
                                $arrFunction,
757
                                array(
758
                                    'title' => $record['title'],
759
                                    'id' => $record['id'],
760
                                )
761
                            );
762
                        } else {
763
                            $selected = '';
764
                        }
765
766
                        array_push(
767
                            $functionsList,
768
                            array(
769
                                'title' => $record['title'],
770
                                'id' => $record['id'],
771
                                'selected' => $selected,
772
                            )
773
                        );
774
                    }
775
                }
776
777
                // get MANAGEDBY
778
                $rolesList = array();
779
                $managedBy = array();
780
                $selected = '';
781
                $rows = DB::query('SELECT id,title FROM ' . prefixTable('roles_title') . ' ORDER BY title ASC');
782
                foreach ($rows as $reccord) {
783
                    $rolesList[$reccord['id']] = array('id' => $reccord['id'], 'title' => $reccord['title']);
784
                }
785
786
                array_push(
787
                    $managedBy,
788
                    array(
789
                        'title' => $lang->get('administrators_only'),
790
                        'id' => 0,
791
                    )
792
                );
793
                foreach ($rolesList as $fonction) {
794
                    if ($session->get('user-admin') === 1 || in_array($fonction['id'], $session->get('user-roles_array'))) {
795
                        if ($rowUser['isAdministratedByRole'] == $fonction['id']) {
796
                            $selected = 'selected';
797
798
                            array_push(
799
                                $arrMngBy,
800
                                array(
801
                                    'title' => $fonction['title'],
802
                                    'id' => $fonction['id'],
803
                                )
804
                            );
805
                        } else {
806
                            $selected = '';
807
                        }
808
809
                        array_push(
810
                            $managedBy,
811
                            array(
812
                                'title' => $lang->get('managers_of') . ' ' . $fonction['title'],
813
                                'id' => $fonction['id'],
814
                                'selected' => $selected,
815
                            )
816
                        );
817
                    }
818
                }
819
820
                if (count($arrMngBy) === 0) {
821
                    array_push(
822
                        $arrMngBy,
823
                        array(
824
                            'title' => $lang->get('administrators_only'),
825
                            'id' => '0',
826
                        )
827
                    );
828
                }
829
830
                // get FOLDERS FORBIDDEN
831
                $forbiddenFolders = array();
832
                $userForbidFolders = explode(';', is_null($rowUser['groupes_interdits']) === true ? '' : $rowUser['groupes_interdits']);
833
                $tree_desc = $tree->getDescendants();
834
                foreach ($tree_desc as $t) {
835
                    if (in_array($t->id, $session->get('user-accessible_folders')) && in_array($t->id, $session->get('user-personal_visible_folders')) === false) {
836
                        $selected = '';
837
                        if (in_array($t->id, $userForbidFolders)) {
838
                            $selected = 'selected';
839
840
                            array_push(
841
                                $arrFldForbidden,
842
                                array(
843
                                    'title' => htmlspecialchars($t->title, ENT_COMPAT, 'UTF-8'),
844
                                    'id' => $t->id,
845
                                )
846
                            );
847
                        }
848
                        array_push(
849
                            $forbiddenFolders,
850
                            array(
851
                                'id' => $t->id,
852
                                'selected' => $selected,
853
                                'title' => @htmlspecialchars($t->title, ENT_COMPAT, 'UTF-8'),
854
                            )
855
                        );
856
                    }
857
                }
858
859
                // get FOLDERS ALLOWED
860
                $allowedFolders = array();
861
                $userAllowFolders = explode(';', $rowUser['groupes_visibles']);
862
                $tree_desc = $tree->getDescendants();
863
                foreach ($tree_desc as $t) {
864
                    if (
865
                        in_array($t->id, $session->get('user-accessible_folders')) === true
866
                        && in_array($t->id, $session->get('user-personal_visible_folders')) === false
867
                    ) {
868
                        $selected = '';
869
                        if (in_array($t->id, $userAllowFolders)) {
870
                            $selected = 'selected';
871
872
                            array_push(
873
                                $arrFldAllowed,
874
                                array(
875
                                    'title' => htmlspecialchars($t->title, ENT_COMPAT, 'UTF-8'),
876
                                    'id' => $t->id,
877
                                )
878
                            );
879
                        }
880
881
                        array_push(
882
                            $allowedFolders,
883
                            array(
884
                                'id' => $t->id,
885
                                'selected' => $selected,
886
                                'title' => @htmlspecialchars($t->title, ENT_COMPAT, 'UTF-8'),
887
                            )
888
                        );
889
                    }
890
                }
891
892
                // get USER STATUS
893
                if ($rowUser['disabled'] == 1) {
894
                    $arrData['info'] = $lang->get('user_info_locked') . '<br><input type="checkbox" value="unlock" name="1" class="chk">&nbsp;<label for="1">' . $lang->get('user_info_unlock_question') . '</label><br><input type="checkbox"  value="delete" id="account_delete" class="chk mr-2" name="2" onclick="confirmDeletion()">label for="2">' . $lang->get('user_info_delete_question') . '</label>';
895
                } else {
896
                    $arrData['info'] = $lang->get('user_info_active') . '<br><input type="checkbox" value="lock" class="chk">&nbsp;' . $lang->get('user_info_lock_question');
897
                }
898
899
                $arrData['error'] = false;
900
                $arrData['login'] = $rowUser['login'];
901
                $arrData['name'] = empty($rowUser['name']) === false && $rowUser['name'] !== NULL ? $rowUser['name'] : '';
902
                $arrData['lastname'] = empty($rowUser['lastname']) === false && $rowUser['lastname'] !== NULL ? $rowUser['lastname'] : '';
903
                $arrData['email'] = $rowUser['email'];
904
                $arrData['function'] = $functionsList;
905
                $arrData['managedby'] = $managedBy;
906
                $arrData['foldersForbid'] = $forbiddenFolders;
907
                $arrData['foldersAllow'] = $allowedFolders;
908
                $arrData['share_function'] = $arrFunction;
909
                $arrData['share_managedby'] = $arrMngBy;
910
                $arrData['share_forbidden'] = $arrFldForbidden;
911
                $arrData['share_allowed'] = $arrFldAllowed;
912
                $arrData['disabled'] = (int) $rowUser['disabled'];
913
                $arrData['gestionnaire'] = (int) $rowUser['gestionnaire'];
914
                $arrData['read_only'] = (int) $rowUser['read_only'];
915
                $arrData['can_create_root_folder'] = (int) $rowUser['can_create_root_folder'];
916
                $arrData['personal_folder'] = (int) $rowUser['personal_folder'];
917
                $arrData['can_manage_all_users'] = (int) $rowUser['can_manage_all_users'];
918
                $arrData['admin'] = (int) $rowUser['admin'];
919
                $arrData['password'] = $password_do_not_change;
920
                $arrData['mfa_enabled'] = (int) $rowUser['mfa_enabled'];
921
922
                echo prepareExchangedData(
923
                    $arrData,
924
                    'encode'
925
                );
926
            } else {
927
                echo prepareExchangedData(
928
                    array(
929
                        'error' => true,
930
                        'message' => $lang->get('error_not_allowed_to'),
931
                    ),
932
                    'encode'
933
                );
934
            }
935
936
            break;
937
938
        /*
939
         * EDIT user
940
         */
941
        case 'store_user_changes':
942
            // Check KEY
943
            if ($post_key !== $session->get('key')) {
944
                echo prepareExchangedData(
945
                    array(
946
                        'error' => true,
947
                        'message' => $lang->get('key_is_not_correct'),
948
                    ),
949
                    'encode'
950
                );
951
                break;
952
            } elseif ($session->get('user-read_only') === 1) {
953
                echo prepareExchangedData(
954
                    array(
955
                        'error' => true,
956
                        'message' => $lang->get('error_not_allowed_to'),
957
                    ),
958
                    'encode'
959
                );
960
                break;
961
            }
962
963
            // Prepare variables
964
            $post_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
965
            $post_login = filter_var($dataReceived['login'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
966
            $post_email = filter_var($dataReceived['email'], FILTER_SANITIZE_EMAIL);
967
            $post_lastname = filter_var($dataReceived['lastname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
968
            $post_name = filter_var($dataReceived['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
969
            $post_is_admin = filter_var($dataReceived['admin'], FILTER_SANITIZE_NUMBER_INT);
970
            $post_is_manager = filter_var($dataReceived['manager'], FILTER_SANITIZE_NUMBER_INT);
971
            $post_is_hr = filter_var($dataReceived['hr'], FILTER_SANITIZE_NUMBER_INT);
972
            $post_is_read_only = filter_var($dataReceived['read_only'], FILTER_SANITIZE_NUMBER_INT);
973
            $post_has_personal_folder = filter_var($dataReceived['personal_folder'], FILTER_SANITIZE_NUMBER_INT);
974
            $post_is_administrated_by = filter_var($dataReceived['isAdministratedByRole'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
975
            $post_groups = filter_var_array($dataReceived['groups'], FILTER_SANITIZE_NUMBER_INT);
976
            $post_allowed_flds = filter_var_array($dataReceived['allowed_flds'], FILTER_SANITIZE_NUMBER_INT);
977
            $post_forbidden_flds = filter_var_array($dataReceived['forbidden_flds'], FILTER_SANITIZE_NUMBER_INT);
978
            $post_root_level = filter_var($dataReceived['form-create-root-folder'], FILTER_SANITIZE_NUMBER_INT);
979
            $post_mfa_enabled = filter_var($dataReceived['mfa_enabled'], FILTER_SANITIZE_NUMBER_INT);
980
981
            // Get info about user to modify
982
            $data_user = DB::queryFirstRow(
983
                'SELECT admin, gestionnaire, can_manage_all_users, isAdministratedByRole FROM ' . prefixTable('users') . '
984
                WHERE id = %i',
985
                $post_id
986
            );
987
988
            // If user removes administrator role on administrator user
989
            // then ensure that it exists still one administrator
990
            if ((int) $data_user['admin'] === 1 && (int) $post_is_admin !== 1) {
991
                // count number of admins
992
                $users = DB::query(
993
                    'SELECT id
994
                    FROM ' . prefixTable('users') . '
995
                    WHERE admin = 1 AND email != "" AND pw != "" AND id != %i',
996
                    $post_id
997
                );
998
                if (DB::count() === 0) {
999
                    echo prepareExchangedData(
1000
                        array(
1001
                            'error' => true,
1002
                            'message' => $lang->get('at_least_one_administrator_is_requested'),
1003
                        ),
1004
                        'encode'
1005
                    );
1006
                    break;
1007
                }
1008
            }
1009
            
1010
            // Init post variables
1011
            $post_action_to_perform = filter_var(htmlspecialchars_decode($dataReceived['action_on_user']), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
1012
            $action_to_perform_after = '';
1013
            
1014
            // Exclude roles from AD - PR #3635
1015
            $adRoles = DB::query(
1016
                'SELECT roles_from_ad_groups
1017
                FROM ' . prefixTable('users') . '
1018
                WHERE id = %i',
1019
                $post_id
1020
            )[0]['roles_from_ad_groups'];
1021
            $fonctions = [];
1022
            if (!is_null($post_groups) && !empty($adRoles)) {
1023
                foreach ($post_groups as $post_group) {
1024
                    if (!in_array($post_group, explode(';', $adRoles))) {
1025
                        $fonctions[] = $post_group;
1026
                    }
1027
                }
1028
            }
1029
            $post_groups = empty($fonctions) === true ? $post_groups : $fonctions;
1030
1031
            // Build array of update
1032
            $changeArray = array(
1033
                'login' => $post_login,
1034
                'name' => $post_name,
1035
                'lastname' => $post_lastname,
1036
                'email' => $post_email,
1037
                'admin' => empty($post_is_admin) === true ? 0 : $post_is_admin,
1038
                'can_manage_all_users' => empty($post_is_hr) === true ? 0 : $post_is_hr,
1039
                'gestionnaire' => empty($post_is_manager) === true ? 0 : $post_is_manager,
1040
                'read_only' => empty($post_is_read_only) === true ? 0 : $post_is_read_only,
1041
                'personal_folder' => empty($post_has_personal_folder) === true ? 0 : $post_has_personal_folder,
1042
                'user_language' => $SETTINGS['default_language'],
1043
                'fonction_id' => is_null($post_groups) === true ? '' : implode(';', array_unique($post_groups)),
1044
                'groupes_interdits' => is_null($post_forbidden_flds) === true ? '' : implode(';', array_unique($post_forbidden_flds)),
1045
                'groupes_visibles' => is_null($post_allowed_flds) === true ? '' : implode(';', array_unique($post_allowed_flds)),
1046
                'isAdministratedByRole' => $post_is_administrated_by,
1047
                'can_create_root_folder' => empty($post_root_level) === true ? 0 : $post_root_level,
1048
                'mfa_enabled' => empty($post_mfa_enabled) === true ? 0 : $post_mfa_enabled,
1049
            );
1050
1051
            // Manage user password change
1052
            // This can occur only if user changes his own password
1053
            // In other case, next condition must be wrong
1054
            if (
1055
                isset($post_password) === true
1056
                && $post_password !== $password_do_not_change
1057
                && $post_id === $session->get('user-id')
1058
            ) {
1059
                // load password library
1060
                $passwordManager = new PasswordManager();
1061
1062
                $changeArray['pw'] = $passwordManager->hashPassword($post_password);
1063
                $changeArray['key_tempo'] = '';
1064
1065
                // We need to adapt the private key with new password
1066
                $session->set('user-private_key', encryptPrivateKey($post_password, $session->get('user-private_key')));
1067
1068
                // TODO
1069
            }
1070
1071
            // Empty user
1072
            if (empty($post_login) === true) {
1073
                echo prepareExchangedData(
1074
                    array(
1075
                        'error' => true,
1076
                        'message' => $lang->get('error_empty_data'),
1077
                    ),
1078
                    'encode'
1079
                );
1080
                break;
1081
            }
1082
1083
            // User has email?
1084
            if (empty($post_email) === true) {
1085
                echo prepareExchangedData(
1086
                    array(
1087
                        'error' => true,
1088
                        'message' => $lang->get('error_no_email'),
1089
                    ),
1090
                    'encode'
1091
                );
1092
                break;
1093
            }
1094
1095
            // Is this user allowed to do this?
1096
            if (
1097
                // Administrator user
1098
                (int) $session->get('user-admin') === 1
1099
                // Manager of basic/ro users in this role but don't allow promote user to admin or managers roles
1100
                || ((int) $session->get('user-manager') === 1
1101
                    && in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array'))
1102
                    && (int) $post_is_admin !== 1 && (int) $data_user['admin'] !== 1
1103
                    && (int) $post_is_hr !== 1 && (int) $data_user['can_manage_all_users'] !== 1
1104
                    && (int) $post_is_manager !== 1 && (int) $data_user['gestionnaire'] !== 1)
1105
                // Manager of all basic/ro users but don't allow promote user to admin or managers roles
1106
                || ((int) $session->get('user-can_manage_all_users') === 1
1107
                    && (int) $post_is_admin !== 1 && (int) $data_user['admin'] !== 1
1108
                    && (int) $post_is_hr !== 1 && (int) $data_user['can_manage_all_users'] !== 1
1109
                    && (int) $post_is_manager !== 1 && (int) $data_user['gestionnaire'] !== 1)
1110
            ) {
1111
                // delete account
1112
                // delete user in database
1113
                if ($post_action_to_perform === 'delete') {
1114
                    DB::delete(
1115
                        prefixTable('users'),
1116
                        'id = %i',
1117
                        $post_id
1118
                    );
1119
                    // delete personal folder and subfolders
1120
                    $data = DB::queryFirstRow(
1121
                        'SELECT id FROM ' . prefixTable('nested_tree') . '
1122
                        WHERE title = %s AND personal_folder = %i',
1123
                        $post_id,
1124
                        '1'
1125
                    );
1126
                    // Get through each subfolder
1127
                    if (!empty($data['id'])) {
1128
                        $folders = $tree->getDescendants($data['id'], true);
1129
                        foreach ($folders as $folder) {
1130
                            // delete folder
1131
                            DB::delete(prefixTable('nested_tree'), 'id = %i AND personal_folder = %i', $folder->id, '1');
1132
                            // delete items & logs
1133
                            $items = DB::query(
1134
                                'SELECT id FROM ' . prefixTable('items') . '
1135
                                WHERE id_tree=%i AND perso = %i',
1136
                                $folder->id,
1137
                                '1'
1138
                            );
1139
                            foreach ($items as $item) {
1140
                                // Delete item
1141
                                DB::delete(prefixTable('items'), 'id = %i', $item['id']);
1142
                                // log
1143
                                DB::delete(prefixTable('log_items'), 'id_item = %i', $item['id']);
1144
                            }
1145
                        }
1146
                        // rebuild tree
1147
                        $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
1148
                        $tree->rebuild();
1149
                    }
1150
                    // update LOG
1151
                    logEvents($SETTINGS, 'user_mngt', 'at_user_deleted', (string) $session->get('user-id'), $session->get('user-login'), $post_id);
1152
                } else {
1153
                    // Get old data about user
1154
                    $oldData = DB::queryFirstRow(
1155
                        'SELECT * FROM ' . prefixTable('users') . '
1156
                        WHERE id = %i',
1157
                        $post_id
1158
                    );
1159
1160
                    // update SESSION
1161
                    if ($session->get('user-id') === $post_id) {
1162
                        $session->set('user-lastname', $post_lastname);
1163
                        $session->set('user-name', $post_name);
1164
                        $session->set('user-email', $post_email);
1165
                    }
1166
1167
                    // Has the groups changed? If yes then ask for a keys regeneration
1168
                    $arrOldData = array_filter(explode(';', $oldData['fonction_id']));
1169
                    $post_groups = is_null($post_groups) === true ? array() : array_filter($post_groups);
1170
1171
                    if ($arrOldData != $post_groups && (int) $oldData['admin'] !== 1) {
1172
                        $action_to_perform_after = 'encrypt_keys';
1173
                    }
1174
1175
                    // update user
1176
                    DB::update(
1177
                        prefixTable('users'),
1178
                        $changeArray,
1179
                        'id = %i',
1180
                        $post_id
1181
                    );
1182
1183
                    // CLear cache tree for this user to force tree
1184
                    DB::delete(
1185
                        prefixTable('cache_tree'),
1186
                        'user_id = %i',
1187
                        $post_id
1188
                    );
1189
1190
                    // update LOG
1191
                    if ($oldData['email'] !== $post_email) {
1192
                        logEvents($SETTINGS, 'user_mngt', 'at_user_email_changed:' . $oldData['email'], (string) $session->get('user-id'), $session->get('user-login'), $post_id);
1193
                    }
1194
                }
1195
                echo prepareExchangedData(
1196
                    array(
1197
                        'error' => false,
1198
                        'message' => '',
1199
                        'post_action' => $action_to_perform_after,
1200
                    ),
1201
                    'encode'
1202
                );
1203
            } else {
1204
                echo prepareExchangedData(
1205
                    array(
1206
                        'error' => true,
1207
                        'message' => $lang->get('error_not_allowed_to'),
1208
                    ),
1209
                    'encode'
1210
                );
1211
            }
1212
            break;
1213
1214
        /*
1215
         * IS LOGIN AVAILABLE?
1216
         */
1217
        case 'is_login_available':
1218
            // Check KEY
1219
            if ($post_key !== $session->get('key')) {
1220
                echo prepareExchangedData(
1221
                    array(
1222
                        'error' => true,
1223
                        'message' => $lang->get('key_is_not_correct'),
1224
                    ),
1225
                    'encode'
1226
                );
1227
                break;
1228
            } elseif ($session->get('user-read_only') === 1) {
1229
                echo prepareExchangedData(
1230
                    array(
1231
                        'error' => true,
1232
                        'message' => $lang->get('error_not_allowed_to'),
1233
                    ),
1234
                    'encode'
1235
                );
1236
                break;
1237
            }
1238
1239
            DB::queryFirstRow(
1240
                'SELECT * FROM ' . prefixTable('users') . '
1241
                WHERE login = %s
1242
                AND deleted_at IS NULL',
1243
                filter_input(INPUT_POST, 'login', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
1244
            );
1245
1246
            echo prepareExchangedData(
1247
                array(
1248
                    'error' => false,
1249
                    'login_exists' => DB::count(),
1250
                ),
1251
                'encode'
1252
            );
1253
1254
            break;
1255
1256
        /*
1257
         * GET USER FOLDER RIGHT
1258
         */
1259
        case 'user_folders_rights':
1260
            // Check KEY
1261
            if ($post_key !== $session->get('key')) {
1262
                echo prepareExchangedData(
1263
                    array(
1264
                        'error' => true,
1265
                        'message' => $lang->get('key_is_not_correct'),
1266
                    ),
1267
                    'encode'
1268
                );
1269
                break;
1270
            } elseif ($session->get('user-read_only') === 1) {
1271
                echo prepareExchangedData(
1272
                    array(
1273
                        'error' => true,
1274
                        'message' => $lang->get('error_not_allowed_to'),
1275
                    ),
1276
                    'encode'
1277
                );
1278
                break;
1279
            }
1280
1281
            // Prepare variables
1282
            $post_id = filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT);
1283
1284
            $arrData = array();
1285
1286
            //Build tree
1287
            $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
1288
1289
            // get User info
1290
            $rowUser = DB::queryFirstRow(
1291
                'SELECT login, name, lastname, email, disabled, fonction_id, groupes_interdits, groupes_visibles, isAdministratedByRole, avatar_thumb, roles_from_ad_groups
1292
                FROM ' . prefixTable('users') . '
1293
                WHERE id = %i',
1294
                $post_id
1295
            );
1296
1297
            // get rights
1298
            $arrFolders = [];
1299
            $html = '';
1300
1301
            if (isset($SETTINGS['ldap_mode']) === true && (int) $SETTINGS['ldap_mode'] === 1 && isset($SETTINGS['enable_ad_users_with_ad_groups']) === true && (int) $SETTINGS['enable_ad_users_with_ad_groups'] === 1) {
1302
                $rowUser['fonction_id'] = empty($rowUser['fonction_id'])  === true ? $rowUser['roles_from_ad_groups'] : $rowUser['fonction_id']. ';' . $rowUser['roles_from_ad_groups'];
1303
            }
1304
            $arrData['functions'] = array_filter(explode(';', $rowUser['fonction_id']));
1305
            $arrData['allowed_folders'] = array_filter(explode(';', $rowUser['groupes_visibles']));
1306
            $arrData['denied_folders'] = array_filter(explode(';', $rowUser['groupes_interdits']));
1307
1308
            // Exit if no roles
1309
            if (count($arrData['functions']) > 0) {
1310
                // refine folders based upon roles
1311
                $rows = DB::query(
1312
                    'SELECT folder_id, type
1313
                    FROM ' . prefixTable('roles_values') . '
1314
                    WHERE role_id IN %ls
1315
                    ORDER BY folder_id ASC',
1316
                    $arrData['functions']
1317
                );
1318
                foreach ($rows as $record) {
1319
                    $bFound = false;
1320
                    $x = 0;
1321
                    foreach ($arrFolders as $fld) {
1322
                        if ($fld['id'] === $record['folder_id']) {
1323
                            // get the level of access on the folder
1324
                            $arrFolders[$x]['type'] = evaluateFolderAccesLevel($record['type'], $arrFolders[$x]['type']);
1325
                            $bFound = true;
1326
                            break;
1327
                        }
1328
                        ++$x;
1329
                    }
1330
                    if ($bFound === false && in_array($record['folder_id'], $arrData['denied_folders']) === false) {
1331
                        array_push($arrFolders, array('id' => $record['folder_id'], 'type' => $record['type'], 'special' => false));
1332
                    }
1333
                }
1334
1335
                // add allowed folders
1336
                foreach($arrData['allowed_folders'] as $Fld) {
1337
                    array_push($arrFolders, array('id' => $Fld, 'type' => 'W', 'special' => true));
1338
                }
1339
                
1340
                $tree_desc = $tree->getDescendants();
1341
                foreach ($tree_desc as $t) {
1342
                    foreach ($arrFolders as $fld) {
1343
                        if ($fld['id'] === $t->id) {
1344
                            // get folder name
1345
                            $row = DB::queryFirstRow(
1346
                                'SELECT title, nlevel, id
1347
                                FROM ' . prefixTable('nested_tree') . '
1348
                                WHERE id = %i',
1349
                                $fld['id']
1350
                            );
1351
1352
                            // manage indentation
1353
                            $ident = '';
1354
                            for ($y = 1; $y < $row['nlevel']; ++$y) {
1355
                                $ident .= '<i class="fas fa-long-arrow-alt-right mr-2"></i>';
1356
                            }
1357
1358
                            // manage right icon
1359
                            if ($fld['type'] == 'W') {
1360
                                $label = '<i class="fas fa-indent infotip text-success mr-2" title="' . $lang->get('write') . '"></i>' .
1361
                                    '<i class="fas fa-edit infotip text-success mr-2" title="' . $lang->get('edit') . '"></i>' .
1362
                                    '<i class="fas fa-eraser infotip text-success" title="' . $lang->get('delete') . '"></i>';
1363
                            } elseif ($fld['type'] == 'ND') {
1364
                                $label = '<i class="fas fa-indent infotip text-warning mr-2" title="' . $lang->get('write') . '"></i>' .
1365
                                    '<i class="fas fa-edit infotip text-success mr-2" title="' . $lang->get('edit') . '"></i>' .
1366
                                    '<i class="fas fa-eraser infotip text-danger" title="' . $lang->get('no_delete') . '"></i>';
1367
                            } elseif ($fld['type'] == 'NE') {
1368
                                $label = '<i class="fas fa-indent infotip text-warning mr-2" title="' . $lang->get('write') . '"></i>' .
1369
                                    '<i class="fas fa-edit infotip text-danger mr-2" title="' . $lang->get('no_edit') . '"></i>' .
1370
                                    '<i class="fas fa-eraser infotip text-success" title="' . $lang->get('delete') . '"></i>';
1371
                            } elseif ($fld['type'] == 'NDNE') {
1372
                                $label = '<i class="fas fa-indent infotip text-warning mr-2" title="' . $lang->get('write') . '"></i>' .
1373
                                    '<i class="fas fa-edit infotip text-danger mr-2" title="' . $lang->get('no_edit') . '"></i>' .
1374
                                    '<i class="fas fa-eraser infotip text-danger" title="' . $lang->get('no_delete') . '"></i>';
1375
                            } elseif ($fld['type'] == '') {
1376
                                $label = '<i class="fas fa-eye-slash infotip text-danger mr-2" title="' . $lang->get('no_access') . '"></i>';
1377
                            } else {
1378
                                $label = '<i class="fas fa-eye infotip text-info mr-2" title="' . $lang->get('read') . '"></i>';
1379
                            }
1380
1381
                            $html .= '<tr><td>' . $ident . $row['title'] .
1382
                                ' <small class="text-info">[' . $row['id'] . ']</small>'.
1383
                                ($fld['special'] === true ? '<i class="fas fa-user-tag infotip text-primary ml-5" title="' . $lang->get('user_specific_right') . '"></i>' : '').
1384
                                '</td><td>' . $label . '</td></tr>';
1385
                            break;
1386
                        }
1387
                    }
1388
                }
1389
1390
                $html_full = '<table id="table-folders" class="table table-bordered table-striped dt-responsive nowrap" style="width:100%"><tbody>' .
1391
                    $html . '</tbody></table>';
1392
            } else {
1393
                $html_full = '';
1394
            }
1395
1396
            echo prepareExchangedData(
1397
                array(
1398
                    'html' => $html_full,
1399
                    'error' => false,
1400
                    'login' => $rowUser['login'],
1401
                    'message' => '',
1402
                ),
1403
                'encode'
1404
            );
1405
            break;
1406
1407
        /*
1408
         * GET LIST OF USERS
1409
         */
1410
        case 'get_list_of_users_for_sharing':
1411
            // Check KEY
1412
            if ($post_key !== $session->get('key')) {
1413
                echo prepareExchangedData(
1414
                    array(
1415
                        'error' => true,
1416
                        'message' => $lang->get('key_is_not_correct'),
1417
                    ),
1418
                    'encode'
1419
                );
1420
                break;
1421
            } elseif ($session->get('user-read_only') === 1) {
1422
                echo prepareExchangedData(
1423
                    array(
1424
                        'error' => true,
1425
                        'message' => $lang->get('error_not_allowed_to'),
1426
                    ),
1427
                    'encode'
1428
                );
1429
                break;
1430
            }
1431
1432
            $arrUsers = [];
1433
1434
            if ((int) $session->get('user-admin') === 0 && (int) $session->get('user-can_manage_all_users') === 0) {
1435
                $rows = DB::query(
1436
                    'SELECT *
1437
                    FROM ' . prefixTable('users') . '
1438
                    WHERE admin = %i AND isAdministratedByRole IN %ls',
1439
                    '0',
1440
                    array_filter($session->get('user-roles_array'))
1441
                );
1442
            } else {
1443
                $rows = DB::query(
1444
                    'SELECT *
1445
                    FROM ' . prefixTable('users') . '
1446
                    WHERE admin = %i',
1447
                    '0'
1448
                );
1449
            }
1450
1451
            foreach ($rows as $record) {
1452
                // Get roles
1453
                $groups = [];
1454
                $groupIds = [];
1455
                foreach (explode(';', $record['fonction_id']) as $group) {
1456
                    $tmp = DB::queryFirstRow(
1457
                        'SELECT id, title FROM ' . prefixTable('roles_title') . '
1458
                        WHERE id = %i',
1459
                        $group
1460
                    );
1461
                    if ($tmp !== null) {
1462
                        array_push($groups, $tmp['title']);
1463
                        array_push($groupIds, $tmp['id']);
1464
                    }
1465
                }
1466
1467
                // Get managed_by
1468
                $managedBy = DB::queryFirstRow(
1469
                    'SELECT id, title FROM ' . prefixTable('roles_title') . '
1470
                    WHERE id = %i',
1471
                    $record['isAdministratedByRole']
1472
                );
1473
1474
                // Get Allowed folders
1475
                $foldersAllowed = [];
1476
                $foldersAllowedIds = [];
1477
                foreach (explode(';', $record['groupes_visibles']) as $role) {
1478
                    $tmp = DB::queryFirstRow(
1479
                        'SELECT id, title FROM ' . prefixTable('nested_tree') . '
1480
                        WHERE id = %i',
1481
                        $role
1482
                    );
1483
                    array_push($foldersAllowed, $tmp !== null ? $tmp['title'] : $lang->get('none'));
1484
                    array_push($foldersAllowedIds, $tmp !== null ? $tmp['id'] : -1);
1485
                }
1486
1487
                // Get denied folders
1488
                $foldersForbidden = [];
1489
                $foldersForbiddenIds = [];
1490
                foreach (explode(';', $record['groupes_interdits']) as $role) {
1491
                    $tmp = DB::queryFirstRow(
1492
                        'SELECT id, title FROM ' . prefixTable('nested_tree') . '
1493
                        WHERE id = %i',
1494
                        $role
1495
                    );
1496
                    array_push($foldersForbidden, $tmp !== null ? $tmp['title'] : $lang->get('none'));
1497
                    array_push($foldersForbiddenIds, $tmp !== null ? $tmp['id'] : -1);
1498
                }
1499
1500
                // Store
1501
                array_push(
1502
                    $arrUsers,
1503
                    array(
1504
                        'id' => $record['id'],
1505
                        'name' => $record['name'],
1506
                        'lastname' => $record['lastname'],
1507
                        'login' => $record['login'],
1508
                        'groups' => implode(', ', $groups),
1509
                        'groupIds' => $groupIds,
1510
                        'managedBy' => $managedBy=== null ? $lang->get('administrator') : $managedBy['title'],
1511
                        'managedById' => $managedBy === null ? 0 : $managedBy['id'],
1512
                        'foldersAllowed' => implode(', ', $foldersAllowed),
1513
                        'foldersAllowedIds' => $foldersAllowedIds,
1514
                        'foldersForbidden' => implode(', ', $foldersForbidden),
1515
                        'foldersForbiddenIds' => $foldersForbiddenIds,
1516
                        'admin' => $record['admin'],
1517
                        'manager' => $record['gestionnaire'],
1518
                        'hr' => $record['can_manage_all_users'],
1519
                        'readOnly' => $record['read_only'],
1520
                        'personalFolder' => $record['personal_folder'],
1521
                        'rootFolder' => $record['can_create_root_folder'],
1522
                    )
1523
                );
1524
            }
1525
1526
            echo prepareExchangedData(
1527
                array(
1528
                    'error' => false,
1529
                    'values' => $arrUsers,
1530
                ),
1531
                'encode'
1532
            );
1533
1534
            break;
1535
1536
            /*
1537
         * UPDATE USERS RIGHTS BY SHARING
1538
         */
1539
        case 'update_users_rights_sharing':
1540
            // Check KEY
1541
            if ($post_key !== $session->get('key')) {
1542
                echo prepareExchangedData(
1543
                    array(
1544
                        'error' => true,
1545
                        'message' => $lang->get('key_is_not_correct'),
1546
                    ),
1547
                    'encode'
1548
                );
1549
                break;
1550
            } elseif ($session->get('user-read_only') === 1) {
1551
                echo prepareExchangedData(
1552
                    array(
1553
                        'error' => true,
1554
                        'message' => $lang->get('error_not_allowed_to'),
1555
                    ),
1556
                    'encode'
1557
                );
1558
                break;
1559
            }
1560
1561
            // Prepare variables
1562
            $data = [
1563
                'source_id' => isset($dataReceived['source_id']) === true ? $dataReceived['source_id'] : 0,
1564
                'destination_ids' => isset($dataReceived['destination_ids']) === true ? $dataReceived['destination_ids'] : 0,
1565
                'user_functions' => isset($dataReceived['user_functions']) === true ? $dataReceived['user_functions'] : '',
1566
                'user_managedby' => isset($dataReceived['user_managedby']) === true ? $dataReceived['user_managedby'] : '',
1567
                'user_fldallowed' => isset($dataReceived['user_fldallowed']) === true ? $dataReceived['user_fldallowed'] : '',
1568
                'user_fldforbid' => isset($dataReceived['user_fldforbid']) === true ? $dataReceived['user_fldforbid'] : '',
1569
                'user_admin' => isset($dataReceived['user_admin']) === true ? $dataReceived['user_admin'] : 0,
1570
                'user_manager' => isset($dataReceived['user_manager']) === true ? $dataReceived['user_manager'] : 0,
1571
                'user_hr' => isset($dataReceived['user_hr']) === true ? $dataReceived['user_hr'] : 0,
1572
                'user_readonly' => isset($dataReceived['user_readonly']) === true ? $dataReceived['user_readonly'] : 1,
1573
                'user_personalfolder' => isset($dataReceived['user_personalfolder']) === true ? $dataReceived['user_personalfolder'] : 0,
1574
                'user_rootfolder' => isset($dataReceived['user_rootfolder']) === true ? $dataReceived['user_rootfolder'] : 0,
1575
            ];
1576
            
1577
            $filters = [
1578
                'source_id' => 'cast:integer',
1579
                'destination_ids' => 'trim|escape',
1580
                'user_functions' => 'trim|escape',
1581
                'user_managedby' => 'trim|escape',
1582
                'user_fldallowed' => 'trim|escape',
1583
                'user_fldforbid' => 'trim|escape',
1584
                'user_admin' => 'cast:integer',
1585
                'user_manager' => 'cast:integer',
1586
                'user_hr' => 'cast:integer',
1587
                'user_readonly' => 'cast:integer',
1588
                'user_personalfolder' => 'cast:integer',
1589
                'user_rootfolder' => 'cast:integer',
1590
            ];
1591
            
1592
            $inputData = dataSanitizer(
1593
                $data,
1594
                $filters
1595
            );
1596
1597
            // Check send values
1598
            if ($inputData['source_id'] === 0 || $inputData['destination_ids'] === 0) {
1599
                // error
1600
                echo prepareExchangedData(
1601
                    array(
1602
                        'error' => true,
1603
                        'message' => $lang->get('error_not_allowed_to'),
1604
                    ),
1605
                    'encode'
1606
                );
1607
            }
1608
1609
            // Get info about user
1610
            $data_user = DB::queryFirstRow(
1611
                'SELECT admin, isAdministratedByRole FROM ' . prefixTable('users') . '
1612
                WHERE id = %i',
1613
                $inputData['source_id']
1614
            );
1615
1616
            // Is this user allowed to do this?
1617
            if (
1618
                (int) $session->get('user-admin') === 1
1619
                || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
1620
                || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
1621
            ) {
1622
                foreach ($inputData['destination_ids'] as $dest_user_id) {
1623
                    // Is this user allowed to do this?
1624
                    if (
1625
                        (int) $session->get('user-admin') === 1
1626
                        || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
1627
                        || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
1628
                    ) {
1629
                        // update user
1630
                        DB::update(
1631
                            prefixTable('users'),
1632
                            array(
1633
                                'fonction_id' => str_replace(",", ";", (string) $inputData['user_functions']),
1634
                                'isAdministratedByRole' => $inputData['user_managedby'],
1635
                                'groupes_visibles' => $inputData['user_fldallowed'],
1636
                                'groupes_interdits' => $inputData['user_fldforbid'],
1637
                                'gestionnaire' => $inputData['user_manager'],
1638
                                'read_only' => $inputData['user_readonly'],
1639
                                'can_create_root_folder' => $inputData['user_rootfolder'],
1640
                                'personal_folder' => $inputData['user_personalfolder'],
1641
                                'can_manage_all_users' => $inputData['user_hr'],
1642
                                'admin' => $inputData['user_admin'],
1643
                            ),
1644
                            'id = %i',
1645
                            $dest_user_id
1646
                        );
1647
                    }
1648
                }
1649
            }
1650
1651
            echo prepareExchangedData(
1652
                array(
1653
                    'error' => false,
1654
                ),
1655
                'encode'
1656
            );
1657
1658
            break;
1659
1660
            /*
1661
         * UPDATE USER PROFILE
1662
         */
1663
        case 'user_profile_update':
1664
            // Check KEY
1665
            if ($post_key !== $session->get('key')) {
1666
                echo prepareExchangedData(
1667
                    array(
1668
                        'error' => true,
1669
                        'message' => $lang->get('key_is_not_correct'),
1670
                    ),
1671
                    'encode'
1672
                );
1673
                break;
1674
            }
1675
1676
            // Check user
1677
            if (
1678
                null === $session->get('user-id')
1679
                || empty($session->get('user-id')) === true
1680
            ) {
1681
                echo prepareExchangedData(
1682
                    array(
1683
                        'error' => true,
1684
                        'message' => $lang->get('no_user'),
1685
                    ),
1686
                    'encode'
1687
                );
1688
                break;
1689
            }
1690
1691
            if (empty($dataReceived) === false) {
1692
                // Sanitize
1693
                $data = [
1694
                    'email' => isset($dataReceived['email']) === true ? $dataReceived['email'] : '',
1695
                    'timezone' => isset($dataReceived['timezone']) === true ? $dataReceived['timezone'] : '',
1696
                    'language' => isset($dataReceived['language']) === true ? $dataReceived['language'] : '',
1697
                    'treeloadstrategy' => isset($dataReceived['treeloadstrategy']) === true ? $dataReceived['treeloadstrategy'] : '',
1698
                    'agsescardid' => isset($dataReceived['agsescardid']) === true ? $dataReceived['agsescardid'] : '',
1699
                    'name' => isset($dataReceived['name']) === true ? $dataReceived['name'] : '',
1700
                    'lastname' => isset($dataReceived['lastname']) === true ? $dataReceived['lastname'] : '',
1701
                    'split_view_mode' => isset($dataReceived['split_view_mode']) === true ? $dataReceived['split_view_mode'] : '',
1702
                ];
1703
                
1704
                $filters = [
1705
                    'email' => 'trim|escape',
1706
                    'timezone' => 'trim|escape',
1707
                    'language' => 'trim|escape',
1708
                    'treeloadstrategy' => 'trim|escape',
1709
                    'agsescardid' => 'trim|escape',
1710
                    'name' => 'trim|escape',
1711
                    'lastname' => 'trim|escape',
1712
                    'split_view_mode' => 'cast:integer',
1713
                ];
1714
                
1715
                $inputData = dataSanitizer(
1716
                    $data,
1717
                    (array) $filters
1718
                );
1719
1720
                // Prevent LFI.
1721
                $inputData['language'] = preg_replace('/[^a-z_]/', "", $inputData['language']);
1722
1723
                // Force english if non-existent language.
1724
                if (!file_exists(__DIR__."/../includes/language/".$inputData['language'].".php")) {
1725
                    $inputData['language'] = 'english';
1726
                }
1727
1728
                // Data to update
1729
                $update_fields = [
1730
                    'split_view_mode' => $inputData['split_view_mode'],
1731
                ];
1732
1733
                // Update SETTINGS
1734
                $session->set('user-split_view_mode', (int) $inputData['split_view_mode']);
1735
1736
                // User profile edit enabled
1737
                if (($SETTINGS['disable_user_edit_profile'] ?? '0') === '0') {
1738
                    // Update database
1739
                    $update_fields['email']    = $inputData['email'];
1740
                    $update_fields['name']     = $inputData['name'];
1741
                    $update_fields['lastname'] = $inputData['lastname'];
1742
                    // Update session
1743
                    $session->set('user-email', $inputData['email']);
1744
                    $session->set('user-name', $inputData['name']);
1745
                    $session->set('user-lastname', $inputData['lastname']);    
1746
                }
1747
1748
                // User language edit enabled
1749
                if (($SETTINGS['disable_user_edit_language'] ?? '0') === '0') {
1750
                    // Update database
1751
                    $update_fields['user_language'] = $inputData['language'];
1752
                    // Update session
1753
                    $session->set('user-language', $inputData['language']);
1754
                }
1755
1756
                // User timezone edit enabled
1757
                if (($SETTINGS['disable_user_edit_timezone'] ?? '0') === '0') {
1758
                    // Update database
1759
                    $update_fields['usertimezone'] = $inputData['timezone'];
1760
                    // Update session
1761
                    $session->set('user-timezone', $inputData['timezone']);
1762
                }
1763
1764
                // User can edit tree load strategy
1765
                if (($SETTINGS['disable_user_edit_tree_load_strategy'] ?? '0') === '0') {
1766
                    // Update database
1767
                    $update_fields['treeloadstrategy'] = $inputData['treeloadstrategy'];
1768
                    // Update session
1769
                    $session->set('user-tree_load_strategy', $inputData['treeloadstrategy']);
1770
                }
1771
1772
                // update user
1773
                DB::update(
1774
                    prefixTable('users'),
1775
                    $update_fields,
1776
                    'id = %i',
1777
                    $session->get('user-id')
1778
                );
1779
1780
            } else {
1781
                // An error appears on JSON format
1782
                echo prepareExchangedData(
1783
                    array(
1784
                        'error' => true,
1785
                        'message' => $lang->get('json_error_format'),
1786
                    ),
1787
                    'encode'
1788
                );
1789
            }
1790
1791
            // Encrypt data to return
1792
            echo prepareExchangedData(
1793
                array(
1794
                    'error' => false,
1795
                    'message' => '',
1796
                    'name' => $session->get('user-name'),
1797
                    'lastname' => $session->get('user-lastname'),
1798
                    'email' => $session->get('user-email'),
1799
                    'split_view_mode' => $session->get('user-split_view_mode'),
1800
                ),
1801
                'encode'
1802
            );
1803
            break;
1804
1805
            //CASE where refreshing table
1806
        case 'save_user_change':
1807
            // Check KEY
1808
            if ($post_key !== $session->get('key')) {
1809
                echo prepareExchangedData(
1810
                    array(
1811
                        'error' => true,
1812
                        'message' => $lang->get('key_is_not_correct'),
1813
                    ),
1814
                    'encode'
1815
                );
1816
                break;
1817
            } elseif ($session->get('user-read_only') === 1) {
1818
                echo prepareExchangedData(
1819
                    array(
1820
                        'error' => true,
1821
                        'message' => $lang->get('error_not_allowed_to'),
1822
                    ),
1823
                    'encode'
1824
                );
1825
                break;
1826
            }
1827
1828
            // prepare variables
1829
            $post_user_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
1830
            $post_field = filter_var($dataReceived['field'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
1831
            $post_new_value = filter_var($dataReceived['value'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
1832
            $post_context = filter_var($dataReceived['context'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
1833
1834
            // If
1835
            if (empty($post_context) === false && $post_context === 'add_one_role_to_user') {
1836
                $data_user = DB::queryFirstRow(
1837
                    'SELECT fonction_id, public_key
1838
                    FROM ' . prefixTable('users') . '
1839
                    WHERE id = %i',
1840
                    $post_user_id
1841
                );
1842
1843
                if ($data_user) {
1844
                    // Ensure array is unique
1845
                    $post_new_value = str_replace(',', ';', $data_user['fonction_id']) . ';' . $post_new_value;
1846
                    $post_new_value = implode(';', array_unique(explode(';', $post_new_value)));
1847
                } else {
1848
                    // User not found
1849
                    echo prepareExchangedData(
1850
                        array(
1851
                            'error' => true,
1852
                            'message' => $lang->get('user_not_exists'),
1853
                        ),
1854
                        'encode'
1855
                    );
1856
                    break;
1857
                }
1858
            }
1859
1860
            // Manage specific case of api key
1861
            if($post_field === 'user_api_key') {
1862
                $encrypted_key = encryptUserObjectKey(base64_encode($post_new_value), $session->get('user-public_key'));
1863
                $session->set('user-api_key', $post_new_value);
1864
1865
                // test if user has an api key
1866
                $data_user = DB::queryFirstRow(
1867
                    'SELECT value
1868
                    FROM ' . prefixTable('api') . '
1869
                    WHERE user_id = %i',
1870
                    $post_user_id
1871
                );
1872
                if ($data_user) {
1873
                    // update
1874
                    DB::update(
1875
                        prefixTable('api'),
1876
                        array(
1877
                            'value' => $encrypted_key,
1878
                            'timestamp' => time()
1879
                        ),
1880
                        'user_id = %i',
1881
                        $post_user_id
1882
                    );
1883
                } else {
1884
                    // insert
1885
                    DB::insert(
1886
                        prefixTable('api'),
1887
                        array(
1888
                            'type' => 'user',
1889
                            'user_id' => $post_user_id,
1890
                            'value' => $encrypted_key,
1891
                            'timestamp' => time()
1892
                        )
1893
                    );
1894
                }
1895
1896
                // send data
1897
                echo prepareExchangedData(
1898
                    array(
1899
                        'error' => false,
1900
                        'message' => ''
1901
                    ),
1902
                    'encode'
1903
                );
1904
1905
                break;
1906
            }
1907
1908
            DB::update(
1909
                prefixTable('users'),
1910
                array(
1911
                    $post_field => $post_new_value,
1912
                ),
1913
                'id = %i',
1914
                $post_user_id
1915
            );
1916
1917
            // special case
1918
            if ($post_field === 'auth_type' && $post_new_value === 'ldap') {
1919
                /*DB::update(
1920
                    prefixTable('users'),
1921
                    array(
1922
                        'special' => 'recrypt-private-key',
1923
                    ),
1924
                    'id = %i',
1925
                    $post_user_id
1926
                );*/
1927
            }
1928
1929
            // send data
1930
            echo prepareExchangedData(
1931
                array(
1932
                    'error' => false,
1933
                    'message' => ''
1934
                ),
1935
                'encode'
1936
            );
1937
1938
            break;
1939
1940
        /*
1941
        * GET LDAP LIST OF USERS
1942
        */
1943
        case 'get_list_of_users_in_ldap':
1944
            // Check KEY
1945
            if ($post_key !== $session->get('key')) {
1946
                echo prepareExchangedData(
1947
                    array(
1948
                        'error' => true,
1949
                        'message' => $lang->get('key_is_not_correct'),
1950
                    ),
1951
                    'encode'
1952
                );
1953
                break;
1954
            }
1955
            
1956
            // Build ldap configuration array
1957
            $config = [
1958
                // Mandatory Configuration Options
1959
                'hosts'            => explode(',', (string) $SETTINGS['ldap_hosts']),
1960
                'base_dn'          => $SETTINGS['ldap_bdn'],
1961
                'username'         => $SETTINGS['ldap_username'],
1962
                'password'         => $SETTINGS['ldap_password'],
1963
            
1964
                // Optional Configuration Options
1965
                'port'             => $SETTINGS['ldap_port'],
1966
                'use_ssl'          => (int) $SETTINGS['ldap_ssl'] === 1 ? true : false,
1967
                'use_tls'          => (int) $SETTINGS['ldap_tls'] === 1 ? true : false,
1968
                'version'          => 3,
1969
                'timeout'          => 5,
1970
                'follow_referrals' => false,
1971
            
1972
                // Custom LDAP Options
1973
                'options' => [
1974
                    // See: http://php.net/ldap_set_option
1975
                    LDAP_OPT_X_TLS_REQUIRE_CERT => isset($SETTINGS['ldap_tls_certifacte_check']) === false ? 'LDAP_OPT_X_TLS_NEVER' : $SETTINGS['ldap_tls_certifacte_check'],
1976
                ]
1977
            ];
1978
            //prepare connection
1979
            $connection = new Connection($config);
1980
1981
            // Connect to LDAP
1982
            try {
1983
                $connection->connect();
1984
            
1985
            } catch (\LdapRecord\Auth\BindException $e) {
1986
                $error = $e->getDetailedError();
1987
                if ($error && defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) {
1988
                    error_log('TEAMPASS Error - LDAP - '.$error->getErrorCode()." - ".$error->getErrorMessage(). " - ".$error->getDiagnosticMessage());
1989
                }
1990
                // deepcode ignore ServerLeak: No important data is sent and it is encrypted before sending
1991
                echo prepareExchangedData(
1992
                    array(
1993
                        'error' => true,
1994
                        'message' => "An error occurred.",
1995
                    ),
1996
                    'encode'
1997
                );
1998
                break;
1999
            }
2000
2001
            $adUsersToSync = array();
2002
            $adRoles = array();
2003
            $usersAlreadyInTeampass = array();
2004
            $adUsedAttributes = array(
2005
                'dn', 'mail', 'givenname', 'samaccountname', 'sn', $SETTINGS['ldap_user_attribute'],
2006
                'memberof', 'name', 'displayname', 'cn', 'shadowexpire', 'distinguishedname'
2007
            );
2008
2009
            try {
2010
                $results = $connection->query()
2011
                    ->rawfilter($SETTINGS['ldap_user_object_filter'])
2012
                    ->in((empty($SETTINGS['ldap_dn_additional_user_dn']) === false ? $SETTINGS['ldap_dn_additional_user_dn'].',' : '').$SETTINGS['ldap_bdn'])
2013
                    ->whereHas($SETTINGS['ldap_user_attribute'])
2014
                    ->paginate(100);
2015
            } catch (\LdapRecord\Auth\BindException $e) {
2016
                $error = $e->getDetailedError();
2017
                if ($error && defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) {
2018
                    error_log('TEAMPASS Error - LDAP - '.$error->getErrorCode()." - ".$error->getErrorMessage(). " - ".$error->getDiagnosticMessage());
2019
                }
2020
                // deepcode ignore ServerLeak: No important data is sent and it is encrypted before sending
2021
                echo prepareExchangedData(
2022
                    array(
2023
                        'error' => true,
2024
                        'message' => "An error occurred.",
2025
                    ),
2026
                    'encode'
2027
                );
2028
                break;
2029
            }
2030
            
2031
            foreach ($results as $adUser) {
2032
                if (isset($adUser[$SETTINGS['ldap_user_attribute']][0]) === false) continue;
2033
                // Build the list of all groups in AD
2034
                if (isset($adUser['memberof']) === true) {
2035
                    foreach($adUser['memberof'] as $j => $adUserGroup) {
2036
                        if (empty($adUserGroup) === false && $j !== "count") {
2037
                            $adGroup = substr($adUserGroup, 3, strpos($adUserGroup, ',') - 3);
2038
                            if (in_array($adGroup, $adRoles) === false && empty($adGroup) === false) {
2039
                                array_push($adRoles, $adGroup);
2040
                            }
2041
                        }
2042
                    }
2043
                }
2044
2045
                // Is user in Teampass ?
2046
                $userLogin = $adUser[$SETTINGS['ldap_user_attribute']][0];
2047
                if (null !== $userLogin) {
2048
                    // Get his ID
2049
                    $userInfo = DB::queryFirstRow(
2050
                        'SELECT id, login, fonction_id, auth_type
2051
                        FROM ' . prefixTable('users') . '
2052
                        WHERE login = %s',
2053
                        $userLogin
2054
                    );
2055
                    // Loop on all user attributes
2056
                    $tmp = [
2057
                        'userInTeampass' => DB::count() > 0 ? (int) $userInfo['id'] : DB::count(),
2058
                        'userAuthType' => isset($userInfo['auth_type']) === true ? $userInfo['auth_type'] : 0,                        
2059
                    ];
2060
                    foreach ($adUsedAttributes as $userAttribute) {
2061
                        if (isset($adUser[$userAttribute]) === true) {
2062
                            if (is_array($adUser[$userAttribute]) === true && array_key_first($adUser[$userAttribute]) !== 'count') {
2063
                                // Loop on all entries
2064
                                $tmpAttrValue = '';
2065
                                foreach ($adUser[$userAttribute] as $userAttributeEntry) {
2066
                                    if ($userAttribute === 'memberof') {
2067
                                        $userAttributeEntry = substr($userAttributeEntry, 3, strpos($userAttributeEntry, ',') - 3);
2068
                                    }
2069
                                    if (empty($tmpAttrValue) === true) {
2070
                                        $tmpAttrValue = $userAttributeEntry;
2071
                                    } else {
2072
                                        $tmpAttrValue .= ','.$userAttributeEntry;
2073
                                    }
2074
                                }
2075
                                $tmp[$userAttribute] = $tmpAttrValue;
2076
                            } else {
2077
                                $tmp[$userAttribute] = $adUser[$userAttribute];
2078
                            }
2079
                        }
2080
                    }
2081
                    array_push($adUsersToSync, $tmp);
2082
                }
2083
            }
2084
2085
            // Get all groups in Teampass
2086
            $teampassRoles = array();
2087
            $rows = DB::query('SELECT id,title FROM ' . prefixTable('roles_title'));
2088
            foreach ($rows as $record) {
2089
                array_push(
2090
                    $teampassRoles,
2091
                    array(
2092
                        'id' => $record['id'],
2093
                        'title' => $record['title']
2094
                    )
2095
                );
2096
            }
2097
2098
            echo (string) prepareExchangedData(
2099
                array(
2100
                    'error' => false,
2101
                    'entries' => $adUsersToSync,
2102
                    'ldap_groups' => $adRoles,
2103
                    'teampass_groups' => $teampassRoles,
2104
                    'usersAlreadyInTeampass' => $usersAlreadyInTeampass,
2105
                ), 
2106
                'encode'
2107
            );
2108
2109
            break;
2110
2111
        /*
2112
         * ADD USER FROM LDAP OR OAUTH2
2113
         */
2114
        case 'add_user_from_ad':
2115
            // Check KEY
2116
            if ($post_key !== $session->get('key')) {
2117
                echo prepareExchangedData(
2118
                    array(
2119
                        'error' => true,
2120
                        'message' => $lang->get('key_is_not_correct'),
2121
                    ),
2122
                    'encode'
2123
                );
2124
                break;
2125
            }
2126
2127
            // Prepare variables
2128
            $post_login = filter_var($dataReceived['login'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2129
            $post_name = filter_var($dataReceived['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2130
            $post_lastname = filter_var($dataReceived['lastname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2131
            $post_email = filter_var($dataReceived['email'], FILTER_SANITIZE_EMAIL);
2132
            $post_roles = filter_var_array(
2133
                $dataReceived['roles'],
2134
                FILTER_SANITIZE_NUMBER_INT
2135
            );
2136
            $post_authType = filter_var($dataReceived['authType'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2137
2138
            // Empty user
2139
            if (empty($post_login) === true || empty($post_email) === true) {
2140
                echo prepareExchangedData(
2141
                    array(
2142
                        'error' => true,
2143
                        'message' => $lang->get('user_must_have_login_and_email'),
2144
                    ),
2145
                    'encode'
2146
                );
2147
                break;
2148
            }
2149
            // Check if user already exists
2150
            $data = DB::query(
2151
                'SELECT id, fonction_id, groupes_interdits, groupes_visibles
2152
                FROM ' . prefixTable('users') . '
2153
                WHERE login = %s',
2154
                $post_login
2155
            );
2156
2157
            if (DB::count() === 0) {
2158
                // check if admin role is set. If yes then check if originator is allowed
2159
                if ((int) $session->get('user-admin') !== 1 && (int) $session->get('user-manager') !== 1) {
2160
                    echo prepareExchangedData(
2161
                        array(
2162
                            'error' => true,
2163
                            'message' => $lang->get('error_empty_data'),
2164
                        ),
2165
                        'encode'
2166
                    );
2167
                    break;
2168
                }
2169
2170
                // load password library
2171
                $passwordManager = new PasswordManager();
2172
2173
                // Prepare variables
2174
                $password = generateQuickPassword(12, true);
2175
                $hashedPassword = $passwordManager->hashPassword($password);
2176
                if ($passwordManager->verifyPassword($hashedPassword, $password) === false) {
2177
                    echo prepareExchangedData(
2178
                        array(
2179
                            'error' => true,
2180
                            'message' => $lang->get('error_not_allowed_to'),
2181
                        ),
2182
                        'encode'
2183
                    );
2184
                    break;
2185
                }
2186
            } else {
2187
                echo prepareExchangedData(
2188
                    array(
2189
                        'error' => true,
2190
                        'message' => $lang->get('error_user_exists'),
2191
                    ),
2192
                    'encode'
2193
                );
2194
                break;
2195
            }
2196
2197
            
2198
            // We need to create his keys
2199
            $userKeys = generateUserKeys($password);
2200
2201
            // Insert user in DB
2202
            DB::insert(
2203
                prefixTable('users'),
2204
                array(
2205
                    'login' => $post_login,
2206
                    'pw' => $hashedPassword,
2207
                    'email' => $post_email,
2208
                    'name' => $post_name,
2209
                    'lastname' => $post_lastname,
2210
                    'admin' => '0',
2211
                    'gestionnaire' => '0',
2212
                    'can_manage_all_users' => '0',
2213
                    'personal_folder' => (int) $SETTINGS['enable_pf_feature'] === 1 ? 1 : 0,
2214
                    'fonction_id' => implode(';', $post_roles),
2215
                    'groupes_interdits' => '',
2216
                    'groupes_visibles' => '',
2217
                    'last_pw_change' => time(),
2218
                    'user_language' => $SETTINGS['default_language'],
2219
                    'encrypted_psk' => '',
2220
                    'isAdministratedByRole' => (isset($SETTINGS['oauth_new_user_is_administrated_by']) === true && empty($SETTINGS['oauth_new_user_is_administrated_by']) === false) ? $SETTINGS['oauth_new_user_is_administrated_by'] : 0,
2221
                    'public_key' => $userKeys['public_key'],
2222
                    'private_key' => $userKeys['private_key'],
2223
                    'special' => 'user_added_from_ad',
2224
                    'auth_type' => $post_authType,
2225
                    'is_ready_for_usage' => isset($SETTINGS['enable_tasks_manager']) === true && (int) $SETTINGS['enable_tasks_manager'] === 1 ? 0 : 1,
2226
                    'created_at' => time(),
2227
                )
2228
            );
2229
            $newUserId = DB::insertId();
2230
2231
            // Create the API key
2232
            DB::insert(
2233
                prefixTable('api'),
2234
                array(
2235
                    'type' => 'user',
2236
                    //'label' => $newUserId,
2237
                    'value' => encryptUserObjectKey(base64_encode(uniqidReal(39)), $userKeys['public_key']),
2238
                    'timestamp' => time(),
2239
                    'user_id' => $newUserId,
2240
                    'allowed_folders' => '',
2241
                )
2242
            );
2243
2244
            // Create personnal folder
2245
            if (isset($SETTINGS['enable_pf_feature']) === true && (int) $SETTINGS['enable_pf_feature'] === 1) {
2246
                DB::insert(
2247
                    prefixTable('nested_tree'),
2248
                    array(
2249
                        'parent_id' => '0',
2250
                        'title' => $newUserId,
2251
                        'bloquer_creation' => '0',
2252
                        'bloquer_modification' => '0',
2253
                        'personal_folder' => '1',
2254
                        'fa_icon' => 'fas fa-folder',
2255
                        'fa_icon_selected' => 'fas fa-folder-open',
2256
                        'categories' => '',
2257
                    )
2258
                );
2259
2260
                // Rebuild tree
2261
                $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
2262
                $tree->rebuild();
2263
            }
2264
2265
            // Send email to new user
2266
            if (isset($SETTINGS['enable_tasks_manager']) === false || (int) $SETTINGS['enable_tasks_manager'] === 0) {
2267
                $emailSettings = new EmailSettings($SETTINGS);
2268
                $emailService = new EmailService();
2269
                $emailService->sendMail(
2270
                    $lang->get('email_subject_new_user'),
2271
                    str_replace(
2272
                        array('#tp_login#', '#enc_code#', '#tp_link#'),
2273
                        array(addslashes($post_login), addslashes($password), $SETTINGS['email_server_url']),
2274
                        $lang->get('email_body_user_added_from_ldap_encryption_code')
2275
                    ),
2276
                    $post_email,
2277
                    $emailSettings
2278
                );
2279
            }
2280
2281
            echo prepareExchangedData(
2282
                array(
2283
                    'error' => false,
2284
                    'message' => '',
2285
                    'user_id' => $newUserId,
2286
                    'user_code' => $password,
2287
                    'visible_otp' => ADMIN_VISIBLE_OTP_ON_LDAP_IMPORT,
2288
                    'post_action' => isset($SETTINGS['enable_tasks_manager']) === true && (int) $SETTINGS['enable_tasks_manager'] === 1 ? 'prepare_tasks' : 'encrypt_keys',
2289
                ),
2290
                'encode'
2291
            );
2292
2293
            break;
2294
2295
        /*
2296
         * CHANGE USER AUTHENTICATION TYPE
2297
         */
2298
        case 'change_user_auth_type':
2299
            // Check KEY
2300
            if ($post_key !== $session->get('key')) {
2301
                echo prepareExchangedData(
2302
                    array(
2303
                        'error' => true,
2304
                        'message' => $lang->get('key_is_not_correct'),
2305
                    ),
2306
                    'encode'
2307
                );
2308
                break;
2309
            }
2310
2311
            // Prepare variables
2312
            $post_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
2313
            $post_auth = filter_var($dataReceived['auth_type'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2314
2315
            // Empty user
2316
            if (empty($post_id) === true) {
2317
                echo prepareExchangedData(
2318
                    array(
2319
                        'error' => true,
2320
                        'message' => $lang->get('user_not_exists'),
2321
                    ),
2322
                    'encode'
2323
                );
2324
                break;
2325
            }
2326
            // Check if user already exists
2327
            DB::query(
2328
                'SELECT id
2329
                FROM ' . prefixTable('users') . '
2330
                WHERE id = %i',
2331
                $post_id
2332
            );
2333
2334
            if (DB::count() > 0) {
2335
                // Change authentication type in DB
2336
                DB::update(
2337
                    prefixTable('users'),
2338
                    array(
2339
                        'auth_type' => $post_auth,
2340
                    ),
2341
                    'id = %i',
2342
                    $post_id
2343
                );
2344
            } else {
2345
                echo prepareExchangedData(
2346
                    array(
2347
                        'error' => true,
2348
                        'message' => $lang->get('user_not_exists'),
2349
                    ),
2350
                    'encode'
2351
                );
2352
                break;
2353
            }
2354
2355
            echo prepareExchangedData(
2356
                array(
2357
                    'message' => '',
2358
                    'error' => false,
2359
                ),
2360
                'encode'
2361
            );
2362
2363
            break;
2364
        
2365
2366
        /*
2367
        * GET OAUTH2 LIST OF USERS
2368
        */
2369
        case 'get_list_of_users_in_oauth2':
2370
            // Check KEY
2371
            if ($post_key !== $session->get('key')) {
2372
                echo prepareExchangedData(
2373
                    array(
2374
                        'error' => true,
2375
                        'message' => $lang->get('key_is_not_correct'),
2376
                    ),
2377
                    'encode'
2378
                );
2379
                break;
2380
            }
2381
2382
            // Création d'une instance du contrôleur
2383
            $OAuth2 = new OAuth2Controller($SETTINGS);
2384
2385
            // Traitement de la réponse de callback Azure
2386
            $usersList = $OAuth2->getAllUsers();            
2387
2388
            // Get all groups in Teampass
2389
            $teampassRoles = array();
2390
            $titleToIdMap = [];
2391
            $rows = DB::query('SELECT id,title FROM ' . prefixTable('roles_title'));
2392
            foreach ($rows as $record) {
2393
                array_push(
2394
                    $teampassRoles,
2395
                    array(
2396
                        'id' => $record['id'],
2397
                        'title' => $record['title']
2398
                    )
2399
                );
2400
                $titleToIdMap[$record['title']] = $record['id'];
2401
            }
2402
2403
            // Do init
2404
            $adUsersToSync = [];
2405
            $adRoles = [];
2406
            $usersAlreadyInTeampass = [];
2407
2408
            function nameFromEmail($email) {
2409
                // Utiliser une expression régulière pour extraire le texte avant le domaine
2410
                if (preg_match('/^(.+)@/', $email, $matches)) {
2411
                    return $matches[1];
2412
                } else {
2413
                    return false;
2414
                }
2415
            }
2416
            
2417
            foreach ($usersList as $oAuthUser) {
2418
                // Build the list of all groups in AD
2419
                if (isset($oAuthUser['groups']) === true) {
2420
                    foreach ($oAuthUser['groups'] as $group) {
2421
                        if (
2422
                            isset($group['displayName']) && !in_array($group['displayName'], $adRoles)
2423
                            && $SETTINGS['oauth_self_register_groups'] !== $group['displayName']
2424
                        ) {
2425
                            $adRoles[] = $group['displayName'];
2426
                        }
2427
                    }
2428
                }
2429
2430
                // Is user in Teampass ?
2431
                $userLogin = nameFromEmail($oAuthUser['userPrincipalName']);
2432
                if (null !== $userLogin) {
2433
                    //error_log(print_r($oAuthUser,true));
2434
                    // Get his ID
2435
                    $userInfo = DB::queryFirstRow(
2436
                        'SELECT id, login, fonction_id, auth_type
2437
                        FROM ' . prefixTable('users') . '
2438
                        WHERE login = %s',
2439
                        $userLogin
2440
                    );
2441
                    // Get array of groups
2442
                    $userGroupsInTeampass = explode(';', (string) is_null($userInfo) ? '' : $userInfo['fonction_id']);
2443
                    // Loop on all user attributes
2444
                    $userADInfos = [
2445
                        'userInTeampass' => isset($userInfo) ? (int) $userInfo['id'] : 0,
2446
                        'userAuthType' => isset($userInfo) ? $userInfo['auth_type'] : 0,     
2447
                        'login' => $userLogin,
2448
                        'mail' => '',
2449
                    ];
2450
                    foreach ($oAuthUser as $key => $value) {
2451
                        if ($key !== 'groups') {
2452
                            $userADInfos[$key] = $value;
2453
                        } else {
2454
                            $userADInfos[$key] = array_column($value, 'displayName');
2455
                        }
2456
                    }
2457
2458
                    // Mettre à jour $user['groups']
2459
                    $updatedGroups = array();
2460
                    foreach ($userADInfos['groups'] as $groupName) {
2461
                        if (isset($titleToIdMap[$groupName])) {
2462
                            $updatedGroups[] = array(
2463
                                'name' => $groupName,
2464
                                'id' => $titleToIdMap[$groupName],
2465
                                'insideGroupInTeampass' => in_array($titleToIdMap[$groupName], $userGroupsInTeampass) ? 1 : 0,
2466
                            );
2467
                        } else {
2468
                            $updatedGroups[] = array(
2469
                                'name' => $groupName,
2470
                                'id' => null,
2471
                                'insideGroupInTeampass' => 0,
2472
                            );
2473
                        }
2474
                    }
2475
2476
                    // Mettre à jour $user['groups'] avec les nouveaux groupes
2477
                    $userADInfos['groups'] = $updatedGroups;
2478
                    array_push($adUsersToSync, $userADInfos);
2479
                }
2480
            }
2481
2482
            echo (string) prepareExchangedData(
2483
                array(
2484
                    'error' => false,
2485
                    'ad_users' => $adUsersToSync,
2486
                    'ad_groups' => $adRoles,
2487
                    'teampass_groups' => $teampassRoles,
2488
                ), 
2489
                'encode'
2490
            );
2491
2492
            break;
2493
2494
        /*
2495
         * CHANGE USER DISABLE
2496
         */
2497
        case 'manage_user_disable_status':
2498
            // Check KEY
2499
            if ($post_key !== $session->get('key')) {
2500
                echo prepareExchangedData(
2501
                    array(
2502
                        'error' => true,
2503
                        'message' => $lang->get('key_is_not_correct'),
2504
                    ),
2505
                    'encode'
2506
                );
2507
                break;
2508
            }
2509
2510
            // Is this user allowed to do this?
2511
            if (
2512
                (int) $session->get('user-admin') !== 1
2513
                && (int) $session->get('user-can_manage_all_users') !== 1
2514
            ) {
2515
                echo prepareExchangedData(
2516
                    array(
2517
                        'error' => true,
2518
                        'message' => $lang->get('error_not_allowed_to'),
2519
                    ),
2520
                    'encode'
2521
                );
2522
                break;
2523
            }
2524
2525
            // Prepare variables
2526
            $post_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
2527
            $post_user_disabled = filter_var($dataReceived['disabled_status'], FILTER_SANITIZE_NUMBER_INT);
2528
2529
2530
            // Empty user
2531
            if (empty($post_id) === true) {
2532
                echo prepareExchangedData(
2533
                    array(
2534
                        'error' => true,
2535
                        'message' => $lang->get('user_not_exists'),
2536
                    ),
2537
                    'encode'
2538
                );
2539
                break;
2540
            }
2541
            // Check if user already exists
2542
            DB::query(
2543
                'SELECT id
2544
                FROM ' . prefixTable('users') . '
2545
                WHERE id = %i',
2546
                $post_id
2547
            );
2548
2549
            if (DB::count() > 0) {
2550
                // Change authentication type in DB
2551
                DB::update(
2552
                    prefixTable('users'),
2553
                    array(
2554
                        'disabled' => empty($post_user_disabled) === true ? 0 : $post_user_disabled,
2555
                    ),
2556
                    'id = %i',
2557
                    $post_id
2558
                );
2559
2560
                // update LOG
2561
                logEvents(
2562
                    $SETTINGS,
2563
                    'user_mngt',
2564
                    $post_user_disabled === 1 ? 'at_user_locked' : 'at_user_unlocked',
2565
                    (string) $session->get('user-id'),
2566
                    $session->get('user-login'),
2567
                    $post_id
2568
                );
2569
            } else {
2570
                echo prepareExchangedData(
2571
                    array(
2572
                        'error' => true,
2573
                        'message' => $lang->get('user_not_exists'),
2574
                    ),
2575
                    'encode'
2576
                );
2577
                break;
2578
            }
2579
2580
            echo prepareExchangedData(
2581
                array(
2582
                    'message' => '',
2583
                    'error' => false,
2584
                ),
2585
                'encode'
2586
            );
2587
2588
            break;
2589
2590
        case "create_new_user_tasks":
2591
            // Check KEY
2592
            if ($post_key !== $session->get('key')) {
2593
                echo prepareExchangedData(
2594
                    array(
2595
                        'error' => true,
2596
                        'message' => $lang->get('key_is_not_correct'),
2597
                    ),
2598
                    'encode'
2599
                );
2600
                break;
2601
            }
2602
2603
            // Prepare variables
2604
            $post_user_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
2605
            $post_user_pwd = isset($dataReceived['user_pwd']) === true ? ($dataReceived['user_pwd']) : '';
2606
            $post_user_code = ($dataReceived['user_code']);
2607
2608
            // Search TP_USER in db        
2609
            $userTP = DB::queryFirstRow(
2610
                'SELECT pw
2611
                FROM ' . prefixTable('users') . '
2612
                WHERE id = %i',
2613
                TP_USER_ID
2614
            );
2615
            if (DB::count() === 0) {
2616
                return prepareExchangedData(
2617
                    array(
2618
                        'error' => true,
2619
                        'message' => 'User not exists',
2620
                    ),
2621
                    'encode'
2622
                );
2623
            }
2624
2625
            // Create process
2626
            DB::insert(
2627
                prefixTable('background_tasks'),
2628
                array(
2629
                    'created_at' => time(),
2630
                    'process_type' => 'create_user_keys',
2631
                    'arguments' => json_encode([
2632
                        'new_user_id' => (int) $post_user_id,
2633
                        'new_user_pwd' => empty($post_user_pwd) === true ? '' : cryption($post_user_pwd, '','encrypt', $SETTINGS)['string'],
2634
                        'new_user_code' => cryption($post_user_code, '','encrypt', $SETTINGS)['string'],
2635
                        'owner_id' => (int) TP_USER_ID,
2636
                        'creator_pwd' => $userTP['pw'],
2637
                        'email_body' => $lang->get('email_body_user_config_5'),
2638
                        'send_email' => 1,
2639
                    ]),
2640
                    'updated_at' => '',
2641
                    'finished_at' => '',
2642
                    'output' => '',
2643
                )
2644
            );
2645
            $processId = DB::insertId();
2646
2647
            // Create tasks
2648
            createUserTasks(
2649
                $processId,
2650
                isset($SETTINGS['maximum_number_of_items_to_treat']) === true ? $SETTINGS['maximum_number_of_items_to_treat'] : NUMBER_ITEMS_IN_BATCH
2651
            );
2652
2653
            //update user is not ready
2654
            DB::update(
2655
                prefixTable('users'),
2656
                array(
2657
                    'is_ready_for_usage' => 1,
2658
                    'otp_provided' => 0,
2659
                    'ongoing_process_id' => $processId,
2660
                    'special' => 'generate-keys',
2661
                    // Notify user that he must re download his keys:
2662
                    'keys_recovery_time' => NULL,
2663
                ),
2664
                'id = %i',
2665
                $post_user_id
2666
            );
2667
2668
            echo prepareExchangedData(
2669
                array(
2670
                    'message' => '',
2671
                    'error' => false,
2672
                ),
2673
                'encode'
2674
            );
2675
2676
            break;
2677
2678
        /*
2679
        * WHAT IS THE PROGRESS OF GENERATING NEW KEYS AND OTP FOR A USER
2680
        */
2681
        case 'get_generate_keys_progress':
2682
            // Check KEY
2683
            if ($post_key !== $session->get('key')) {
2684
                echo prepareExchangedData(
2685
                    array(
2686
                        'error' => true,
2687
                        'message' => $lang->get('key_is_not_correct'),
2688
                    ),
2689
                    'encode'
2690
                );
2691
                break;
2692
            } elseif ($session->get('user-read_only') === 1) {
2693
                echo prepareExchangedData(
2694
                    array(
2695
                        'error' => true,
2696
                        'message' => $lang->get('error_not_allowed_to'),
2697
                    ),
2698
                    'encode'
2699
                );
2700
                break;
2701
            }
2702
2703
            if (isset($dataReceived['user_id']) === false) {
2704
                // Exit nothing to be done
2705
                echo prepareExchangedData(
2706
                    array(
2707
                        'error' => true,
2708
                        'message' => '',
2709
                        'user_id' => '',
2710
                        'status' => '',
2711
                        'debug' => '',
2712
                    ),
2713
                    'encode'
2714
                );
2715
            }
2716
2717
            // Prepare variables
2718
            $user_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
2719
2720
            // get user info
2721
            $processesProgress = DB::query(
2722
                'SELECT u.ongoing_process_id, pt.task, pt.updated_at, pt.finished_at, pt.is_in_progress
2723
                FROM ' . prefixTable('users') . ' AS u
2724
                INNER JOIN ' . prefixTable('background_subtasks') . ' AS pt ON (pt.task_id = u.ongoing_process_id)
2725
                WHERE u.id = %i',
2726
                $user_id
2727
            );
2728
2729
            //print_r($processesProgress);
2730
            $finished_steps = 0;
2731
            $nb_steps = count($processesProgress);
2732
            foreach($processesProgress as $process) {
2733
                if ((int) $process['is_in_progress'] === -1) {
2734
                    $finished_steps ++;
2735
                }
2736
            }
2737
2738
            echo prepareExchangedData(
2739
                array(
2740
                    'error' => false,
2741
                    'message' => '',
2742
                    'user_id' => $user_id,
2743
                    'status' => $finished_steps === $nb_steps ? 'finished' : number_format($finished_steps/$nb_steps*100, 0).'%',
2744
                    'debug' => $finished_steps.",".$nb_steps,
2745
                ),
2746
                'encode'
2747
            );
2748
2749
            break;
2750
2751
2752
        /**
2753
         * CHECK IF USER IS FINISHED WITH GENERATING NEW KEYS AND OTP FOR A USER
2754
         */
2755
        case "get_user_infos":
2756
            // Check KEY
2757
            if ($post_key !== $session->get('key')) {
2758
                echo prepareExchangedData(
2759
                    array(
2760
                        'error' => true,
2761
                        'message' => $lang->get('key_is_not_correct'),
2762
                    ),
2763
                    'encode'
2764
                );
2765
                break;
2766
            } elseif ($session->get('user-read_only') === 1) {
2767
                echo prepareExchangedData(
2768
                    array(
2769
                        'error' => true,
2770
                        'message' => $lang->get('error_not_allowed_to'),
2771
                    ),
2772
                    'encode'
2773
                );
2774
                break;
2775
            }
2776
2777
            // Prepare variables
2778
            $user_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
2779
2780
            $fullUserInfos = getFullUserInfos((int) $user_id);
2781
2782
            // Filter only on useful fields
2783
            $userInfos['id'] = $fullUserInfos['id'];
2784
            $userInfos['ongoing_process_id'] = $fullUserInfos['ongoing_process_id'];
2785
2786
            echo prepareExchangedData(
2787
                array(
2788
                    'error' => false,
2789
                    'message' => '',
2790
                    'user_id' => $user_id,
2791
                    'user_infos' => $userInfos,
2792
                    'debug' => '',
2793
                ),
2794
                'encode'
2795
            );
2796
2797
            break;
2798
        
2799
        case "reset_antibruteforce":
2800
            // Check KEY
2801
            if ($post_key !== $session->get('key')) {
2802
                echo prepareExchangedData(
2803
                    array(
2804
                        'error' => true,
2805
                        'message' => $lang->get('key_is_not_correct'),
2806
                    ),
2807
                    'encode'
2808
                );
2809
                break;
2810
            }
2811
2812
            // Prepare variables
2813
            $login = getFullUserInfos((int) $dataReceived['user_id'])['login'];
2814
2815
            // Delete all logs for this user
2816
            DB::delete(
2817
                prefixTable('auth_failures'),
2818
                'source = %s AND value = %s',
2819
                'login',
2820
                $login
2821
            );
2822
            
2823
            break;
2824
    }
2825
    // # NEW LOGIN FOR USER HAS BEEN DEFINED ##
2826
} elseif (!empty(filter_input(INPUT_POST, 'newValue', FILTER_SANITIZE_FULL_SPECIAL_CHARS))) {
2827
    // Prepare POST variables
2828
    $value = explode('_', filter_input(INPUT_POST, 'id', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
2829
    $post_newValue = filter_input(INPUT_POST, 'newValue', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
2830
2831
    // Get info about user
2832
    $data_user = DB::queryFirstRow(
2833
        'SELECT admin, isAdministratedByRole FROM ' . prefixTable('users') . '
2834
        WHERE id = %i',
2835
        $value[1]
2836
    );
2837
2838
    // Is this user allowed to do this?
2839
    if (
2840
        (int) $session->get('user-admin') === 1
2841
        || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
2842
        || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
2843
        || ($session->get('user-id') === $value[1])
2844
    ) {
2845
        if ($value[0] === 'userlanguage') {
2846
            $value[0] = 'user_language';
2847
            $post_newValue = strtolower($post_newValue);
2848
        }
2849
        
2850
        // Check that operation is allowed
2851
        if (in_array(
2852
            $value[0],
2853
            array('login', 'pw', 'email', 'treeloadstrategy', 'usertimezone', 'yubico_user_key', 'yubico_user_id', 'agses-usercardid', 'user_language', 'psk', 'split_view_mode')
2854
        )) {
2855
            DB::update(
2856
                prefixTable('users'),
2857
                array(
2858
                    $value[0] => $post_newValue,
2859
                ),
2860
                'id = %i',
2861
                $value[1]
2862
            );
2863
            // update LOG
2864
            logEvents(
2865
                $SETTINGS,
2866
                'user_mngt',
2867
                'at_user_new_' . $value[0] . ':' . $value[1],
2868
                (string) $session->get('user-id'),
2869
                $session->get('user-login'),
2870
                filter_input(INPUT_POST, 'id', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
2871
            );
2872
2873
            // refresh SESSION if requested
2874
            // Session keys mapping
2875
            $sessionMapping = [
2876
                'treeloadstrategy' => 'user-tree_load_strategy',
2877
                'usertimezone' => 'user-timezone',
2878
                'userlanguage' => 'user-language',
2879
                'agses-usercardid' => null, 
2880
                'email' => 'user-email',
2881
                'split_view_mode' => 'user-split_view_mode',
2882
            ];
2883
            // Update session
2884
            if (array_key_exists($value[0], $sessionMapping)) {
2885
                $sessionKey = $sessionMapping[$value[0]];
2886
                if ($sessionKey !== null) {
2887
                    $session->set($sessionKey, $post_newValue);
2888
                }
2889
            }
2890
            
2891
            // Display info
2892
            echo htmlentities($post_newValue, ENT_QUOTES);
2893
        }
2894
    }
2895
    // # ADMIN FOR USER HAS BEEN DEFINED ##
2896
} elseif (null !== filter_input(INPUT_POST, 'newadmin', FILTER_SANITIZE_NUMBER_INT)) {
2897
    $id = explode('_', filter_input(INPUT_POST, 'id', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
2898
2899
    // Get info about user
2900
    $data_user = DB::queryFirstRow(
2901
        'SELECT admin, isAdministratedByRole FROM ' . prefixTable('users') . '
2902
        WHERE id = %i',
2903
        $id[1]
2904
    );
2905
2906
    // Is this user allowed to do this?
2907
    if (
2908
        (int) $session->get('user-admin') === 1
2909
        || (in_array($data_user['isAdministratedByRole'], $session->get('user-roles_array')))
2910
        || ((int) $session->get('user-can_manage_all_users') === 1 && (int) $data_user['admin'] !== 1)
2911
        || ($session->get('user-id') === $id[1])
2912
    ) {
2913
        DB::update(
2914
            prefixTable('users'),
2915
            array(
2916
                'admin' => filter_input(INPUT_POST, 'newadmin', FILTER_SANITIZE_NUMBER_INT),
2917
            ),
2918
            'id = %i',
2919
            $id[1]
2920
        );
2921
        // Display info
2922
        if (filter_input(INPUT_POST, 'newadmin', FILTER_SANITIZE_NUMBER_INT) === 1) {
2923
            echo 'Oui';
2924
        } else {
2925
            echo 'Non';
2926
        }
2927
    }
2928
}
2929
2930
/**
2931
 * Return the level of access on a folder.
2932
 *
2933
 * @param string $new_val      New value
2934
 * @param string $existing_val Current value
2935
 *
2936
 * @return string Returned index
2937
 */
2938
function evaluateFolderAccesLevel($new_val, $existing_val)
2939
{
2940
    $levels = array(
2941
        'W' => 30,
2942
        'ND' => 20,
2943
        'NE' => 15,
2944
        'NDNE' => 10,
2945
        'R' => 10,
2946
    );
2947
2948
    $current_level_points = empty($existing_val) === true ? 0 : $levels[$existing_val];
2949
    $new_level_points = empty($new_val) === true ? 0 : $levels[$new_val];
2950
2951
    // check if new is > to current one (always keep the highest level)
2952
    if (($new_val === 'ND' && $existing_val === 'NE')
2953
        || ($new_val === 'NE' && $existing_val === 'ND')
2954
    ) {
2955
        return 'NDNE';
2956
    } else {
2957
        if ($current_level_points > $new_level_points) {
2958
            return $existing_val;
2959
        } else {
2960
            return $new_val;
2961
        }
2962
    }
2963
}
2964