diff --git a/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php b/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php deleted file mode 100644 index 822cf0250..000000000 --- a/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php +++ /dev/null @@ -1,55 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Services\Subusers; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Services\Subusers\PermissionCreationService; -use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface; - -class PermissionCreationServiceTest extends TestCase -{ - /** - * @var \Pterodactyl\Contracts\Repository\PermissionRepositoryInterface|\Mockery\Mock - */ - protected $repository; - - /** - * @var \Pterodactyl\Services\Subusers\PermissionCreationService - */ - protected $service; - - /** - * Setup tests. - */ - public function setUp(): void - { - parent::setUp(); - - $this->repository = m::mock(PermissionRepositoryInterface::class); - $this->service = new PermissionCreationService($this->repository); - } - - /** - * Test that permissions can be assigned correctly. - */ - public function testPermissionsAreAssignedCorrectly() - { - $permissions = ['access-sftp']; - - $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf() - ->shouldReceive('insert')->with([ - ['subuser_id' => 1, 'permission' => 'access-sftp'], - ])->once()->andReturn(true); - - $this->service->handle(1, $permissions); - $this->assertTrue(true); - } -} diff --git a/tests/Unit/Services/Subusers/SubuserCreationServiceTest.php b/tests/Unit/Services/Subusers/SubuserCreationServiceTest.php deleted file mode 100644 index c8a71577e..000000000 --- a/tests/Unit/Services/Subusers/SubuserCreationServiceTest.php +++ /dev/null @@ -1,186 +0,0 @@ -connection = m::mock(ConnectionInterface::class); - $this->subuserRepository = m::mock(SubuserRepositoryInterface::class); - $this->serverRepository = m::mock(ServerRepositoryInterface::class); - $this->userCreationService = m::mock(UserCreationService::class); - $this->userRepository = m::mock(UserRepositoryInterface::class); - } - - /** - * Test that a user without an existing account can be added as a subuser. - */ - public function testAccountIsCreatedForNewUser() - { - $permissions = ['test-1' => 'test:1', 'test-2' => null]; - $server = factory(Server::class)->make(); - $user = factory(User::class)->make([ - 'email' => 'known.1+test@example.com', - ]); - $subuser = factory(Subuser::class)->make(['user_id' => $user->id, 'server_id' => $server->id]); - - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->userRepository->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andThrow(new RecordNotFoundException); - $this->userCreationService->shouldReceive('handle')->with(m::on(function ($data) use ($user) { - $subset = m::subset([ - 'email' => $user->email, - 'name_first' => 'Server', - 'name_last' => 'Subuser', - 'root_admin' => false, - ])->match($data); - - $username = substr(array_get($data, 'username', ''), 0, -3) === 'known.1test'; - - return $subset && $username; - }))->once()->andReturn($user); - - $this->subuserRepository->shouldReceive('create')->with(['user_id' => $user->id, 'server_id' => $server->id]) - ->once()->andReturn($subuser); - $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); - - $response = $this->getService()->handle($server, $user->email, array_keys($permissions)); - $this->assertInstanceOf(Subuser::class, $response); - $this->assertSame($subuser, $response); - } - - /** - * Test that an existing user can be added as a subuser. - */ - public function testExistingUserCanBeAddedAsASubuser() - { - $permissions = ['access-sftp']; - $server = factory(Server::class)->make(); - $user = factory(User::class)->make(); - $subuser = factory(Subuser::class)->make(['user_id' => $user->id, 'server_id' => $server->id]); - - $this->serverRepository->shouldReceive('find')->with($server->id)->once()->andReturn($server); - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->userRepository->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user); - $this->subuserRepository->shouldReceive('findCountWhere')->with([ - ['user_id', '=', $user->id], - ['server_id', '=', $server->id], - ])->once()->andReturn(0); - - $this->subuserRepository->shouldReceive('create')->with(['user_id' => $user->id, 'server_id' => $server->id]) - ->once()->andReturn($subuser); - $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); - - $response = $this->getService()->handle($server->id, $user->email, $permissions); - $this->assertInstanceOf(Subuser::class, $response); - $this->assertSame($subuser, $response); - } - - /** - * Test that an exception gets thrown if the subuser is actually the server owner. - */ - public function testExceptionIsThrownIfUserIsServerOwner() - { - $user = factory(User::class)->make(); - $server = factory(Server::class)->make(['owner_id' => $user->id]); - - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->userRepository->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user); - - try { - $this->getService()->handle($server, $user->email, []); - } catch (DisplayException $exception) { - $this->assertInstanceOf(UserIsServerOwnerException::class, $exception); - $this->assertEquals(trans('exceptions.subusers.user_is_owner'), $exception->getMessage()); - } - } - - /** - * Test that an exception is thrown if the user is already added as a subuser. - */ - public function testExceptionIsThrownIfUserIsAlreadyASubuser() - { - $user = factory(User::class)->make(); - $server = factory(Server::class)->make(); - - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->userRepository->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user); - $this->subuserRepository->shouldReceive('findCountWhere')->with([ - ['user_id', '=', $user->id], - ['server_id', '=', $server->id], - ])->once()->andReturn(1); - - try { - $this->getService()->handle($server, $user->email, []); - } catch (DisplayException $exception) { - $this->assertInstanceOf(ServerSubuserExistsException::class, $exception); - $this->assertEquals(trans('exceptions.subusers.subuser_exists'), $exception->getMessage()); - } - } - - /** - * Return an instance of the service with mocked dependencies. - * - * @return \Pterodactyl\Services\Subusers\SubuserCreationService - */ - private function getService(): SubuserCreationService - { - return new SubuserCreationService( - $this->connection, - $this->subuserRepository, - $this->userCreationService, - $this->userRepository - ); - } -} diff --git a/tests/Unit/Services/Users/ToggleTwoFactorServiceTest.php b/tests/Unit/Services/Users/ToggleTwoFactorServiceTest.php deleted file mode 100644 index 86b1a2dc4..000000000 --- a/tests/Unit/Services/Users/ToggleTwoFactorServiceTest.php +++ /dev/null @@ -1,128 +0,0 @@ -config = m::mock(Repository::class); - $this->encrypter = m::mock(Encrypter::class); - $this->google2FA = m::mock(Google2FA::class); - $this->repository = m::mock(UserRepositoryInterface::class); - - $this->config->shouldReceive('get')->with('pterodactyl.auth.2fa.window')->once()->andReturn(self::TEST_WINDOW_INT); - $this->encrypter->shouldReceive('decrypt')->with(self::USER_TOTP_SECRET)->once()->andReturn(self::DECRYPTED_USER_SECRET); - } - - /** - * Test that 2FA can be enabled for a user. - */ - public function testTwoFactorIsEnabledForUser() - { - $model = factory(User::class)->make(['totp_secret' => self::USER_TOTP_SECRET, 'use_totp' => false]); - - $this->google2FA->shouldReceive('verifyKey')->with(self::DECRYPTED_USER_SECRET, 'test-token', self::TEST_WINDOW_INT)->once()->andReturn(true); - $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [ - 'totp_authenticated_at' => Carbon::now(), - 'use_totp' => true, - ])->once()->andReturnNull(); - - $this->assertTrue($this->getService()->handle($model, 'test-token')); - } - - /** - * Test that 2FA can be disabled for a user. - */ - public function testTwoFactorIsDisabled() - { - $model = factory(User::class)->make(['totp_secret' => self::USER_TOTP_SECRET, 'use_totp' => true]); - - $this->google2FA->shouldReceive('verifyKey')->with(self::DECRYPTED_USER_SECRET, 'test-token', self::TEST_WINDOW_INT)->once()->andReturn(true); - $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [ - 'totp_authenticated_at' => Carbon::now(), - 'use_totp' => false, - ])->once()->andReturnNull(); - - $this->assertTrue($this->getService()->handle($model, 'test-token')); - } - - /** - * Test that 2FA will remain disabled for a user. - */ - public function testTwoFactorRemainsDisabledForUser() - { - $model = factory(User::class)->make(['totp_secret' => self::USER_TOTP_SECRET, 'use_totp' => false]); - - $this->google2FA->shouldReceive('verifyKey')->with(self::DECRYPTED_USER_SECRET, 'test-token', self::TEST_WINDOW_INT)->once()->andReturn(true); - $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [ - 'totp_authenticated_at' => Carbon::now(), - 'use_totp' => false, - ])->once()->andReturnNull(); - - $this->assertTrue($this->getService()->handle($model, 'test-token', false)); - } - - /** - * Test that an exception is thrown if the token provided is invalid. - * - * @expectedException \Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid - */ - public function testExceptionIsThrownIfTokenIsInvalid() - { - $model = factory(User::class)->make(['totp_secret' => self::USER_TOTP_SECRET]); - $this->google2FA->shouldReceive('verifyKey')->once()->andReturn(false); - - $this->getService()->handle($model, 'test-token'); - } - - /** - * Return an instance of the service with mocked dependencies. - * - * @return \Pterodactyl\Services\Users\ToggleTwoFactorService - */ - private function getService(): ToggleTwoFactorService - { - return new ToggleTwoFactorService($this->encrypter, $this->google2FA, $this->config, $this->repository); - } -} diff --git a/tests/Unit/Services/Users/TwoFactorSetupServiceTest.php b/tests/Unit/Services/Users/TwoFactorSetupServiceTest.php deleted file mode 100644 index 83b3109bd..000000000 --- a/tests/Unit/Services/Users/TwoFactorSetupServiceTest.php +++ /dev/null @@ -1,81 +0,0 @@ -config = m::mock(Repository::class); - $this->encrypter = m::mock(Encrypter::class); - $this->repository = m::mock(UserRepositoryInterface::class); - } - - /** - * Test that the correct data is returned. - */ - public function testSecretAndImageAreReturned() - { - $model = factory(User::class)->make(); - - $this->config->shouldReceive('get')->with('pterodactyl.auth.2fa.bytes', 16)->andReturn(32); - $this->config->shouldReceive('get')->with('app.name')->andReturn('Company Name'); - $this->encrypter->shouldReceive('encrypt') - ->with(m::on(function ($value) { - return preg_match('/([A-Z234567]{32})/', $value) !== false; - })) - ->once() - ->andReturn('encryptedSecret'); - - $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, ['totp_secret' => 'encryptedSecret'])->once()->andReturnNull(); - - $response = $this->getService()->handle($model); - $this->assertNotEmpty($response); - - $companyName = preg_quote(rawurlencode('CompanyName')); - $email = preg_quote(rawurlencode($model->email)); - - $this->assertRegExp( - '/otpauth:\/\/totp\/' . $companyName . ':' . $email . '\?secret=([A-Z234567]{32})&issuer=' . $companyName . '/', - $response - ); - } - - /** - * Return an instance of the service to test with mocked dependencies. - * - * @return \Pterodactyl\Services\Users\TwoFactorSetupService - */ - private function getService(): TwoFactorSetupService - { - return new TwoFactorSetupService($this->config, $this->encrypter, $this->repository); - } -} diff --git a/tests/Unit/Services/Users/UserCreationServiceTest.php b/tests/Unit/Services/Users/UserCreationServiceTest.php deleted file mode 100644 index 7627a656d..000000000 --- a/tests/Unit/Services/Users/UserCreationServiceTest.php +++ /dev/null @@ -1,157 +0,0 @@ -connection = m::mock(ConnectionInterface::class); - $this->hasher = m::mock(Hasher::class); - $this->passwordBroker = m::mock(PasswordBroker::class); - $this->repository = m::mock(UserRepositoryInterface::class); - } - - /** - * Test that a user is created when a password is passed. - */ - public function testUserIsCreatedWhenPasswordIsProvided() - { - $user = factory(User::class)->make(); - - $this->hasher->shouldReceive('make')->with('raw-password')->once()->andReturn('enc-password'); - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->repository->shouldReceive('create')->with([ - 'password' => 'enc-password', - 'uuid' => $this->getKnownUuid(), - ], true, true)->once()->andReturn($user); - $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); - - $response = $this->getService()->handle([ - 'password' => 'raw-password', - ]); - - $this->assertNotNull($response); - Notification::assertSentTo($user, AccountCreated::class, function ($notification) use ($user) { - $this->assertSame($user, $notification->user); - $this->assertNull($notification->token); - - return true; - }); - } - - /** - * Test that a UUID passed in the submission data is not used when - * creating the user. - */ - public function testUuidPassedInDataIsIgnored() - { - $user = factory(User::class)->make(); - - $this->hasher->shouldReceive('make')->andReturn('enc-password'); - $this->connection->shouldReceive('beginTransaction')->andReturnNull(); - $this->repository->shouldReceive('create')->with([ - 'password' => 'enc-password', - 'uuid' => $this->getKnownUuid(), - ], true, true)->once()->andReturn($user); - $this->connection->shouldReceive('commit')->andReturnNull(); - - $response = $this->getService()->handle([ - 'password' => 'raw-password', - 'uuid' => 'test-uuid', - ]); - - $this->assertNotNull($response); - $this->assertInstanceOf(User::class, $response); - Notification::assertSentTo($user, AccountCreated::class, function ($notification) use ($user) { - $this->assertSame($user, $notification->user); - $this->assertNull($notification->token); - - return true; - }); - } - - /** - * Test that a user is created with a random password when no password is provided. - */ - public function testUserIsCreatedWhenNoPasswordIsProvided() - { - $user = factory(User::class)->make(); - - $this->hasher->shouldNotReceive('make'); - $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->hasher->shouldReceive('make')->once()->andReturn('created-enc-password'); - $this->passwordBroker->shouldReceive('createToken')->with($user)->once()->andReturn('random-token'); - - $this->repository->shouldReceive('create')->with([ - 'password' => 'created-enc-password', - 'email' => $user->email, - 'uuid' => $this->getKnownUuid(), - ], true, true)->once()->andReturn($user); - - $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); - - $response = $this->getService()->handle([ - 'email' => $user->email, - ]); - - $this->assertNotNull($response); - $this->assertInstanceOf(User::class, $response); - Notification::assertSentTo($user, AccountCreated::class, function ($notification) use ($user) { - $this->assertSame($user, $notification->user); - $this->assertSame('random-token', $notification->token); - - return true; - }); - } - - /** - * Return a new instance of the service using mocked dependencies. - * - * @return \Pterodactyl\Services\Users\UserCreationService - */ - private function getService(): UserCreationService - { - return new UserCreationService($this->connection, $this->hasher, $this->passwordBroker, $this->repository); - } -} diff --git a/tests/Unit/Services/Users/UserDeletionServiceTest.php b/tests/Unit/Services/Users/UserDeletionServiceTest.php deleted file mode 100644 index 1b185ad9b..000000000 --- a/tests/Unit/Services/Users/UserDeletionServiceTest.php +++ /dev/null @@ -1,103 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Services\Users; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\User; -use Illuminate\Contracts\Translation\Translator; -use Pterodactyl\Services\Users\UserDeletionService; -use Pterodactyl\Contracts\Repository\UserRepositoryInterface; -use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; - -class UserDeletionServiceTest extends TestCase -{ - /** - * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface - */ - protected $repository; - - /** - * @var \Illuminate\Contracts\Translation\Translator - */ - protected $translator; - - /** - * @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface - */ - protected $serverRepository; - - /** - * @var \Pterodactyl\Services\Users\UserDeletionService - */ - protected $service; - - /** - * @var User - */ - protected $user; - - /** - * Setup tests. - */ - public function setUp(): void - { - parent::setUp(); - - $this->user = factory(User::class)->make(); - $this->repository = m::mock(UserRepositoryInterface::class); - $this->translator = m::mock(Translator::class); - $this->serverRepository = m::mock(ServerRepositoryInterface::class); - - $this->service = new UserDeletionService( - $this->serverRepository, - $this->translator, - $this->repository - ); - } - - /** - * Test that a user is deleted if they have no servers. - */ - public function testUserIsDeletedIfNoServersAreAttachedToAccount() - { - $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() - ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(1); - - $this->assertEquals(1, $this->service->handle($this->user->id)); - } - - /** - * Test that an exception is thrown if trying to delete a user with servers. - * - * @expectedException \Pterodactyl\Exceptions\DisplayException - */ - public function testExceptionIsThrownIfServersAreAttachedToAccount() - { - $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() - ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(1); - $this->translator->shouldReceive('trans')->with('admin/user.exceptions.user_has_servers')->once()->andReturnNull(); - - $this->service->handle($this->user->id); - } - - /** - * Test that the function supports passing in a model or an ID. - */ - public function testModelCanBePassedInPlaceOfUserId() - { - $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() - ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(1); - - $this->assertEquals(1, $this->service->handle($this->user)); - } -} diff --git a/tests/Unit/Services/Users/UserUpdateServiceTest.php b/tests/Unit/Services/Users/UserUpdateServiceTest.php deleted file mode 100644 index dd4eca36e..000000000 --- a/tests/Unit/Services/Users/UserUpdateServiceTest.php +++ /dev/null @@ -1,126 +0,0 @@ -hasher = m::mock(Hasher::class); - $this->repository = m::mock(UserRepositoryInterface::class); - } - - /** - * Test that the handle function does not attempt to hash a password if no - * password is provided or the password is null. - * - * @dataProvider badPasswordDataProvider - */ - public function testUpdateUserWithoutTouchingHasherIfNoPasswordPassed(array $data) - { - $user = factory(User::class)->make(); - $this->repository->shouldReceive('update')->with($user->id, ['test-data' => 'value'])->once()->andReturnNull(); - - $response = $this->getService()->handle($user, $data); - $this->assertInstanceOf(Collection::class, $response); - $this->assertTrue($response->has('model')); - $this->assertTrue($response->has('exceptions')); - } - - /** - * Provide a test data set with passwords that should not be hashed. - * - * @return array - */ - public function badPasswordDataProvider(): array - { - return [ - [['test-data' => 'value']], - [['test-data' => 'value', 'password' => null]], - [['test-data' => 'value', 'password' => '']], - [['test-data' => 'value', 'password' => 0]], - ]; - } - - /** - * Test that the handle function hashes a password if passed in the data array. - */ - public function testUpdateUserAndHashPasswordIfProvided() - { - $user = factory(User::class)->make(); - $this->hasher->shouldReceive('make')->with('raw_pass')->once()->andReturn('enc_pass'); - $this->repository->shouldReceive('update')->with($user->id, ['password' => 'enc_pass'])->once()->andReturnNull(); - - $response = $this->getService()->handle($user, ['password' => 'raw_pass']); - $this->assertInstanceOf(Collection::class, $response); - $this->assertTrue($response->has('model')); - $this->assertTrue($response->has('exceptions')); - } - - /** - * Test that an admin can revoke a user's administrative status. - */ - public function testAdministrativeUserRevokingAdminStatus() - { - $user = factory(User::class)->make(['root_admin' => true]); - $service = $this->getService(); - $service->setUserLevel(User::USER_LEVEL_ADMIN); - - $this->repository->shouldReceive('update')->with($user->id, ['root_admin' => false])->once()->andReturnNull(); - - $response = $service->handle($user, ['root_admin' => false]); - $this->assertInstanceOf(Collection::class, $response); - $this->assertTrue($response->has('model')); - $this->assertTrue($response->has('exceptions')); - } - - /** - * Test that a normal user is unable to set an administrative status for themselves. - */ - public function testNormalUserShouldNotRevokeAdminStatus() - { - $user = factory(User::class)->make(['root_admin' => false]); - $service = $this->getService(); - $service->setUserLevel(User::USER_LEVEL_USER); - - $this->repository->shouldReceive('update')->with($user->id, [])->once()->andReturnNull(); - - $response = $service->handle($user, ['root_admin' => true]); - $this->assertInstanceOf(Collection::class, $response); - $this->assertTrue($response->has('model')); - $this->assertTrue($response->has('exceptions')); - } - - /** - * Return an instance of the service for testing. - * - * @return \Pterodactyl\Services\Users\UserUpdateService - */ - private function getService(): UserUpdateService - { - return new UserUpdateService($this->hasher, $this->repository); - } -}