diff --git a/app/Console/Commands/User/DeleteUserCommand.php b/app/Console/Commands/User/DeleteUserCommand.php index b4c7254d4..ce8427630 100644 --- a/app/Console/Commands/User/DeleteUserCommand.php +++ b/app/Console/Commands/User/DeleteUserCommand.php @@ -51,6 +51,12 @@ class DeleteUserCommand extends Command */ protected $signature = 'p:user:delete {--user=}'; + /** + * DeleteUserCommand constructor. + * + * @param \Pterodactyl\Services\Users\UserDeletionService $deletionService + * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository + */ public function __construct( UserDeletionService $deletionService, UserRepositoryInterface $repository diff --git a/app/Console/Commands/User/MakeUserCommand.php b/app/Console/Commands/User/MakeUserCommand.php index f98517e41..02bdd1baf 100644 --- a/app/Console/Commands/User/MakeUserCommand.php +++ b/app/Console/Commands/User/MakeUserCommand.php @@ -34,7 +34,10 @@ class MakeUserCommand extends Command */ protected $creationService; - protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--no-password}'; + /** + * @var string + */ + protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--admin=} {--no-password}'; /** * MakeUserCommand constructor. @@ -56,6 +59,7 @@ class MakeUserCommand extends Command */ public function handle() { + $root_admin = $this->option('admin') ?? $this->confirm(trans('command/messages.user.ask_admin')); $email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email')); $username = $this->option('username') ?? $this->ask(trans('command/messages.user.ask_username')); $name_first = $this->option('name-first') ?? $this->ask(trans('command/messages.user.ask_name_first')); @@ -67,12 +71,13 @@ class MakeUserCommand extends Command $password = $this->secret(trans('command/messages.user.ask_password')); } - $user = $this->creationService->handle(compact('email', 'username', 'name_first', 'name_last', 'password')); + $user = $this->creationService->handle(compact('email', 'username', 'name_first', 'name_last', 'password', 'root_admin')); $this->table(['Field', 'Value'], [ ['UUID', $user->uuid], ['Email', $user->email], ['Username', $user->username], ['Name', $user->name], + ['Admin', $user->root_admin ? 'Yes' : 'No'], ]); } } diff --git a/resources/lang/en/command/messages.php b/resources/lang/en/command/messages.php index b6bb40fe6..b9fb56cbc 100644 --- a/resources/lang/en/command/messages.php +++ b/resources/lang/en/command/messages.php @@ -37,6 +37,7 @@ return [ 'confirm_delete' => 'Are you sure you want to delete this user from the Panel?', 'no_users_found' => 'No users were found for the search term provided.', 'multiple_found' => 'Multiple accounts were found for the user provided, unable to delete a user because of the --no-interaction flag.', + 'ask_admin' => 'Is this user an administrator?', 'ask_email' => 'Email Address', 'ask_username' => 'Username', 'ask_name_first' => 'First Name', diff --git a/tests/Unit/Commands/User/MakeUserCommandTest.php b/tests/Unit/Commands/User/MakeUserCommandTest.php new file mode 100644 index 000000000..d634aa225 --- /dev/null +++ b/tests/Unit/Commands/User/MakeUserCommandTest.php @@ -0,0 +1,164 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Tests\Unit\Commands\User; + +use Mockery as m; +use Tests\TestCase; +use Pterodactyl\Models\User; +use Pterodactyl\Services\Users\UserCreationService; +use Symfony\Component\Console\Tester\CommandTester; + +class MakeUserCommandTest extends TestCase +{ + /** + * @var \Pterodactyl\Console\Commands\User\MakeUserCommand + */ + protected $command; + + /** + * @var \Pterodactyl\Services\Users\UserCreationService + */ + protected $creationService; + + /** + * Setup tests. + */ + public function setUp() + { + parent::setUp(); + + $this->creationService = m::mock(UserCreationService::class); + + $this->command = m::mock('\Pterodactyl\Console\Commands\User\MakeUserCommand[confirm, ask, secret]', [$this->creationService]); + $this->command->setLaravel($this->app); + } + + /** + * Test that the command executes if no options are passed. + */ + public function testCommandWithNoPassedOptions() + { + $user = factory(User::class)->make(['root_admin' => true]); + + $this->command->shouldReceive('confirm')->with(trans('command/messages.user.ask_admin'))->once()->andReturn($user->root_admin); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_email'))->once()->andReturn($user->email); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_username'))->once()->andReturn($user->username); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_name_first'))->once()->andReturn($user->name_first); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_name_last'))->once()->andReturn($user->name_last); + $this->command->shouldReceive('secret')->with(trans('command/messages.user.ask_password'))->once()->andReturn('Password123'); + + $this->creationService->shouldReceive('handle')->with([ + 'email' => $user->email, + 'username' => $user->username, + 'name_first' => $user->name_first, + 'name_last' => $user->name_last, + 'password' => 'Password123', + 'root_admin' => $user->root_admin, + ])->once()->andReturn($user); + + $response = new CommandTester($this->command); + $response->execute([]); + + $display = $response->getDisplay(); + $this->assertNotEmpty($display); + $this->assertContains(trans('command/messages.user.ask_password_help'), $display); + $this->assertContains($user->uuid, $display); + $this->assertContains($user->email, $display); + $this->assertContains($user->username, $display); + $this->assertContains($user->name, $display); + $this->assertContains('Yes', $display); + } + + /** + * Test that the --no-password flag works as intended. + */ + public function testCommandWithNoPasswordOption() + { + $user = factory(User::class)->make(['root_admin' => true]); + + $this->command->shouldReceive('confirm')->with(trans('command/messages.user.ask_admin'))->once()->andReturn($user->root_admin); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_email'))->once()->andReturn($user->email); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_username'))->once()->andReturn($user->username); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_name_first'))->once()->andReturn($user->name_first); + $this->command->shouldReceive('ask')->with(trans('command/messages.user.ask_name_last'))->once()->andReturn($user->name_last); + $this->command->shouldNotReceive('secret'); + + $this->creationService->shouldReceive('handle')->with([ + 'email' => $user->email, + 'username' => $user->username, + 'name_first' => $user->name_first, + 'name_last' => $user->name_last, + 'password' => null, + 'root_admin' => $user->root_admin, + ])->once()->andReturn($user); + + $response = new CommandTester($this->command); + $response->execute(['--no-password' => true]); + + $display = $response->getDisplay(); + $this->assertNotEmpty($display); + $this->assertNotContains(trans('command/messages.user.ask_password_help'), $display); + } + + /** + * Test command when arguments are passed as flags. + */ + public function testCommandWithOptionsPassed() + { + $user = factory(User::class)->make(['root_admin' => false]); + + $this->command->shouldNotReceive('confirm'); + $this->command->shouldNotReceive('ask'); + $this->command->shouldNotReceive('secret'); + + $this->creationService->shouldReceive('handle')->with([ + 'email' => $user->email, + 'username' => $user->username, + 'name_first' => $user->name_first, + 'name_last' => $user->name_last, + 'password' => 'Password123', + 'root_admin' => $user->root_admin, + ])->once()->andReturn($user); + + $response = new CommandTester($this->command); + $response->execute([ + '--email' => $user->email, + '--username' => $user->username, + '--name-first' => $user->name_first, + '--name-last' => $user->name_last, + '--password' => 'Password123', + '--admin' => 0, + ]); + + $display = $response->getDisplay(); + $this->assertNotEmpty($display); + $this->assertNotContains(trans('command/messages.user.ask_password_help'), $display); + $this->assertContains($user->uuid, $display); + $this->assertContains($user->email, $display); + $this->assertContains($user->username, $display); + $this->assertContains($user->name, $display); + $this->assertContains('No', $display); + } +}