PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 16ms RepoModel.GetById 1ms 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
  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
 11namespace Cockpit\Controller;
 12
 13class Accounts extends \Cockpit\AuthController {
 14
 15    public function index() {
 16
 17        if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
 18            return $this->helper('admin')->denyRequest();
 19        }
 20
 21        $current  = $this->user['_id'];
 22        $groups   = $this->module('cockpit')->getGroups();
 23
 24        return $this->render('cockpit:views/accounts/index.php', compact('current', 'groups'));
 25    }
 26
 27
 28    public function account($uid=null) {
 29
 30        if (!$uid) {
 31            $uid = $this->user['_id'];
 32        }
 33
 34        if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts') && $uid != $this->user['_id']) {
 35            return $this->helper('admin')->denyRequest();
 36        }
 37
 38        $account = $this->app->storage->findOne('cockpit/accounts', ['_id' => $uid]);
 39
 40        $this->app['user'] = $this->user;
 41
 42        if (!$account) {
 43            return false;
 44        }
 45
 46        unset($account["password"]);
 47
 48        $fields    = $this->app->retrieve('config/account/fields', null);
 49        $languages = $this->getLanguages();
 50        $groups    = $this->module('cockpit')->getGroups();
 51
 52        if (!$this->app->helper('admin')->isResourceEditableByCurrentUser($uid, $meta)) {
 53            return $this->render('cockpit:views/base/locked.php', compact('meta'));
 54        }
 55
 56        $this->app->helper('admin')->lockResourceId($uid);
 57
 58        $this->app->trigger('cockpit.account.fields', [&$fields, &$account]);
 59
 60        return $this->render('cockpit:views/accounts/account.php', compact('account', 'uid', 'languages', 'groups', 'fields'));
 61    }
 62
 63    public function create() {
 64
 65        if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
 66            return $this->helper('admin')->denyRequest();
 67        }
 68
 69        $uid       = null;
 70        $account   = [
 71            'user'   => '',
 72            'email'  => '',
 73            'active' => true,
 74            'group'  => 'admin',
 75            'i18n'   => $this->app->helper('i18n')->locale
 76        ];
 77
 78        $fields    = $this->app->retrieve('config/account/fields', null);
 79        $languages = $this->getLanguages();
 80        $groups    = $this->module('cockpit')->getGroups();
 81
 82        $this->app->trigger('cockpit.account.fields', [&$fields, &$account]);
 83
 84        return $this->render('cockpit:views/accounts/account.php', compact('account', 'uid', 'languages', 'groups', 'fields'));
 85    }
 86
 87    public function save() {
 88
 89        if ($data = $this->param('account', false)) {
 90
 91            // check rights
 92            if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
 93
 94                if (!isset($data['_id']) || $data['_id'] != $this->user['_id']) {
 95                    return $this->helper('admin')->denyRequest();
 96                }
 97            }
 98
 99            $data['_modified'] = time();
100            $isUpdate = false;
101
102            if (!isset($data['_id'])) {
103
104                // new user needs a password
105                if (!isset($data['password']) || !trim($data['password'])) {
106                    return $this->stop(['error' => 'User password required'], 412);
107                }
108
109                if (!isset($data['user']) || !trim($data['user'])) {
110                    return $this->stop(['error' => 'Username required'], 412);
111                }
112
113                $data['_created'] = $data['_modified'];
114                
115            } else {
116                
117                if (!$this->app->helper('admin')->isResourceEditableByCurrentUser($data['_id'])) {
118                    $this->stop(['error' => "Saving failed! Account is locked!"], 412);
119                }
120
121                $isUpdate = true;
122            }
123
124            if (isset($data['group']) && !$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
125                unset($data['group']);
126            }
127
128            if (isset($data['password'])) {
129
130                if (strlen($data['password'])){
131                    $data['password'] = $this->app->hash($data['password']);
132                } else {
133                    unset($data['password']);
134                }
135            }
136
137            if (isset($data['email']) && !$this->helper('utils')->isEmail($data['email'])) {
138                return $this->stop(['error' => 'Valid email required'], 412);
139            }
140
141            if (isset($data['user']) && !trim($data['user'])) {
142                return $this->stop(['error' => 'Username cannot be empty!'], 412);
143            }
144
145            foreach (['name', 'user', 'email'] as $key) {
146                if (isset($data[$key])) $data[$key] = strip_tags(trim($data[$key]));
147            }
148
149            // unique check
150            // --
151            if (isset($data['user'])) {
152
153                $_account = $this->app->storage->findOne('cockpit/accounts', ['user'  => $data['user']]);
154
155                if ($_account && (!isset($data['_id']) || $data['_id'] != $_account['_id'])) {
156                    $this->app->stop(['error' =>  'Username is already used!'], 412);
157                }
158            }
159
160            if (isset($data['email'])) {
161
162                $_account = $this->app->storage->findOne('cockpit/accounts', ['email'  => $data['email']]);
163
164                if ($_account && (!isset($data['_id']) || $data['_id'] != $_account['_id'])) {
165                    $this->app->stop(['error' =>  'Email is already used!'], 412);
166                }
167            }
168            // --
169
170            $this->app->trigger('cockpit.accounts.save', [&$data, isset($data['_id'])]);
171            $this->app->storage->save('cockpit/accounts', $data);
172
173            $data = $this->app->storage->findOne('cockpit/accounts', ['_id' => $data['_id']]);
174
175            if (isset($data['password'])) unset($data['password']);
176            if (isset($data['_reset_token'])) unset($data['_reset_token']);
177
178            if ($data['_id'] == $this->user['_id']) {
179                $this->module('cockpit')->setUser($data);
180            }
181
182            if (!$isUpdate) {
183                $this->app->helper('admin')->lockResourceId($data['_id']);
184            }
185
186            return json_encode($data);
187        }
188
189        return false;
190
191    }
192
193    public function remove() {
194
195        if (!$this->module('cockpit')->hasaccess('cockpit', 'accounts')) {
196            return $this->helper('admin')->denyRequest();
197        }
198
199        if ($data = $this->param('account', false)) {
200
201            // user can't delete himself
202            if ($data['_id'] != $this->user['_id']) {
203
204                $this->app->storage->remove('cockpit/accounts', ['_id' => $data['_id']]);
205
206                return '{"success":true}';
207            }
208        }
209
210        return false;
211    }
212
213    public function find() {
214
215        \session_write_close();
216
217        $options = array_merge([
218            'sort'   => ['user' => 1]
219        ], $this->param('options', []));
220
221        if (isset($options['filter']) && is_string($options['filter'])) {
222
223            $filter = null;
224
225            if (\preg_match('/^\{(.*)\}$/', $options['filter'])) {
226
227                try {
228                    $filter = json5_decode($options['filter'], true);
229                } catch (\Exception $e) {}
230            }
231
232            if (!$filter) {
233                $filter = [
234                    '$or' => [
235                        ['name' => ['$regex' => $options['filter']]],
236                        ['user' => ['$regex' => $options['filter']]],
237                        ['email' => ['$regex' => $options['filter']]],
238                    ]
239                ];
240            }
241
242            $options['filter'] = $filter;
243        }
244
245        $accounts = $this->app->storage->find('cockpit/accounts', $options)->toArray();
246        $count    = (!isset($options['skip']) && !isset($options['limit'])) ? count($accounts) : $this->app->storage->count('cockpit/accounts', isset($options['filter']) ? $options['filter'] : []);
247        $pages    = isset($options['limit']) ? ceil($count / $options['limit']) : 1;
248        $page     = 1;
249
250        if ($pages > 1 && isset($options['skip'])) {
251            $page = ceil($options['skip'] / $options['limit']) + 1;
252        }
253
254        foreach ($accounts as &$account) {
255            unset($account['password'], $account['api_key'], $account['_reset_token']);
256            $this->app->trigger('cockpit.accounts.disguise', [&$account]);
257        }
258
259        return compact('accounts', 'count', 'pages', 'page');
260    }
261
262    protected function getLanguages() {
263
264        $languages = [['i18n' => 'en', 'language' => 'English']];
265
266        foreach ($this->app->helper('fs')->ls('*.php', '#config:cockpit/i18n') as $file) {
267
268            $lang     = include($file->getRealPath());
269            $i18n     = $file->getBasename('.php');
270            $language = $lang['@meta']['language'] ?? $i18n;
271
272            $languages[] = ['i18n' => $i18n, 'language'=> $language];
273        }
274
275        return $languages;
276    }
277
278}