webauthn: add controllers and transformers
This commit is contained in:
parent
cdd07fa275
commit
28146f5bb6
7 changed files with 329 additions and 90 deletions
99
app/Http/Controllers/Auth/WebauthnController.php
Normal file
99
app/Http/Controllers/Auth/WebauthnController.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Auth;
|
||||
|
||||
use Exception;
|
||||
use Pterodactyl\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Auth\AuthManager;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use LaravelWebauthn\Facades\Webauthn;
|
||||
use Webauthn\PublicKeyCredentialRequestOptions;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Contracts\Cache\Repository as CacheRepository;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||
|
||||
class WebauthnController extends AbstractLoginController
|
||||
{
|
||||
private const SESSION_PUBLICKEY_REQUEST = 'webauthn.publicKeyRequest';
|
||||
|
||||
private CacheRepository $cache;
|
||||
|
||||
public function __construct(AuthManager $auth, ConfigRepository $config, CacheRepository $cache)
|
||||
{
|
||||
parent::__construct($auth, $config);
|
||||
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse|void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function auth(Request $request): JsonResponse
|
||||
{
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->sendLockoutResponse($request);
|
||||
return;
|
||||
}
|
||||
|
||||
$token = $request->input('confirmation_token');
|
||||
try {
|
||||
/** @var \Pterodactyl\Models\User $user */
|
||||
$user = User::query()->findOrFail($this->cache->get($token, 0));
|
||||
} catch (ModelNotFoundException $exception) {
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
$this->sendFailedLoginResponse(
|
||||
$request,
|
||||
null,
|
||||
'The authentication token provided has expired, please refresh the page and try again.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
$this->auth->guard()->onceUsingId($user->id);
|
||||
|
||||
try {
|
||||
$publicKey = $request->session()->pull(self::SESSION_PUBLICKEY_REQUEST);
|
||||
if (!$publicKey instanceof PublicKeyCredentialRequestOptions) {
|
||||
throw new ModelNotFoundException(trans('webauthn::errors.auth_data_not_found'));
|
||||
}
|
||||
|
||||
$result = Webauthn::doAuthenticate(
|
||||
$user,
|
||||
$publicKey,
|
||||
$this->input($request, 'data'),
|
||||
);
|
||||
|
||||
if (!$result) {
|
||||
return new JsonResponse([
|
||||
'error' => [
|
||||
'message' => 'Nice attempt, you didn\'t pass the challenge.',
|
||||
],
|
||||
], JsonResponse::HTTP_I_AM_A_TEAPOT);
|
||||
}
|
||||
|
||||
$this->cache->delete($token);
|
||||
|
||||
return $this->sendLoginResponse($user, $request);
|
||||
} catch (Exception $e) {
|
||||
return new JsonResponse([
|
||||
'error' => [
|
||||
'message' => $e->getMessage(),
|
||||
],
|
||||
], JsonResponse::HTTP_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the input with a string result.
|
||||
*/
|
||||
private function input(Request $request, string $name, string $default = ''): string
|
||||
{
|
||||
$result = $request->input($name);
|
||||
|
||||
return is_string($result) ? $result : $default;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue