api-functions.php 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. <?php /** @noinspection SqlResolve */
  2. /** @noinspection SqlResolve */
  3. /** @noinspection SqlResolve */
  4. /** @noinspection SqlResolve */
  5. /** @noinspection SyntaxError */
  6. function login($array)
  7. {
  8. // Grab username and Password from login form
  9. $username = $password = $oAuth = $oAuthType = '';
  10. foreach ($array['data'] as $items) {
  11. foreach ($items as $key => $value) {
  12. if ($key == 'name') {
  13. $newKey = $value;
  14. }
  15. if ($key == 'value') {
  16. $newValue = $value;
  17. }
  18. if (isset($newKey) && isset($newValue)) {
  19. $$newKey = $newValue;
  20. }
  21. }
  22. }
  23. $username = strtolower($username);
  24. $days = (isset($remember)) ? 7 : 1;
  25. $oAuth = (isset($oAuth)) ? $oAuth : false;
  26. try {
  27. $database = new Dibi\Connection([
  28. 'driver' => 'sqlite3',
  29. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  30. ]);
  31. $authSuccess = false;
  32. $function = 'plugin_auth_' . $GLOBALS['authBackend'];
  33. if (!$oAuth) {
  34. $result = $database->fetch('SELECT * FROM users WHERE username = ? COLLATE NOCASE OR email = ? COLLATE NOCASE', $username, $username);
  35. switch ($GLOBALS['authType']) {
  36. case 'external':
  37. if (function_exists($function)) {
  38. $authSuccess = $function($username, $password);
  39. }
  40. break;
  41. /** @noinspection PhpMissingBreakStatementInspection */
  42. case 'both':
  43. if (function_exists($function)) {
  44. $authSuccess = $function($username, $password);
  45. }
  46. // no break
  47. default: // Internal
  48. if (!$authSuccess) {
  49. // perform the internal authentication step
  50. if (password_verify($password, $result['password'])) {
  51. $authSuccess = true;
  52. }
  53. }
  54. }
  55. } else {
  56. // Has oAuth Token!
  57. switch ($oAuthType) {
  58. case 'plex':
  59. $tokenInfo = checkPlexToken($oAuth);
  60. if ($tokenInfo) {
  61. $authSuccess = array(
  62. 'username' => $tokenInfo['user']['username'],
  63. 'email' => $tokenInfo['user']['email'],
  64. 'image' => $tokenInfo['user']['thumb'],
  65. 'token' => $tokenInfo['user']['authToken']
  66. );
  67. $authSuccess = ((!empty($GLOBALS['plexAdmin']) && strtolower($GLOBALS['plexAdmin']) == strtolower($tokenInfo['user']['username'])) || checkPlexUser($tokenInfo['user']['username'])) ? $authSuccess : false;
  68. }
  69. break;
  70. default:
  71. return 'error';
  72. break;
  73. }
  74. $result = ($authSuccess) ? $database->fetch('SELECT * FROM users WHERE username = ? COLLATE NOCASE OR email = ? COLLATE NOCASE', $authSuccess['username'], $authSuccess['email']) : '';
  75. }
  76. if ($authSuccess) {
  77. // Make sure user exists in database
  78. $userExists = false;
  79. $passwordMatches = ($oAuth) ? true : false;
  80. $token = (is_array($authSuccess) && isset($authSuccess['token']) ? $authSuccess['token'] : '');
  81. if ($result['username']) {
  82. $userExists = true;
  83. $username = $result['username'];
  84. $passwordMatches = (password_verify($password, $result['password'])) ? true : false;
  85. }
  86. if ($userExists) {
  87. //does org password need to be updated
  88. if (!$passwordMatches) {
  89. $database->query('
  90. UPDATE users SET', [
  91. 'password' => password_hash($password, PASSWORD_BCRYPT)
  92. ], '
  93. WHERE id=?', $result['id']);
  94. writeLog('success', 'Login Function - User Password updated from backend', $username);
  95. }
  96. if ($token !== '') {
  97. if ($token !== $result['plex_token']) {
  98. $database->query('
  99. UPDATE users SET', [
  100. 'plex_token' => $token
  101. ], '
  102. WHERE id=?', $result['id']);
  103. writeLog('success', 'Login Function - User Plex Token updated from backend', $username);
  104. }
  105. }
  106. // 2FA might go here
  107. if ($result['auth_service'] !== 'internal' && strpos($result['auth_service'], '::') !== false) {
  108. $TFA = explode('::', $result['auth_service']);
  109. // Is code with login info?
  110. if ($tfaCode == '') {
  111. return '2FA';
  112. } else {
  113. if (!verify2FA($TFA[1], $tfaCode, $TFA[0])) {
  114. return '2FA-incorrect';
  115. }
  116. }
  117. }
  118. // End 2FA
  119. // authentication passed - 1) mark active and update token
  120. if (createToken($result['username'], $result['email'], $result['image'], $result['group'], $result['group_id'], $GLOBALS['organizrHash'], $days)) {
  121. writeLoginLog($username, 'success');
  122. writeLog('success', 'Login Function - A User has logged in', $username);
  123. ssoCheck($username, $password, $token); //need to work on this
  124. return true;
  125. } else {
  126. return 'error';
  127. }
  128. } else {
  129. // Create User
  130. ssoCheck($username, $password, $token);
  131. return authRegister((is_array($authSuccess) && isset($authSuccess['username']) ? $authSuccess['username'] : $username), $password, defaultUserGroup(), (is_array($authSuccess) && isset($authSuccess['email']) ? $authSuccess['email'] : ''));
  132. }
  133. } else {
  134. // authentication failed
  135. writeLoginLog($username, 'error');
  136. writeLog('error', 'Login Function - Wrong Password', $username);
  137. return 'mismatch';
  138. }
  139. } catch (Dibi\Exception $e) {
  140. return $e;
  141. }
  142. }
  143. function createDB($path, $filename)
  144. {
  145. try {
  146. if (!file_exists($path)) {
  147. mkdir($path, 0777, true);
  148. }
  149. $createDB = new Dibi\Connection([
  150. 'driver' => 'sqlite3',
  151. 'database' => $path . $filename,
  152. ]);
  153. // Create Users
  154. $createDB->query('CREATE TABLE `users` (
  155. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  156. `username` TEXT UNIQUE,
  157. `password` TEXT,
  158. `email` TEXT,
  159. `plex_token` TEXT,
  160. `group` TEXT,
  161. `group_id` INTEGER,
  162. `locked` INTEGER,
  163. `image` TEXT,
  164. `register_date` DATE,
  165. `auth_service` TEXT DEFAULT \'internal\'
  166. );');
  167. // Create Tokens
  168. $createDB->query('CREATE TABLE `chatroom` (
  169. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  170. `username` TEXT,
  171. `gravatar` TEXT,
  172. `uid` TEXT,
  173. `date` DATE,
  174. `ip` TEXT,
  175. `message` TEXT
  176. );');
  177. $createDB->query('CREATE TABLE `tokens` (
  178. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  179. `token` TEXT UNIQUE,
  180. `user_id` INTEGER,
  181. `created` DATE,
  182. `expires` DATE
  183. );');
  184. $createDB->query('CREATE TABLE `groups` (
  185. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  186. `group` TEXT UNIQUE,
  187. `group_id` INTEGER,
  188. `image` TEXT,
  189. `default` INTEGER
  190. );');
  191. $createDB->query('CREATE TABLE `categories` (
  192. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  193. `order` INTEGER,
  194. `category` TEXT UNIQUE,
  195. `category_id` INTEGER,
  196. `image` TEXT,
  197. `default` INTEGER
  198. );');
  199. // Create Tabs
  200. $createDB->query('CREATE TABLE `tabs` (
  201. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  202. `order` INTEGER,
  203. `category_id` INTEGER,
  204. `name` TEXT,
  205. `url` TEXT,
  206. `url_local` TEXT,
  207. `default` INTEGER,
  208. `enabled` INTEGER,
  209. `group_id` INTEGER,
  210. `image` TEXT,
  211. `type` INTEGER,
  212. `splash` INTEGER,
  213. `ping` INTEGER,
  214. `ping_url` TEXT
  215. );');
  216. // Create Options
  217. $createDB->query('CREATE TABLE `options` (
  218. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  219. `name` TEXT UNIQUE,
  220. `value` TEXT
  221. );');
  222. // Create Invites
  223. $createDB->query('CREATE TABLE `invites` (
  224. `id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
  225. `code` TEXT UNIQUE,
  226. `date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  227. `email` TEXT,
  228. `username` TEXT,
  229. `dateused` TIMESTAMP,
  230. `usedby` TEXT,
  231. `ip` TEXT,
  232. `valid` TEXT,
  233. `type` TEXT
  234. );');
  235. return true;
  236. } catch (Dibi\Exception $e) {
  237. return false;
  238. }
  239. }
  240. // Upgrade Database
  241. function updateDB($oldVerNum = false)
  242. {
  243. $tempLock = $GLOBALS['dbLocation'] . 'DBLOCK.txt';
  244. if (!file_exists($tempLock)) {
  245. touch($tempLock);
  246. // Create Temp DB First
  247. $migrationDB = 'tempMigration.db';
  248. $pathDigest = pathinfo($GLOBALS['dbLocation'] . $GLOBALS['dbName']);
  249. if (file_exists($GLOBALS['dbLocation'] . $migrationDB)) {
  250. unlink($GLOBALS['dbLocation'] . $migrationDB);
  251. }
  252. $backupDB = $pathDigest['dirname'] . '/' . $pathDigest['filename'] . '[' . date('Y-m-d_H-i-s') . ']' . ($oldVerNum ? '[' . $oldVerNum . ']' : '') . '.bak.db';
  253. copy($GLOBALS['dbLocation'] . $GLOBALS['dbName'], $backupDB);
  254. $success = createDB($GLOBALS['dbLocation'], $migrationDB);
  255. if ($success) {
  256. try {
  257. $connectOldDB = new Dibi\Connection([
  258. 'driver' => 'sqlite3',
  259. 'database' => $backupDB,
  260. ]);
  261. $connectNewDB = new Dibi\Connection([
  262. 'driver' => 'sqlite3',
  263. 'database' => $GLOBALS['dbLocation'] . $migrationDB,
  264. ]);
  265. $tables = $connectOldDB->fetchAll('SELECT name FROM sqlite_master WHERE type="table"');
  266. foreach ($tables as $table) {
  267. $data = $connectOldDB->fetchAll('SELECT * FROM ' . $table['name']);
  268. foreach ($data as $row) {
  269. $connectNewDB->query('INSERT into ' . $table['name'], $row);
  270. }
  271. }
  272. $connectOldDB->disconnect();
  273. $connectNewDB->disconnect();
  274. // Remove Current Database
  275. if (file_exists($GLOBALS['dbLocation'] . $migrationDB)) {
  276. $oldFileSize = filesize($GLOBALS['dbLocation'] . $GLOBALS['dbName']);
  277. $newFileSize = filesize($GLOBALS['dbLocation'] . $migrationDB);
  278. if ($newFileSize >= $oldFileSize) {
  279. @unlink($GLOBALS['dbLocation'] . $GLOBALS['dbName']);
  280. copy($GLOBALS['dbLocation'] . $migrationDB, $GLOBALS['dbLocation'] . $GLOBALS['dbName']);
  281. @unlink($GLOBALS['dbLocation'] . $migrationDB);
  282. writeLog('success', 'Update Function - Migrated Old Info to new Database', 'Database');
  283. unlink($tempLock);
  284. return true;
  285. }
  286. }
  287. unlink($tempLock);
  288. return false;
  289. } catch (Dibi\Exception $e) {
  290. writeLog('error', 'Update Function - Error [' . $e . ']', 'Database');
  291. unlink($tempLock);
  292. return false;
  293. }
  294. }
  295. unlink($tempLock);
  296. return false;
  297. }
  298. return false;
  299. }
  300. function createFirstAdmin($path, $filename, $username, $password, $email)
  301. {
  302. try {
  303. $createDB = new Dibi\Connection([
  304. 'driver' => 'sqlite3',
  305. 'database' => $path . $filename,
  306. ]);
  307. $userInfo = [
  308. 'username' => $username,
  309. 'password' => password_hash($password, PASSWORD_BCRYPT),
  310. 'email' => $email,
  311. 'group' => 'Admin',
  312. 'group_id' => 0,
  313. 'image' => gravatar($email),
  314. 'register_date' => $GLOBALS['currentTime'],
  315. ];
  316. $groupInfo0 = [
  317. 'group' => 'Admin',
  318. 'group_id' => 0,
  319. 'default' => false,
  320. 'image' => 'plugins/images/groups/admin.png',
  321. ];
  322. $groupInfo1 = [
  323. 'group' => 'Co-Admin',
  324. 'group_id' => 1,
  325. 'default' => false,
  326. 'image' => 'plugins/images/groups/coadmin.png',
  327. ];
  328. $groupInfo2 = [
  329. 'group' => 'Super User',
  330. 'group_id' => 2,
  331. 'default' => false,
  332. 'image' => 'plugins/images/groups/superuser.png',
  333. ];
  334. $groupInfo3 = [
  335. 'group' => 'Power User',
  336. 'group_id' => 3,
  337. 'default' => false,
  338. 'image' => 'plugins/images/groups/poweruser.png',
  339. ];
  340. $groupInfo4 = [
  341. 'group' => 'User',
  342. 'group_id' => 4,
  343. 'default' => true,
  344. 'image' => 'plugins/images/groups/user.png',
  345. ];
  346. $groupInfoGuest = [
  347. 'group' => 'Guest',
  348. 'group_id' => 999,
  349. 'default' => false,
  350. 'image' => 'plugins/images/groups/guest.png',
  351. ];
  352. $settingsInfo = [
  353. 'order' => 1,
  354. 'category_id' => 0,
  355. 'name' => 'Settings',
  356. 'url' => 'api/?v1/settings/page',
  357. 'default' => false,
  358. 'enabled' => true,
  359. 'group_id' => 1,
  360. 'image' => 'fontawesome::cog',
  361. 'type' => 0
  362. ];
  363. $homepageInfo = [
  364. 'order' => 2,
  365. 'category_id' => 0,
  366. 'name' => 'Homepage',
  367. 'url' => 'api/?v1/homepage/page',
  368. 'default' => false,
  369. 'enabled' => false,
  370. 'group_id' => 4,
  371. 'image' => 'fontawesome::home',
  372. 'type' => 0
  373. ];
  374. $unsortedInfo = [
  375. 'order' => 1,
  376. 'category' => 'Unsorted',
  377. 'category_id' => 0,
  378. 'image' => 'plugins/images/categories/unsorted.png',
  379. 'default' => true
  380. ];
  381. $createDB->query('INSERT INTO [users]', $userInfo);
  382. $createDB->query('INSERT INTO [groups]', $groupInfo0);
  383. $createDB->query('INSERT INTO [groups]', $groupInfo1);
  384. $createDB->query('INSERT INTO [groups]', $groupInfo2);
  385. $createDB->query('INSERT INTO [groups]', $groupInfo3);
  386. $createDB->query('INSERT INTO [groups]', $groupInfo4);
  387. $createDB->query('INSERT INTO [groups]', $groupInfoGuest);
  388. $createDB->query('INSERT INTO [tabs]', $settingsInfo);
  389. $createDB->query('INSERT INTO [tabs]', $homepageInfo);
  390. $createDB->query('INSERT INTO [categories]', $unsortedInfo);
  391. return true;
  392. } catch (Dibi\Exception $e) {
  393. writeLog('error', 'Wizard Function - Error [' . $e . ']', 'Wizard');
  394. return false;
  395. }
  396. }
  397. function defaultUserGroup()
  398. {
  399. try {
  400. $connect = new Dibi\Connection([
  401. 'driver' => 'sqlite3',
  402. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  403. ]);
  404. $all = $connect->fetch('SELECT * FROM groups WHERE `default` = 1');
  405. return $all;
  406. } catch (Dibi\Exception $e) {
  407. return false;
  408. }
  409. }
  410. function defaultTabCategory()
  411. {
  412. try {
  413. $connect = new Dibi\Connection([
  414. 'driver' => 'sqlite3',
  415. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  416. ]);
  417. $all = $connect->fetch('SELECT * FROM categories WHERE `default` = 1');
  418. return $all;
  419. } catch (Dibi\Exception $e) {
  420. return false;
  421. }
  422. }
  423. function getGuest()
  424. {
  425. if (isset($GLOBALS['dbLocation'])) {
  426. try {
  427. $connect = new Dibi\Connection([
  428. 'driver' => 'sqlite3',
  429. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  430. ]);
  431. $all = $connect->fetch('SELECT * FROM groups WHERE `group` = "Guest"');
  432. return $all;
  433. } catch (Dibi\Exception $e) {
  434. return false;
  435. }
  436. } else {
  437. return array(
  438. 'group' => 'Guest',
  439. 'group_id' => 999,
  440. 'image' => 'plugins/images/groups/guest.png'
  441. );
  442. }
  443. }
  444. function adminEditGroup($array)
  445. {
  446. switch ($array['data']['action']) {
  447. case 'changeDefaultGroup':
  448. try {
  449. $connect = new Dibi\Connection([
  450. 'driver' => 'sqlite3',
  451. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  452. ]);
  453. $connect->query('UPDATE groups SET `default` = 0');
  454. $connect->query('
  455. UPDATE groups SET', [
  456. 'default' => 1
  457. ], '
  458. WHERE id=?', $array['data']['id']);
  459. writeLog('success', 'Group Management Function - Changed Default Group from [' . $array['data']['oldGroupName'] . '] to [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  460. return true;
  461. } catch (Dibi\Exception $e) {
  462. return false;
  463. }
  464. break;
  465. case 'deleteUserGroup':
  466. try {
  467. $connect = new Dibi\Connection([
  468. 'driver' => 'sqlite3',
  469. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  470. ]);
  471. $connect->query('DELETE FROM groups WHERE id = ?', $array['data']['id']);
  472. writeLog('success', 'Group Management Function - Deleted Group [' . $array['data']['groupName'] . ']', $GLOBALS['organizrUser']['username']);
  473. return true;
  474. } catch (Dibi\Exception $e) {
  475. return false;
  476. }
  477. break;
  478. case 'addUserGroup':
  479. try {
  480. $connect = new Dibi\Connection([
  481. 'driver' => 'sqlite3',
  482. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  483. ]);
  484. $newGroup = [
  485. 'group' => $array['data']['newGroupName'],
  486. 'group_id' => $array['data']['newGroupID'],
  487. 'default' => false,
  488. 'image' => $array['data']['newGroupImage'],
  489. ];
  490. $connect->query('INSERT INTO [groups]', $newGroup);
  491. writeLog('success', 'Group Management Function - Added Group [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  492. return true;
  493. } catch (Dibi\Exception $e) {
  494. return false;
  495. }
  496. break;
  497. case 'editUserGroup':
  498. try {
  499. $connect = new Dibi\Connection([
  500. 'driver' => 'sqlite3',
  501. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  502. ]);
  503. $connect->query('
  504. UPDATE groups SET', [
  505. 'group' => $array['data']['groupName'],
  506. 'image' => $array['data']['groupImage'],
  507. ], '
  508. WHERE id=?', $array['data']['id']);
  509. writeLog('success', 'Group Management Function - Edited Group Info for [' . $array['data']['oldGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  510. return true;
  511. } catch (Dibi\Exception $e) {
  512. return false;
  513. }
  514. break;
  515. default:
  516. return false;
  517. break;
  518. }
  519. }
  520. function adminEditUser($array)
  521. {
  522. switch ($array['data']['action']) {
  523. case 'changeGroup':
  524. try {
  525. $connect = new Dibi\Connection([
  526. 'driver' => 'sqlite3',
  527. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  528. ]);
  529. $connect->query('
  530. UPDATE users SET', [
  531. 'group' => $array['data']['newGroupName'],
  532. 'group_id' => $array['data']['newGroupID'],
  533. ], '
  534. WHERE id=?', $array['data']['id']);
  535. writeLog('success', 'User Management Function - User: ' . $array['data']['username'] . '\'s group was changed from [' . $array['data']['oldGroup'] . '] to [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  536. return true;
  537. } catch (Dibi\Exception $e) {
  538. writeLog('error', 'User Management Function - Error - User: ' . $array['data']['username'] . '\'s group was changed from [' . $array['data']['oldGroup'] . '] to [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  539. return false;
  540. }
  541. break;
  542. case 'editUser':
  543. try {
  544. $connect = new Dibi\Connection([
  545. 'driver' => 'sqlite3',
  546. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  547. ]);
  548. if (!usernameTakenExcept($array['data']['username'], $array['data']['email'], $array['data']['id'])) {
  549. $connect->query('
  550. UPDATE users SET', [
  551. 'username' => $array['data']['username'],
  552. 'email' => $array['data']['email'],
  553. ], '
  554. WHERE id=?', $array['data']['id']);
  555. if (!empty($array['data']['password'])) {
  556. $connect->query('
  557. UPDATE users SET', [
  558. 'password' => password_hash($array['data']['password'], PASSWORD_BCRYPT)
  559. ], '
  560. WHERE id=?', $array['data']['id']);
  561. }
  562. writeLog('success', 'User Management Function - User: ' . $array['data']['username'] . '\'s info was changed', $GLOBALS['organizrUser']['username']);
  563. return true;
  564. } else {
  565. return false;
  566. }
  567. } catch (Dibi\Exception $e) {
  568. writeLog('error', 'User Management Function - Error - User: ' . $array['data']['username'] . '\'s group was changed from [' . $array['data']['oldGroup'] . '] to [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  569. return false;
  570. }
  571. break;
  572. case 'addNewUser':
  573. $defaults = defaultUserGroup();
  574. if (createUser($array['data']['username'], $array['data']['password'], $defaults, $array['data']['email'])) {
  575. writeLog('success', 'Create User Function - Account created for [' . $array['data']['username'] . ']', $GLOBALS['organizrUser']['username']);
  576. return true;
  577. } else {
  578. writeLog('error', 'Registration Function - An error occurred', $GLOBALS['organizrUser']['username']);
  579. return 'username taken';
  580. }
  581. break;
  582. case 'deleteUser':
  583. try {
  584. $connect = new Dibi\Connection([
  585. 'driver' => 'sqlite3',
  586. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  587. ]);
  588. $connect->query('DELETE FROM users WHERE id = ?', $array['data']['id']);
  589. writeLog('success', 'User Management Function - Deleted User [' . $array['data']['username'] . ']', $GLOBALS['organizrUser']['username']);
  590. return true;
  591. } catch (Dibi\Exception $e) {
  592. return false;
  593. }
  594. break;
  595. default:
  596. return false;
  597. break;
  598. }
  599. }
  600. function editTabs($array)
  601. {
  602. switch ($array['data']['action']) {
  603. case 'changeGroup':
  604. try {
  605. $connect = new Dibi\Connection([
  606. 'driver' => 'sqlite3',
  607. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  608. ]);
  609. $connect->query('
  610. UPDATE tabs SET', [
  611. 'group_id' => $array['data']['newGroupID'],
  612. ], '
  613. WHERE id=?', $array['data']['id']);
  614. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s group was changed to [' . $array['data']['newGroupName'] . ']', $GLOBALS['organizrUser']['username']);
  615. return true;
  616. } catch (Dibi\Exception $e) {
  617. return false;
  618. }
  619. break;
  620. case 'changeCategory':
  621. try {
  622. $connect = new Dibi\Connection([
  623. 'driver' => 'sqlite3',
  624. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  625. ]);
  626. $connect->query('
  627. UPDATE tabs SET', [
  628. 'category_id' => $array['data']['newCategoryID'],
  629. ], '
  630. WHERE id=?', $array['data']['id']);
  631. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s category was changed to [' . $array['data']['newCategoryName'] . ']', $GLOBALS['organizrUser']['username']);
  632. return true;
  633. } catch (Dibi\Exception $e) {
  634. return false;
  635. }
  636. break;
  637. case 'changeType':
  638. try {
  639. $connect = new Dibi\Connection([
  640. 'driver' => 'sqlite3',
  641. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  642. ]);
  643. $connect->query('
  644. UPDATE tabs SET', [
  645. 'type' => $array['data']['newTypeID'],
  646. ], '
  647. WHERE id=?', $array['data']['id']);
  648. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s type was changed to [' . $array['data']['newTypeName'] . ']', $GLOBALS['organizrUser']['username']);
  649. return true;
  650. } catch (Dibi\Exception $e) {
  651. return false;
  652. }
  653. break;
  654. case 'changeEnabled':
  655. try {
  656. $connect = new Dibi\Connection([
  657. 'driver' => 'sqlite3',
  658. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  659. ]);
  660. $connect->query('
  661. UPDATE tabs SET', [
  662. 'enabled' => $array['data']['tabEnabled'],
  663. ], '
  664. WHERE id=?', $array['data']['id']);
  665. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s enable status was changed to [' . $array['data']['tabEnabledWord'] . ']', $GLOBALS['organizrUser']['username']);
  666. return true;
  667. } catch (Dibi\Exception $e) {
  668. return false;
  669. }
  670. break;
  671. case 'changeSplash':
  672. try {
  673. $connect = new Dibi\Connection([
  674. 'driver' => 'sqlite3',
  675. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  676. ]);
  677. $connect->query('
  678. UPDATE tabs SET', [
  679. 'splash' => $array['data']['tabSplash'],
  680. ], '
  681. WHERE id=?', $array['data']['id']);
  682. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s splash status was changed to [' . $array['data']['tabSplashWord'] . ']', $GLOBALS['organizrUser']['username']);
  683. return true;
  684. } catch (Dibi\Exception $e) {
  685. return false;
  686. }
  687. break;
  688. case 'changePing':
  689. try {
  690. $connect = new Dibi\Connection([
  691. 'driver' => 'sqlite3',
  692. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  693. ]);
  694. $connect->query('
  695. UPDATE tabs SET', [
  696. 'ping' => $array['data']['tabPing'],
  697. ], '
  698. WHERE id=?', $array['data']['id']);
  699. writeLog('success', 'Tab Editor Function - Tab: ' . $array['data']['tab'] . '\'s ping status was changed to [' . $array['data']['tabPingWord'] . ']', $GLOBALS['organizrUser']['username']);
  700. return true;
  701. } catch (Dibi\Exception $e) {
  702. return false;
  703. }
  704. break;
  705. case 'changeDefault':
  706. try {
  707. $connect = new Dibi\Connection([
  708. 'driver' => 'sqlite3',
  709. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  710. ]);
  711. $connect->query('UPDATE tabs SET `default` = 0');
  712. $connect->query('
  713. UPDATE tabs SET', [
  714. 'default' => 1
  715. ], '
  716. WHERE id=?', $array['data']['id']);
  717. writeLog('success', 'Tab Editor Function - Changed Default Tab to [' . $array['data']['tab'] . ']', $GLOBALS['organizrUser']['username']);
  718. return true;
  719. } catch (Dibi\Exception $e) {
  720. return false;
  721. }
  722. break;
  723. case 'deleteTab':
  724. try {
  725. $connect = new Dibi\Connection([
  726. 'driver' => 'sqlite3',
  727. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  728. ]);
  729. $connect->query('DELETE FROM tabs WHERE id = ?', $array['data']['id']);
  730. writeLog('success', 'Tab Editor Function - Deleted Tab [' . $array['data']['tab'] . ']', $GLOBALS['organizrUser']['username']);
  731. return true;
  732. } catch (Dibi\Exception $e) {
  733. return false;
  734. }
  735. break;
  736. case 'editTab':
  737. try {
  738. $connect = new Dibi\Connection([
  739. 'driver' => 'sqlite3',
  740. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  741. ]);
  742. $connect->query('
  743. UPDATE tabs SET', [
  744. 'name' => $array['data']['tabName'],
  745. 'url' => $array['data']['tabURL'],
  746. 'ping_url' => $array['data']['pingURL'],
  747. 'image' => $array['data']['tabImage'],
  748. ], '
  749. WHERE id=?', $array['data']['id']);
  750. writeLog('success', 'Tab Editor Function - Edited Tab Info for [' . $array['data']['tabName'] . ']', $GLOBALS['organizrUser']['username']);
  751. return true;
  752. } catch (Dibi\Exception $e) {
  753. return false;
  754. }
  755. case 'changeOrder':
  756. try {
  757. $connect = new Dibi\Connection([
  758. 'driver' => 'sqlite3',
  759. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  760. ]);
  761. foreach ($array['data']['tabs']['tab'] as $key => $value) {
  762. if ($value['order'] != $value['originalOrder']) {
  763. $connect->query('
  764. UPDATE tabs SET', [
  765. 'order' => $value['order'],
  766. ], '
  767. WHERE id=?', $value['id']);
  768. writeLog('success', 'Tab Editor Function - ' . $value['name'] . ' Order Changed From ' . $value['order'] . ' to ' . $value['originalOrder'], $GLOBALS['organizrUser']['username']);
  769. }
  770. }
  771. writeLog('success', 'Tab Editor Function - Tab Order Changed', $GLOBALS['organizrUser']['username']);
  772. return true;
  773. } catch (Dibi\Exception $e) {
  774. return false;
  775. }
  776. break;
  777. case 'addNewTab':
  778. try {
  779. $default = defaultTabCategory()['category_id'];
  780. $connect = new Dibi\Connection([
  781. 'driver' => 'sqlite3',
  782. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  783. ]);
  784. $newTab = [
  785. 'order' => $array['data']['tabOrder'],
  786. 'category_id' => $default,
  787. 'name' => $array['data']['tabName'],
  788. 'url' => $array['data']['tabURL'],
  789. 'ping_url' => $array['data']['pingURL'],
  790. 'default' => $array['data']['tabDefault'],
  791. 'enabled' => 1,
  792. 'group_id' => $array['data']['tabGroupID'],
  793. 'image' => $array['data']['tabImage'],
  794. 'type' => $array['data']['tabType']
  795. ];
  796. $connect->query('INSERT INTO [tabs]', $newTab);
  797. writeLog('success', 'Tab Editor Function - Created Tab for: ' . $array['data']['tabName'], $GLOBALS['organizrUser']['username']);
  798. return true;
  799. } catch (Dibi\Exception $e) {
  800. return false;
  801. }
  802. break;
  803. default:
  804. return false;
  805. break;
  806. }
  807. }
  808. function editCategories($array)
  809. {
  810. switch ($array['data']['action']) {
  811. case 'changeDefault':
  812. try {
  813. $connect = new Dibi\Connection([
  814. 'driver' => 'sqlite3',
  815. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  816. ]);
  817. $connect->query('UPDATE categories SET `default` = 0');
  818. $connect->query('
  819. UPDATE categories SET', [
  820. 'default' => 1
  821. ], '
  822. WHERE id=?', $array['data']['id']);
  823. writeLog('success', 'Category Editor Function - Changed Default Category from [' . $array['data']['oldCategoryName'] . '] to [' . $array['data']['newCategoryName'] . ']', $GLOBALS['organizrUser']['username']);
  824. return true;
  825. } catch (Dibi\Exception $e) {
  826. return false;
  827. }
  828. break;
  829. case 'deleteCategory':
  830. try {
  831. $connect = new Dibi\Connection([
  832. 'driver' => 'sqlite3',
  833. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  834. ]);
  835. $connect->query('DELETE FROM categories WHERE id = ?', $array['data']['id']);
  836. writeLog('success', 'Category Editor Function - Deleted Category [' . $array['data']['category'] . ']', $GLOBALS['organizrUser']['username']);
  837. return true;
  838. } catch (Dibi\Exception $e) {
  839. return false;
  840. }
  841. break;
  842. case 'addNewCategory':
  843. try {
  844. $connect = new Dibi\Connection([
  845. 'driver' => 'sqlite3',
  846. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  847. ]);
  848. $newCategory = [
  849. 'category' => $array['data']['categoryName'],
  850. 'order' => $array['data']['categoryOrder'],
  851. 'category_id' => $array['data']['categoryID'],
  852. 'default' => false,
  853. 'image' => $array['data']['categoryImage'],
  854. ];
  855. $connect->query('INSERT INTO [categories]', $newCategory);
  856. writeLog('success', 'Category Editor Function - Added Category [' . $array['data']['categoryName'] . ']', $GLOBALS['organizrUser']['username']);
  857. return true;
  858. } catch (Dibi\Exception $e) {
  859. return $e;
  860. }
  861. break;
  862. case 'editCategory':
  863. try {
  864. $connect = new Dibi\Connection([
  865. 'driver' => 'sqlite3',
  866. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  867. ]);
  868. $connect->query('
  869. UPDATE categories SET', [
  870. 'category' => $array['data']['name'],
  871. 'image' => $array['data']['image'],
  872. ], '
  873. WHERE id=?', $array['data']['id']);
  874. writeLog('success', 'Category Editor Function - Edited Category Info for [' . $array['data']['name'] . ']', $GLOBALS['organizrUser']['username']);
  875. return true;
  876. } catch (Dibi\Exception $e) {
  877. return false;
  878. }
  879. break;
  880. case 'changeOrder':
  881. try {
  882. $connect = new Dibi\Connection([
  883. 'driver' => 'sqlite3',
  884. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  885. ]);
  886. foreach ($array['data']['categories']['category'] as $key => $value) {
  887. if ($value['order'] != $value['originalOrder']) {
  888. $connect->query('
  889. UPDATE categories SET', [
  890. 'order' => $value['order'],
  891. ], '
  892. WHERE id=?', $value['id']);
  893. writeLog('success', 'Category Editor Function - ' . $value['name'] . ' Order Changed From ' . $value['order'] . ' to ' . $value['originalOrder'], $GLOBALS['organizrUser']['username']);
  894. }
  895. }
  896. writeLog('success', 'Category Editor Function - Category Order Changed', $GLOBALS['organizrUser']['username']);
  897. return true;
  898. } catch (Dibi\Exception $e) {
  899. return false;
  900. }
  901. break;
  902. default:
  903. return false;
  904. break;
  905. }
  906. }
  907. function allUsers()
  908. {
  909. try {
  910. $connect = new Dibi\Connection([
  911. 'driver' => 'sqlite3',
  912. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  913. ]);
  914. $users = $connect->fetchAll('SELECT * FROM users');
  915. $groups = $connect->fetchAll('SELECT * FROM groups ORDER BY group_id ASC');
  916. foreach ($users as $k => $v) {
  917. // clear password from array
  918. unset($users[$k]['password']);
  919. }
  920. $all['users'] = $users;
  921. $all['groups'] = $groups;
  922. return $all;
  923. } catch (Dibi\Exception $e) {
  924. return false;
  925. }
  926. }
  927. function usernameTaken($username, $email)
  928. {
  929. try {
  930. $connect = new Dibi\Connection([
  931. 'driver' => 'sqlite3',
  932. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  933. ]);
  934. $all = $connect->fetch('SELECT * FROM users WHERE username = ? COLLATE NOCASE OR email = ? COLLATE NOCASE', $username, $email);
  935. return ($all) ? true : false;
  936. } catch (Dibi\Exception $e) {
  937. return false;
  938. }
  939. }
  940. function usernameTakenExcept($username, $email, $id)
  941. {
  942. try {
  943. $connect = new Dibi\Connection([
  944. 'driver' => 'sqlite3',
  945. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  946. ]);
  947. $all = $connect->fetch('SELECT * FROM users WHERE id IS NOT ? AND username = ? COLLATE NOCASE OR id IS NOT ? AND email = ? COLLATE NOCASE', $id, $username, $id, $email);
  948. return ($all) ? true : false;
  949. } catch (Dibi\Exception $e) {
  950. return false;
  951. }
  952. }
  953. function createUser($username, $password, $defaults, $email = null)
  954. {
  955. $email = ($email) ? $email : random_ascii_string(10) . '@placeholder.eml';
  956. try {
  957. if (!usernameTaken($username, $email)) {
  958. $createDB = new Dibi\Connection([
  959. 'driver' => 'sqlite3',
  960. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  961. ]);
  962. $userInfo = [
  963. 'username' => $username,
  964. 'password' => password_hash($password, PASSWORD_BCRYPT),
  965. 'email' => $email,
  966. 'group' => $defaults['group'],
  967. 'group_id' => $defaults['group_id'],
  968. 'image' => gravatar($email),
  969. 'register_date' => $GLOBALS['currentTime'],
  970. ];
  971. $createDB->query('INSERT INTO [users]', $userInfo);
  972. return true;
  973. } else {
  974. return false;
  975. }
  976. } catch (Dibi\Exception $e) {
  977. return false;
  978. }
  979. }
  980. function importUsers($array)
  981. {
  982. $imported = 0;
  983. $defaults = defaultUserGroup();
  984. foreach ($array as $user) {
  985. $password = random_ascii_string(30);
  986. if ($user['username'] !== '' && $user['email'] !== '' && $password !== '' && $defaults !== '') {
  987. $newUser = createUser($user['username'], $password, $defaults, $user['email']);
  988. if (!$newUser) {
  989. writeLog('error', 'Import Function - Error', $user['username']);
  990. } else {
  991. $imported++;
  992. }
  993. }
  994. }
  995. return $imported;
  996. }
  997. function importUsersType($array)
  998. {
  999. $type = $array['data']['type'];
  1000. if ($type !== '') {
  1001. switch ($type) {
  1002. case 'plex':
  1003. return importUsers(allPlexUsers(true));
  1004. break;
  1005. default:
  1006. return false;
  1007. }
  1008. }
  1009. return false;
  1010. }
  1011. function allTabs()
  1012. {
  1013. if (file_exists('config' . DIRECTORY_SEPARATOR . 'config.php')) {
  1014. try {
  1015. $connect = new Dibi\Connection([
  1016. 'driver' => 'sqlite3',
  1017. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  1018. ]);
  1019. $all['tabs'] = $connect->fetchAll('SELECT * FROM tabs ORDER BY `order` ASC');
  1020. $all['categories'] = $connect->fetchAll('SELECT * FROM categories ORDER BY `order` ASC');
  1021. $all['groups'] = $connect->fetchAll('SELECT * FROM groups ORDER BY `group_id` ASC');
  1022. return $all;
  1023. } catch (Dibi\Exception $e) {
  1024. return false;
  1025. }
  1026. }
  1027. return false;
  1028. }
  1029. function allGroups()
  1030. {
  1031. if (file_exists('config' . DIRECTORY_SEPARATOR . 'config.php')) {
  1032. try {
  1033. $connect = new Dibi\Connection([
  1034. 'driver' => 'sqlite3',
  1035. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  1036. ]);
  1037. $all = $connect->fetchAll('SELECT * FROM groups ORDER BY `group_id` ASC');
  1038. return $all;
  1039. } catch (Dibi\Exception $e) {
  1040. return false;
  1041. }
  1042. }
  1043. return false;
  1044. }
  1045. function loadTabs()
  1046. {
  1047. if (file_exists('config' . DIRECTORY_SEPARATOR . 'config.php')) {
  1048. try {
  1049. $connect = new Dibi\Connection([
  1050. 'driver' => 'sqlite3',
  1051. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  1052. ]);
  1053. $sort = ($GLOBALS['unsortedTabs'] == 'top') ? 'DESC' : 'ASC';
  1054. $tabs = $connect->fetchAll('SELECT * FROM tabs WHERE `group_id` >= ? AND `enabled` = 1 ORDER BY `order` ' . $sort, $GLOBALS['organizrUser']['groupID']);
  1055. $categories = $connect->fetchAll('SELECT * FROM categories ORDER BY `order` ASC');
  1056. $all['tabs'] = $tabs;
  1057. foreach ($tabs as $k => $v) {
  1058. $v['access_url'] = isset($v['url_local']) && getenv('SERVER_ADDR') == userIP() ? $v['url_local'] : $v['url'];
  1059. }
  1060. $count = array_map(function ($element) {
  1061. return $element['category_id'];
  1062. }, $tabs);
  1063. $count = (array_count_values($count));
  1064. foreach ($categories as $k => $v) {
  1065. $v['count'] = isset($count[$v['category_id']]) ? $count[$v['category_id']] : 0;
  1066. }
  1067. $all['categories'] = $categories;
  1068. return $all;
  1069. } catch (Dibi\Exception $e) {
  1070. return false;
  1071. }
  1072. }
  1073. return false;
  1074. }
  1075. function getActiveTokens()
  1076. {
  1077. try {
  1078. $connect = new Dibi\Connection([
  1079. 'driver' => 'sqlite3',
  1080. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  1081. ]);
  1082. $all = $connect->fetchAll('SELECT * FROM `tokens` WHERE `user_id` = ? AND `expires` > ?', $GLOBALS['organizrUser']['userID'], $GLOBALS['currentTime']);
  1083. return $all;
  1084. } catch (Dibi\Exception $e) {
  1085. return false;
  1086. }
  1087. }
  1088. function revokeToken($array)
  1089. {
  1090. if ($array['data']['token']) {
  1091. try {
  1092. $connect = new Dibi\Connection([
  1093. 'driver' => 'sqlite3',
  1094. 'database' => $GLOBALS['dbLocation'] . $GLOBALS['dbName'],
  1095. ]);
  1096. $connect->query('DELETE FROM tokens WHERE user_id = ? AND token = ?', $GLOBALS['organizrUser']['userID'], $array['data']['token']);
  1097. return true;
  1098. } catch (Dibi\Exception $e) {
  1099. return false;
  1100. }
  1101. }
  1102. }