Logic cleanup after a bit of dust collection
This commit is contained in:
parent
8971e78ab5
commit
969d40d6c1
6 changed files with 74 additions and 43 deletions
|
@ -61,6 +61,7 @@ class SecurityKeyController extends ClientApiController
|
|||
$tokenId = Str::random(64);
|
||||
$credentials = $this->createPublicKeyCredentials->handle($request->user());
|
||||
|
||||
// TODO: session
|
||||
$this->cache->put(
|
||||
"register-security-key:$tokenId",
|
||||
serialize($credentials),
|
||||
|
|
|
@ -7,27 +7,27 @@ use Illuminate\Support\Str;
|
|||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use LaravelWebauthn\Facades\Webauthn;
|
||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||
use Pterodactyl\Models\SecurityKey;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Contracts\View\View as ViewContract;
|
||||
use Pterodactyl\Services\Users\SecurityKeys\GeneratePublicKeyCredentialsRequestService;
|
||||
|
||||
class LoginController extends AbstractLoginController
|
||||
{
|
||||
private const SESSION_PUBLICKEY_REQUEST = 'webauthn.publicKeyRequest';
|
||||
|
||||
private const METHOD_TOTP = 'totp';
|
||||
private const METHOD_WEBAUTHN = 'webauthn';
|
||||
private const SESSION_PUBLICKEY_REQUEST = 'webauthn.publicKeyRequest';
|
||||
|
||||
private ViewFactory $view;
|
||||
protected GeneratePublicKeyCredentialsRequestService $service;
|
||||
|
||||
/**
|
||||
* LoginController constructor.
|
||||
* @param \Pterodactyl\Services\Users\SecurityKeys\GeneratePublicKeyCredentialsRequestService $service
|
||||
*/
|
||||
public function __construct(ViewFactory $view)
|
||||
public function __construct(GeneratePublicKeyCredentialsRequestService $service)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->view = $view;
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,9 +35,9 @@ class LoginController extends AbstractLoginController
|
|||
* base authentication view component. React will take over at this point and
|
||||
* turn the login area into an SPA.
|
||||
*/
|
||||
public function index(): View
|
||||
public function index(): ViewContract
|
||||
{
|
||||
return $this->view->make('templates/auth.core');
|
||||
return View::make('templates/auth.core');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,23 +75,11 @@ class LoginController extends AbstractLoginController
|
|||
return;
|
||||
}
|
||||
|
||||
$useTotp = $user->use_totp;
|
||||
$webauthnKeys = $user->webauthnKeys()->get();
|
||||
|
||||
if (!$useTotp && count($webauthnKeys) < 1) {
|
||||
if (!$user->use_totp && empty($user->security_keys_count)) {
|
||||
return $this->sendLoginResponse($user, $request);
|
||||
}
|
||||
|
||||
$methods = [];
|
||||
if ($useTotp) {
|
||||
$methods[] = self::METHOD_TOTP;
|
||||
}
|
||||
if (count($webauthnKeys) > 0) {
|
||||
$methods[] = self::METHOD_WEBAUTHN;
|
||||
}
|
||||
|
||||
$token = Str::random(64);
|
||||
|
||||
$request->session()->put('auth_confirmation_token', [
|
||||
'user_id' => $user->id,
|
||||
'token_value' => $token,
|
||||
|
@ -100,17 +88,21 @@ class LoginController extends AbstractLoginController
|
|||
|
||||
$response = [
|
||||
'complete' => false,
|
||||
'methods' => $methods,
|
||||
'methods' => array_filter([
|
||||
$user->use_totp ? self::METHOD_TOTP : null,
|
||||
$user->security_keys_count > 0 ? self::METHOD_WEBAUTHN : null,
|
||||
]),
|
||||
'confirmation_token' => $token,
|
||||
];
|
||||
|
||||
if (count($webauthnKeys) > 0) {
|
||||
$publicKey = Webauthn::getAuthenticateData($user);
|
||||
$request->session()->put(self::SESSION_PUBLICKEY_REQUEST, $publicKey);
|
||||
|
||||
$response['webauthn'] = [
|
||||
'public_key' => $publicKey,
|
||||
];
|
||||
if ($user->security_keys_count > 0) {
|
||||
// $key = $this->service->handle($user);
|
||||
//
|
||||
// $request->session()->put(self::SESSION_PUBLICKEY_REQUEST, $publicKey);
|
||||
//
|
||||
// $response['webauthn'] = [
|
||||
// 'public_key' => $publicKey,
|
||||
// ];
|
||||
}
|
||||
|
||||
return new JsonResponse($response);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Pterodactyl\Models;
|
||||
|
||||
use Stringable;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Webauthn\TrustPath\TrustPath;
|
||||
|
@ -82,12 +81,7 @@ class SecurityKey extends Model
|
|||
return null;
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function getPublicKeyCredentialsDescriptorAttribute(): PublicKeyCredentialDescriptor
|
||||
public function getPublicKeyCredentialDescriptor(): PublicKeyCredentialDescriptor
|
||||
{
|
||||
return new PublicKeyCredentialDescriptor(
|
||||
$this->type,
|
||||
|
@ -96,7 +90,7 @@ class SecurityKey extends Model
|
|||
);
|
||||
}
|
||||
|
||||
public function getPublicKeyCredentialSourceAttribute(): PublicKeyCredentialSource
|
||||
public function getPublicKeyCredentialSource(): PublicKeyCredentialSource
|
||||
{
|
||||
return new PublicKeyCredentialSource(
|
||||
$this->public_key_id,
|
||||
|
@ -110,4 +104,9 @@ class SecurityKey extends Model
|
|||
$this->counter
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyRepositoryInterfac
|
|||
->where('public_key_id', $id)
|
||||
->first();
|
||||
|
||||
return $key ? $key->public_key_credential_source : null;
|
||||
return optional($key)->getPublicKeyCredentialSource();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyRepositoryInterfac
|
|||
->get();
|
||||
|
||||
return $results->map(function (SecurityKey $key) {
|
||||
return $key->public_key_credential_source;
|
||||
return $key->getPublicKeyCredentialSource();
|
||||
})->values()->toArray();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class CreatePublicKeyCredentialsService
|
|||
$entity = new PublicKeyCredentialUserEntity($user->username, $user->uuid, $user->email, null);
|
||||
|
||||
$excluded = $user->securityKeys->map(function (SecurityKey $key) {
|
||||
return $key->public_key_credentials_descriptor;
|
||||
return $key->getPublicKeyCredentialDescriptor();
|
||||
})->values()->toArray();
|
||||
|
||||
$server = $this->webauthnServerRepository->getServer($user);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Services\Users\SecurityKeys;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Models\SecurityKey;
|
||||
use Webauthn\PublicKeyCredentialRequestOptions;
|
||||
use Pterodactyl\Repositories\SecurityKeys\WebauthnServerRepository;
|
||||
|
||||
class GeneratePublicKeyCredentialsRequestService
|
||||
{
|
||||
protected WebauthnServerRepository $serverRepository;
|
||||
|
||||
/**
|
||||
* @param \Pterodactyl\Repositories\SecurityKeys\WebauthnServerRepository $serverRepository
|
||||
*/
|
||||
public function __construct(WebauthnServerRepository $serverRepository)
|
||||
{
|
||||
$this->serverRepository = $serverRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Pterodactyl\Models\User $user
|
||||
* @return \Webauthn\PublicKeyCredentialRequestOptions
|
||||
*/
|
||||
public function handle(User $user): PublicKeyCredentialRequestOptions
|
||||
{
|
||||
$credentials = $user->securityKeys->map(function (SecurityKey $key) {
|
||||
return $key->getPublicKeyCredentialDescriptor();
|
||||
});
|
||||
|
||||
$response = $this->serverRepository->getServer($user)
|
||||
->generatePublicKeyCredentialRequestOptions(
|
||||
PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED, $credentials
|
||||
);
|
||||
|
||||
return $response->setTimeout(300);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue