PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/Cockpit/Controller/Accounts.php

https://github.com/agentejo/cockpit
PHP | 278 lines | 180 code | 84 blank | 14 comment | 56 complexity | 5a8b19a05406d33f257dbd839186f82d MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This file is part of the Cockpit project.
  4. *
  5. * (c) Artur Heinze - πŸ…°πŸ…ΆπŸ…΄πŸ…½πŸ†ƒπŸ…΄πŸ…ΉπŸ…Ύ, http://agentejo.com
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Cockpit\Controller;
  11. class Accounts extends \Cockpit\AuthController {
  12. public function index() {
  13. if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
  14. return $this->helper('admin')->denyRequest();
  15. }
  16. $current = $this->user['_id'];
  17. $groups = $this->module('cockpit')->getGroups();
  18. return $this->render('cockpit:views/accounts/index.php', compact('current', 'groups'));
  19. }
  20. public function account($uid=null) {
  21. if (!$uid) {
  22. $uid = $this->user['_id'];
  23. }
  24. if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts') && $uid != $this->user['_id']) {
  25. return $this->helper('admin')->denyRequest();
  26. }
  27. $account = $this->app->storage->findOne('cockpit/accounts', ['_id' => $uid]);
  28. $this->app['user'] = $this->user;
  29. if (!$account) {
  30. return false;
  31. }
  32. unset($account["password"]);
  33. $fields = $this->app->retrieve('config/account/fields', null);
  34. $languages = $this->getLanguages();
  35. $groups = $this->module('cockpit')->getGroups();
  36. if (!$this->app->helper('admin')->isResourceEditableByCurrentUser($uid, $meta)) {
  37. return $this->render('cockpit:views/base/locked.php', compact('meta'));
  38. }
  39. $this->app->helper('admin')->lockResourceId($uid);
  40. $this->app->trigger('cockpit.account.fields', [&$fields, &$account]);
  41. return $this->render('cockpit:views/accounts/account.php', compact('account', 'uid', 'languages', 'groups', 'fields'));
  42. }
  43. public function create() {
  44. if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
  45. return $this->helper('admin')->denyRequest();
  46. }
  47. $uid = null;
  48. $account = [
  49. 'user' => '',
  50. 'email' => '',
  51. 'active' => true,
  52. 'group' => 'admin',
  53. 'i18n' => $this->app->helper('i18n')->locale
  54. ];
  55. $fields = $this->app->retrieve('config/account/fields', null);
  56. $languages = $this->getLanguages();
  57. $groups = $this->module('cockpit')->getGroups();
  58. $this->app->trigger('cockpit.account.fields', [&$fields, &$account]);
  59. return $this->render('cockpit:views/accounts/account.php', compact('account', 'uid', 'languages', 'groups', 'fields'));
  60. }
  61. public function save() {
  62. if ($data = $this->param('account', false)) {
  63. // check rights
  64. if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
  65. if (!isset($data['_id']) || $data['_id'] != $this->user['_id']) {
  66. return $this->helper('admin')->denyRequest();
  67. }
  68. }
  69. $data['_modified'] = time();
  70. $isUpdate = false;
  71. if (!isset($data['_id'])) {
  72. // new user needs a password
  73. if (!isset($data['password']) || !trim($data['password'])) {
  74. return $this->stop(['error' => 'User password required'], 412);
  75. }
  76. if (!isset($data['user']) || !trim($data['user'])) {
  77. return $this->stop(['error' => 'Username required'], 412);
  78. }
  79. $data['_created'] = $data['_modified'];
  80. } else {
  81. if (!$this->app->helper('admin')->isResourceEditableByCurrentUser($data['_id'])) {
  82. $this->stop(['error' => "Saving failed! Account is locked!"], 412);
  83. }
  84. $isUpdate = true;
  85. }
  86. if (isset($data['group']) && !$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
  87. unset($data['group']);
  88. }
  89. if (isset($data['password'])) {
  90. if (strlen($data['password'])){
  91. $data['password'] = $this->app->hash($data['password']);
  92. } else {
  93. unset($data['password']);
  94. }
  95. }
  96. if (isset($data['email']) && !$this->helper('utils')->isEmail($data['email'])) {
  97. return $this->stop(['error' => 'Valid email required'], 412);
  98. }
  99. if (isset($data['user']) && !trim($data['user'])) {
  100. return $this->stop(['error' => 'Username cannot be empty!'], 412);
  101. }
  102. foreach (['name', 'user', 'email'] as $key) {
  103. if (isset($data[$key])) $data[$key] = strip_tags(trim($data[$key]));
  104. }
  105. // unique check
  106. // --
  107. if (isset($data['user'])) {
  108. $_account = $this->app->storage->findOne('cockpit/accounts', ['user' => $data['user']]);
  109. if ($_account && (!isset($data['_id']) || $data['_id'] != $_account['_id'])) {
  110. $this->app->stop(['error' => 'Username is already used!'], 412);
  111. }
  112. }
  113. if (isset($data['email'])) {
  114. $_account = $this->app->storage->findOne('cockpit/accounts', ['email' => $data['email']]);
  115. if ($_account && (!isset($data['_id']) || $data['_id'] != $_account['_id'])) {
  116. $this->app->stop(['error' => 'Email is already used!'], 412);
  117. }
  118. }
  119. // --
  120. $this->app->trigger('cockpit.accounts.save', [&$data, isset($data['_id'])]);
  121. $this->app->storage->save('cockpit/accounts', $data);
  122. $data = $this->app->storage->findOne('cockpit/accounts', ['_id' => $data['_id']]);
  123. if (isset($data['password'])) unset($data['password']);
  124. if (isset($data['_reset_token'])) unset($data['_reset_token']);
  125. if ($data['_id'] == $this->user['_id']) {
  126. $this->module('cockpit')->setUser($data);
  127. }
  128. if (!$isUpdate) {
  129. $this->app->helper('admin')->lockResourceId($data['_id']);
  130. }
  131. return json_encode($data);
  132. }
  133. return false;
  134. }
  135. public function remove() {
  136. if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
  137. return $this->helper('admin')->denyRequest();
  138. }
  139. if ($data = $this->param('account', false)) {
  140. // user can't delete himself
  141. if ($data['_id'] != $this->user['_id']) {
  142. $this->app->storage->remove('cockpit/accounts', ['_id' => $data['_id']]);
  143. return '{"success":true}';
  144. }
  145. }
  146. return false;
  147. }
  148. public function find() {
  149. \session_write_close();
  150. $options = array_merge([
  151. 'sort' => ['user' => 1]
  152. ], $this->param('options', []));
  153. if (isset($options['filter']) && is_string($options['filter'])) {
  154. $filter = null;
  155. if (\preg_match('/^\{(.*)\}$/', $options['filter'])) {
  156. try {
  157. $filter = json5_decode($options['filter'], true);
  158. } catch (\Exception $e) {}
  159. }
  160. if (!$filter) {
  161. $filter = [
  162. '$or' => [
  163. ['name' => ['$regex' => $options['filter']]],
  164. ['user' => ['$regex' => $options['filter']]],
  165. ['email' => ['$regex' => $options['filter']]],
  166. ]
  167. ];
  168. }
  169. $options['filter'] = $filter;
  170. }
  171. $accounts = $this->app->storage->find('cockpit/accounts', $options)->toArray();
  172. $count = (!isset($options['skip']) && !isset($options['limit'])) ? count($accounts) : $this->app->storage->count('cockpit/accounts', isset($options['filter']) ? $options['filter'] : []);
  173. $pages = isset($options['limit']) ? ceil($count / $options['limit']) : 1;
  174. $page = 1;
  175. if ($pages > 1 && isset($options['skip'])) {
  176. $page = ceil($options['skip'] / $options['limit']) + 1;
  177. }
  178. foreach ($accounts as &$account) {
  179. unset($account['password'], $account['api_key'], $account['_reset_token']);
  180. $this->app->trigger('cockpit.accounts.disguise', [&$account]);
  181. }
  182. return compact('accounts', 'count', 'pages', 'page');
  183. }
  184. protected function getLanguages() {
  185. $languages = [['i18n' => 'en', 'language' => 'English']];
  186. foreach ($this->app->helper('fs')->ls('*.php', '#config:cockpit/i18n') as $file) {
  187. $lang = include($file->getRealPath());
  188. $i18n = $file->getBasename('.php');
  189. $language = $lang['@meta']['language'] ?? $i18n;
  190. $languages[] = ['i18n' => $i18n, 'language'=> $language];
  191. }
  192. return $languages;
  193. }
  194. }