diff --git a/app/Controllers/Routing.php b/app/Controllers/Routing.php index 1c608314..664972c3 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 fa15c88e..952bcea3 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 061223e3..382aa730 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 4425f339..154d164a 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 b5790a01..1961cfb5 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 441bc4e9..b02bbeca 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 00000000..9cf4ac29 --- /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 02f2b788..a817fbd2 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 3cce9d0d..00b11ec8 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 fee75def..17bdfbbf 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 "Из соображений безопасности вы не можете переместить администраторов в другую группу. Если всё же вы хотите их переместить, то сделайте это в их профилях."