1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* @file (api)functions.php |
5
|
|
|
* @author Nils Laumaillé |
6
|
|
|
* @version 2.1.0 |
7
|
|
|
* @copyright (c) 2009-2018 Nils Laumaillé |
8
|
|
|
* @licensing GNU GPL-3.0 |
9
|
|
|
* @link http://www.teampass.net |
10
|
|
|
* |
11
|
|
|
* This library is distributed in the hope that it will be useful, |
12
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
$api_version = "2.1"; |
17
|
|
|
$_SESSION['CPM'] = 1; |
18
|
|
|
require_once "../includes/config/include.php"; |
19
|
|
|
require_once "../sources/main.functions.php"; |
20
|
|
|
|
21
|
|
|
function get_ip() |
22
|
|
|
{ |
23
|
|
|
if (function_exists('apache_request_headers')) { |
24
|
|
|
$headers = apache_request_headers(); |
25
|
|
|
} else { |
26
|
|
|
$headers = $_SERVER; |
27
|
|
|
} |
28
|
|
|
if (array_key_exists('X-Forwarded-For', $headers) && filter_var($headers['X-Forwarded-For'], FILTER_VALIDATE_IP)) { |
29
|
|
|
$the_ip = $headers['X-Forwarded-For']; |
30
|
|
|
} elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $headers) && filter_var($headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP)) { |
31
|
|
|
$the_ip = $headers['HTTP_X_FORWARDED_FOR']; |
32
|
|
|
} else { |
33
|
|
|
$the_ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP); |
34
|
|
|
} |
35
|
|
|
return $the_ip; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
|
39
|
|
|
function teampass_api_enabled() |
40
|
|
|
{ |
41
|
|
|
teampass_connect(); |
42
|
|
|
$response = DB::queryFirstRow( |
43
|
|
|
"SELECT `valeur` FROM ".prefix_table("misc")." WHERE type = %s AND intitule = %s", |
44
|
|
|
"admin", |
45
|
|
|
"api" |
46
|
|
|
); |
47
|
|
|
return $response['valeur']; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
function teampass_whitelist() |
51
|
|
|
{ |
52
|
|
|
teampass_connect(); |
53
|
|
|
$apiip_pool = teampass_get_ips(); |
54
|
|
|
if (count($apiip_pool) > 0 && array_search(get_ip(), $apiip_pool) === false) { |
55
|
|
|
rest_error('IPWHITELIST'); |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
function teampass_connect() |
60
|
|
|
{ |
61
|
|
|
global $server, $user, $pass, $database, $link, $port, $encoding; |
|
|
|
|
62
|
|
|
require_once("../includes/config/settings.php"); |
63
|
|
|
require_once('../includes/libraries/Database/Meekrodb/db.class.php'); |
64
|
|
|
$pass = defuse_return_decrypted($pass); |
65
|
|
|
DB::$host = $server; |
66
|
|
|
DB::$user = $user; |
67
|
|
|
DB::$password = $pass; |
68
|
|
|
DB::$dbName = $database; |
69
|
|
|
DB::$port = $port; |
70
|
|
|
DB::$encoding = $encoding; |
71
|
|
|
DB::$error_handler = true; |
72
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
73
|
|
|
$link->set_charset($encoding); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
function teampass_get_ips() |
77
|
|
|
{ |
78
|
|
|
$array_of_results = array(); |
79
|
|
|
teampass_connect(); |
80
|
|
|
$response = DB::query("select value from ".prefix_table("api")." WHERE type = %s", "ip"); |
81
|
|
|
foreach ($response as $data) { |
82
|
|
|
array_push($array_of_results, $data['value']); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return $array_of_results; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
function teampass_get_keys() |
89
|
|
|
{ |
90
|
|
|
teampass_connect(); |
91
|
|
|
$response = array_unique(array_merge( |
92
|
|
|
DB::queryOneColumn("value", "select * from ".prefix_table("api")." WHERE type = %s", "key"), |
93
|
|
|
DB::queryOneColumn("user_api_key", "select * from ".prefix_table("users")."") |
94
|
|
|
)); |
95
|
|
|
|
96
|
|
|
// remove none value |
97
|
|
|
if (($key = array_search('none', $response)) !== false) { |
98
|
|
|
unset($response[$key]); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
return $response; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
function rest_head() |
105
|
|
|
{ |
106
|
|
|
header('HTTP/1.1 402 Payment Required'); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
function addToCacheTable($item_id) |
110
|
|
|
{ |
111
|
|
|
teampass_connect(); |
112
|
|
|
// get data |
113
|
|
|
$data = DB::queryfirstrow( |
114
|
|
|
"SELECT i.label AS label, i.description AS description, i.id_tree AS id_tree, i.perso AS perso, i.restricted_to AS restricted_to, i.login AS login, i.id AS id |
115
|
|
|
FROM ".prefix_table("items")." AS i |
116
|
|
|
AND ".prefix_table("log_items")." AS l ON (l.id_item = i.id) |
117
|
|
|
WHERE i.id = %i |
118
|
|
|
AND l.action = %s", |
119
|
|
|
intval($item_id), |
120
|
|
|
'at_creation' |
121
|
|
|
); |
122
|
|
|
|
123
|
|
|
// Get all TAGS |
124
|
|
|
$tags = ""; |
125
|
|
|
$data_tags = DB::query("SELECT tag FROM ".prefix_table("tags")." WHERE item_id=%i", $item_id); |
126
|
|
|
foreach ($data_tags as $itemTag) { |
127
|
|
|
if (!empty($itemTag['tag'])) { |
128
|
|
|
$tags .= $itemTag['tag']." "; |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
// finaly update |
133
|
|
|
DB::insert( |
134
|
|
|
prefix_table("cache"), |
135
|
|
|
array( |
136
|
|
|
"id" => $data['id'], |
137
|
|
|
"label" => $data['label'], |
138
|
|
|
"description" => $data['description'], |
139
|
|
|
"tags" => $tags, |
140
|
|
|
"id_tree" => $data['id_tree'], |
141
|
|
|
"perso" => $data['perso'], |
142
|
|
|
"restricted_to" => $data['restricted_to'], |
143
|
|
|
"login" => $data['login'], |
144
|
|
|
"folder" => "", |
145
|
|
|
//"restricted_to" => "0", |
|
|
|
|
146
|
|
|
"author" => API_USER_ID, |
147
|
|
|
"renewal_period" => 0, |
148
|
|
|
"timestamp" => time(), |
149
|
|
|
"url" => 0 |
150
|
|
|
) |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* @param string $setting |
157
|
|
|
*/ |
158
|
|
|
function getSettingValue($setting) |
159
|
|
|
{ |
160
|
|
|
// get default language |
161
|
|
|
$set = DB::queryFirstRow( |
162
|
|
|
"SELECT `valeur` FROM ".prefix_table("misc")." WHERE type = %s AND intitule = %s", |
163
|
|
|
"admin", |
164
|
|
|
$setting |
165
|
|
|
); |
166
|
|
|
|
167
|
|
|
return $set['valeur']; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Permits to get rid of special characters that can break the url |
172
|
|
|
* |
173
|
|
|
* @param string $string adapted base64 encoded string |
174
|
|
|
* @return string |
175
|
|
|
*/ |
176
|
|
|
function Urlsafe_b64decode($string) |
177
|
|
|
{ |
178
|
|
|
$data = str_replace( |
179
|
|
|
array('-', '_'), |
180
|
|
|
array('+', '/'), |
181
|
|
|
$string |
182
|
|
|
); |
183
|
|
|
$mod4 = strlen($data) % 4; |
184
|
|
|
if ($mod4) { |
185
|
|
|
$data .= substr('====', $mod4); |
186
|
|
|
} |
187
|
|
|
return base64_decode($data); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
function rest_delete() |
191
|
|
|
{ |
192
|
|
|
if (!@count($GLOBALS['request']) == 0) { |
193
|
|
|
$request_uri = $GLOBALS['_SERVER']['REQUEST_URI']; |
194
|
|
|
preg_match('/\/api(\/index.php|)\/(.*)\?apikey=(.*)/', $request_uri, $matches); |
195
|
|
|
if (count($matches) == 0) { |
196
|
|
|
rest_error('REQUEST_SENT_NOT_UNDERSTANDABLE'); |
197
|
|
|
} |
198
|
|
|
$GLOBALS['request'] = explode('/', $matches[2]); |
199
|
|
|
} |
200
|
|
|
if (apikey_checker($GLOBALS['apikey'])) { |
201
|
|
|
include "../sources/main.functions.php"; |
202
|
|
|
teampass_connect(); |
203
|
|
|
$category_query = ""; |
204
|
|
|
|
205
|
|
|
if ($GLOBALS['request'][0] == "write") { |
206
|
|
|
if ($GLOBALS['request'][1] == "category") { |
207
|
|
|
$array_category = explode(';', $GLOBALS['request'][2]); |
208
|
|
|
|
209
|
|
|
foreach ($array_category as $category) { |
210
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $category, $result)) { |
211
|
|
|
rest_error('CATEGORY_MALFORMED'); |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
if (count($array_category) > 1 && count($array_category) < 5) { |
216
|
|
|
for ($i = count($array_category); $i > 0; $i--) { |
217
|
|
|
$slot = $i - 1; |
218
|
|
|
if (!$slot) { |
219
|
|
|
$category_query .= "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[$slot], FILTER_SANITIZE_STRING)."' AND parent_id = 0"; |
220
|
|
|
} else { |
221
|
|
|
$category_query .= "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[$slot], FILTER_SANITIZE_STRING)."' AND parent_id = ("; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
for ($i = 1; $i < count($array_category); $i++) { |
|
|
|
|
225
|
|
|
$category_query .= ")"; |
226
|
|
|
} |
227
|
|
|
} elseif (count($array_category) == 1) { |
228
|
|
|
$category_query = "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[0], FILTER_SANITIZE_STRING)."' AND parent_id = 0"; |
229
|
|
|
} else { |
230
|
|
|
rest_error('NO_CATEGORY'); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
// Delete items which in category |
234
|
|
|
$response = DB::delete(prefix_table("items"), "id_tree = (".$category_query.")"); |
|
|
|
|
235
|
|
|
// Delete sub-categories which in category |
236
|
|
|
$response = DB::delete(prefix_table("nested_tree"), "parent_id = (".$category_query.")"); |
237
|
|
|
// Delete category |
238
|
|
|
$response = DB::delete(prefix_table("nested_tree"), "id = (".$category_query.")"); |
239
|
|
|
|
240
|
|
|
$json['type'] = 'category'; |
|
|
|
|
241
|
|
|
$json['category'] = $GLOBALS['request'][2]; |
242
|
|
|
if ($response) { |
243
|
|
|
$json['status'] = 'OK'; |
244
|
|
|
} else { |
245
|
|
|
$json['status'] = 'KO'; |
246
|
|
|
} |
247
|
|
|
} elseif ($GLOBALS['request'][1] == "item") { |
248
|
|
|
$array_category = explode(';', $GLOBALS['request'][2]); |
249
|
|
|
$item = $GLOBALS['request'][3]; |
250
|
|
|
|
251
|
|
|
foreach ($array_category as $category) { |
252
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $category, $result)) { |
253
|
|
|
rest_error('CATEGORY_MALFORMED'); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $item, $result)) { |
258
|
|
|
rest_error('ITEM_MALFORMED'); |
259
|
|
|
} elseif (empty($item) || count($array_category) == 0) { |
260
|
|
|
rest_error('MALFORMED'); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
if (count($array_category) > 1 && count($array_category) < 5) { |
264
|
|
|
for ($i = count($array_category); $i > 0; $i--) { |
265
|
|
|
$slot = $i - 1; |
266
|
|
|
if (!$slot) { |
267
|
|
|
$category_query .= "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[$slot], FILTER_SANITIZE_STRING)."' AND parent_id = 0"; |
268
|
|
|
} else { |
269
|
|
|
$category_query .= "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[$slot], FILTER_SANITIZE_STRING)."' AND parent_id = ("; |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
for ($i = 1; $i < count($array_category); $i++) { |
|
|
|
|
273
|
|
|
$category_query .= ")"; |
274
|
|
|
} |
275
|
|
|
} elseif (count($array_category) == 1) { |
276
|
|
|
$category_query = "select id from ".prefix_table("nested_tree")." where title LIKE '".filter_var($array_category[0], FILTER_SANITIZE_STRING)."' AND parent_id = 0"; |
277
|
|
|
} else { |
278
|
|
|
rest_error('NO_CATEGORY'); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
// Delete item |
282
|
|
|
$response = DB::delete(prefix_table("items"), "id_tree = (".$category_query.") and label LIKE '".filter_var($item, FILTER_SANITIZE_STRING)."'"); |
283
|
|
|
$json['type'] = 'item'; |
284
|
|
|
$json['item'] = $item; |
285
|
|
|
$json['category'] = $GLOBALS['request'][2]; |
286
|
|
|
if ($response) { |
287
|
|
|
$json['status'] = 'OK'; |
288
|
|
|
} else { |
289
|
|
|
$json['status'] = 'KO'; |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
if ($json) { |
|
|
|
|
294
|
|
|
echo json_encode($json); |
295
|
|
|
} else { |
296
|
|
|
rest_error('EMPTY'); |
297
|
|
|
} |
298
|
|
|
} else { |
299
|
|
|
rest_error('METHOD'); |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
function rest_get() |
305
|
|
|
{ |
306
|
|
|
global $api_version; |
|
|
|
|
307
|
|
|
global $SETTINGS; |
|
|
|
|
308
|
|
|
global $link; |
|
|
|
|
309
|
|
|
|
310
|
|
|
if (!@count($GLOBALS['request']) == 0) { |
311
|
|
|
$request_uri = $GLOBALS['_SERVER']['REQUEST_URI']; |
312
|
|
|
preg_match('/\/api(\/index.php|)\/(.*)\?apikey=(.*)/', $request_uri, $matches); |
313
|
|
|
if (count($matches) == 0) { |
314
|
|
|
rest_error('REQUEST_SENT_NOT_UNDERSTANDABLE'); |
315
|
|
|
} |
316
|
|
|
$GLOBALS['request'] = explode('/', $matches[2]); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
if (apikey_checker($GLOBALS['apikey'])) { |
320
|
|
|
|
321
|
|
|
teampass_connect(); |
322
|
|
|
|
323
|
|
|
// define the API user through the LABEL of apikey |
324
|
|
|
$api_info = DB::queryFirstRow( |
325
|
|
|
"SELECT label |
326
|
|
|
FROM ".prefix_table("api")." |
327
|
|
|
WHERE value = %s", |
328
|
|
|
$GLOBALS['apikey'] |
329
|
|
|
); |
330
|
|
|
|
331
|
|
|
// Load config |
332
|
|
|
if (file_exists('../includes/config/tp.config.php')) { |
333
|
|
|
require_once '../includes/config/tp.config.php'; |
334
|
|
|
} else { |
335
|
|
|
throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
if ($GLOBALS['request'][0] == "read") { |
339
|
|
|
if ($GLOBALS['request'][1] == "folder") { |
340
|
|
|
/* |
341
|
|
|
* READ FOLDERS |
342
|
|
|
*/ |
343
|
|
|
|
344
|
|
|
// load library |
345
|
|
|
require_once '../sources/SplClassLoader.php'; |
346
|
|
|
//Load Tree |
347
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
348
|
|
|
$tree->register(); |
349
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
350
|
|
|
|
351
|
|
|
// get ids |
352
|
|
|
if (strpos($GLOBALS['request'][2], ";") > 0) { |
353
|
|
|
$condition = "id_tree IN %ls"; |
354
|
|
|
$condition_value = explode(';', $GLOBALS['request'][2]); |
355
|
|
|
} else { |
356
|
|
|
$condition = "id_tree = %s"; |
357
|
|
|
$condition_value = $GLOBALS['request'][2]; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
// get items in this folder |
361
|
|
|
$response = DB::query( |
362
|
|
|
"SELECT id, label, login, pw, pw_iv, url, id_tree, description, email |
363
|
|
|
FROM ".prefix_table("items")." |
364
|
|
|
WHERE inactif='0' AND ".$condition, |
365
|
|
|
$condition_value |
366
|
|
|
); |
367
|
|
|
$inc = 0; |
368
|
|
|
foreach ($response as $data) { |
369
|
|
|
// build the path to the Item |
370
|
|
|
$path = ""; |
371
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
372
|
|
|
foreach ($arbo as $elem) { |
373
|
|
|
if (empty($path)) { |
374
|
|
|
$path = stripslashes($elem->title); |
375
|
|
|
} else { |
376
|
|
|
$path .= " > ".stripslashes($elem->title); |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
// prepare output |
381
|
|
|
$json[$inc]['id'] = $data['id']; |
382
|
|
|
$json[$inc]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
383
|
|
|
$json[$inc]['description'] = mb_convert_encoding($data['description'], mb_detect_encoding($data['description']), 'UTF-8'); |
384
|
|
|
$json[$inc]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
385
|
|
|
$json[$inc]['email'] = mb_convert_encoding($data['email'], mb_detect_encoding($data['email']), 'UTF-8'); |
386
|
|
|
$json[$inc]['url'] = mb_convert_encoding($data['url'], mb_detect_encoding($data['url']), 'UTF-8'); |
387
|
|
|
$crypt_pw = cryption( |
388
|
|
|
$data['pw'], |
389
|
|
|
"", |
390
|
|
|
"decrypt" |
391
|
|
|
); |
392
|
|
|
$json[$inc]['pw'] = $crypt_pw['string']; |
393
|
|
|
$json[$inc]['folder_id'] = $data['id_tree']; |
394
|
|
|
$json[$inc]['path'] = $path; |
395
|
|
|
|
396
|
|
|
$inc++; |
397
|
|
|
} |
398
|
|
|
} elseif ($GLOBALS['request'][1] == "userpw") { |
399
|
|
|
/* |
400
|
|
|
* READ USER ITEMS |
401
|
|
|
*/ |
402
|
|
|
|
403
|
|
|
// load library |
404
|
|
|
require_once '../sources/SplClassLoader.php'; |
405
|
|
|
//Load Tree |
406
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
407
|
|
|
$tree->register(); |
408
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
409
|
|
|
|
410
|
|
|
// about the user |
411
|
|
|
$username = $GLOBALS['request'][2]; |
412
|
|
|
if (strcmp($username, "admin") == 0) { |
|
|
|
|
413
|
|
|
// forbid admin access |
414
|
|
|
} |
415
|
|
|
$response = DB::query( |
416
|
|
|
"SELECT fonction_id |
417
|
|
|
FROM ".prefix_table("users")." |
418
|
|
|
WHERE login = %s'", |
419
|
|
|
$username |
420
|
|
|
); |
421
|
|
|
if (count($response) === 0) { |
422
|
|
|
rest_error('USER_NOT_EXISTS'); |
423
|
|
|
} |
424
|
|
|
foreach ($response as $data) { |
425
|
|
|
$role_str = $data['fonction_id']; |
426
|
|
|
} |
427
|
|
|
$folder_arr = array(); |
428
|
|
|
$roles = explode(";", $role_str); |
|
|
|
|
429
|
|
|
foreach ($roles as $role) { |
430
|
|
|
$response = DB::query( |
431
|
|
|
"SELECT folder_id |
432
|
|
|
FROM ".prefix_table("roles_values")." |
433
|
|
|
WHERE role_id = %i", |
434
|
|
|
$role |
435
|
|
|
); |
436
|
|
|
foreach ($response as $data) { |
437
|
|
|
$folder_id = $data['folder_id']; |
438
|
|
|
if (!array_key_exists($folder_id, $folder_arr)) { |
439
|
|
|
array_push($folder_arr, $folder_id); |
440
|
|
|
} |
441
|
|
|
} |
442
|
|
|
} |
443
|
|
|
$folder_str = array_filter($folder_arr); |
444
|
|
|
|
445
|
|
|
// get ids |
446
|
|
|
if (is_array($folder_str)) { |
|
|
|
|
447
|
|
|
$condition = "id_tree IN %ls"; |
448
|
|
|
$condition_value = $folder_str; |
449
|
|
|
} else { |
450
|
|
|
$condition = "id_tree = %s"; |
451
|
|
|
$condition_value = $folder_str; |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
$data = ""; |
|
|
|
|
455
|
|
|
// get items in this module |
456
|
|
|
$response = DB::query( |
457
|
|
|
"SELECT id,label,url,login,pw, pw_iv, url, id_tree, description, email |
458
|
|
|
FROM ".prefix_table("items")." |
459
|
|
|
WHERE inactif='0' AND ".$condition, |
460
|
|
|
$condition_value |
461
|
|
|
); |
462
|
|
|
$inc = 0; |
463
|
|
|
foreach ($response as $data) { |
464
|
|
|
// build the path to the Item |
465
|
|
|
$path = ""; |
466
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
467
|
|
|
foreach ($arbo as $elem) { |
468
|
|
|
if (empty($path)) { |
469
|
|
|
$path = stripslashes($elem->title); |
470
|
|
|
} else { |
471
|
|
|
$path .= " > ".stripslashes($elem->title); |
472
|
|
|
} |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
// prepare output |
476
|
|
|
$json[$data['id']]['id'] = $data['id']; |
477
|
|
|
$json[$data['id']]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
478
|
|
|
$json[$data['id']]['description'] = mb_convert_encoding($data['description'], mb_detect_encoding($data['description']), 'UTF-8'); |
479
|
|
|
$json[$data['id']]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
480
|
|
|
$json[$data['id']]['email'] = mb_convert_encoding($data['email'], mb_detect_encoding($data['email']), 'UTF-8'); |
481
|
|
|
$json[$data['id']]['url'] = mb_convert_encoding($data['url'], mb_detect_encoding($data['url']), 'UTF-8'); |
482
|
|
|
$crypt_pw = cryption($data['pw'], "", "decrypt"); |
483
|
|
|
$json[$data['id']]['pw'] = $crypt_pw['string']; |
484
|
|
|
$json[$data['id']]['folder_id'] = $data['id_tree']; |
485
|
|
|
$json[$data['id']]['path'] = $path; |
486
|
|
|
|
487
|
|
|
$inc++; |
488
|
|
|
} |
489
|
|
|
} elseif ($GLOBALS['request'][1] == "userfolders") { |
490
|
|
|
/* |
491
|
|
|
* READ USER FOLDERS |
492
|
|
|
* Sends back a list of folders |
493
|
|
|
*/ |
494
|
|
|
$json = ""; |
495
|
|
|
$username = $GLOBALS['request'][2]; |
496
|
|
|
if (strcmp($username, "admin") == 0) { |
|
|
|
|
497
|
|
|
// forbid admin access |
498
|
|
|
} |
499
|
|
|
$response = DB::query( |
500
|
|
|
"SELECT fonction_id |
501
|
|
|
FROM ".prefix_table("users")." |
502
|
|
|
WHERE login = %s", |
503
|
|
|
$username |
504
|
|
|
); |
505
|
|
|
if (count($response) === 0) { |
506
|
|
|
rest_error('USER_NOT_EXISTS'); |
507
|
|
|
} |
508
|
|
|
foreach ($response as $data) { |
509
|
|
|
$role_str = $data['fonction_id']; |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
$folder_arr = array(); |
513
|
|
|
$roles = explode(";", $role_str); |
514
|
|
|
$inc = 0; |
515
|
|
|
foreach ($roles as $role) { |
516
|
|
|
$response = DB::query( |
517
|
|
|
"SELECT folder_id, type |
518
|
|
|
FROM ".prefix_table("roles_values")." |
519
|
|
|
WHERE role_id = %i", |
520
|
|
|
$role |
521
|
|
|
); |
522
|
|
|
foreach ($response as $data) { |
523
|
|
|
$folder_id = $data['folder_id']; |
524
|
|
|
if (!array_key_exists($folder_id, $folder_arr)) { |
525
|
|
|
array_push($folder_arr, $folder_id); |
526
|
|
|
|
527
|
|
|
$response2 = DB::queryFirstRow( |
528
|
|
|
"SELECT title, nlevel |
529
|
|
|
FROM ".prefix_table("nested_tree")." |
530
|
|
|
WHERE id = %i", |
531
|
|
|
$folder_id |
532
|
|
|
); |
533
|
|
|
|
534
|
|
|
if (!empty($response2['title'])) { |
535
|
|
|
$json[$folder_id]['id'] = $folder_id; |
536
|
|
|
$json[$folder_id]['title'] = $response2['title']; |
537
|
|
|
$json[$folder_id]['level'] = $response2['nlevel']; |
538
|
|
|
$json[$folder_id]['access_type'] = $data['type']; |
539
|
|
|
$inc++; |
540
|
|
|
} |
541
|
|
|
} |
542
|
|
|
} |
543
|
|
|
} |
544
|
|
|
} elseif ($GLOBALS['request'][1] == "items") { |
545
|
|
|
/* |
546
|
|
|
* READ ITEMS asked |
547
|
|
|
*/ |
548
|
|
|
|
549
|
|
|
// load library |
550
|
|
|
require_once '../sources/SplClassLoader.php'; |
551
|
|
|
//Load Tree |
552
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
553
|
|
|
$tree->register(); |
554
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
555
|
|
|
|
556
|
|
|
// get parameters |
557
|
|
|
$array_items = explode(';', $GLOBALS['request'][2]); |
558
|
|
|
|
559
|
|
|
// check if not empty |
560
|
|
|
if (count($array_items) == 0) { |
561
|
|
|
rest_error('NO_ITEM'); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
// only accepts numeric |
565
|
|
|
foreach ($array_items as $item) { |
566
|
|
|
if (!is_numeric($item)) { |
567
|
|
|
rest_error('ITEM_MALFORMED'); |
568
|
|
|
} |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
$response = DB::query( |
572
|
|
|
"SELECT id,label,login,pw, pw_iv, url, id_tree, description, email |
573
|
|
|
FROM ".prefix_table("items")." |
574
|
|
|
WHERE inactif = %i AND id IN %ls", |
575
|
|
|
"0", |
576
|
|
|
$array_items |
577
|
|
|
); |
578
|
|
|
$inc = 0; |
579
|
|
|
foreach ($response as $data) { |
580
|
|
|
// build the path to the Item |
581
|
|
|
$path = ""; |
582
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
583
|
|
|
foreach ($arbo as $elem) { |
584
|
|
|
if (empty($path)) { |
585
|
|
|
$path = stripslashes($elem->title); |
586
|
|
|
} else { |
587
|
|
|
$path .= " > ".stripslashes($elem->title); |
588
|
|
|
} |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
// prepare output |
592
|
|
|
$json[$inc]['id'] = $data['id']; |
593
|
|
|
$json[$inc]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
594
|
|
|
$json[$inc]['description'] = mb_convert_encoding($data['description'], mb_detect_encoding($data['description']), 'UTF-8'); |
595
|
|
|
$json[$inc]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
596
|
|
|
$json[$inc]['email'] = mb_convert_encoding($data['email'], mb_detect_encoding($data['email']), 'UTF-8'); |
597
|
|
|
$json[$inc]['url'] = mb_convert_encoding($data['url'], mb_detect_encoding($data['url']), 'UTF-8'); |
598
|
|
|
$crypt_pw = cryption($data['pw'], "", "decrypt"); |
599
|
|
|
$json[$inc]['pw'] = $crypt_pw['string']; |
600
|
|
|
$json[$inc]['folder_id'] = $data['id_tree']; |
601
|
|
|
$json[$inc]['path'] = $path; |
602
|
|
|
|
603
|
|
|
$inc++; |
604
|
|
|
} |
605
|
|
|
} elseif ($GLOBALS['request'][1] == "folder_descendants") { |
606
|
|
|
/* |
607
|
|
|
* PRovide full list of folders |
608
|
|
|
* <url to teampass>/api/index.php/read/folder_descendants/<id OR title>/<folder_id or folder_title>?apikey=<valid api key> |
609
|
|
|
*/ |
610
|
|
|
|
611
|
|
|
// get parameters |
612
|
|
|
if (isset($GLOBALS['request'][2]) === true && isset($GLOBALS['request'][3]) === true) { |
613
|
|
|
// load library |
614
|
|
|
require_once '../sources/SplClassLoader.php'; |
615
|
|
|
//Load Tree |
616
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
617
|
|
|
$tree->register(); |
618
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
619
|
|
|
|
620
|
|
|
// get parameters |
621
|
|
|
$parameter_by = $GLOBALS['request'][2]; |
622
|
|
|
$parameter_criteria = $GLOBALS['request'][3]; |
623
|
|
|
|
624
|
|
|
// Check data consistency |
625
|
|
|
if (preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $parameter_by, $result) === false) { |
626
|
|
|
rest_error('MALFORMED'); |
627
|
|
|
} |
628
|
|
|
|
629
|
|
|
if (preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $parameter_criteria, $result) === false) { |
630
|
|
|
rest_error('MALFORMED'); |
631
|
|
|
} |
632
|
|
|
|
633
|
|
|
// Is BY criteria correct |
634
|
|
|
if ($parameter_by !== "id" && $parameter_by !== "title") { |
635
|
|
|
rest_error('EXPECTED_PARAMETER_NOT_PROVIDED'); |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
// If criteria is by Title |
639
|
|
|
// Then search its id first |
640
|
|
|
if ($parameter_by === "title") { |
641
|
|
|
$response = DB::queryFirstRow( |
642
|
|
|
"SELECT id |
643
|
|
|
FROM ".prefix_table("nested_tree")." |
644
|
|
|
WHERE |
645
|
|
|
title LIKE %s", |
646
|
|
|
$parameter_criteria |
647
|
|
|
); |
648
|
|
|
$parameter_criteria = $response['id']; |
649
|
|
|
} |
650
|
|
|
|
651
|
|
|
// List folder descendants |
652
|
|
|
$folders = $tree->getDescendants(intval($parameter_criteria), true, false, false); |
653
|
|
|
if (count($folders) > 0) { |
654
|
|
|
$inc = 0; |
655
|
|
|
foreach ($folders as $folder) { |
656
|
|
|
// Prepare answer |
657
|
|
|
$json[$inc]['id'] = mb_convert_encoding($folder->id, mb_detect_encoding($folder->id), 'UTF-8'); |
658
|
|
|
$json[$inc]['parent_id'] = mb_convert_encoding($folder->parent_id, mb_detect_encoding($folder->parent_id), 'UTF-8'); |
659
|
|
|
$json[$inc]['title'] = mb_convert_encoding(htmlspecialchars_decode($folder->title, ENT_QUOTES), mb_detect_encoding($folder->title), 'UTF-8'); |
660
|
|
|
$json[$inc]['nleft'] = mb_convert_encoding($folder->nleft, mb_detect_encoding($folder->nleft), 'UTF-8'); |
661
|
|
|
$json[$inc]['nright'] = mb_convert_encoding($folder->nright, mb_detect_encoding($folder->nright), 'UTF-8'); |
662
|
|
|
$json[$inc]['nlevel'] = mb_convert_encoding($folder->nlevel, mb_detect_encoding($folder->nlevel), 'UTF-8'); |
663
|
|
|
$json[$inc]['personal'] = mb_convert_encoding($folder->personal_folder, mb_detect_encoding($folder->personal_folder), 'UTF-8'); |
664
|
|
|
|
665
|
|
|
$inc ++; |
666
|
|
|
} |
667
|
|
|
} |
668
|
|
|
} |
669
|
|
|
} |
670
|
|
|
|
671
|
|
|
if (isset($json) && $json) { |
672
|
|
|
echo json_encode($json); |
673
|
|
|
} else { |
674
|
|
|
rest_error('EMPTY'); |
675
|
|
|
} |
676
|
|
|
} elseif ($GLOBALS['request'][0] == "find") { |
677
|
|
|
if ($GLOBALS['request'][1] == "item") { |
678
|
|
|
/* |
679
|
|
|
* FIND ITEMS in FOLDERS |
680
|
|
|
*/ |
681
|
|
|
|
682
|
|
|
// load library |
683
|
|
|
require_once '../sources/SplClassLoader.php'; |
684
|
|
|
//Load Tree |
685
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
686
|
|
|
$tree->register(); |
687
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
688
|
|
|
|
689
|
|
|
// get parameters |
690
|
|
|
$array_category = explode(';', $GLOBALS['request'][2]); |
691
|
|
|
$item = $GLOBALS['request'][3]; |
692
|
|
|
foreach ($array_category as $category) { |
693
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $category, $result)) { |
694
|
|
|
rest_error('CATEGORY_MALFORMED'); |
695
|
|
|
} |
696
|
|
|
} |
697
|
|
|
|
698
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $item, $result)) { |
699
|
|
|
rest_error('ITEM_MALFORMED'); |
700
|
|
|
} elseif (empty($item) || count($array_category) == 0) { |
701
|
|
|
rest_error('MALFORMED'); |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
if (count($array_category) === 0) { |
705
|
|
|
rest_error('NO_CATEGORY'); |
706
|
|
|
} |
707
|
|
|
|
708
|
|
|
DB::debugMode(false); |
709
|
|
|
$response = DB::query( |
710
|
|
|
"SELECT id, label, login, pw, pw_iv, url, id_tree, description, email |
711
|
|
|
FROM ".prefix_table("items")." |
712
|
|
|
WHERE |
713
|
|
|
inactif = %i |
714
|
|
|
AND id_tree IN %ls |
715
|
|
|
AND label LIKE %ss", |
716
|
|
|
"0", |
717
|
|
|
$array_category, |
718
|
|
|
$item |
719
|
|
|
); |
720
|
|
|
$inc = 0; |
721
|
|
|
foreach ($response as $data) { |
722
|
|
|
// build the path to the Item |
723
|
|
|
$path = ""; |
724
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
725
|
|
|
foreach ($arbo as $elem) { |
726
|
|
|
if (empty($path)) { |
727
|
|
|
$path = stripslashes($elem->title); |
728
|
|
|
} else { |
729
|
|
|
$path .= " > ".stripslashes($elem->title); |
730
|
|
|
} |
731
|
|
|
} |
732
|
|
|
|
733
|
|
|
// prepare output |
734
|
|
|
$json[$inc]['id'] = mb_convert_encoding($data['id'], mb_detect_encoding($data['id']), 'UTF-8'); |
735
|
|
|
$json[$inc]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
736
|
|
|
$json[$inc]['description'] = mb_convert_encoding($data['description'], mb_detect_encoding($data['description']), 'UTF-8'); |
737
|
|
|
$json[$inc]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
738
|
|
|
$json[$inc]['email'] = mb_convert_encoding($data['email'], mb_detect_encoding($data['email']), 'UTF-8'); |
739
|
|
|
$json[$inc]['url'] = mb_convert_encoding($data['url'], mb_detect_encoding($data['url']), 'UTF-8'); |
740
|
|
|
$crypt_pw = cryption($data['pw'], "", "decrypt"); |
741
|
|
|
$json[$inc]['pw'] = $crypt_pw['string']; |
742
|
|
|
$json[$inc]['folder_id'] = $data['id_tree']; |
743
|
|
|
$json[$inc]['path'] = $path; |
744
|
|
|
$json[$inc]['status'] = utf8_encode("OK"); |
745
|
|
|
|
746
|
|
|
$inc++; |
747
|
|
|
} |
748
|
|
|
if (isset($json) && $json) { |
749
|
|
|
echo json_encode($json); |
750
|
|
|
} else { |
751
|
|
|
rest_error('EMPTY'); |
752
|
|
|
} |
753
|
|
|
} |
754
|
|
|
} elseif ($GLOBALS['request'][0] == "add") { |
755
|
|
|
if ($GLOBALS['request'][1] == "item") { |
756
|
|
|
// get sent parameters |
757
|
|
|
$params = explode(';', Urlsafe_b64decode($GLOBALS['request'][2])); |
758
|
|
|
if (count($params) != 9) { |
759
|
|
|
rest_error('ITEMBADDEFINITION'); |
760
|
|
|
} |
761
|
|
|
|
762
|
|
|
$item_label = $params[0]; |
763
|
|
|
$item_pwd = $params[1]; |
764
|
|
|
$item_desc = $params[2]; |
765
|
|
|
$item_folder_id = $params[3]; |
766
|
|
|
$item_login = $params[4]; |
767
|
|
|
$item_email = $params[5]; |
768
|
|
|
$item_url = $params[6]; |
769
|
|
|
$item_tags = $params[7]; |
770
|
|
|
$item_anyonecanmodify = $params[8]; |
771
|
|
|
|
772
|
|
|
// do some checks |
773
|
|
|
if (!empty($item_label) && !empty($item_pwd) && !empty($item_folder_id)) { |
774
|
|
|
// Check length |
775
|
|
|
if (strlen($item_pwd) > 50) { |
776
|
|
|
rest_error('PASSWORDTOOLONG'); |
777
|
|
|
} |
778
|
|
|
|
779
|
|
|
// Check Folder ID |
780
|
|
|
DB::query("SELECT * FROM ".prefix_table("nested_tree")." WHERE id = %i", $item_folder_id); |
781
|
|
|
$counter = DB::count(); |
782
|
|
|
if ($counter == 0) { |
783
|
|
|
rest_error('NOSUCHFOLDER'); |
784
|
|
|
} |
785
|
|
|
|
786
|
|
|
// check if element doesn't already exist |
787
|
|
|
$item_duplicate_allowed = getSettingValue("duplicate_item"); |
788
|
|
|
if ($item_duplicate_allowed !== "1") { |
789
|
|
|
DB::query( |
790
|
|
|
"SELECT * |
791
|
|
|
FROM ".prefix_table("items")." |
792
|
|
|
WHERE label = %s AND inactif = %i", |
793
|
|
|
addslashes($item_label), |
794
|
|
|
"0" |
795
|
|
|
); |
796
|
|
|
$counter = DB::count(); |
797
|
|
|
if ($counter != 0) { |
798
|
|
|
$itemExists = 1; |
799
|
|
|
// prevent the error if the label already exists |
800
|
|
|
// so lets just add the time() as a random factor |
801
|
|
|
$item_label .= " (".time().")"; |
802
|
|
|
} else { |
803
|
|
|
$itemExists = 0; |
804
|
|
|
} |
805
|
|
|
} else { |
806
|
|
|
$itemExists = 0; |
807
|
|
|
} |
808
|
|
|
if ($itemExists === 0) { |
809
|
|
|
$encrypt = cryption( |
810
|
|
|
$item_pwd, |
811
|
|
|
"", |
812
|
|
|
"encrypt" |
813
|
|
|
); |
814
|
|
|
if (empty($encrypt['string'])) { |
815
|
|
|
rest_error('PASSWORDEMPTY'); |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
// ADD item |
819
|
|
|
try { |
820
|
|
|
DB::insert( |
821
|
|
|
prefix_table("items"), |
822
|
|
|
array( |
823
|
|
|
"label" => $item_label, |
824
|
|
|
"description" => $item_desc, |
825
|
|
|
'pw' => $encrypt['string'], |
826
|
|
|
'pw_iv' => '', |
827
|
|
|
"email" => $item_email, |
828
|
|
|
"url" => $item_url, |
829
|
|
|
"id_tree" => intval($item_folder_id), |
830
|
|
|
"login" => $item_login, |
831
|
|
|
"inactif" => 0, |
832
|
|
|
"restricted_to" => "", |
833
|
|
|
"perso" => 0, |
834
|
|
|
"anyone_can_modify" => intval($item_anyonecanmodify) |
835
|
|
|
) |
836
|
|
|
); |
837
|
|
|
$newID = DB::InsertId(); |
838
|
|
|
|
839
|
|
|
// log |
840
|
|
|
DB::insert( |
841
|
|
|
prefix_table("log_items"), |
842
|
|
|
array( |
843
|
|
|
"id_item" => $newID, |
844
|
|
|
"date" => time(), |
845
|
|
|
"id_user" => API_USER_ID, |
846
|
|
|
"action" => "at_creation", |
847
|
|
|
"raison" => $api_info['label'] |
848
|
|
|
) |
849
|
|
|
); |
850
|
|
|
|
851
|
|
|
// Add tags |
852
|
|
|
$tags = explode(' ', $item_tags); |
853
|
|
|
foreach ((array) $tags as $tag) { |
854
|
|
|
if (!empty($tag)) { |
855
|
|
|
DB::insert( |
856
|
|
|
prefix_table("tags"), |
857
|
|
|
array( |
858
|
|
|
"item_id" => $newID, |
859
|
|
|
"tag" => strtolower($tag) |
860
|
|
|
) |
861
|
|
|
); |
862
|
|
|
} |
863
|
|
|
} |
864
|
|
|
|
865
|
|
|
// Update CACHE table |
866
|
|
|
DB::insert( |
867
|
|
|
prefix_table("cache"), |
868
|
|
|
array( |
869
|
|
|
"id" => $newID, |
870
|
|
|
"label" => $item_label, |
871
|
|
|
"description" => $item_desc, |
872
|
|
|
"tags" => $item_tags, |
873
|
|
|
"id_tree" => $item_folder_id, |
874
|
|
|
"perso" => "0", |
875
|
|
|
"restricted_to" => "", |
876
|
|
|
"login" => $item_login, |
877
|
|
|
"folder" => "", |
878
|
|
|
"author" => API_USER_ID, |
879
|
|
|
"renewal_period" => "0", |
880
|
|
|
"timestamp" => time(), |
881
|
|
|
"url" => "0" |
882
|
|
|
) |
883
|
|
|
); |
884
|
|
|
|
885
|
|
|
echo '{"status":"item added" , "new_item_id" : "'.$newID.'"}'; |
886
|
|
|
} catch (PDOException $ex) { |
887
|
|
|
echo '<br />'.$ex->getMessage(); |
888
|
|
|
} |
889
|
|
|
} else { |
890
|
|
|
rest_error('ITEMEXISTS'); |
891
|
|
|
} |
892
|
|
|
} else { |
893
|
|
|
rest_error('ITEMMISSINGDATA'); |
894
|
|
|
} |
895
|
|
|
} elseif ($GLOBALS['request'][1] == "user") { |
896
|
|
|
/* |
897
|
|
|
* Case where a new user has to be added |
898
|
|
|
* |
899
|
|
|
* Expected call format: .../api/index.php/add/user/<LOGIN>;<NAME>;<LASTNAME>;<PASSWORD>;<EMAIL>;<ADMINISTRATEDBY>;<READ_ONLY>;<ROLE1,ROLE2,...>;<IS_ADMIN>;<ISMANAGER>;<PERSONAL_FOLDER>?apikey=<VALID API KEY> |
900
|
|
|
* with: |
901
|
|
|
* for READ_ONLY, IS_ADMIN, IS_MANAGER, PERSONAL_FOLDER, accepted value is 1 for TRUE and 0 for FALSE |
902
|
|
|
* for ADMINISTRATEDBY and ROLE1, accepted value is the real label (not the IDs) |
903
|
|
|
* |
904
|
|
|
* Example: /api/index.php/add/user/U4;Nils;Laumaille;test;[email protected];Users;0;Managers,Users;0;1;1?apikey=sae6iekahxiseL3viShoo0chahc1ievei8aequi |
905
|
|
|
* |
906
|
|
|
*/ |
907
|
|
|
|
908
|
|
|
// get user definition |
909
|
|
|
$array_user = explode(';', Urlsafe_b64decode($GLOBALS['request'][2])); |
910
|
|
|
if (count($array_user) != 11) { |
911
|
|
|
rest_error('USERBADDEFINITION'); |
912
|
|
|
} |
913
|
|
|
|
914
|
|
|
$login = $array_user[0]; |
915
|
|
|
$name = $array_user[1]; |
916
|
|
|
$lastname = $array_user[2]; |
917
|
|
|
$password = $array_user[3]; |
918
|
|
|
$email = $array_user[4]; |
919
|
|
|
$adminby = urldecode($array_user[5]); |
920
|
|
|
$isreadonly = urldecode($array_user[6]); |
921
|
|
|
$roles = urldecode($array_user[7]); |
922
|
|
|
$isadmin = $array_user[8]; |
923
|
|
|
$ismanager = $array_user[9]; |
924
|
|
|
$haspf = $array_user[10]; |
925
|
|
|
|
926
|
|
|
// Empty user |
927
|
|
|
if (mysqli_escape_string($link, htmlspecialchars_decode($login)) == "") { |
928
|
|
|
rest_error('USERLOGINEMPTY'); |
929
|
|
|
} |
930
|
|
|
// Check if user already exists |
931
|
|
|
$data = DB::query( |
932
|
|
|
"SELECT id, fonction_id, groupes_interdits, groupes_visibles |
933
|
|
|
FROM ".prefix_table("users")." |
934
|
|
|
WHERE login LIKE %ss", |
935
|
|
|
mysqli_escape_string($link, stripslashes($login)) |
936
|
|
|
); |
937
|
|
|
|
938
|
|
|
if (DB::count() == 0) { |
939
|
|
|
try { |
940
|
|
|
// find AdminRole code in DB |
941
|
|
|
$resRole = DB::queryFirstRow( |
942
|
|
|
"SELECT id |
943
|
|
|
FROM ".prefix_table("roles_title")." |
944
|
|
|
WHERE title LIKE %ss", |
945
|
|
|
mysqli_escape_string($link, stripslashes($adminby)) |
946
|
|
|
); |
947
|
|
|
|
948
|
|
|
// get default language |
949
|
|
|
$lang = DB::queryFirstRow( |
950
|
|
|
"SELECT `valeur` |
951
|
|
|
FROM ".prefix_table("misc")." |
952
|
|
|
WHERE type = %s AND intitule = %s", |
953
|
|
|
"admin", |
954
|
|
|
"default_language" |
955
|
|
|
); |
956
|
|
|
|
957
|
|
|
// prepare roles list |
958
|
|
|
$rolesList = ""; |
959
|
|
|
foreach (explode(',', $roles) as $role) { |
960
|
|
|
$tmp = DB::queryFirstRow( |
961
|
|
|
"SELECT `id` |
962
|
|
|
FROM ".prefix_table("roles_title")." |
963
|
|
|
WHERE title = %s", |
964
|
|
|
$role |
965
|
|
|
); |
966
|
|
|
if (empty($rolesList)) { |
967
|
|
|
$rolesList = $tmp['id']; |
968
|
|
|
} else { |
969
|
|
|
$rolesList .= ";".$tmp['id']; |
970
|
|
|
} |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
// Add user in DB |
974
|
|
|
DB::insert( |
975
|
|
|
prefix_table("users"), |
976
|
|
|
array( |
977
|
|
|
'login' => $login, |
978
|
|
|
'name' => $name, |
979
|
|
|
'lastname' => $lastname, |
980
|
|
|
'pw' => bCrypt(stringUtf8Decode($password), COST), |
981
|
|
|
'email' => $email, |
982
|
|
|
'admin' => intval($isadmin), |
983
|
|
|
'gestionnaire' => intval($ismanager), |
984
|
|
|
'read_only' => intval($isreadonly), |
985
|
|
|
'personal_folder' => intval($haspf), |
986
|
|
|
'user_language' => $lang['valeur'], |
987
|
|
|
'fonction_id' => $rolesList, |
988
|
|
|
'groupes_interdits' => '0', |
989
|
|
|
'groupes_visibles' => '0', |
990
|
|
|
'isAdministratedByRole' => empty($resRole) ? '0' : $resRole['id'] |
991
|
|
|
) |
992
|
|
|
); |
993
|
|
|
$new_user_id = DB::insertId(); |
994
|
|
|
// Create personnal folder |
995
|
|
|
if (intval($haspf) === 1) { |
996
|
|
|
DB::insert( |
997
|
|
|
prefix_table("nested_tree"), |
998
|
|
|
array( |
999
|
|
|
'parent_id' => '0', |
1000
|
|
|
'title' => $new_user_id, |
1001
|
|
|
'bloquer_creation' => '0', |
1002
|
|
|
'bloquer_modification' => '0', |
1003
|
|
|
'personal_folder' => '1' |
1004
|
|
|
) |
1005
|
|
|
); |
1006
|
|
|
} |
1007
|
|
|
|
1008
|
|
|
// load settings |
1009
|
|
|
loadSettings(); |
1010
|
|
|
|
1011
|
|
|
// Send email to new user |
1012
|
|
|
@sendEmail( |
|
|
|
|
1013
|
|
|
$LANG['email_subject_new_user'], |
|
|
|
|
1014
|
|
|
str_replace( |
1015
|
|
|
array('#tp_login#', '#tp_pw#', '#tp_link#'), |
1016
|
|
|
array(" ".addslashes($login), addslashes($password), $SETTINGS['email_server_url']), |
1017
|
|
|
$LANG['email_new_user_mail'] |
1018
|
|
|
), |
1019
|
|
|
$email, |
1020
|
|
|
$LANG, |
1021
|
|
|
$SETTINGS |
1022
|
|
|
); |
1023
|
|
|
|
1024
|
|
|
// update LOG |
1025
|
|
|
logEvents('user_mngt', 'at_user_added', 'api - '.$GLOBALS['apikey'], $new_user_id, ""); |
1026
|
|
|
|
1027
|
|
|
echo '{"status":"user added"}'; |
1028
|
|
|
} catch (PDOException $ex) { |
1029
|
|
|
echo '<br />'.$ex->getMessage(); |
1030
|
|
|
} |
1031
|
|
|
} else { |
1032
|
|
|
rest_error('USERALREADYEXISTS'); |
1033
|
|
|
} |
1034
|
|
|
} elseif ($GLOBALS['request'][1] == "folder") { |
1035
|
|
|
/* |
1036
|
|
|
* ADDING A FOLDER |
1037
|
|
|
* <url to teampass>/api/index.php/add/folder/<title>;<complexity_level>;<parent_id>;<renewal_period>;<personal>?apikey=<valid api key> |
1038
|
|
|
* http://localhost/teampass/api/index.php/add/folder/Import from API;0;38;0;0?apikey=piesae7ahghae1iiP9ohPhaefaideeThohgh1te |
1039
|
|
|
*/ |
1040
|
|
|
if (!empty($GLOBALS['request'][2])) { |
1041
|
|
|
// get sent parameters |
1042
|
|
|
$params = explode(';', Urlsafe_b64decode($GLOBALS['request'][2])); |
1043
|
|
|
|
1044
|
|
|
if (empty($params[0]) === false && (intval($params[1]) >= 0 && intval($params[1]) <= 1000)) { |
1045
|
|
|
if (empty($params[3])) { |
1046
|
|
|
$params[3] = 0; |
1047
|
|
|
} |
1048
|
|
|
if (empty($params[4])) { |
1049
|
|
|
$params[4] = 0; |
1050
|
|
|
} |
1051
|
|
|
if (empty($params[2])) { |
1052
|
|
|
rest_error('NO_DESTINATION_FOLDER'); |
1053
|
|
|
} |
1054
|
|
|
if ($params[2] < 0) { |
1055
|
|
|
rest_error('NO_DATA_EXIST'); |
1056
|
|
|
} |
1057
|
|
|
|
1058
|
|
|
//Check if title doesn't contains html codes |
1059
|
|
|
if (preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $params[0], $out)) { |
1060
|
|
|
rest_error('HTML_CODES_NOT_ALLOWED'); |
1061
|
|
|
} |
1062
|
|
|
|
1063
|
|
|
// check if title is numeric |
1064
|
|
|
if (is_numeric($params[0]) === true) { |
1065
|
|
|
rest_error('TITLE_ONLY_WITH_NUMBERS'); |
1066
|
|
|
} |
1067
|
|
|
|
1068
|
|
|
//Check if duplicate folders name are allowed |
1069
|
|
|
$data = DB::queryfirstrow( |
1070
|
|
|
"SELECT valeur |
1071
|
|
|
FROM ".prefix_table("misc")." |
1072
|
|
|
WHERE type = %s AND intitule = %s", |
1073
|
|
|
"admin", |
1074
|
|
|
"duplicate_folder" |
1075
|
|
|
); |
1076
|
|
|
// if valeur = 0 then duplicate folders not allowed |
1077
|
|
|
if ($data['valeur'] === '0') { |
1078
|
|
|
DB::query( |
1079
|
|
|
"SELECT * |
1080
|
|
|
FROM ".prefix_table("nested_tree")." |
1081
|
|
|
WHERE title = %s", |
1082
|
|
|
$params[0] |
1083
|
|
|
); |
1084
|
|
|
$counter = DB::count(); |
1085
|
|
|
if ($counter != 0) { |
1086
|
|
|
rest_error('ALREADY_EXISTS'); |
1087
|
|
|
} |
1088
|
|
|
} |
1089
|
|
|
|
1090
|
|
|
//check if parent folder is personal |
1091
|
|
|
$data = DB::queryfirstrow( |
1092
|
|
|
"SELECT personal_folder |
1093
|
|
|
FROM ".prefix_table("nested_tree")." |
1094
|
|
|
WHERE id = %i", |
1095
|
|
|
$params[2] |
1096
|
|
|
); |
1097
|
|
|
if ($data['personal_folder'] === "1") { |
1098
|
|
|
$isPersonal = 1; |
1099
|
|
|
} else { |
1100
|
|
|
if ($params[4] === 1) { |
|
|
|
|
1101
|
|
|
$isPersonal = 1; |
1102
|
|
|
} else { |
1103
|
|
|
$isPersonal = 0; |
1104
|
|
|
} |
1105
|
|
|
|
1106
|
|
|
// get complexity level for this folder |
1107
|
|
|
$data = DB::queryfirstrow( |
1108
|
|
|
"SELECT valeur |
1109
|
|
|
FROM ".prefix_table("misc")." |
1110
|
|
|
WHERE intitule = %i AND type = %s", |
1111
|
|
|
$params[2], |
1112
|
|
|
"complex" |
1113
|
|
|
); |
1114
|
|
|
if (intval($params[1]) < intval($data['valeur'])) { |
1115
|
|
|
rest_error('COMPLEXICITY_LEVEL_NOT_REACHED'); |
1116
|
|
|
} |
1117
|
|
|
} |
1118
|
|
|
|
1119
|
|
|
try { |
1120
|
|
|
//create folder |
1121
|
|
|
DB::insert( |
1122
|
|
|
prefix_table("nested_tree"), |
1123
|
|
|
array( |
1124
|
|
|
'parent_id' => $params[2], |
1125
|
|
|
'title' => $params[0], |
1126
|
|
|
'personal_folder' => $isPersonal, |
1127
|
|
|
'renewal_period' => $params[3], |
1128
|
|
|
'bloquer_creation' => '0', |
1129
|
|
|
'bloquer_modification' => '0' |
1130
|
|
|
) |
1131
|
|
|
); |
1132
|
|
|
$newId = DB::insertId(); |
1133
|
|
|
|
1134
|
|
|
//Add complexity |
1135
|
|
|
DB::insert( |
1136
|
|
|
prefix_table("misc"), |
1137
|
|
|
array( |
1138
|
|
|
'type' => 'complex', |
1139
|
|
|
'intitule' => $newId, |
1140
|
|
|
'valeur' => $params[1] |
1141
|
|
|
) |
1142
|
|
|
); |
1143
|
|
|
|
1144
|
|
|
// Run nested tree update |
1145
|
|
|
require_once '../sources/SplClassLoader.php'; |
1146
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
1147
|
|
|
$tree->register(); |
1148
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
1149
|
|
|
$tree->rebuild(); |
1150
|
|
|
|
1151
|
|
|
// We need to allocate the same access rights as the parent |
1152
|
|
|
// We will considere that if created as root then its rights must be set through the GUI |
1153
|
|
|
$ret = DB::query( |
1154
|
|
|
"SELECT role_id, type |
1155
|
|
|
FROM ".prefix_table("roles_values")." |
1156
|
|
|
WHERE folder_id = %i", |
1157
|
|
|
$params[2] |
1158
|
|
|
); |
1159
|
|
|
foreach ($ret as $entry) { |
1160
|
|
|
DB::insert( |
1161
|
|
|
prefix_table("roles_values"), |
1162
|
|
|
array( |
1163
|
|
|
'role_id' => $entry['role_id'], |
1164
|
|
|
'folder_id' => $newId, |
1165
|
|
|
'type' => $entry['type'] |
1166
|
|
|
) |
1167
|
|
|
); |
1168
|
|
|
} |
1169
|
|
|
|
1170
|
|
|
echo '{"status":"folder created" , "new_folder_id":"'.$newId.'"}'; |
1171
|
|
|
} catch (PDOException $ex) { |
1172
|
|
|
echo '<br />'.$ex->getMessage(); |
1173
|
|
|
} |
1174
|
|
|
} else { |
1175
|
|
|
rest_error('NO_DATA_EXIST'); |
1176
|
|
|
} |
1177
|
|
|
} else { |
1178
|
|
|
rest_error('SET_NO_DATA'); |
1179
|
|
|
} |
1180
|
|
|
} |
1181
|
|
|
} elseif ($GLOBALS['request'][0] == "update") { |
1182
|
|
|
/* |
1183
|
|
|
* Section dedicated for UPDATING |
1184
|
|
|
*/ |
1185
|
|
|
if ($GLOBALS['request'][1] == "item") { |
1186
|
|
|
/* |
1187
|
|
|
* Expected call format: .../api/index.php/update/item/<item_id>/<label>;<password>;<description>;<folder_id>;<login>;<email>;<url>;<tags>;<any one can modify>?apikey=<VALID API KEY> |
1188
|
|
|
*/ |
1189
|
|
|
if ($GLOBALS['request'][2] !== "" && is_numeric($GLOBALS['request'][2])) { |
1190
|
|
|
// get sent parameters |
1191
|
|
|
$params = explode(';', Urlsafe_b64decode($GLOBALS['request'][3])); |
1192
|
|
|
|
1193
|
|
|
if (!empty($params[0]) && !empty($params[1]) && !empty($params[3])) { |
1194
|
|
|
// Check length |
1195
|
|
|
if (strlen($params[1]) > 50) { |
1196
|
|
|
rest_error('PASSWORDTOOLONG'); |
1197
|
|
|
} |
1198
|
|
|
|
1199
|
|
|
// Check Folder ID |
1200
|
|
|
DB::query( |
1201
|
|
|
"SELECT * |
1202
|
|
|
FROM ".prefix_table("nested_tree")." |
1203
|
|
|
WHERE id = %i", |
1204
|
|
|
$params[3] |
1205
|
|
|
); |
1206
|
|
|
$counter = DB::count(); |
1207
|
|
|
if ($counter == 0) { |
1208
|
|
|
rest_error('NOSUCHFOLDER'); |
1209
|
|
|
} |
1210
|
|
|
|
1211
|
|
|
// check if item exists |
1212
|
|
|
DB::query( |
1213
|
|
|
"SELECT * |
1214
|
|
|
FROM ".prefix_table("items")." |
1215
|
|
|
WHERE id = %i", |
1216
|
|
|
$GLOBALS['request'][2] |
1217
|
|
|
); |
1218
|
|
|
$counter = DB::count(); |
1219
|
|
|
if ($counter > 0) { |
1220
|
|
|
// encrypt pwd |
1221
|
|
|
$encrypt = cryption( |
1222
|
|
|
$params[1], |
1223
|
|
|
"", |
1224
|
|
|
"encrypt" |
1225
|
|
|
); |
1226
|
|
|
if (empty($encrypt['string'])) { |
1227
|
|
|
rest_error('PASSWORDEMPTY'); |
1228
|
|
|
} |
1229
|
|
|
|
1230
|
|
|
// ADD item |
1231
|
|
|
try { |
1232
|
|
|
DB::update( |
1233
|
|
|
prefix_table("items"), |
1234
|
|
|
array( |
1235
|
|
|
"label" => $params[0], |
1236
|
|
|
"description" => $params[2], |
1237
|
|
|
'pw' => $encrypt['string'], |
1238
|
|
|
'pw_iv' => '', |
1239
|
|
|
"email" => $params[5], |
1240
|
|
|
"url" => $params[6], |
1241
|
|
|
"id_tree" => intval($params[3]), |
1242
|
|
|
"login" => $params[4], |
1243
|
|
|
"anyone_can_modify" => intval($params[8]) |
1244
|
|
|
), |
1245
|
|
|
"id = %i", |
1246
|
|
|
$GLOBALS['request'][2] |
1247
|
|
|
); |
1248
|
|
|
|
1249
|
|
|
// log |
1250
|
|
|
DB::insert( |
1251
|
|
|
prefix_table("log_items"), |
1252
|
|
|
array( |
1253
|
|
|
"id_item" => $GLOBALS['request'][2], |
1254
|
|
|
"date" => time(), |
1255
|
|
|
"id_user" => API_USER_ID, |
1256
|
|
|
"action" => "at_modification" |
1257
|
|
|
) |
1258
|
|
|
); |
1259
|
|
|
|
1260
|
|
|
// Add tags |
1261
|
|
|
$tags = explode(' ', $params[7]); |
1262
|
|
|
foreach ((array) $tags as $tag) { |
1263
|
|
|
if (!empty($tag)) { |
1264
|
|
|
// check if already exists |
1265
|
|
|
DB::query( |
1266
|
|
|
"SELECT * |
1267
|
|
|
FROM ".prefix_table("tags")." |
1268
|
|
|
WHERE tag = %s AND item_id = %i", |
1269
|
|
|
strtolower($tag), |
1270
|
|
|
$GLOBALS['request'][2] |
1271
|
|
|
); |
1272
|
|
|
$counter = DB::count(); |
1273
|
|
|
if ($counter === 0) { |
1274
|
|
|
DB::insert( |
1275
|
|
|
prefix_table("tags"), |
1276
|
|
|
array( |
1277
|
|
|
"item_id" => $GLOBALS['request'][2], |
1278
|
|
|
"tag" => strtolower($tag) |
1279
|
|
|
) |
1280
|
|
|
); |
1281
|
|
|
} |
1282
|
|
|
} |
1283
|
|
|
} |
1284
|
|
|
|
1285
|
|
|
// Update CACHE table |
1286
|
|
|
DB::update( |
1287
|
|
|
prefix_table("cache"), |
1288
|
|
|
array( |
1289
|
|
|
"label" => $params[0], |
1290
|
|
|
"description" => $params[2], |
1291
|
|
|
"tags" => $params[7], |
1292
|
|
|
"id_tree" => intval($params[3]), |
1293
|
|
|
"perso" => "0", |
1294
|
|
|
"restricted_to" => "", |
1295
|
|
|
"login" => $params[4], |
1296
|
|
|
"folder" => "", |
1297
|
|
|
"author" => API_USER_ID, |
1298
|
|
|
"renewal_period" => "0", |
1299
|
|
|
"timestamp" => time(), |
1300
|
|
|
"url" => $params[6], |
1301
|
|
|
), |
1302
|
|
|
"id = %i", |
1303
|
|
|
$GLOBALS['request'][2] |
1304
|
|
|
); |
1305
|
|
|
|
1306
|
|
|
echo '{"status":"item updated"}'; |
1307
|
|
|
} catch (PDOException $ex) { |
1308
|
|
|
echo '<br />'.$ex->getMessage(); |
1309
|
|
|
} |
1310
|
|
|
} else { |
1311
|
|
|
rest_error('NO_DATA_EXIST'); |
1312
|
|
|
} |
1313
|
|
|
} else { |
1314
|
|
|
rest_error('ITEMMISSINGDATA'); |
1315
|
|
|
} |
1316
|
|
|
} else { |
1317
|
|
|
rest_error('NO_ITEM'); |
1318
|
|
|
} |
1319
|
|
|
} elseif ($GLOBALS['request'][1] == "folder") { |
1320
|
|
|
/* |
1321
|
|
|
* UPDATING A FOLDER |
1322
|
|
|
* <url to teampass>/api/index.php/update/folder/<folder_id>/<title>;<complexity_level>;<renewal_period>?apikey=<valid api key> |
1323
|
|
|
*/ |
1324
|
|
|
if ($GLOBALS['request'][2] !== "" && is_numeric($GLOBALS['request'][2])) { |
1325
|
|
|
// get sent parameters |
1326
|
|
|
$params = explode(';', Urlsafe_b64decode($GLOBALS['request'][3])); |
1327
|
|
|
|
1328
|
|
|
if (!empty($params[0])) { |
1329
|
|
|
if ($params[1] < 0) { |
1330
|
|
|
rest_error('NO_DATA_EXIST'); |
1331
|
|
|
} |
1332
|
|
|
if (empty($params[2])) { |
1333
|
|
|
$params[2] = 0; |
1334
|
|
|
} |
1335
|
|
|
|
1336
|
|
|
// check if folder exists and get folder data |
1337
|
|
|
$data_folder = DB::queryfirstrow( |
1338
|
|
|
"SELECT * |
1339
|
|
|
FROM ".prefix_table("nested_tree")." |
1340
|
|
|
WHERE id = %s", |
1341
|
|
|
$GLOBALS['request'][2] |
1342
|
|
|
); |
1343
|
|
|
$counter = DB::count(); |
1344
|
|
|
if ($counter === 0) { |
1345
|
|
|
rest_error('NO_DATA_EXIST'); |
1346
|
|
|
} |
1347
|
|
|
|
1348
|
|
|
//Check if title doesn't contains html codes |
1349
|
|
|
if (preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $params[0], $out)) { |
1350
|
|
|
rest_error('HTML_CODES_NOT_ALLOWED'); |
1351
|
|
|
} |
1352
|
|
|
|
1353
|
|
|
// check if title is numeric |
1354
|
|
|
if (is_numeric($params[0]) === true) { |
1355
|
|
|
rest_error('TITLE_ONLY_WITH_NUMBERS'); |
1356
|
|
|
} |
1357
|
|
|
|
1358
|
|
|
// get complexity level for this folder |
1359
|
|
|
$data = DB::queryfirstrow( |
1360
|
|
|
"SELECT valeur |
1361
|
|
|
FROM ".prefix_table("misc")." |
1362
|
|
|
WHERE intitule = %i AND type = %s", |
1363
|
|
|
$data_folder['parent_id'], |
1364
|
|
|
"complex" |
1365
|
|
|
); |
1366
|
|
|
if (intval($params[1]) < intval($data['valeur'])) { |
1367
|
|
|
rest_error('COMPLEXICITY_LEVEL_NOT_REACHED'); |
1368
|
|
|
} |
1369
|
|
|
|
1370
|
|
|
try { |
1371
|
|
|
DB::update( |
1372
|
|
|
prefix_table("nested_tree"), |
1373
|
|
|
array( |
1374
|
|
|
'parent_id' => $data_folder['parent_id'], |
1375
|
|
|
'title' => $params[0], |
1376
|
|
|
'personal_folder' => 0, |
1377
|
|
|
'renewal_period' => $params[2], |
1378
|
|
|
'bloquer_creation' => '0', |
1379
|
|
|
'bloquer_modification' => '0' |
1380
|
|
|
), |
1381
|
|
|
"id = %i", |
1382
|
|
|
$GLOBALS['request'][2] |
1383
|
|
|
); |
1384
|
|
|
|
1385
|
|
|
//Add complexity |
1386
|
|
|
DB::update( |
1387
|
|
|
prefix_table("misc"), |
1388
|
|
|
array( |
1389
|
|
|
'valeur' => $params[1] |
1390
|
|
|
), |
1391
|
|
|
"intitule = %s AND type = %s", |
1392
|
|
|
$GLOBALS['request'][2], |
1393
|
|
|
"complex" |
1394
|
|
|
); |
1395
|
|
|
|
1396
|
|
|
// Run nested tree update |
1397
|
|
|
require_once '../sources/SplClassLoader.php'; |
1398
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
1399
|
|
|
$tree->register(); |
1400
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
1401
|
|
|
$tree->rebuild(); |
1402
|
|
|
|
1403
|
|
|
echo '{"status":"folder updated"}'; |
1404
|
|
|
} catch (PDOException $ex) { |
1405
|
|
|
echo '<br />'.$ex->getMessage(); |
1406
|
|
|
} |
1407
|
|
|
} else { |
1408
|
|
|
rest_error('ITEMMISSINGDATA'); |
1409
|
|
|
} |
1410
|
|
|
} else { |
1411
|
|
|
rest_error('NO_ITEM'); |
1412
|
|
|
} |
1413
|
|
|
} elseif ($GLOBALS['request'][1] == "user") { |
1414
|
|
|
/* |
1415
|
|
|
* Case where a user has to be updated |
1416
|
|
|
* |
1417
|
|
|
* Expected call format: .../api/index.php/updated/user/<LOGIN>;<NAME>;<LASTNAME>;<PASSWORD>;<EMAIL>;<ADMINISTRATEDBY>;<READ_ONLY>;<ROLE1,ROLE2,...>;<IS_ADMIN>;<ISMANAGER>;<PERSONAL_FOLDER>?apikey=<VALID API KEY> |
1418
|
|
|
* with: |
1419
|
|
|
* for READ_ONLY, IS_ADMIN, IS_MANAGER, PERSONAL_FOLDER, accepted value is 1 for TRUE and 0 for FALSE |
1420
|
|
|
* for ADMINISTRATEDBY and ROLE1, accepted value is the real label (not the IDs) |
1421
|
|
|
* |
1422
|
|
|
* Example: /api/index.php/update/user/U4;Nils;Laumaille;test;[email protected];Users;0;Managers,Users;0;1;1?apikey=sae6iekahxiseL3viShoo0chahc1ievei8aequi |
1423
|
|
|
* |
1424
|
|
|
*/ |
1425
|
|
|
|
1426
|
|
|
// get user definition |
1427
|
|
|
$array_user = explode(';', Urlsafe_b64decode($GLOBALS['request'][2])); |
1428
|
|
|
if (count($array_user) != 11) { |
1429
|
|
|
rest_error('USERBADDEFINITION'); |
1430
|
|
|
} |
1431
|
|
|
|
1432
|
|
|
$login = $array_user[0]; |
1433
|
|
|
$name = $array_user[1]; |
1434
|
|
|
$lastname = $array_user[2]; |
1435
|
|
|
$password = $array_user[3]; |
1436
|
|
|
$email = $array_user[4]; |
1437
|
|
|
$adminby = urldecode($array_user[5]); |
1438
|
|
|
$isreadonly = urldecode($array_user[6]); |
1439
|
|
|
$roles = urldecode($array_user[7]); |
1440
|
|
|
$isadmin = $array_user[8]; |
1441
|
|
|
$ismanager = $array_user[9]; |
1442
|
|
|
$haspf = $array_user[10]; |
1443
|
|
|
|
1444
|
|
|
// Empty user |
1445
|
|
|
if (mysqli_escape_string($link, htmlspecialchars_decode($login)) == "") { |
1446
|
|
|
rest_error('USERLOGINEMPTY'); |
1447
|
|
|
} |
1448
|
|
|
// Check if user already exists |
1449
|
|
|
$data = DB::query( |
1450
|
|
|
"SELECT id, fonction_id, groupes_interdits, groupes_visibles, personal_folder |
1451
|
|
|
FROM ".prefix_table("users")." |
1452
|
|
|
WHERE login LIKE %ss", |
1453
|
|
|
mysqli_escape_string($link, stripslashes($login)) |
1454
|
|
|
); |
1455
|
|
|
|
1456
|
|
|
if (DB::count() === 1) { |
1457
|
|
|
try { |
1458
|
|
|
// find AdminRole code in DB |
1459
|
|
|
$resRole = DB::queryFirstRow( |
1460
|
|
|
"SELECT id |
1461
|
|
|
FROM ".prefix_table("roles_title")." |
1462
|
|
|
WHERE title LIKE %ss", |
1463
|
|
|
mysqli_escape_string($link, stripslashes($adminby)) |
1464
|
|
|
); |
1465
|
|
|
|
1466
|
|
|
|
1467
|
|
|
// get default language |
1468
|
|
|
$lang = DB::queryFirstRow( |
1469
|
|
|
"SELECT `valeur` |
1470
|
|
|
FROM ".prefix_table("misc")." |
1471
|
|
|
WHERE type = %s AND intitule = %s", |
1472
|
|
|
"admin", |
1473
|
|
|
"default_language" |
1474
|
|
|
); |
1475
|
|
|
|
1476
|
|
|
// prepare roles list |
1477
|
|
|
$rolesList = ""; |
1478
|
|
|
foreach (explode(',', $roles) as $role) { |
1479
|
|
|
$tmp = DB::queryFirstRow( |
1480
|
|
|
"SELECT `id` |
1481
|
|
|
FROM ".prefix_table("roles_title")." |
1482
|
|
|
WHERE title = %s", |
1483
|
|
|
$role |
1484
|
|
|
); |
1485
|
|
|
if (empty($rolesList)) { |
1486
|
|
|
$rolesList = $tmp['id']; |
1487
|
|
|
} else { |
1488
|
|
|
$rolesList .= ";".$tmp['id']; |
1489
|
|
|
} |
1490
|
|
|
} |
1491
|
|
|
|
1492
|
|
|
// Update user in DB |
1493
|
|
|
DB::update( |
1494
|
|
|
prefix_table("users"), |
1495
|
|
|
array( |
1496
|
|
|
'login' => $login, |
1497
|
|
|
'name' => $name, |
1498
|
|
|
'lastname' => $lastname, |
1499
|
|
|
'pw' => bCrypt(stringUtf8Decode($password), COST), |
1500
|
|
|
'email' => $email, |
1501
|
|
|
'admin' => intval($isadmin), |
1502
|
|
|
'gestionnaire' => intval($ismanager), |
1503
|
|
|
'read_only' => intval($isreadonly), |
1504
|
|
|
'personal_folder' => intval($haspf), |
1505
|
|
|
'user_language' => $lang['valeur'], |
1506
|
|
|
'fonction_id' => $rolesList, |
1507
|
|
|
'groupes_interdits' => '0', |
1508
|
|
|
'groupes_visibles' => '0', |
1509
|
|
|
'isAdministratedByRole' => empty($resRole) ? '0' : $resRole['id'] |
1510
|
|
|
), |
1511
|
|
|
"id = %i", |
1512
|
|
|
$data['id'] |
1513
|
|
|
); |
1514
|
|
|
|
1515
|
|
|
// Create personnal folder |
1516
|
|
|
if (intval($haspf) === 1) { |
1517
|
|
|
DB::query( |
1518
|
|
|
"SELECT id |
1519
|
|
|
FROM ".prefix_table("nested_tree")." |
1520
|
|
|
WHERE title = %s", |
1521
|
|
|
$data['id'] |
1522
|
|
|
); |
1523
|
|
|
if (DB::count() === 0) { |
1524
|
|
|
DB::insert( |
1525
|
|
|
prefix_table("nested_tree"), |
1526
|
|
|
array( |
1527
|
|
|
'parent_id' => '0', |
1528
|
|
|
'title' => $data['id'], |
1529
|
|
|
'bloquer_creation' => '0', |
1530
|
|
|
'bloquer_modification' => '0', |
1531
|
|
|
'personal_folder' => '1' |
1532
|
|
|
) |
1533
|
|
|
); |
1534
|
|
|
} |
1535
|
|
|
} |
1536
|
|
|
|
1537
|
|
|
// load settings |
1538
|
|
|
loadSettings(); |
1539
|
|
|
|
1540
|
|
|
// update LOG |
1541
|
|
|
logEvents('user_mngt', 'at_user_updated', 'api - '.$GLOBALS['apikey'], $data['id'], ""); |
1542
|
|
|
|
1543
|
|
|
echo '{"status":"user added"}'; |
1544
|
|
|
} catch (PDOException $ex) { |
1545
|
|
|
echo '<br />'.$ex->getMessage(); |
1546
|
|
|
} |
1547
|
|
|
} else { |
1548
|
|
|
rest_error('USER_NOT_EXISTS'); |
1549
|
|
|
} |
1550
|
|
|
} |
1551
|
|
|
} elseif ($GLOBALS['request'][0] == "auth") { |
1552
|
|
|
/* |
1553
|
|
|
** FOR SECURITY PURPOSE, it is mandatory to use SSL to connect your teampass instance. The user password is not encrypted! |
1554
|
|
|
** |
1555
|
|
|
** |
1556
|
|
|
** Expected call format: .../api/index.php/auth/<PROTOCOL>/<URL>/<login>/<password>?apikey=<VALID API KEY> |
1557
|
|
|
** Example: https://127.0.0.1/teampass/api/index.php/auth/http/www.zadig-tge.adp.com/U1/test/76?apikey=chahthait5Aidood6johh6Avufieb6ohpaixain |
1558
|
|
|
** RESTRICTIONS: |
1559
|
|
|
** - <PROTOCOL> ==> http|https|ftp|... |
1560
|
|
|
** - <URL> ==> encode URL without protocol (example: http://www.teampass.net becomes www.teampass.net) |
1561
|
|
|
** - <login> ==> user's login |
1562
|
|
|
** - <password> ==> currently clear password |
1563
|
|
|
** |
1564
|
|
|
** RETURNED ANSWER: |
1565
|
|
|
** - format sent back is JSON |
1566
|
|
|
** - Example: {"<item_id>":{"label":"<pass#1>","login":"<login#1>","pw":"<pwd#1>"},"<item_id>":{"label":"<pass#2>","login":"<login#2>","pw":"<pwd#2>"}} |
1567
|
|
|
** |
1568
|
|
|
*/ |
1569
|
|
|
// get user credentials |
1570
|
|
|
if (isset($GLOBALS['request'][3]) && isset($GLOBALS['request'][4])) { |
1571
|
|
|
// get url |
1572
|
|
|
if (isset($GLOBALS['request'][1]) && isset($GLOBALS['request'][2])) { |
1573
|
|
|
// is user granted? |
1574
|
|
|
$userData = DB::queryFirstRow( |
1575
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id` |
1576
|
|
|
FROM ".prefix_table("users")." |
1577
|
|
|
WHERE login = %s", |
1578
|
|
|
$GLOBALS['request'][3] |
1579
|
|
|
); |
1580
|
|
|
|
1581
|
|
|
// load passwordLib library |
1582
|
|
|
require_once '../sources/SplClassLoader.php'; |
1583
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
1584
|
|
|
$pwdlib->register(); |
1585
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
1586
|
|
|
|
1587
|
|
|
if ($pwdlib->verifyPasswordHash($GLOBALS['request'][4], $userData['pw']) === true) { |
1588
|
|
|
// define the restriction of "id_tree" of this user |
1589
|
|
|
//db::debugMode(true); |
|
|
|
|
1590
|
|
|
$userDef = DB::queryOneColumn( |
1591
|
|
|
'folder_id', |
1592
|
|
|
"SELECT DISTINCT folder_id |
1593
|
|
|
FROM ".prefix_table("roles_values")." |
1594
|
|
|
WHERE type IN ('R', 'W', 'ND', 'NE', 'NDNE', 'NEND') ", |
1595
|
|
|
empty($userData['groupes_interdits']) ? "" : " |
1596
|
|
|
AND folder_id NOT IN (".str_replace(";", ",", $userData['groupes_interdits']).")", |
1597
|
|
|
"AND role_id IN %ls |
1598
|
|
|
GROUP BY folder_id", |
1599
|
|
|
explode(";", $userData['groupes_interdits']) |
1600
|
|
|
); |
1601
|
|
|
// complete with "groupes_visibles" |
1602
|
|
|
foreach (explode(";", $userData['groupes_visibles']) as $v) { |
1603
|
|
|
array_push($userDef, $v); |
1604
|
|
|
} |
1605
|
|
|
|
1606
|
|
|
// find the item associated to the url |
1607
|
|
|
$response = DB::query( |
1608
|
|
|
"SELECT id, label, login, pw, pw_iv, id_tree, restricted_to |
1609
|
|
|
FROM ".prefix_table("items")." |
1610
|
|
|
WHERE url LIKE %s |
1611
|
|
|
AND id_tree IN (".implode(",", $userDef).") |
1612
|
|
|
ORDER BY id DESC", |
1613
|
|
|
$GLOBALS['request'][1]."://".urldecode($GLOBALS['request'][2].'%') |
1614
|
|
|
); |
1615
|
|
|
$counter = DB::count(); |
1616
|
|
|
|
1617
|
|
|
if ($counter > 0) { |
1618
|
|
|
$json = ""; |
1619
|
|
|
foreach ($response as $data) { |
1620
|
|
|
// check if item visible |
1621
|
|
|
if (empty($data['restricted_to']) || |
1622
|
|
|
($data['restricted_to'] != "" && in_array($userData['id'], explode(";", $data['restricted_to']))) |
1623
|
|
|
) { |
1624
|
|
|
// prepare export |
1625
|
|
|
$json[$data['id']]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
1626
|
|
|
$json[$data['id']]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
1627
|
|
|
$crypt_pw = cryption( |
1628
|
|
|
$data['pw'], |
1629
|
|
|
"", |
1630
|
|
|
"decrypt" |
1631
|
|
|
); |
1632
|
|
|
$json[$data['id']]['pw'] = $crypt_pw['string']; |
1633
|
|
|
} |
1634
|
|
|
} |
1635
|
|
|
// prepare answer. If no access then inform |
1636
|
|
|
if (empty($json)) { |
|
|
|
|
1637
|
|
|
rest_error('AUTH_NO_DATA'); |
1638
|
|
|
} else { |
1639
|
|
|
echo json_encode($json); |
1640
|
|
|
} |
1641
|
|
|
} else { |
1642
|
|
|
rest_error('NO_DATA_EXIST'); |
1643
|
|
|
} |
1644
|
|
|
} else { |
1645
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
1646
|
|
|
} |
1647
|
|
|
} else { |
1648
|
|
|
rest_error('AUTH_NO_URL'); |
1649
|
|
|
} |
1650
|
|
|
} else { |
1651
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
1652
|
|
|
} |
1653
|
|
|
} elseif ($GLOBALS['request'][0] === "auth_tpc") { |
1654
|
|
|
/* |
1655
|
|
|
** TO BE USED ONLY BY TEAMPASS-CONNECT |
1656
|
|
|
** |
1657
|
|
|
*/ |
1658
|
|
|
// get user credentials |
1659
|
|
|
if (isset($GLOBALS['request'][1])) { |
1660
|
|
|
// Get passed variables |
1661
|
|
|
$passedData = explode(';', Urlsafe_b64decode($GLOBALS['request'][1])); |
1662
|
|
|
if (count($passedData) === 4) { |
1663
|
|
|
$tpc_url = $passedData[0]; |
1664
|
|
|
$user_login = $passedData[1]; |
1665
|
|
|
$user_pwd = $passedData[2]; |
1666
|
|
|
$user_saltkey = $passedData[3]; |
1667
|
|
|
|
1668
|
|
|
// get url |
1669
|
|
|
if (isset($tpc_url)) { |
1670
|
|
|
// is user granted? |
1671
|
|
|
$userData = DB::queryFirstRow( |
1672
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id`, `encrypted_psk` |
1673
|
|
|
FROM ".prefix_table("users")." |
1674
|
|
|
WHERE login = %s", |
1675
|
|
|
$user_login |
1676
|
|
|
); |
1677
|
|
|
|
1678
|
|
|
// Check if user exists |
1679
|
|
|
if (empty($userData['id']) === true) { |
1680
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
1681
|
|
|
} |
1682
|
|
|
|
1683
|
|
|
// check if psk is correct. |
1684
|
|
|
if (empty($user_saltkey) === false) { |
1685
|
|
|
$user_saltkey = defuse_validate_personal_key( |
1686
|
|
|
$user_saltkey, |
1687
|
|
|
$userData['encrypted_psk'] |
1688
|
|
|
); |
1689
|
|
|
if (strpos($user_saltkey, "Error ") !== false) { |
1690
|
|
|
// error |
1691
|
|
|
rest_error('AUTH_PSK_ERROR'); |
1692
|
|
|
} |
1693
|
|
|
} |
1694
|
|
|
|
1695
|
|
|
// load passwordLib library |
1696
|
|
|
require_once '../sources/SplClassLoader.php'; |
1697
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
1698
|
|
|
$pwdlib->register(); |
1699
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
1700
|
|
|
|
1701
|
|
|
if ($pwdlib->verifyPasswordHash($user_pwd, $userData['pw']) === true) { |
1702
|
|
|
// Manage the case TPC asks for user identification |
1703
|
|
|
if ($tpc_url === 'identify_user') { |
1704
|
|
|
echo json_encode(array('err' => '', 'status' => 'USER_GRANTED')); |
1705
|
|
|
return false; |
1706
|
|
|
} |
1707
|
|
|
|
1708
|
|
|
// define the restriction of "id_tree" of this user |
1709
|
|
|
//db::debugMode(true); |
|
|
|
|
1710
|
|
|
$userDef = DB::queryOneColumn( |
1711
|
|
|
'folder_id', |
1712
|
|
|
"SELECT DISTINCT folder_id |
1713
|
|
|
FROM ".prefix_table("roles_values")." |
1714
|
|
|
WHERE type IN ('R', 'W', 'ND', 'NE', 'NDNE', 'NEND') ", |
1715
|
|
|
empty($userData['groupes_interdits']) ? "" : "AND folder_id NOT IN (".str_replace(";", ",", $userData['groupes_interdits']).")", |
1716
|
|
|
"AND role_id IN %ls |
1717
|
|
|
GROUP BY folder_id", |
1718
|
|
|
explode(";", $userData['groupes_interdits']) |
1719
|
|
|
); |
1720
|
|
|
// complete with "groupes_visibles" |
1721
|
|
|
foreach (explode(";", $userData['groupes_visibles']) as $v) { |
1722
|
|
|
array_push($userDef, $v); |
1723
|
|
|
} |
1724
|
|
|
|
1725
|
|
|
// add PF |
1726
|
|
|
$userpf = DB::queryFirstRow( |
1727
|
|
|
"SELECT `id` FROM ".prefix_table("nested_tree")." WHERE title = %s", |
1728
|
|
|
$userData['id'] |
1729
|
|
|
); |
1730
|
|
|
array_push($userDef, $userpf['id']); |
1731
|
|
|
|
1732
|
|
|
// Parse provided URL |
1733
|
|
|
$url_scheme = parse_url($tpc_url, PHP_URL_SCHEME); |
1734
|
|
|
$url_post = parse_url($tpc_url, PHP_URL_HOST); |
1735
|
|
|
|
1736
|
|
|
// find the item associated to the url |
1737
|
|
|
//db::debugmode(true); |
|
|
|
|
1738
|
|
|
$response = DB::query( |
1739
|
|
|
"SELECT id, label, login, pw, pw_iv, id_tree, restricted_to, perso |
1740
|
|
|
FROM ".prefix_table("items")." |
1741
|
|
|
WHERE url LIKE %s |
1742
|
|
|
AND id_tree IN (".implode(",", array_filter($userDef)).") |
1743
|
|
|
AND inactif = %i |
1744
|
|
|
ORDER BY id DESC", |
1745
|
|
|
$url_scheme.'://'.$url_post.'%', |
1746
|
|
|
0 |
1747
|
|
|
); |
1748
|
|
|
$counter = DB::count(); |
1749
|
|
|
|
1750
|
|
|
if ($counter > 0) { |
1751
|
|
|
$json = []; |
1752
|
|
|
foreach ($response as $data) { |
1753
|
|
|
// check if item visible |
1754
|
|
|
if (empty($data['restricted_to']) || |
1755
|
|
|
($data['restricted_to'] != "" && in_array($userData['id'], explode(";", $data['restricted_to']))) |
1756
|
|
|
) { |
1757
|
|
|
// prepare export |
1758
|
|
|
$json[$data['id']]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
1759
|
|
|
$json[$data['id']]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
1760
|
|
|
if ($data['perso'] === "0") { |
1761
|
|
|
$crypt_pw = cryption( |
1762
|
|
|
$data['pw'], |
1763
|
|
|
"", |
1764
|
|
|
"decrypt" |
1765
|
|
|
); |
1766
|
|
|
} elseif (empty($user_saltkey)) { |
1767
|
|
|
$crypt_pw['string'] = "no_psk"; |
1768
|
|
|
} else { |
1769
|
|
|
$crypt_pw = cryption( |
1770
|
|
|
$data['pw'], |
1771
|
|
|
$user_saltkey, |
1772
|
|
|
"decrypt" |
1773
|
|
|
); |
1774
|
|
|
} |
1775
|
|
|
$json[$data['id']]['pw'] = mb_detect_encoding($crypt_pw['string'], 'UTF-8', true) ? $crypt_pw['string'] : "not_utf8"; |
1776
|
|
|
$json[$data['id']]['perso'] = $data['perso']; |
1777
|
|
|
$json[$data['id']]['domain'] = $url_scheme.'://'.$url_post; |
1778
|
|
|
$json[$data['id']]['id'] = $data['id']; |
1779
|
|
|
} |
1780
|
|
|
} |
1781
|
|
|
// prepare answer. If no access then inform |
1782
|
|
|
if (empty($json)) { |
1783
|
|
|
rest_error('AUTH_NO_DATA'); |
1784
|
|
|
} else { |
1785
|
|
|
echo json_encode($json); |
1786
|
|
|
} |
1787
|
|
|
} else { |
1788
|
|
|
rest_error('NO_DATA_EXIST'); |
1789
|
|
|
} |
1790
|
|
|
} else { |
1791
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
1792
|
|
|
} |
1793
|
|
|
} else { |
1794
|
|
|
rest_error('AUTH_NO_URL'); |
1795
|
|
|
} |
1796
|
|
|
} else { |
1797
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
1798
|
|
|
} |
1799
|
|
|
} else { |
1800
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
1801
|
|
|
} |
1802
|
|
|
} else if ($GLOBALS['request'][0] === "tpc_find") { |
1803
|
|
|
// get user credentials |
1804
|
|
|
if (isset($GLOBALS['request'][1])) { |
1805
|
|
|
// Get passed variables |
1806
|
|
|
$passedData = explode(';', Urlsafe_b64decode($GLOBALS['request'][1])); |
1807
|
|
|
$tpc_phrase = $passedData[0]; |
1808
|
|
|
$user_login = $passedData[1]; |
1809
|
|
|
$user_pwd = $passedData[2]; |
1810
|
|
|
$user_saltkey = $passedData[3]; |
1811
|
|
|
|
1812
|
|
|
// get url |
1813
|
|
|
if (isset($tpc_phrase)) { |
1814
|
|
|
// is user granted? |
1815
|
|
|
//db::debugMode(true); |
|
|
|
|
1816
|
|
|
$userData = DB::queryFirstRow( |
1817
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id`, `encrypted_psk` |
1818
|
|
|
FROM ".prefix_table("users")." |
1819
|
|
|
WHERE login = %s", |
1820
|
|
|
$user_login |
1821
|
|
|
); |
1822
|
|
|
|
1823
|
|
|
// check if psk is correct. |
1824
|
|
|
if (empty($user_saltkey) === false) { |
1825
|
|
|
$user_saltkey = defuse_validate_personal_key( |
1826
|
|
|
$user_saltkey, |
1827
|
|
|
$userData['encrypted_psk'] |
1828
|
|
|
); |
1829
|
|
|
if (strpos($user_saltkey, "Error ") !== false) { |
1830
|
|
|
// error |
1831
|
|
|
rest_error('AUTH_PSK_ERROR'); |
1832
|
|
|
} |
1833
|
|
|
} |
1834
|
|
|
|
1835
|
|
|
// load passwordLib library |
1836
|
|
|
require_once '../sources/SplClassLoader.php'; |
1837
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
1838
|
|
|
$pwdlib->register(); |
1839
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
1840
|
|
|
|
1841
|
|
|
if ($pwdlib->verifyPasswordHash($user_pwd, $userData['pw']) === true) { |
1842
|
|
|
// define the restriction of "id_tree" of this user |
1843
|
|
|
//db::debugMode(true); |
|
|
|
|
1844
|
|
|
$userDef = DB::queryOneColumn( |
1845
|
|
|
'folder_id', |
1846
|
|
|
"SELECT DISTINCT folder_id |
1847
|
|
|
FROM ".prefix_table("roles_values")." |
1848
|
|
|
WHERE type IN ('R', 'W', 'ND', 'NE', 'NDNE', 'NEND') ", |
1849
|
|
|
empty($userData['groupes_interdits']) ? "" : "AND folder_id NOT IN (".str_replace(";", ",", $userData['groupes_interdits']).")", |
1850
|
|
|
"AND role_id IN %ls |
1851
|
|
|
GROUP BY folder_id", |
1852
|
|
|
explode(";", $userData['groupes_interdits']) |
1853
|
|
|
); |
1854
|
|
|
// complete with "groupes_visibles" |
1855
|
|
|
foreach (explode(";", $userData['groupes_visibles']) as $v) { |
1856
|
|
|
array_push($userDef, $v); |
1857
|
|
|
} |
1858
|
|
|
|
1859
|
|
|
// add PF |
1860
|
|
|
$userpf = DB::queryFirstRow( |
1861
|
|
|
"SELECT `id` FROM ".prefix_table("nested_tree")." WHERE title = %s", |
1862
|
|
|
$userData['id'] |
1863
|
|
|
); |
1864
|
|
|
array_push($userDef, $userpf['id']); |
1865
|
|
|
|
1866
|
|
|
// Clean phrase |
1867
|
|
|
if (!preg_match_all("/^([\w\:\'\-\sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)$/i", $tpc_phrase, $result)) { |
1868
|
|
|
rest_error('ITEM_MALFORMED'); |
1869
|
|
|
} elseif (empty($tpc_phrase)) { |
1870
|
|
|
rest_error('MALFORMED'); |
1871
|
|
|
} |
1872
|
|
|
|
1873
|
|
|
// find the item associated to the url |
1874
|
|
|
//db::debugmode(true); |
|
|
|
|
1875
|
|
|
$response = DB::query( |
1876
|
|
|
"SELECT id, label, login, pw, pw_iv, id_tree, restricted_to, perso, url |
1877
|
|
|
FROM ".prefix_table("items")." |
1878
|
|
|
WHERE (url LIKE %s OR label LIKE %s) |
1879
|
|
|
AND id_tree IN (".implode(",", array_filter($userDef)).") |
1880
|
|
|
AND inactif = %i |
1881
|
|
|
ORDER BY id DESC", |
1882
|
|
|
$tpc_phrase.'%', |
1883
|
|
|
$tpc_phrase.'%', |
1884
|
|
|
0 |
1885
|
|
|
); |
1886
|
|
|
$counter = DB::count(); |
1887
|
|
|
|
1888
|
|
|
if ($counter > 0) { |
1889
|
|
|
$json = []; |
1890
|
|
|
$i = 0; |
1891
|
|
|
foreach ($response as $data) { |
1892
|
|
|
// check if item visible |
1893
|
|
|
if (empty($data['restricted_to']) || |
1894
|
|
|
($data['restricted_to'] != "" && in_array($userData['id'], explode(";", $data['restricted_to']))) |
1895
|
|
|
) { |
1896
|
|
|
// prepare export |
1897
|
|
|
$json[$i]['label'] = mb_convert_encoding($data['label'], mb_detect_encoding($data['label']), 'UTF-8'); |
1898
|
|
|
$json[$i]['login'] = mb_convert_encoding($data['login'], mb_detect_encoding($data['login']), 'UTF-8'); |
1899
|
|
|
if ($data['perso'] === "0") { |
1900
|
|
|
$crypt_pw = cryption( |
1901
|
|
|
$data['pw'], |
1902
|
|
|
"", |
1903
|
|
|
"decrypt" |
1904
|
|
|
); |
1905
|
|
|
} elseif (empty($user_saltkey)) { |
1906
|
|
|
$crypt_pw['string'] = "no_psk"; |
1907
|
|
|
} else { |
1908
|
|
|
$crypt_pw = cryption( |
1909
|
|
|
$data['pw'], |
1910
|
|
|
$user_saltkey, |
1911
|
|
|
"decrypt" |
1912
|
|
|
); |
1913
|
|
|
} |
1914
|
|
|
$json[$i]['pw'] = mb_detect_encoding($crypt_pw['string'], 'UTF-8', true) ? $crypt_pw['string'] : "not_utf8"; |
1915
|
|
|
$json[$i]['perso'] = $data['perso']; |
1916
|
|
|
$json[$i]['domain'] = $data['url']; |
1917
|
|
|
$json[$i]['id'] = $data['id']; |
1918
|
|
|
|
1919
|
|
|
$i++; |
1920
|
|
|
} |
1921
|
|
|
} |
1922
|
|
|
// prepare answer. If no access then inform |
1923
|
|
|
if (empty($json)) { |
1924
|
|
|
rest_error('AUTH_NO_DATA'); |
1925
|
|
|
} else { |
1926
|
|
|
echo json_encode($json); |
1927
|
|
|
} |
1928
|
|
|
} else { |
1929
|
|
|
rest_error('NO_DATA_EXIST'); |
1930
|
|
|
} |
1931
|
|
|
} else { |
1932
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
1933
|
|
|
} |
1934
|
|
|
} else { |
1935
|
|
|
rest_error('AUTH_NO_URL'); |
1936
|
|
|
} |
1937
|
|
|
} else { |
1938
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
1939
|
|
|
} |
1940
|
|
|
} elseif ($GLOBALS['request'][0] == "tpc_userfolders") { |
1941
|
|
|
/* |
1942
|
|
|
* READ USER FOLDERS |
1943
|
|
|
* Sends back a list of folders |
1944
|
|
|
*/ |
1945
|
|
|
// get user credentials |
1946
|
|
|
if (isset($GLOBALS['request'][1])) { |
1947
|
|
|
// Get passed variables |
1948
|
|
|
$passedData = explode(';', Urlsafe_b64decode($GLOBALS['request'][1])); |
1949
|
|
|
$user_login = $passedData[0]; |
1950
|
|
|
$user_pwd = $passedData[1]; |
|
|
|
|
1951
|
|
|
$user_saltkey = $passedData[2]; |
|
|
|
|
1952
|
|
|
|
1953
|
|
|
$json = []; |
1954
|
|
|
$inc = 0; |
1955
|
|
|
if (strcmp($user_login, "admin") == 0) { |
|
|
|
|
1956
|
|
|
// forbid admin access |
1957
|
|
|
} |
1958
|
|
|
$response = DB::query( |
1959
|
|
|
"SELECT id AS user_id, fonction_id |
1960
|
|
|
FROM ".prefix_table("users")." |
1961
|
|
|
WHERE login = %s", |
1962
|
|
|
$user_login |
1963
|
|
|
); |
1964
|
|
|
if (count($response) === 0) { |
1965
|
|
|
rest_error('USER_NOT_EXISTS '); |
1966
|
|
|
} |
1967
|
|
|
foreach ($response as $data) { |
1968
|
|
|
$role_str = $data['fonction_id']; |
1969
|
|
|
$user_id = $data['user_id']; |
1970
|
|
|
} |
1971
|
|
|
|
1972
|
|
|
// Build tree |
1973
|
|
|
require_once '../sources/SplClassLoader.php'; |
1974
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
1975
|
|
|
$tree->register(); |
1976
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
1977
|
|
|
$tree->rebuild(); |
1978
|
|
|
|
1979
|
|
|
// If personal exists then get list of PF |
1980
|
|
|
$persoFld = DB::queryfirstrow( |
1981
|
|
|
"SELECT id, title, nlevel |
1982
|
|
|
FROM ".prefix_table("nested_tree")." |
1983
|
|
|
WHERE title = %s", |
1984
|
|
|
$user_id |
|
|
|
|
1985
|
|
|
); |
1986
|
|
|
if (empty($persoFld['id']) === false) { |
1987
|
|
|
// Store main PF |
1988
|
|
|
$json[$inc]['id'] = $persoFld['id']; |
1989
|
|
|
$json[$inc]['title'] = $user_login; |
1990
|
|
|
$json[$inc]['level'] = $persoFld['nlevel']; |
1991
|
|
|
$json[$inc]['access_type'] = "W"; |
1992
|
|
|
$inc++; |
1993
|
|
|
|
1994
|
|
|
// get all descendants |
1995
|
|
|
$ids = $tree->getDescendants($persoFld['id'], false, false); |
1996
|
|
|
foreach ($ids as $ident) { |
1997
|
|
|
// Do query to get folder info |
1998
|
|
|
$fldInfo = DB::queryfirstrow( |
1999
|
|
|
"SELECT title, nlevel |
2000
|
|
|
FROM ".prefix_table("nested_tree")." |
2001
|
|
|
WHERE id = %i", |
2002
|
|
|
$ident->id |
2003
|
|
|
); |
2004
|
|
|
|
2005
|
|
|
// Store info |
2006
|
|
|
$json[$inc]['id'] = $ident->id; |
2007
|
|
|
$json[$inc]['title'] = $fldInfo['title']; |
2008
|
|
|
$json[$inc]['level'] = $fldInfo['nlevel']; |
2009
|
|
|
$json[$inc]['personal'] = "1"; |
2010
|
|
|
$json[$inc]['access_type'] = "W"; |
2011
|
|
|
$inc++; |
2012
|
|
|
} |
2013
|
|
|
} |
2014
|
|
|
|
2015
|
|
|
$folder_arr = array(); |
2016
|
|
|
$roles = explode(";", $role_str); |
2017
|
|
|
foreach ($roles as $role) { |
2018
|
|
|
$response = DB::query( |
2019
|
|
|
"SELECT folder_id, type |
2020
|
|
|
FROM ".prefix_table("roles_values")." |
2021
|
|
|
WHERE role_id = %i", |
2022
|
|
|
$role |
2023
|
|
|
); |
2024
|
|
|
foreach ($response as $data) { |
2025
|
|
|
$folder_id = $data['folder_id']; |
2026
|
|
|
if (array_key_exists($folder_id, $folder_arr) === false) { |
2027
|
|
|
array_push($folder_arr, $folder_id); |
2028
|
|
|
|
2029
|
|
|
$response2 = DB::queryFirstRow( |
2030
|
|
|
"SELECT title, nlevel |
2031
|
|
|
FROM ".prefix_table("nested_tree")." |
2032
|
|
|
WHERE id = %i", |
2033
|
|
|
$folder_id |
2034
|
|
|
); |
2035
|
|
|
|
2036
|
|
|
if (empty($response2['title']) === false) { |
2037
|
|
|
// get all descendants |
2038
|
|
|
$ids = $tree->getDescendants($folder_id, true, false); |
2039
|
|
|
foreach ($ids as $ident) { |
2040
|
|
|
if (array_key_exists($ident->id, $folder_arr) === false) { |
2041
|
|
|
array_push($folder_arr, $ident->id); |
2042
|
|
|
// Do query to get folder info |
2043
|
|
|
$fldInfo = DB::queryfirstrow( |
2044
|
|
|
"SELECT title, nlevel |
2045
|
|
|
FROM ".prefix_table("nested_tree")." |
2046
|
|
|
WHERE id = %i", |
2047
|
|
|
$ident->id |
2048
|
|
|
); |
2049
|
|
|
|
2050
|
|
|
// Store info |
2051
|
|
|
$json[$inc]['id'] = $ident->id; |
2052
|
|
|
$json[$inc]['title'] = $fldInfo['title']; |
2053
|
|
|
$json[$inc]['level'] = $fldInfo['nlevel']; |
2054
|
|
|
$json[$inc]['personal'] = "0"; |
2055
|
|
|
$json[$inc]['access_type'] = "W"; |
2056
|
|
|
$inc++; |
2057
|
|
|
} |
2058
|
|
|
} |
2059
|
|
|
/*$json[$inc]['id'] = $folder_id; |
|
|
|
|
2060
|
|
|
$json[$inc]['title'] = $response2['title']; |
2061
|
|
|
$json[$inc]['level'] = $response2['nlevel']; |
2062
|
|
|
$json[$inc]['access_type'] = $data['type']; |
2063
|
|
|
$json[$inc]['personal'] = "0"; |
2064
|
|
|
$inc++;*/ |
2065
|
|
|
} |
2066
|
|
|
} |
2067
|
|
|
} |
2068
|
|
|
} |
2069
|
|
|
// prepare answer. If no access then inform |
2070
|
|
|
if (empty($json)) { |
2071
|
|
|
rest_error('AUTH_NO_DATA'); |
2072
|
|
|
} else { |
2073
|
|
|
echo json_encode($json); |
2074
|
|
|
} |
2075
|
|
|
} |
2076
|
|
|
} elseif ($GLOBALS['request'][0] == "set") { |
2077
|
|
|
/* |
2078
|
|
|
* Expected call format: .../api/index.php/set/<login_to_save>/<password_to_save>/<url>/<user_login>/<user_password>/<label>/<protocol>?apikey=<VALID API KEY> |
2079
|
|
|
* Example: https://127.0.0.1/teampass/api/index.php/set/newLogin/newPassword/newUrl/myLogin/myPassword?apikey=gu6Eexaewaishooph6iethoh5woh0yoit6ohquo |
2080
|
|
|
* |
2081
|
|
|
* NEW ITEM WILL BE STORED IN SPECIFIC FOLDER |
2082
|
|
|
*/ |
2083
|
|
|
// get user credentials |
2084
|
|
|
if (isset($GLOBALS['request'][4]) && isset($GLOBALS['request'][5])) { |
2085
|
|
|
// get url |
2086
|
|
|
if (isset($GLOBALS['request'][1]) && isset($GLOBALS['request'][2]) && isset($GLOBALS['request'][3])) { |
2087
|
|
|
// is user granted? |
2088
|
|
|
$userData = DB::queryFirstRow( |
2089
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id` |
2090
|
|
|
FROM ".prefix_table("users")." |
2091
|
|
|
WHERE login = %s", |
2092
|
|
|
$GLOBALS['request'][4] |
2093
|
|
|
); |
2094
|
|
|
if (DB::count() == 0) { |
2095
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2096
|
|
|
} |
2097
|
|
|
|
2098
|
|
|
// load passwordLib library |
2099
|
|
|
require_once '../sources/SplClassLoader.php'; |
2100
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
2101
|
|
|
$pwdlib->register(); |
2102
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
2103
|
|
|
|
2104
|
|
|
// is user identified? |
2105
|
|
|
if ($pwdlib->verifyPasswordHash($GLOBALS['request'][5], $userData['pw']) === true) { |
2106
|
|
|
// does the personal folder of this user exists? |
2107
|
|
|
DB::queryFirstRow( |
2108
|
|
|
"SELECT `id` |
2109
|
|
|
FROM ".prefix_table("nested_tree")." |
2110
|
|
|
WHERE title = %s AND personal_folder = 1", |
2111
|
|
|
$userData['id'] |
2112
|
|
|
); |
2113
|
|
|
if (DB::count() > 0) { |
2114
|
|
|
// check if "teampass-connect" folder exists |
2115
|
|
|
// if not create it |
2116
|
|
|
$folder = DB::queryFirstRow( |
2117
|
|
|
"SELECT `id` |
2118
|
|
|
FROM " . $pre."nested_tree |
|
|
|
|
2119
|
|
|
WHERE title = %s", |
2120
|
|
|
"teampass-connect" |
2121
|
|
|
); |
2122
|
|
|
if (DB::count() == 0) { |
2123
|
|
|
DB::insert( |
2124
|
|
|
prefix_table("nested_tree"), |
2125
|
|
|
array( |
2126
|
|
|
'parent_id' => '0', |
2127
|
|
|
'title' => "teampass-connect" |
2128
|
|
|
) |
2129
|
|
|
); |
2130
|
|
|
$tpc_folder_id = DB::insertId(); |
2131
|
|
|
|
2132
|
|
|
//Add complexity |
2133
|
|
|
DB::insert( |
2134
|
|
|
prefix_table("misc"), |
2135
|
|
|
array( |
2136
|
|
|
'type' => 'complex', |
2137
|
|
|
'intitule' => $tpc_folder_id, |
2138
|
|
|
'valeur' => '0' |
2139
|
|
|
) |
2140
|
|
|
); |
2141
|
|
|
|
2142
|
|
|
// rebuild tree |
2143
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
2144
|
|
|
$tree->register(); |
2145
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
2146
|
|
|
$tree->rebuild(); |
2147
|
|
|
} else { |
2148
|
|
|
$tpc_folder_id = $folder['id']; |
2149
|
|
|
} |
2150
|
|
|
|
2151
|
|
|
// encrypt password |
2152
|
|
|
$encrypt = cryption( |
2153
|
|
|
$GLOBALS['request'][2], |
2154
|
|
|
"", |
2155
|
|
|
"encrypt" |
2156
|
|
|
); |
2157
|
|
|
|
2158
|
|
|
// is there a protocol? |
2159
|
|
|
if (isset($GLOBALS['request'][7]) || empty($GLOBALS['request'][7])) { |
2160
|
|
|
$protocol = "http://"; |
|
|
|
|
2161
|
|
|
} else { |
2162
|
|
|
$protocol = urldecode($GLOBALS['request'][7])."://"; |
2163
|
|
|
} |
2164
|
|
|
|
2165
|
|
|
// add new item |
2166
|
|
|
DB::insert( |
2167
|
|
|
prefix_table("items"), |
2168
|
|
|
array( |
2169
|
|
|
'label' => "Credentials for ".urldecode($GLOBALS['request'][3]), |
2170
|
|
|
'description' => "Imported with Teampass-Connect", |
2171
|
|
|
'pw' => $encrypt['string'], |
2172
|
|
|
'pw_iv' => "", |
2173
|
|
|
'email' => "", |
2174
|
|
|
'url' => urldecode($GLOBALS['request'][3]), |
2175
|
|
|
'id_tree' => $tpc_folder_id, |
2176
|
|
|
'login' => $GLOBALS['request'][1], |
2177
|
|
|
'inactif' => '0', |
2178
|
|
|
'restricted_to' => $userData['id'], |
2179
|
|
|
'perso' => '0', |
2180
|
|
|
'anyone_can_modify' => '0', |
2181
|
|
|
'complexity_level' => '0' |
2182
|
|
|
) |
2183
|
|
|
); |
2184
|
|
|
$newID = DB::insertId(); |
2185
|
|
|
|
2186
|
|
|
// log |
2187
|
|
|
logItems( |
2188
|
|
|
$newID, |
2189
|
|
|
"Credentials for ".urldecode($GLOBALS['request'][3].'%'), |
2190
|
|
|
$userData['id'], |
2191
|
|
|
'at_creation', |
2192
|
|
|
$GLOBALS['request'][1] |
2193
|
|
|
); |
2194
|
|
|
|
2195
|
|
|
$json['status'] = "ok"; |
|
|
|
|
2196
|
|
|
// prepare answer. If no access then inform |
2197
|
|
|
if (empty($json)) { |
2198
|
|
|
rest_error('AUTH_NO_DATA'); |
2199
|
|
|
} else { |
2200
|
|
|
echo json_encode($json); |
2201
|
|
|
} |
2202
|
|
|
} else { |
2203
|
|
|
rest_error('NO_PF_EXIST_FOR_USER'); |
2204
|
|
|
} |
2205
|
|
|
} else { |
2206
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
2207
|
|
|
} |
2208
|
|
|
} else { |
2209
|
|
|
rest_error('SET_NO_DATA'); |
2210
|
|
|
} |
2211
|
|
|
} else { |
2212
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2213
|
|
|
} |
2214
|
|
|
} elseif ($GLOBALS['request'][0] == "set_tpc") { |
2215
|
|
|
/* |
2216
|
|
|
* TO BE USED ONLY BY TEAMPASS-CONNECT |
2217
|
|
|
*/ |
2218
|
|
|
// get user credentials |
2219
|
|
|
if (isset($GLOBALS['request'][1]) === true && isset($GLOBALS['request'][2]) === true && isset($GLOBALS['request'][3]) === true) { |
2220
|
|
|
// Get passed variables |
2221
|
|
|
$item_definition = json_decode(Urlsafe_b64decode($GLOBALS['request'][2]), true); |
2222
|
|
|
$passedData = explode(';', Urlsafe_b64decode($GLOBALS['request'][3])); |
2223
|
|
|
$user_login = $passedData[0]; |
2224
|
|
|
$user_pwd = $passedData[1]; |
2225
|
|
|
$user_saltkey = $passedData[2]; |
2226
|
|
|
|
2227
|
|
|
// is user granted? |
2228
|
|
|
$userData = DB::queryFirstRow( |
2229
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id` |
2230
|
|
|
FROM ".prefix_table("users")." |
2231
|
|
|
WHERE login = %s", |
2232
|
|
|
$user_login |
2233
|
|
|
); |
2234
|
|
|
if (DB::count() === 0) { |
2235
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2236
|
|
|
} |
2237
|
|
|
|
2238
|
|
|
// load passwordLib library |
2239
|
|
|
require_once '../sources/SplClassLoader.php'; |
2240
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
2241
|
|
|
$pwdlib->register(); |
2242
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
2243
|
|
|
|
2244
|
|
|
// is user identified? |
2245
|
|
|
if ($pwdlib->verifyPasswordHash($user_pwd, $userData['pw']) === true) { |
2246
|
|
|
// It is a new ITEM |
2247
|
|
|
if ($GLOBALS['request'][1] === "add") { |
2248
|
|
|
// encrypt PW |
2249
|
|
|
if ($item_definition['personal'] === '1') { |
2250
|
|
|
$passwd = cryption( |
2251
|
|
|
$item_definition['pwd'], |
2252
|
|
|
$user_saltkey, |
2253
|
|
|
"encrypt" |
2254
|
|
|
); |
2255
|
|
|
} else { |
2256
|
|
|
$passwd = cryption( |
2257
|
|
|
$item_definition['pwd'], |
2258
|
|
|
"", |
2259
|
|
|
"encrypt" |
2260
|
|
|
); |
2261
|
|
|
} |
2262
|
|
|
|
2263
|
|
|
// add new item |
2264
|
|
|
DB::insert( |
2265
|
|
|
prefix_table("items"), |
2266
|
|
|
array( |
2267
|
|
|
'label' => $item_definition['label'], |
2268
|
|
|
'description' => $item_definition['description'], |
2269
|
|
|
'pw' => $passwd['string'], |
2270
|
|
|
'pw_iv' => "", |
2271
|
|
|
'email' => "", |
2272
|
|
|
'url' => $item_definition['url'], |
2273
|
|
|
'id_tree' => $item_definition['destination_folder'], |
2274
|
|
|
'login' => $item_definition['login'], |
2275
|
|
|
'inactif' => '0', |
2276
|
|
|
'restricted_to' => $userData['id'], |
2277
|
|
|
'perso' => '0', |
2278
|
|
|
'anyone_can_modify' => '0', |
2279
|
|
|
'complexity_level' => '0' |
2280
|
|
|
) |
2281
|
|
|
); |
2282
|
|
|
$newID = DB::insertId(); |
2283
|
|
|
|
2284
|
|
|
// log |
2285
|
|
|
logItems( |
2286
|
|
|
$newID, |
2287
|
|
|
$item_definition['label'], |
2288
|
|
|
$userData['id'], |
2289
|
|
|
'at_creation', |
2290
|
|
|
$GLOBALS['request'][1] |
2291
|
|
|
); |
2292
|
|
|
|
2293
|
|
|
// rebuild tree |
2294
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
2295
|
|
|
$tree->register(); |
2296
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
2297
|
|
|
$tree->rebuild(); |
2298
|
|
|
|
2299
|
|
|
echo json_encode(array('new_id' => $newID , 'err' => '')); |
2300
|
|
|
} elseif ($GLOBALS['request'][1] === "edit") { |
2301
|
|
|
// Is this folder a personal one? |
2302
|
|
|
$fldData = DB::queryFirstRow( |
2303
|
|
|
"SELECT `personal_folder` |
2304
|
|
|
FROM ".prefix_table("nested_tree")." |
2305
|
|
|
WHERE id = %i", |
2306
|
|
|
$item_definition['item_id'] |
2307
|
|
|
); |
2308
|
|
|
|
2309
|
|
|
// encrypt PW |
2310
|
|
|
if ($fldData['personal_folder'] === '1') { |
2311
|
|
|
$passwd = cryption( |
2312
|
|
|
$item_definition['pwd'], |
2313
|
|
|
$user_saltkey, |
2314
|
|
|
"encrypt" |
2315
|
|
|
); |
2316
|
|
|
} else { |
2317
|
|
|
$passwd = cryption( |
2318
|
|
|
$item_definition['pwd'], |
2319
|
|
|
"", |
2320
|
|
|
"encrypt" |
2321
|
|
|
); |
2322
|
|
|
} |
2323
|
|
|
|
2324
|
|
|
// UPDATE item |
2325
|
|
|
DB::update( |
2326
|
|
|
prefix_table("items"), |
2327
|
|
|
array( |
2328
|
|
|
'pw' => $passwd['string'], |
2329
|
|
|
'pw_iv' => '', |
2330
|
|
|
"url" => $item_definition['url'], |
2331
|
|
|
"login" => $item_definition['login'] |
2332
|
|
|
), |
2333
|
|
|
"id = %i", |
2334
|
|
|
$item_definition['item_id'] |
2335
|
|
|
); |
2336
|
|
|
|
2337
|
|
|
// log |
2338
|
|
|
DB::insert( |
2339
|
|
|
prefix_table("log_items"), |
2340
|
|
|
array( |
2341
|
|
|
"id_item" => $item_definition['item_id'], |
2342
|
|
|
"date" => time(), |
2343
|
|
|
"id_user" => $userData['id'], |
2344
|
|
|
"action" => "at_modification" |
2345
|
|
|
) |
2346
|
|
|
); |
2347
|
|
|
|
2348
|
|
|
// Update CACHE table |
2349
|
|
|
DB::update( |
2350
|
|
|
prefix_table("cache"), |
2351
|
|
|
array( |
2352
|
|
|
"login" => $item_definition['login'], |
2353
|
|
|
"author" => $userData['id'], |
2354
|
|
|
"timestamp" => time(), |
2355
|
|
|
"url" => $item_definition['url'], |
2356
|
|
|
), |
2357
|
|
|
"id = %i", |
2358
|
|
|
$item_definition['item_id'] |
2359
|
|
|
); |
2360
|
|
|
|
2361
|
|
|
echo json_encode(array('new_id' => '' , 'err' => '')); |
2362
|
|
|
} |
2363
|
|
|
} else { |
2364
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
2365
|
|
|
} |
2366
|
|
|
} else { |
2367
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2368
|
|
|
} |
2369
|
|
|
} elseif ($GLOBALS['request'][0] == "tpc_delete") { |
2370
|
|
|
/* |
2371
|
|
|
* TO BE USED ONLY BY TEAMPASS-CONNECT |
2372
|
|
|
*/ |
2373
|
|
|
// get user credentials |
2374
|
|
|
if (isset($GLOBALS['request'][1]) === true) { |
2375
|
|
|
// Get passed variables |
2376
|
|
|
$passedData = explode(';', Urlsafe_b64decode($GLOBALS['request'][1])); |
2377
|
|
|
$item_id = $passedData[0]; |
2378
|
|
|
$user_login = $passedData[1]; |
2379
|
|
|
$user_pwd = $passedData[2]; |
2380
|
|
|
$user_saltkey = $passedData[3]; |
2381
|
|
|
|
2382
|
|
|
// is user granted? |
2383
|
|
|
$userData = DB::queryFirstRow( |
2384
|
|
|
"SELECT `id`, `pw`, `groupes_interdits`, `groupes_visibles`, `fonction_id` |
2385
|
|
|
FROM ".prefix_table("users")." |
2386
|
|
|
WHERE login = %s", |
2387
|
|
|
$user_login |
2388
|
|
|
); |
2389
|
|
|
if (DB::count() == 0) { |
2390
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2391
|
|
|
} |
2392
|
|
|
|
2393
|
|
|
// load passwordLib library |
2394
|
|
|
require_once '../sources/SplClassLoader.php'; |
2395
|
|
|
$pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries'); |
2396
|
|
|
$pwdlib->register(); |
2397
|
|
|
$pwdlib = new PasswordLib\PasswordLib(); |
2398
|
|
|
|
2399
|
|
|
// is user identified? |
2400
|
|
|
if ($pwdlib->verifyPasswordHash($user_pwd, $userData['pw']) === true) { |
2401
|
|
|
DB::update( |
2402
|
|
|
prefix_table("items"), |
2403
|
|
|
array( |
2404
|
|
|
'inactif' => '1', |
2405
|
|
|
), |
2406
|
|
|
"id = %i", |
2407
|
|
|
$item_id |
2408
|
|
|
); |
2409
|
|
|
//log |
2410
|
|
|
DB::insert( |
2411
|
|
|
prefix_table("log_items"), |
2412
|
|
|
array( |
2413
|
|
|
'id_item' => $item_id, |
2414
|
|
|
'date' => time(), |
2415
|
|
|
'id_user' => $userData['id'], |
2416
|
|
|
'action' => 'at_delete' |
2417
|
|
|
) |
2418
|
|
|
); |
2419
|
|
|
|
2420
|
|
|
//Update CACHE table |
2421
|
|
|
updateCacheTable("delete_value", $item_id); |
2422
|
|
|
|
2423
|
|
|
echo json_encode(array('code' => 'done')); |
2424
|
|
|
} else { |
2425
|
|
|
rest_error('AUTH_NOT_GRANTED'); |
2426
|
|
|
} |
2427
|
|
|
} else { |
2428
|
|
|
rest_error('AUTH_NO_IDENTIFIER'); |
2429
|
|
|
} |
2430
|
|
|
} elseif ($GLOBALS['request'][0] === "delete") { |
2431
|
|
|
/* |
2432
|
|
|
* DELETE |
2433
|
|
|
* |
2434
|
|
|
* Expected call format: .../api/index.php/delete/folder/<folder_id1;folder_id2;folder_id3>?apikey=<VALID API KEY> |
2435
|
|
|
* Expected call format: .../api/index.php/delete/item>/<item_id1;item_id2;item_id3>?apikey=<VALID API KEY> |
2436
|
|
|
*/ |
2437
|
|
|
if ($GLOBALS['request'][1] === "folder") { |
2438
|
|
|
$array_category = explode(';', $GLOBALS['request'][2]); |
2439
|
|
|
|
2440
|
|
|
// get user info |
2441
|
|
|
if (isset($GLOBALS['request'][3]) && !empty($GLOBALS['request'][3])) { |
2442
|
|
|
$userData = DB::queryFirstRow( |
2443
|
|
|
"SELECT `id` FROM ".$pre."users WHERE login = %s", |
2444
|
|
|
$GLOBALS['request'][3] |
2445
|
|
|
); |
2446
|
|
|
if (DB::count() == 0) { |
2447
|
|
|
$user_id = API_USER_ID; |
2448
|
|
|
} else { |
2449
|
|
|
$user_id = $userData['id']; |
2450
|
|
|
} |
2451
|
|
|
} else { |
2452
|
|
|
$user_id = API_USER_ID; |
2453
|
|
|
} |
2454
|
|
|
|
2455
|
|
|
if (count($array_category) > 0 && count($array_category) < 5) { |
2456
|
|
|
// load passwordLib library |
2457
|
|
|
require_once '../sources/SplClassLoader.php'; |
2458
|
|
|
|
2459
|
|
|
// prepare tree |
2460
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
2461
|
|
|
$tree->register(); |
2462
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title', 'personal_folder'); |
|
|
|
|
2463
|
|
|
|
2464
|
|
|
// this will delete all sub folders and items associated |
2465
|
|
|
for ($i = 0; $i < count($array_category); $i++) { |
|
|
|
|
2466
|
|
|
// Does this folder exist? |
2467
|
|
|
DB::queryFirstRow( |
2468
|
|
|
"SELECT id |
2469
|
|
|
FROM ".prefix_table("nested_tree")." |
2470
|
|
|
WHERE id = %i", |
2471
|
|
|
$array_category[$i] |
2472
|
|
|
); |
2473
|
|
|
if (DB::count() > 0) { |
2474
|
|
|
// Get through each subfolder |
2475
|
|
|
$folders = $tree->getDescendants($array_category[$i], true); |
|
|
|
|
2476
|
|
|
if (count($folders) > 0) { |
2477
|
|
|
foreach ($folders as $folder) { |
2478
|
|
|
if (($folder->parent_id > 0 || $folder->parent_id == 0) && $folder->personal_folder != 1) { |
2479
|
|
|
//Store the deleted folder (recycled bin) |
2480
|
|
|
DB::insert( |
2481
|
|
|
prefix_table("misc"), |
2482
|
|
|
array( |
2483
|
|
|
'type' => 'folder_deleted', |
2484
|
|
|
'intitule' => "f".$array_category[$i], |
2485
|
|
|
'valeur' => $folder->id.', '.$folder->parent_id.', '. |
2486
|
|
|
$folder->title.', '.$folder->nleft.', '.$folder->nright.', '.$folder->nlevel.', 0, 0, 0, 0' |
2487
|
|
|
) |
2488
|
|
|
); |
2489
|
|
|
//delete folder |
2490
|
|
|
DB::delete(prefix_table("nested_tree"), "id = %i", $folder->id); |
2491
|
|
|
|
2492
|
|
|
//delete items & logs |
2493
|
|
|
$items = DB::query( |
2494
|
|
|
"SELECT id |
2495
|
|
|
FROM ".prefix_table("items")." |
2496
|
|
|
WHERE id_tree=%i", |
2497
|
|
|
$folder->id |
2498
|
|
|
); |
2499
|
|
|
foreach ($items as $item) { |
2500
|
|
|
DB::update( |
2501
|
|
|
prefix_table("items"), |
2502
|
|
|
array( |
2503
|
|
|
'inactif' => '1', |
2504
|
|
|
), |
2505
|
|
|
"id = %i", |
2506
|
|
|
$item['id'] |
2507
|
|
|
); |
2508
|
|
|
//log |
2509
|
|
|
DB::insert( |
2510
|
|
|
prefix_table("log_items"), |
2511
|
|
|
array( |
2512
|
|
|
'id_item' => $item['id'], |
2513
|
|
|
'date' => time(), |
2514
|
|
|
'id_user' => $user_id, |
2515
|
|
|
'action' => 'at_delete' |
2516
|
|
|
) |
2517
|
|
|
); |
2518
|
|
|
} |
2519
|
|
|
//Update CACHE table |
2520
|
|
|
updateCacheTable("delete_value", $array_category[$i]); |
2521
|
|
|
} |
2522
|
|
|
} |
2523
|
|
|
} |
2524
|
|
|
} else { |
|
|
|
|
2525
|
|
|
// Folder doesn't exist |
2526
|
|
|
} |
2527
|
|
|
} |
2528
|
|
|
} else { |
2529
|
|
|
rest_error('NO_CATEGORY'); |
2530
|
|
|
} |
2531
|
|
|
|
2532
|
|
|
$json['status'] = 'OK'; |
2533
|
|
|
} elseif ($GLOBALS['request'][1] == "item") { |
2534
|
|
|
$array_items = explode(';', $GLOBALS['request'][2]); |
2535
|
|
|
|
2536
|
|
|
// get user info |
2537
|
|
|
if (isset($GLOBALS['request'][3]) && !empty($GLOBALS['request'][3])) { |
2538
|
|
|
$userData = DB::queryFirstRow( |
2539
|
|
|
"SELECT `id` FROM ".$pre."users WHERE login = %s", |
2540
|
|
|
$GLOBALS['request'][3] |
2541
|
|
|
); |
2542
|
|
|
if (DB::count() == 0) { |
2543
|
|
|
$user_id = API_USER_ID; |
2544
|
|
|
} else { |
2545
|
|
|
$user_id = $userData['id']; |
2546
|
|
|
} |
2547
|
|
|
} |
2548
|
|
|
|
2549
|
|
|
for ($i = 0, $c = count($array_items); $i < $c; $i++) { |
2550
|
|
|
DB::update( |
2551
|
|
|
prefix_table("items"), |
2552
|
|
|
array( |
2553
|
|
|
'inactif' => '1', |
2554
|
|
|
), |
2555
|
|
|
"id = %i", |
2556
|
|
|
$array_items[$i] |
2557
|
|
|
); |
2558
|
|
|
//log |
2559
|
|
|
DB::insert( |
2560
|
|
|
prefix_table("log_items"), |
2561
|
|
|
array( |
2562
|
|
|
'id_item' => $array_items[$i], |
2563
|
|
|
'date' => time(), |
2564
|
|
|
'id_user' => $user_id, |
2565
|
|
|
'action' => 'at_delete' |
2566
|
|
|
) |
2567
|
|
|
); |
2568
|
|
|
|
2569
|
|
|
//Update CACHE table |
2570
|
|
|
updateCacheTable("delete_value", $array_items[$i]); |
2571
|
|
|
} |
2572
|
|
|
|
2573
|
|
|
$json['status'] = 'OK'; |
2574
|
|
|
} |
2575
|
|
|
|
2576
|
|
|
if ($json) { |
|
|
|
|
2577
|
|
|
echo json_encode($json); |
2578
|
|
|
} else { |
2579
|
|
|
rest_error('EMPTY'); |
2580
|
|
|
} |
2581
|
|
|
} elseif ($GLOBALS['request'][0] == "new_password") { |
2582
|
|
|
if (!empty($GLOBALS['request'][1])) { |
2583
|
|
|
$params = explode(";", $GLOBALS['request'][1]); |
2584
|
|
|
|
2585
|
|
|
if (empty($params[0])) { |
2586
|
|
|
$params[0] = 8; |
2587
|
|
|
} |
2588
|
|
|
if (empty($params[1])) { |
2589
|
|
|
$params[1] = 0; |
2590
|
|
|
} |
2591
|
|
|
if (empty($params[2])) { |
2592
|
|
|
$params[2] = 0; |
2593
|
|
|
} |
2594
|
|
|
if (empty($params[3])) { |
2595
|
|
|
$params[3] = 0; |
2596
|
|
|
} |
2597
|
|
|
if (empty($params[4])) { |
2598
|
|
|
$params[4] = 0; |
2599
|
|
|
} |
2600
|
|
|
if (empty($params[5])) { |
2601
|
|
|
$params[5] = 0; |
2602
|
|
|
} |
2603
|
|
|
if (empty($params[6])) { |
2604
|
|
|
$params[6] = 0; |
2605
|
|
|
} |
2606
|
|
|
|
2607
|
|
|
// Generate key |
2608
|
|
|
$pwd = GenerateCryptKey( |
2609
|
|
|
$params[0], |
2610
|
|
|
$params[1] === "1" ? true : false, |
2611
|
|
|
$params[2] === "1" ? true : false, |
2612
|
|
|
$params[3] === "1" ? true : false, |
2613
|
|
|
$params[5] === "1" && $params[6] === "1" ? true : false |
2614
|
|
|
); |
2615
|
|
|
|
2616
|
|
|
// generate and send back (generate in base64 if symbols are asked) |
2617
|
|
|
if ($params[6] === "1") { |
2618
|
|
|
echo '{"password" : "'.base64_encode($pwd).'"}'; |
2619
|
|
|
} else { |
2620
|
|
|
echo '{"password" : "'.$pwd.'"}'; |
2621
|
|
|
} |
2622
|
|
|
} else { |
2623
|
|
|
rest_error('NO_PARAMETERS'); |
2624
|
|
|
} |
2625
|
|
|
} elseif ($GLOBALS['request'][0] === "info") { |
2626
|
|
|
if ($GLOBALS['request'][1] === "complexicity_levels_list") { |
2627
|
|
|
require_once '../includes/language/english.php'; |
2628
|
|
|
$json = array( |
2629
|
|
|
0=> $LANG['complex_level0'], |
2630
|
|
|
25=> $LANG['complex_level1'], |
2631
|
|
|
50=> $LANG['complex_level2'], |
2632
|
|
|
60=> $LANG['complex_level3'], |
2633
|
|
|
70=> $LANG['complex_level4'], |
2634
|
|
|
80=> $LANG['complex_level5'], |
2635
|
|
|
90=> $LANG['complex_level6'] |
2636
|
|
|
); |
2637
|
|
|
|
2638
|
|
|
echo json_encode($json); |
2639
|
|
|
} elseif ($GLOBALS['request'][1] === "folder") { |
2640
|
|
|
if (!empty($GLOBALS['request'][2]) && is_numeric($GLOBALS['request'][2])) { |
2641
|
|
|
$data = DB::queryFirstRow( |
2642
|
|
|
"SELECT * FROM ".$pre."nested_tree WHERE id = %i", |
2643
|
|
|
$GLOBALS['request'][2] |
2644
|
|
|
); |
2645
|
|
|
if (DB::count() == 0) { |
2646
|
|
|
rest_error('NOSUCHFOLDER'); |
2647
|
|
|
} |
2648
|
|
|
|
2649
|
|
|
// form id_tree to full foldername |
2650
|
|
|
require_once '../sources/SplClassLoader.php'; |
2651
|
|
|
//Load Tree |
2652
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
2653
|
|
|
$tree->register(); |
2654
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
2655
|
|
|
|
2656
|
|
|
$folder = ""; |
2657
|
|
|
$arbo = $tree->getPath($GLOBALS['request'][2], true); |
2658
|
|
|
foreach ($arbo as $elem) { |
2659
|
|
|
if (empty($folder)) { |
2660
|
|
|
$folder = stripslashes($elem->title); |
2661
|
|
|
} else { |
2662
|
|
|
$folder .= " > ".stripslashes($elem->title); |
2663
|
|
|
} |
2664
|
|
|
} |
2665
|
|
|
|
2666
|
|
|
// prepare info |
2667
|
|
|
$json = array( |
2668
|
|
|
"title" => $data['title'], |
2669
|
|
|
"personal_folder" => $data['personal_folder'], |
2670
|
|
|
"renewal_period" => $data['renewal_period'], |
2671
|
|
|
"parent_id" => $data['parent_id'], |
2672
|
|
|
"path" => $folder, |
2673
|
|
|
); |
2674
|
|
|
|
2675
|
|
|
echo json_encode($json); |
2676
|
|
|
} else { |
2677
|
|
|
rest_error('NO_PARAMETERS'); |
2678
|
|
|
} |
2679
|
|
|
} elseif ($GLOBALS['request'][1] === "version") { |
2680
|
|
|
echo '{"api-version":"'.$api_version.'"}'; |
2681
|
|
|
} else { |
2682
|
|
|
rest_error('NO_PARAMETERS'); |
2683
|
|
|
} |
2684
|
|
|
} else { |
2685
|
|
|
rest_error('METHOD'); |
2686
|
|
|
} |
2687
|
|
|
} |
2688
|
|
|
} |
2689
|
|
|
|
2690
|
|
|
function rest_put() |
2691
|
|
|
{ |
2692
|
|
|
if (!@count($GLOBALS['request']) == 0) { |
2693
|
|
|
$request_uri = $GLOBALS['_SERVER']['REQUEST_URI']; |
2694
|
|
|
preg_match('/\/api(\/index.php|)\/(.*)\?apikey=(.*)/', $request_uri, $matches); |
2695
|
|
|
if (count($matches) == 0) { |
2696
|
|
|
rest_error('REQUEST_SENT_NOT_UNDERSTANDABLE'); |
2697
|
|
|
} |
2698
|
|
|
$GLOBALS['request'] = explode('/', $matches[2]); |
2699
|
|
|
} |
2700
|
|
|
if (apikey_checker($GLOBALS['apikey'])) { |
2701
|
|
|
teampass_connect(); |
2702
|
|
|
} |
2703
|
|
|
} |
2704
|
|
|
|
2705
|
|
|
/** |
2706
|
|
|
* @param string $type |
2707
|
|
|
*/ |
2708
|
|
|
function rest_error($type, $detail = 'N/A') |
2709
|
|
|
{ |
2710
|
|
|
switch ($type) { |
2711
|
|
|
case 'APIKEY': |
2712
|
|
|
$message = array('err' => 'This api_key '.$GLOBALS['apikey'].' doesn\'t exist', 'code' => 'API_KEY_NOT_FOUND'); |
2713
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2714
|
|
|
break; |
2715
|
|
|
case 'NO_CATEGORY': |
2716
|
|
|
$message = array('err' => 'No folder specified'); |
2717
|
|
|
break; |
2718
|
|
|
case 'NO_ITEM': |
2719
|
|
|
$message = array('err' => 'No item specified'); |
2720
|
|
|
break; |
2721
|
|
|
case 'EMPTY': |
2722
|
|
|
$message = array('err' => 'No results'); |
2723
|
|
|
break; |
2724
|
|
|
case 'IPWHITELIST': |
2725
|
|
|
$message = array('err' => 'Ip address not allowed.'); |
2726
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2727
|
|
|
break; |
2728
|
|
|
case 'MYSQLERR': |
2729
|
|
|
$message = array('err' => $detail); |
2730
|
|
|
header('HTTP/1.1 500 Internal Server Error'); |
2731
|
|
|
break; |
2732
|
|
|
case 'METHOD': |
2733
|
|
|
$message = array('err' => 'Method not authorized', 'code' => 'METHOD_NOT_AUTHORIZED'); |
2734
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2735
|
|
|
break; |
2736
|
|
|
case 'ITEMBADDEFINITION': |
2737
|
|
|
$message = array('err' => 'Item definition not complete'); |
2738
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2739
|
|
|
break; |
2740
|
|
|
case 'ITEM_MALFORMED': |
2741
|
|
|
$message = array('err' => 'Item definition not numeric'); |
2742
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2743
|
|
|
break; |
2744
|
|
|
case 'USERBADDEFINITION': |
2745
|
|
|
$message = array('err' => 'User definition not complete'); |
2746
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2747
|
|
|
break; |
2748
|
|
|
case 'USERLOGINEMPTY': |
2749
|
|
|
$message = array('err' => 'Empty Login given'); |
2750
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2751
|
|
|
break; |
2752
|
|
|
case 'USERALREADYEXISTS': |
2753
|
|
|
$message = array('err' => 'User already exists'); |
2754
|
|
|
header('HTTP/1.1 405 Method Not Allowed'); |
2755
|
|
|
break; |
2756
|
|
|
case 'REQUEST_SENT_NOT_UNDERSTANDABLE': |
2757
|
|
|
$message = array('err' => 'URL format is not following requirements'); |
2758
|
|
|
break; |
2759
|
|
|
case 'AUTH_NOT_GRANTED': |
2760
|
|
|
$message = array('err' => 'Bad credentials for user', 'code' => 'AUTH_NOT_GRANTED'); |
2761
|
|
|
header('HTTP/1.1 404 Error'); |
2762
|
|
|
break; |
2763
|
|
|
case 'AUTH_NO_URL': |
2764
|
|
|
$message = array('err' => 'URL needed to grant access'); |
2765
|
|
|
break; |
2766
|
|
|
case 'AUTH_NO_IDENTIFIER': |
2767
|
|
|
$message = array('err' => 'Credentials needed to grant access', 'code' => 'AUTH_NO_IDENTIFIER'); |
2768
|
|
|
break; |
2769
|
|
|
case 'AUTH_NO_DATA': |
2770
|
|
|
$message = array('err' => 'Data not allowed for the user', 'code' => 'AUTH_NO_DATA'); |
2771
|
|
|
break; |
2772
|
|
|
case 'AUTH_PSK_ERROR': |
2773
|
|
|
$message = array('err' => 'Personal Saltkey is wrong', 'code' => 'AUTH_PSK_ERROR'); |
2774
|
|
|
header('HTTP/1.1 404 Error'); |
2775
|
|
|
break; |
2776
|
|
|
case 'NO_DATA_EXIST': |
2777
|
|
|
$message = array('err' => 'No data exists', 'code' => 'NO_DATA_EXIST'); |
2778
|
|
|
break; |
2779
|
|
|
case 'NO_DESTINATION_FOLDER': |
2780
|
|
|
$message = array('err' => 'No destination folder provided'); |
2781
|
|
|
break; |
2782
|
|
|
case 'PASSWORDTOOLONG': |
2783
|
|
|
$message = array('err' => 'Password is too long'); |
2784
|
|
|
break; |
2785
|
|
|
case 'NOSUCHFOLDER': |
2786
|
|
|
$message = array('err' => 'Folder ID does not exist'); |
2787
|
|
|
break; |
2788
|
|
|
case 'PASSWORDEMPTY': |
2789
|
|
|
$message = array('err' => 'Password is empty'); |
2790
|
|
|
break; |
2791
|
|
|
case 'ITEMEXISTS': |
2792
|
|
|
$message = array('err' => 'Label already exists'); |
2793
|
|
|
break; |
2794
|
|
|
case 'ITEMMISSINGDATA': |
2795
|
|
|
$message = array('err' => 'Label or Password or Folder ID is missing'); |
2796
|
|
|
break; |
2797
|
|
|
case 'SET_NO_DATA': |
2798
|
|
|
$message = array('err' => 'No data to be stored'); |
2799
|
|
|
break; |
2800
|
|
|
case 'NO_PF_EXIST_FOR_USER': |
2801
|
|
|
$message = array('err' => 'No Personal Folder exists for this user'); |
2802
|
|
|
break; |
2803
|
|
|
case 'HTML_CODES_NOT_ALLOWED': |
2804
|
|
|
$message = array('err' => 'HTML tags not allowed'); |
2805
|
|
|
break; |
2806
|
|
|
case 'TITLE_ONLY_WITH_NUMBERS': |
2807
|
|
|
$message = array('err' => 'Title only with numbers not allowed'); |
2808
|
|
|
break; |
2809
|
|
|
case 'ALREADY_EXISTS': |
2810
|
|
|
$message = array('err' => 'Data already exists'); |
2811
|
|
|
break; |
2812
|
|
|
case 'COMPLEXICITY_LEVEL_NOT_REACHED': |
2813
|
|
|
$message = array('err' => 'complexity level was not reached'); |
2814
|
|
|
break; |
2815
|
|
|
case 'NO_PARAMETERS': |
2816
|
|
|
$message = array('err' => 'No parameters given'); |
2817
|
|
|
break; |
2818
|
|
|
case 'USER_NOT_EXISTS': |
2819
|
|
|
$message = array('err' => 'User does not exist'); |
2820
|
|
|
break; |
2821
|
|
|
case 'NO_PSALTK_PROVIDED': |
2822
|
|
|
$message = array('err' => 'No Personal saltkey provided'); |
2823
|
|
|
break; |
2824
|
|
|
case 'EXPECTED_PARAMETER_NOT_PROVIDED': |
2825
|
|
|
$message = array('err' => 'Provided parameters are not correct'); |
2826
|
|
|
break; |
2827
|
|
|
default: |
2828
|
|
|
$message = array('err' => 'Something happen ... but what ?'); |
2829
|
|
|
header('HTTP/1.1 500 Internal Server Error'); |
2830
|
|
|
break; |
2831
|
|
|
} |
2832
|
|
|
|
2833
|
|
|
echo json_encode($message); |
2834
|
|
|
exit(0); |
|
|
|
|
2835
|
|
|
} |
2836
|
|
|
|
2837
|
|
|
function apikey_checker($apikey_used) |
2838
|
|
|
{ |
2839
|
|
|
teampass_connect(); |
2840
|
|
|
$apikey_pool = teampass_get_keys(); |
2841
|
|
|
|
2842
|
|
|
// if needed extract key from credentials |
2843
|
|
|
if (strlen($apikey_used) > 40) { |
2844
|
|
|
$userCredentials = Urlsafe_b64decode(substr($apikey_used, 40)); |
|
|
|
|
2845
|
|
|
$apikey_used = substr($apikey_used, 0, 39); |
2846
|
|
|
} |
2847
|
|
|
|
2848
|
|
|
if (in_array($apikey_used, $apikey_pool)) { |
2849
|
|
|
return(1); |
2850
|
|
|
} else { |
2851
|
|
|
rest_error('APIKEY', $apikey_used); |
2852
|
|
|
} |
2853
|
|
|
} |
2854
|
|
|
|
2855
|
|
|
function teampass_pbkdf2_hash($var_p, $var_s, $var_c, $var_kl, $var_st = 0, $var_a = 'sha256') |
2856
|
|
|
{ |
2857
|
|
|
$var_kb = $var_st + $var_kl; |
2858
|
|
|
$var_dk = ''; |
2859
|
|
|
|
2860
|
|
|
for ($block = 1; $block <= $var_kb; $block++) { |
2861
|
|
|
$var_ib = $var_h = hash_hmac($var_a, $var_s.pack('N', $block), $var_p, true); |
2862
|
|
|
for ($var_i = 1; $var_i < $var_c; $var_i++) { |
2863
|
|
|
$var_ib ^= ($var_h = hash_hmac($var_a, $var_h, $var_p, true)); |
2864
|
|
|
} |
2865
|
|
|
$var_dk .= $var_ib; |
2866
|
|
|
} |
2867
|
|
|
|
2868
|
|
|
return substr($var_dk, $var_st, $var_kl); |
2869
|
|
|
} |
2870
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.