From c087f6429f9f6c95f389718e779d46b1649fe46f Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 8 Dec 2019 11:02:59 -0800 Subject: [PATCH] Temporary patch to get user management pages displaying correctly --- app/Http/Controllers/Admin/UserController.php | 26 +++-------- app/Http/Requests/Admin/UserFormRequest.php | 21 ++++----- app/Models/User.php | 2 +- app/Services/Users/ToggleTwoFactorService.php | 15 ++----- app/Services/Users/UserUpdateService.php | 43 +++++------------- resources/views/admin/users/view.blade.php | 44 ------------------- 6 files changed, 32 insertions(+), 119 deletions(-) diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 7431023aa..7889b4757 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -164,27 +164,11 @@ class UserController extends Controller */ public function update(UserFormRequest $request, User $user) { - $this->updateService->setUserLevel(User::USER_LEVEL_ADMIN); - $data = $this->updateService->handle($user, $request->normalize()); + $this->updateService + ->setUserLevel(User::USER_LEVEL_ADMIN) + ->handle($user, $request->normalize()); - if (! empty($data->get('exceptions'))) { - foreach ($data->get('exceptions') as $node => $exception) { - /** @var \GuzzleHttp\Exception\RequestException $exception */ - /** @var \GuzzleHttp\Psr7\Response|null $response */ - $response = method_exists($exception, 'getResponse') ? $exception->getResponse() : null; - $message = trans('admin/server.exceptions.daemon_exception', [ - 'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(), - ]); - - $this->alert->danger(trans('exceptions.users.node_revocation_failed', [ - 'node' => $node, - 'error' => $message, - 'link' => route('admin.nodes.view', $node), - ]))->flash(); - } - } - - $this->alert->success($this->translator->trans('admin/user.notices.account_updated'))->flash(); + $this->alert->success(trans('admin/user.notices.account_updated'))->flash(); return redirect()->route('admin.users.view', $user->id); } @@ -193,7 +177,7 @@ class UserController extends Controller * Get a JSON response of users on the system. * * @param \Illuminate\Http\Request $request - * @return \Illuminate\Database\Eloquent\Collection + * @return \Illuminate\Support\Collection */ public function json(Request $request) { diff --git a/app/Http/Requests/Admin/UserFormRequest.php b/app/Http/Requests/Admin/UserFormRequest.php index 119afec1d..4203e65d9 100644 --- a/app/Http/Requests/Admin/UserFormRequest.php +++ b/app/Http/Requests/Admin/UserFormRequest.php @@ -3,6 +3,7 @@ namespace Pterodactyl\Http\Requests\Admin; use Pterodactyl\Models\User; +use Illuminate\Support\Collection; class UserFormRequest extends AdminFormRequest { @@ -12,16 +13,16 @@ class UserFormRequest extends AdminFormRequest */ public function rules() { - $rules = collect(User::getRules()); - if ($this->method() === 'PATCH') { - $rules = collect(User::getRulesForUpdate($this->route()->parameter('user')))->merge([ - 'ignore_connection_error' => ['sometimes', 'nullable', 'boolean'], - ]); - } - - return $rules->only([ - 'email', 'username', 'name_first', 'name_last', 'password', - 'language', 'ignore_connection_error', 'root_admin', + return Collection::make( + User::getRulesForUpdate($this->route()->parameter('user')) + )->only([ + 'email', + 'username', + 'name_first', + 'name_last', + 'password', + 'language', + 'root_admin', ])->toArray(); } } diff --git a/app/Models/User.php b/app/Models/User.php index 2e312d46c..2f0a79713 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -158,7 +158,7 @@ class User extends Validable implements 'username' => 'required|between:1,255|unique:users,username', 'name_first' => 'required|string|between:1,255', 'name_last' => 'required|string|between:1,255', - 'password' => 'required|nullable|string', + 'password' => 'sometimes|nullable|string', 'root_admin' => 'boolean', 'language' => 'required|string', 'use_totp' => 'boolean', diff --git a/app/Services/Users/ToggleTwoFactorService.php b/app/Services/Users/ToggleTwoFactorService.php index 0f68b76c2..b68dc911d 100644 --- a/app/Services/Users/ToggleTwoFactorService.php +++ b/app/Services/Users/ToggleTwoFactorService.php @@ -5,18 +5,12 @@ namespace Pterodactyl\Services\Users; use Carbon\Carbon; use Pterodactyl\Models\User; use PragmaRX\Google2FA\Google2FA; -use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Encryption\Encrypter; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid; class ToggleTwoFactorService { - /** - * @var \Illuminate\Contracts\Config\Repository - */ - private $config; - /** * @var \Illuminate\Contracts\Encryption\Encrypter */ @@ -37,16 +31,13 @@ class ToggleTwoFactorService * * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter * @param \PragmaRX\Google2FA\Google2FA $google2FA - * @param \Illuminate\Contracts\Config\Repository $config * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository */ public function __construct( Encrypter $encrypter, Google2FA $google2FA, - Repository $config, UserRepositoryInterface $repository ) { - $this->config = $config; $this->encrypter = $encrypter; $this->google2FA = $google2FA; $this->repository = $repository; @@ -60,16 +51,18 @@ class ToggleTwoFactorService * @param bool|null $toggleState * @return bool * + * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid */ public function handle(User $user, string $token, bool $toggleState = null): bool { - $window = $this->config->get('pterodactyl.auth.2fa.window'); $secret = $this->encrypter->decrypt($user->totp_secret); - $isValidToken = $this->google2FA->verifyKey($secret, $token, $window); + $isValidToken = $this->google2FA->verifyKey($secret, $token, config()->get('pterodactyl.auth.2fa.window')); if (! $isValidToken) { throw new TwoFactorAuthenticationTokenInvalid; diff --git a/app/Services/Users/UserUpdateService.php b/app/Services/Users/UserUpdateService.php index 4f6d99a5a..4e1911a32 100644 --- a/app/Services/Users/UserUpdateService.php +++ b/app/Services/Users/UserUpdateService.php @@ -3,11 +3,9 @@ namespace Pterodactyl\Services\Users; use Pterodactyl\Models\User; -use Illuminate\Support\Collection; use Illuminate\Contracts\Hashing\Hasher; use Pterodactyl\Traits\Services\HasUserLevels; -use Pterodactyl\Contracts\Repository\UserRepositoryInterface; -use Pterodactyl\Services\DaemonKeys\RevokeMultipleDaemonKeysService; +use Pterodactyl\Repositories\Eloquent\UserRepository; class UserUpdateService { @@ -19,44 +17,33 @@ class UserUpdateService private $hasher; /** - * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface + * @var \Pterodactyl\Repositories\Eloquent\UserRepository */ private $repository; - /** - * @var \Pterodactyl\Services\DaemonKeys\RevokeMultipleDaemonKeysService - */ - private $revocationService; - /** * UpdateService constructor. * * @param \Illuminate\Contracts\Hashing\Hasher $hasher - * @param \Pterodactyl\Services\DaemonKeys\RevokeMultipleDaemonKeysService $revocationService - * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository + * @param \Pterodactyl\Repositories\Eloquent\UserRepository $repository */ - public function __construct( - Hasher $hasher, - RevokeMultipleDaemonKeysService $revocationService, - UserRepositoryInterface $repository - ) { + public function __construct(Hasher $hasher, UserRepository $repository) + { $this->hasher = $hasher; $this->repository = $repository; - $this->revocationService = $revocationService; } /** - * Update the user model instance. If the user has been removed as an administrator - * revoke all of the authentication tokens that have been assigned to their account. + * Update the user model instance. * * @param \Pterodactyl\Models\User $user * @param array $data - * @return \Illuminate\Support\Collection + * @return \Pterodactyl\Models\User * * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function handle(User $user, array $data): Collection + public function handle(User $user, array $data) { if (! empty(array_get($data, 'password'))) { $data['password'] = $this->hasher->make($data['password']); @@ -64,17 +51,9 @@ class UserUpdateService unset($data['password']); } - if ($this->isUserLevel(User::USER_LEVEL_ADMIN)) { - if (array_get($data, 'root_admin', 0) == 0 && $user->root_admin) { - $this->revocationService->handle($user, array_get($data, 'ignore_connection_error', false)); - } - } else { - unset($data['root_admin']); - } + /** @var \Pterodactyl\Models\User $response */ + $response = $this->repository->update($user->id, $data); - return collect([ - 'model' => $this->repository->update($user->id, $data), - 'exceptions' => $this->revocationService->getExceptions(), - ]); + return $response; } } diff --git a/resources/views/admin/users/view.blade.php b/resources/views/admin/users/view.blade.php index 125719d9c..e1a49ef0a 100644 --- a/resources/views/admin/users/view.blade.php +++ b/resources/views/admin/users/view.blade.php @@ -102,55 +102,11 @@

Setting this to 'Yes' gives a user full administrative access.

-
- - -

If checked, any errors thrown while revoking keys across nodes will be ignored. You should avoid this checkbox if possible as any non-revoked keys could continue to be active for up to 24 hours after this account is changed. If you are needing to revoke account permissions immediately and are facing node issues, you should check this box and then restart any nodes that failed to be updated to clear out any stored keys.

-
- {{--
--}} - {{--
--}} - {{--
--}} - {{--

Associated Servers

--}} - {{--
--}} - {{--
--}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{--@foreach($user->setAccessLevel('subuser')->access()->get() as $server)--}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{----}} - {{--@endforeach--}} - {{----}} - {{--
IdentifierServer NameAccessNode
{{ $server->uuidShort }}{{ $server->name }}--}} - {{--@if($server->owner_id === $user->id)--}} - {{--Owner--}} - {{--@else--}} - {{--Subuser--}} - {{--@endif--}} - {{--{{ $server->node->name }}@if($server->suspended === 0)Active@elseSuspended@endif
--}} - {{--
--}} - {{--
--}} - {{--
--}}