misc_pterodactyl-panel/tests/Unit/Http/Middleware/Api/Admin/AuthenticateKeyTest.php
Dane Everitt f9fc3f4370
Update interface to begin change to seperate account API keys and application keys
Main difference is permissions, cleaner UI for normal users, and account keys use permissions assigned to servers and subusers while application keys use R/W ACLs stored in the key table.
2018-01-14 13:30:55 -06:00

126 lines
4.5 KiB
PHP

<?php
namespace Tests\Unit\Http\Middleware\Api\Admin;
use Mockery as m;
use Cake\Chronos\Chronos;
use Pterodactyl\Models\ApiKey;
use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Encryption\Encrypter;
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Pterodactyl\Http\Middleware\Api\Admin\AuthenticateKey;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
class AuthenticateKeyTest extends MiddlewareTestCase
{
/**
* @var \Illuminate\Auth\AuthManager|\Mockery\Mock
*/
private $auth;
/**
* @var \Illuminate\Contracts\Encryption\Encrypter|\Mockery\Mock
*/
private $encrypter;
/**
* @var \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface|\Mockery\Mock
*/
private $repository;
/**
* Setup tests.
*/
public function setUp()
{
parent::setUp();
Chronos::setTestNow(Chronos::now());
$this->auth = m::mock(AuthManager::class);
$this->encrypter = m::mock(Encrypter::class);
$this->repository = m::mock(ApiKeyRepositoryInterface::class);
}
/**
* Test that a missing bearer token will throw an exception.
*/
public function testMissingBearerTokenThrowsException()
{
$this->request->shouldReceive('bearerToken')->withNoArgs()->once()->andReturnNull();
try {
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
} catch (HttpException $exception) {
$this->assertEquals(401, $exception->getStatusCode());
$this->assertEquals(['WWW-Authenticate' => 'Bearer'], $exception->getHeaders());
}
}
/**
* Test that an invalid API identifer throws an exception.
*
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
*/
public function testInvalidIdentifier()
{
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn('abcd1234');
$this->repository->shouldReceive('findFirstWhere')->andThrow(new RecordNotFoundException);
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
}
/**
* Test that a valid token can continue past the middleware.
*/
public function testValidToken()
{
$model = factory(ApiKey::class)->make();
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn($model->identifier . 'decrypted');
$this->repository->shouldReceive('findFirstWhere')->with([
['identifier', '=', $model->identifier],
['key_type', '=', ApiKey::TYPE_APPLICATION],
])->once()->andReturn($model);
$this->encrypter->shouldReceive('decrypt')->with($model->token)->once()->andReturn('decrypted');
$this->auth->shouldReceive('guard->loginUsingId')->with($model->user_id)->once()->andReturnNull();
$this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [
'last_used_at' => Chronos::now(),
])->once()->andReturnNull();
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
$this->assertEquals($model, $this->request->attributes->get('api_key'));
}
/**
* Test that a valid token identifier with an invalid token attached to it
* triggers an exception.
*
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
*/
public function testInvalidTokenForIdentifier()
{
$model = factory(ApiKey::class)->make();
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn($model->identifier . 'asdf');
$this->repository->shouldReceive('findFirstWhere')->with([
['identifier', '=', $model->identifier],
['key_type', '=', ApiKey::TYPE_APPLICATION],
])->once()->andReturn($model);
$this->encrypter->shouldReceive('decrypt')->with($model->token)->once()->andReturn('decrypted');
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
}
/**
* Return an instance of the middleware with mocked dependencies for testing.
*
* @return \Pterodactyl\Http\Middleware\Api\Admin\AuthenticateKey
*/
private function getMiddleware(): AuthenticateKey
{
return new AuthenticateKey($this->repository, $this->auth, $this->encrypter);
}
}