api-functions.php 34 KB

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