misc_pterodactyl-panel/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php
Dane Everitt e3df0738da
Change the way API keys are stored and validated; clarify API namespacing
Previously, a single key was used to access the API, this has not changed in terms of what the user sees. However, API keys now use an identifier and token internally. The identifier is the first 16 characters of the key, and the token is the remaining 32. The token is stored encrypted at rest in the database and the identifier is used by the API middleware to grab that record and make a timing attack safe comparison.
2018-01-13 16:06:19 -06:00

69 lines
1.9 KiB
PHP

<?php
namespace Pterodactyl\Http\Middleware\Api\Daemon;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class DaemonAuthenticate
{
/**
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
*/
private $repository;
/**
* Daemon routes that this middleware should be skipped on.
*
* @var array
*/
protected $except = [
'daemon.configuration',
];
/**
* DaemonAuthenticate constructor.
*
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
*/
public function __construct(NodeRepositoryInterface $repository)
{
$this->repository = $repository;
}
/**
* Check if a request from the daemon can be properly attributed back to a single node instance.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
public function handle(Request $request, Closure $next)
{
if (in_array($request->route()->getName(), $this->except)) {
return $next($request);
}
$token = $request->bearerToken();
if (is_null($token)) {
throw new HttpException(401, null, null, ['WWW-Authenticate' => 'Bearer']);
}
try {
$node = $this->repository->findFirstWhere([['daemonSecret', '=', $token]]);
} catch (RecordNotFoundException $exception) {
throw new AccessDeniedHttpException;
}
$request->attributes->set('node', $node);
return $next($request);
}
}