Passed
Push — master ( 64c076...b207d0 )
by Nils
09:35
created

loadLastTasksExec()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 43
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 23
c 0
b 0
f 0
nc 4
nop 2
dl 0
loc 43
rs 9.552
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Teampass - a collaborative passwords manager.
7
 * ---
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 * ---
12
 * @project   Teampass
13
 * @file      tasks.queries.php
14
 * ---
15
 * @author    Nils Laumaillé ([email protected])
16
 * @copyright 2009-2023 Teampass.net
17
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
18
 * ---
19
 * @see       https://www.teampass.net
20
 */
21
22
23
require_once __DIR__.'/SecureHandler.php';
24
session_name('teampass_session');
25
session_start();
26
if (
27
    isset($_SESSION['CPM']) === false
28
    || $_SESSION['CPM'] !== 1
29
    || isset($_SESSION['user_id']) === false || empty($_SESSION['user_id'])
30
    || isset($_SESSION['key']) === false || empty($_SESSION['key'])
31
) {
32
    die('Hacking attempt...');
33
}
34
35
// Load config if $SETTINGS not defined
36
if (isset($SETTINGS['cpassman_dir']) === false || empty($SETTINGS['cpassman_dir'])) {
37
    if (file_exists('../includes/config/tp.config.php')) {
38
        include_once '../includes/config/tp.config.php';
39
    } elseif (file_exists('./includes/config/tp.config.php')) {
40
        include_once './includes/config/tp.config.php';
41
    } elseif (file_exists('../../includes/config/tp.config.php')) {
42
        include_once '../../includes/config/tp.config.php';
43
    } else {
44
        throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
45
    }
46
}
47
48
/* do checks */
49
require_once $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
50
require_once $SETTINGS['cpassman_dir'] . '/sources/checks.php';
51
if (!checkUser($_SESSION['user_id'], $_SESSION['key'], 'options', $SETTINGS)) {
52
    $_SESSION['error']['code'] = ERR_NOT_ALLOWED; //not allowed page
53
    include $SETTINGS['cpassman_dir'] . '/error.php';
54
    exit;
55
}
56
57
require_once $SETTINGS['cpassman_dir'] . '/includes/language/' . $_SESSION['user']['user_language'] . '.php';
58
require_once $SETTINGS['cpassman_dir'] . '/includes/config/settings.php';
59
require_once $SETTINGS['cpassman_dir'] . '/includes/config/tp.config.php';
60
61
header('Content-type: text/html; charset=utf-8');
62
header('Cache-Control: no-cache, no-store, must-revalidate');
63
64
require_once $SETTINGS['cpassman_dir'] . '/sources/SplClassLoader.php';
65
66
// connect to the server
67
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php';
68
if (defined('DB_PASSWD_CLEAR') === false) {
69
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
70
}
71
DB::$host = DB_HOST;
72
DB::$user = DB_USER;
73
DB::$password = DB_PASSWD_CLEAR;
74
DB::$dbName = DB_NAME;
75
DB::$port = DB_PORT;
76
DB::$encoding = DB_ENCODING;
77
DB::$ssl = DB_SSL;
78
DB::$connect_options = DB_CONNECT_OPTIONS;
79
80
//Load AES
81
$aes = new SplClassLoader('Encryption\Crypt', '../includes/libraries');
82
$aes->register();
83
84
// Prepare POST variables
85
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
86
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
87
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
88
$post_task = filter_input(INPUT_POST, 'task', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
89
90
if (null !== $post_type) {
91
    // Do checks
92
    if ($post_key !== $_SESSION['key']) {
93
        echo prepareExchangedData(
94
            $SETTINGS['cpassman_dir'],
95
            array(
96
                'error' => true,
97
                'message' => langHdl('key_is_not_correct'),
98
            ),
99
            'encode'
100
        );
101
        return false;
102
    } elseif ($_SESSION['user_read_only'] === true) {
103
        echo prepareExchangedData(
104
            $SETTINGS['cpassman_dir'],
105
            array(
106
                'error' => true,
107
                'message' => langHdl('error_not_allowed_to'),
108
            ),
109
            'encode'
110
        );
111
        return false;
112
    }
113
114
    // Get PHP binary
115
    $phpBinaryPath = getPHPBinary();
116
117
    switch ($post_type) {
118
        case 'perform_task':
119
            echo performTask($post_task, $SETTINGS['cpassman_dir'], $phpBinaryPath, $SETTINGS['date_format'].' '.$SETTINGS['time_format']);
120
121
            break;
122
123
        case 'load_last_tasks_execution':
124
            echo loadLastTasksExec($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $SETTINGS['cpassman_dir']);
0 ignored issues
show
Bug introduced by
Are you sure the usage of loadLastTasksExec($SETTI...TTINGS['cpassman_dir']) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure loadLastTasksExec($SETTI...TTINGS['cpassman_dir']) of type void can be used in echo? ( Ignorable by Annotation )

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

124
            echo /** @scrutinizer ignore-type */ loadLastTasksExec($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $SETTINGS['cpassman_dir']);
Loading history...
125
126
            break;  
127
    }
128
}
129
130
/**
131
 * Load the last tasks execution
132
 *
133
 * @param string $datetimeFormat
134
 * @param string $dir
135
 * @return void
136
 */
137
function loadLastTasksExec(string $datetimeFormat, string $dir)
138
{
139
    $lastExec = [];
140
141
    // get exec from processes table
142
    $rows = DB::query(
143
        'SELECT max(finished_at), process_type
144
        FROM ' . prefixTable('processes') . '
145
        GROUP BY process_type'
146
    );
147
    foreach ($rows as $row) {
148
        array_push(
149
            $lastExec,
150
            [
151
                'task' => loadLastTasksExec_getBadge($row['process_type']),
152
                'datetime' => date($datetimeFormat, (int) $row['max(finished_at)'])
153
            ]
154
        );
155
    }
156
157
    // get exec from processes_log table
158
    $rows = DB::query(
159
        'SELECT max(finished_at), job as process_type
160
        FROM ' . prefixTable('processes_logs') . '
161
        GROUP BY process_type'
162
    );
163
    foreach ($rows as $row) {
164
        array_push(
165
            $lastExec,
166
            [
167
                'task' => loadLastTasksExec_getBadge($row['process_type']),
168
                'datetime' => date($datetimeFormat, (int) $row['max(finished_at)'])
169
            ]
170
        );
171
    }
172
173
    return prepareExchangedData(
0 ignored issues
show
Bug Best Practice introduced by
The expression return prepareExchangedD...($lastExec)), 'encode') returns the type string which is incompatible with the documented return type void.
Loading history...
174
        $dir,
175
        array(
176
            'error' => false,
177
            'task' => json_encode($lastExec),
178
        ),
179
        'encode'
180
    );
181
}
182
183
function loadLastTasksExec_getBadge(string $processLabel): string
184
{
185
    $existingTasks = [
186
        'do_maintenance - clean-orphan-objects' => [
187
            'db' => 'do_maintenance - clean-orphan-objects',
188
            'task' => 'clean_orphan_objects_task',
189
        ],
190
        'do_maintenance - purge-old-files' => [
191
            'db' => 'do_maintenance - purge-old-files',
192
            'task' => 'purge_temporary_files_task',
193
        ],
194
        'do_maintenance - rebuild-config-file' => [
195
            'db' => 'do_maintenance - rebuild-config-file',
196
            'task' => 'rebuild_config_file_task',
197
        ],
198
        'do_maintenance - reload-cache-table' => [
199
            'db' => 'do_maintenance - reload-cache-table',
200
            'task' => 'reload_cache_table_task',
201
        ],
202
        'do_maintenance - users-personal-folder' => [
203
            'db' => 'do_maintenance - users-personal-folder',
204
            'task' => 'users_personal_folder_task',
205
        ],
206
        'send_email' => [
207
            'db' => 'send_email',
208
            'task' => 'sending_emails_job_frequency',
209
        ],
210
        'do_calculation' => [
211
            'db' => 'do_calculation',
212
            'task' => 'items_statistics_job_frequency',
213
        ],
214
        'item_keys' => [
215
            'db' => 'item_keys',
216
            'task' => 'items_ops_job_frequency',
217
        ],
218
        'user_task' => [
219
            'db' => 'user_task',
220
            'task' => 'user_keys_job_frequency',
221
        ],
222
        'sending_email' => [
223
            'db' => 'sending_email',
224
            'task' => 'sending_emails_job_frequency',
225
        ],
226
    ];
227
228
    return isset($existingTasks[$processLabel]) === true ? $existingTasks[$processLabel]['task'] : $processLabel;
229
}
230
231
/**
232
 * Perform a task
233
 *
234
 * @param string $task
235
 * @param string $dir
236
 * @param string $phpBinaryPath
237
 * @param string $datetimeFormat
238
 * @return string
239
 */
240
function performTask(string $task, string $dir, string $phpBinaryPath, string $datetimeFormat): string
241
{
242
    switch ($task) {
243
        case 'users_personal_folder_task':
244
245
            $process = new Symfony\Component\Process\Process([
246
                $phpBinaryPath,
247
                __DIR__.'/../scripts/task_maintenance_users_personal_folder.php',
248
            ]);
249
250
            break;
251
252
        case 'clean_orphan_objects_task':
253
254
            $process = new Symfony\Component\Process\Process([
255
                $phpBinaryPath,
256
                __DIR__.'/../scripts/task_maintenance_clean_orphan_objects.php',
257
            ]);
258
259
            break;
260
261
        case 'purge_temporary_files_task':
262
263
            $process = new Symfony\Component\Process\Process([
264
                $phpBinaryPath,
265
                __DIR__.'/../scripts/task_maintenance_purge_old_files.php',
266
            ]);
267
268
            break;
269
270
        case 'rebuild_config_file_task':
271
272
            $process = new Symfony\Component\Process\Process([
273
                $phpBinaryPath,
274
                __DIR__.'/../scripts/task_maintenance_rebuild_config_file.php',
275
            ]);
276
277
            break;
278
279
        case 'reload_cache_table_task':
280
281
            $process = new Symfony\Component\Process\Process([
282
                $phpBinaryPath,
283
                __DIR__.'/../scripts/task_maintenance_reload_cache_table.php',
284
            ]);
285
286
            break;
287
        }
288
289
    // execute the process
290
    try {
291
        $process->start();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $process does not seem to be defined for all execution paths leading up to this point.
Loading history...
292
293
        while ($process->isRunning()) {
294
            // waiting for process to finish
295
        }
296
297
        $process->wait();
298
    
299
        $output = $process->getOutput();
300
        $error = false;
301
    } catch (ProcessFailedException $exception) {
0 ignored issues
show
Bug introduced by
The type ProcessFailedException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
302
        $error = true;
303
        $output = $exception->getMessage();
304
    }
305
306
    return prepareExchangedData(
307
        $dir,
308
        array(
309
            'error' => $error,
310
            'output' => $output,
311
            'datetime' => date($datetimeFormat, time()),
312
        ),
313
        'encode'
314
    );
315
}