diff --git a/app/Controllers/Routing.php b/app/Controllers/Routing.php index 1c6083146986668435c091e2491414d58a7c243b..664972c325dd77e4f12c0d126b0f5466d138a843 100644 --- a/app/Controllers/Routing.php +++ b/app/Controllers/Routing.php @@ -126,6 +126,8 @@ class Routing $r->add(['GET', 'POST'], '/admin/users', 'AdminUsers:view', 'AdminUsers'); $r->add(['GET', 'POST'], '/admin/users/result/{data}[/{page:[1-9]\d*}]', 'AdminUsersResult:view', 'AdminUsersResult'); + $r->add(['GET', 'POST'], '/admin/users/{action:\w+}/{ids:\d+(?:-\d+)*}', 'AdminUsersAction:view', 'AdminUsersAction'); + if ($user->canViewIP) { $r->add('GET', '/admin/get/host/{ip:[0-9a-fA-F:.]+}', 'AdminHost:view', 'AdminHost'); diff --git a/app/Models/Pages/Admin/Users.php b/app/Models/Pages/Admin/Users.php index fa15c88e2d84cc8d69208af0272246c405d30065..952bcea35b54c7b1de6c91f4635052c4aa50fb97 100644 --- a/app/Models/Pages/Admin/Users.php +++ b/app/Models/Pages/Admin/Users.php @@ -4,9 +4,15 @@ namespace ForkBB\Models\Pages\Admin; use ForkBB\Core\Container; use ForkBB\Models\Pages\Admin; +use ForkBB\Models\User\Model as User; +use ForkBB\Models\Rules; abstract class Users extends Admin { + const ACTION_BAN = 'ban'; + const ACTION_DEL = 'delete'; + const ACTION_CHG = 'change_group'; + /** * Конструктор * @@ -16,7 +22,7 @@ abstract class Users extends Admin { parent::__construct($container); - $this->aIndex = 'users'; + $this->aIndex = 'users'; $this->c->Lang->load('admin_users'); } @@ -68,4 +74,75 @@ abstract class Users extends Admin return $data; } + + /** + * Проверяет доступность действий над выбранными пользователями + * + * @param array $selected + * @param string $action // ???? + * + * @return false|array + */ + protected function checkSelected(array $selected, $action) + { + $bad = \array_filter($selected, function ($value) { + return $value < 2; // ???? например '03' + }); + + if (! empty($bad)) { + $this->fIswev = ['v', \ForkBB\__('Action not available')]; + return false; + } + + if (! $this->rules instanceof Rules) { + $this->rules = $this->c->UsersRules->init(); + } + + $userList = $this->c->users->load($selected); + $result = []; + foreach ($userList as $user) { + if (! $user instanceof User) { + continue; + } + + switch ($action) { + case self::ACTION_BAN: + if (! $this->rules->canBanUser($user)) { + $this->fIswev = ['v', \ForkBB\__('You are not allowed to ban the %s', $user->username)]; + if ($user->isAdmin) { + $this->fIswev = ['i', \ForkBB\__('No ban admins message')]; + } elseif ($user->isAdmMod) { + $this->fIswev = ['i', \ForkBB\__('No ban mods message')]; + } + return false; + } + break; + case self::ACTION_DEL: + if (! $this->rules->canDeleteUser($user)) { + $this->fIswev = ['v', \ForkBB\__('You are not allowed to delete the %s', $user->username)]; + if ($user->isAdmin) { + $this->fIswev = ['i', \ForkBB\__('No delete admins message')]; + } + return false; + } + break; + case self::ACTION_CHG: + if (! $this->rules->canChangeGroup($user)) { + $this->fIswev = ['v', \ForkBB\__('You are not allowed to change group for %s', $user->username)]; + if ($user->isAdmin) { + $this->fIswev = ['i', \ForkBB\__('No move admins message')]; + } + return false; + } + break; + default: + $this->fIswev = ['v', \ForkBB\__('Action not available')]; + return false; + } + + $result[] = $user->id; + } + + return $result; + } } diff --git a/app/Models/Pages/Admin/Users/Result.php b/app/Models/Pages/Admin/Users/Result.php index 061223e3548363b56b8b6b6f937982e6e4058605..382aa7307828cfe61c897729e57bb908b6aaae7c 100644 --- a/app/Models/Pages/Admin/Users/Result.php +++ b/app/Models/Pages/Admin/Users/Result.php @@ -22,15 +22,17 @@ class Result extends Users return $this->c->Message->message('Bad request'); } + $this->rules = $this->c->UsersRules->init(); + if (isset($data['ip'])) { - if (! $this->user->canViewIP) { + if (! $this->rules->viewIP) { return $this->c->Message->message('Bad request'); } - $ids = $this->forIP($data['ip']); + $ids = $this->forIP($data['ip']); $crName = $data['ip']; } else { - $ids = $this->forFilter($data); + $ids = $this->forFilter($data); $crName = \ForkBB\__('Results head'); } @@ -49,15 +51,58 @@ class Result extends Users return $this->c->Message->message('Bad request'); } + if ('POST' === $method) { + $v = $this->c->Validator->reset() + ->addValidators([ + ])->addRules([ + 'token' => 'token:AdminUsersResult', + 'users' => 'required|array', + 'users.*' => 'required|integer|min:2|max:9999999999', + 'ban' => $this->rules->banUsers ? 'checkbox' : 'absent', + 'delete' => $this->rules->deleteUsers ? 'checkbox' : 'absent', + 'change_group' => $this->rules->changeGroup ? 'checkbox' : 'absent', + ])->addAliases([ + 'users' => 'Select', + 'users.*' => 'Select', + ])->addArguments([ + 'token' => $args, + ])->addMessages([ + 'users.required' => 'No users selected', + 'ban' => 'Action not available', + 'delete' => 'Action not available', + 'change_group' => 'Action not available', + ]); + + if ($v->validation($_POST)) { + if (! empty($v->ban) && $this->rules->banUsers) { + $action = self::ACTION_BAN; + } elseif (! empty($v->delete) && $this->rules->deleteUsers) { + $action = self::ACTION_DEL; + } elseif (! empty($v->change_group) && $this->rules->changeGroup) { + $action = self::ACTION_CHG; + } else { + $this->fIswev = ['v', \ForkBB\__('Action not available')]; + } + + if (empty($this->fIswev)) { + $selected = $this->checkSelected($v->users, $action); + if (\is_array($selected)) { + return $this->c->Redirect->page('AdminUsersAction', ['action' => $action, 'ids' => \implode('-', $selected)]); + } + } + } + + $this->fIswev = $v->getErrors(); + } + $startNum = ($page - 1) * $this->c->config->o_disp_users; $ids = \array_slice($ids, $startNum, $this->c->config->o_disp_users); $userList = $this->c->users->load($ids); $this->nameTpl = 'admin/users_result'; - $this->aIndex = 'users'; $this->mainSuffix = '-one-column'; $this->aCrumbs[] = [$this->c->Router->link('AdminUsersResult', ['data' => $args['data']]), $crName]; - $this->formResult = $this->form($userList, $startNum); + $this->formResult = $this->form($userList, $startNum, $args); $this->pagination = $this->c->Func->paginate($pages, $page, 'AdminUsersResult', ['data' => $args['data']]); return $this; @@ -138,36 +183,43 @@ class Result extends Users * * @param array $users * @param int $number + * @param array $args * * @return array */ - protected function form(array $users, $number) + protected function form(array $users, $number, array $args) { $form = [ - 'action' => $this->c->Router->link(''), + 'action' => $this->c->Router->link('AdminUsersResult', $args), 'hidden' => [ - 'token' => $this->c->Csrf->create(''), + 'token' => $this->c->Csrf->create('AdminUsersResult', $args), ], 'sets' => [], - 'btns' => [ - 'ban' => [ - 'type' => 'submit', - 'value' => \ForkBB\__('Ban'), - 'accesskey' => null, - ], - 'delete' => [ - 'type' => 'submit', - 'value' => \ForkBB\__('Delete'), - 'accesskey' => null, - ], - 'change_group' => [ - 'type' => 'submit', - 'value' => \ForkBB\__('Change group'), - 'accesskey' => null, - ], - ], + 'btns' => [], ]; + if ($this->rules->banUsers) { + $form['btns']['ban'] = [ + 'type' => 'submit', + 'value' => \ForkBB\__('Ban'), + 'accesskey' => null, + ]; + } + if ($this->rules->deleteUsers) { + $form['btns']['delete'] = [ + 'type' => 'submit', + 'value' => \ForkBB\__('Delete'), + 'accesskey' => null, + ]; + } + if ($this->rules->changeGroup) { + $form['btns']['change_group'] = [ + 'type' => 'submit', + 'value' => \ForkBB\__('Change group'), + 'accesskey' => null, + ]; + } + \array_unshift($users, $this->c->users->create(['id' => -1])); foreach ($users as $user) { diff --git a/app/Models/Pages/Admin/Users/Stat.php b/app/Models/Pages/Admin/Users/Stat.php index 4425f33921b936b8ff27138241940131c75e45c1..154d164a15bdb554b959ec31c353568858bd053c 100644 --- a/app/Models/Pages/Admin/Users/Stat.php +++ b/app/Models/Pages/Admin/Users/Stat.php @@ -37,7 +37,6 @@ class Stat extends Users } $this->nameTpl = 'admin/users_result'; - $this->aIndex = 'users'; $this->mainSuffix = '-one-column'; $this->aCrumbs[] = [$this->c->Router->link('AdminUserStat', ['id' => $args['id']]), $user->username]; $this->formResult = $this->form($stat, $startNum); diff --git a/app/Models/Pages/Admin/Users/View.php b/app/Models/Pages/Admin/Users/View.php index b5790a011122b9caf4ae5fb73844675434905b35..1961cfb50e159f43e464da7b97950adc93e19f58 100644 --- a/app/Models/Pages/Admin/Users/View.php +++ b/app/Models/Pages/Admin/Users/View.php @@ -117,10 +117,9 @@ class View extends Users } $this->nameTpl = 'admin/users'; - $this->aIndex = 'users'; $this->formSearch = $this->form($data); - if ($this->user->canViewIP) { + if ($this->c->UsersRules->init()->viewIP) { $this->formIP = $this->formIP($data); } diff --git a/app/Models/Rules/Profile.php b/app/Models/Rules/Profile.php index 441bc4e98ea597cafbd0972e08a346a18b2a0c02..b02bbeca743797a00f74c4c8a97f395b38dc0797 100644 --- a/app/Models/Rules/Profile.php +++ b/app/Models/Rules/Profile.php @@ -22,6 +22,8 @@ class Profile extends Rules */ public function setUser(User $curUser) { + $this->a = []; + $this->aCalc = []; $this->ready = true; $this->user = $this->c->user; diff --git a/app/Models/Rules/Users.php b/app/Models/Rules/Users.php new file mode 100644 index 0000000000000000000000000000000000000000..9cf4ac29eb9b000e3c1902ba2cd25aa3658d26a3 --- /dev/null +++ b/app/Models/Rules/Users.php @@ -0,0 +1,70 @@ +a = []; + $this->aCalc = []; + $this->ready = true; + $this->user = $this->c->user; + + return $this; + } + + protected function getviewIP() + { + return $this->user->canViewIP; + } + + protected function getdeleteUsers() + { + return $this->user->isAdmin; + } + + protected function getbanUsers() + { + return $this->user->isAdmin || ($this->user->isAdmMod && '1' == $this->user->g_mod_ban_users); + } + + protected function getchangeGroup() + { + return $this->user->isAdmin; + } + + public function canDeleteUser(User $user) + { + if (! $this->profileRules instanceof ProfileRules) { + $this->profileRules = $this->c->ProfileRules; + } + + return $this->profileRules->setUser($user)->deleteUser; + } + + public function canBanUser(User $user) + { + if (! $this->profileRules instanceof ProfileRules) { + $this->profileRules = $this->c->ProfileRules; + } + + return $this->profileRules->setUser($user)->banUser; + } + + public function canChangeGroup(User $user) + { + return $this->user->isAdmin && ! $user->isAdmin; + } +} diff --git a/app/config/main.dist.php b/app/config/main.dist.php index 02f2b788b7e49d34af6b68bb4fd4f308bd5aa70a..a817fbd2072e606545efe30e57a46544d9f08bbd 100644 --- a/app/config/main.dist.php +++ b/app/config/main.dist.php @@ -255,5 +255,6 @@ return [ 'SearchModelExecute' => \ForkBB\Models\Search\Execute::class, 'ProfileRules' => \ForkBB\Models\Rules\Profile::class, + 'UsersRules' => \ForkBB\Models\Rules\Users::class, ], ]; diff --git a/app/lang/en/admin_users.po b/app/lang/en/admin_users.po index 3cce9d0d23984b99ecd6f5d7e0a1c28a608cbedb..00b11ec857df0e65b58060c3e1bea61f7d7b4a9f 100644 --- a/app/lang/en/admin_users.po +++ b/app/lang/en/admin_users.po @@ -24,6 +24,18 @@ msgstr "Not verified" msgid "No users selected" msgstr "No users selected." +msgid "Action not available" +msgstr "Action not available." + +msgid "You are not allowed to delete the %s" +msgstr "You are not allowed to delete the %s." + +msgid "You are not allowed to ban the %s" +msgstr "You are not allowed to ban the %s." + +msgid "You are not allowed to change group for %s" +msgstr "You are not allowed to change group for %s." + msgid "No move admins message" msgstr "For security reasons, you are not allowed to move multiple administrators to another group. If you want to move these administrators, you can do so on their respective user profiles." diff --git a/app/lang/ru/admin_users.po b/app/lang/ru/admin_users.po index fee75defeef5242bb794e69497c41ba800677ba5..17bdfbbf81b3eb6257f2c2944ef91d1967a9cc7c 100644 --- a/app/lang/ru/admin_users.po +++ b/app/lang/ru/admin_users.po @@ -24,6 +24,18 @@ msgstr "Не проверенный" msgid "No users selected" msgstr "Пользователи не выбраны." +msgid "Action not available" +msgstr "Действие недоступно." + +msgid "You are not allowed to delete the %s" +msgstr "Недостаточно прав для удаления %s." + +msgid "You are not allowed to ban the %s" +msgstr "Недостаточно прав для бана %s." + +msgid "You are not allowed to change group for %s" +msgstr "Недостаточно прав для изменения группы у %s." + msgid "No move admins message" msgstr "Из соображений безопасности вы не можете переместить администраторов в другую группу. Если всё же вы хотите их переместить, то сделайте это в их профилях."