Ensure tokens are found in the database using the expected logic
This commit is contained in:
parent
e9c633fd03
commit
f7fc67344e
5 changed files with 39 additions and 25 deletions
|
@ -47,6 +47,18 @@ class Handler extends ExceptionHandler
|
||||||
ValidationException::class,
|
ValidationException::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps exceptions to a specific response code. This handles special exception
|
||||||
|
* types that don't have a defined response code.
|
||||||
|
*
|
||||||
|
* @var array<string, int>
|
||||||
|
*/
|
||||||
|
protected static array $exceptionResponseCodes = [
|
||||||
|
AuthenticationException::class => 401,
|
||||||
|
AuthorizationException::class => 403,
|
||||||
|
ValidationException::class => 422,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of the inputs that are never flashed for validation exceptions.
|
* A list of the inputs that are never flashed for validation exceptions.
|
||||||
*
|
*
|
||||||
|
@ -187,12 +199,14 @@ class Handler extends ExceptionHandler
|
||||||
*/
|
*/
|
||||||
public static function convertToArray(Throwable $exception, array $override = []): array
|
public static function convertToArray(Throwable $exception, array $override = []): array
|
||||||
{
|
{
|
||||||
|
$match = self::$exceptionResponseCodes[get_class($exception)] ?? null;
|
||||||
|
|
||||||
$error = [
|
$error = [
|
||||||
'code' => class_basename($exception),
|
'code' => class_basename($exception),
|
||||||
'status' => method_exists($exception, 'getStatusCode')
|
'status' => method_exists($exception, 'getStatusCode')
|
||||||
? strval($exception->getStatusCode())
|
? strval($exception->getStatusCode())
|
||||||
: ($exception instanceof ValidationException ? '422' : '500'),
|
: strval($match ?? '500'),
|
||||||
'detail' => $exception instanceof HttpExceptionInterface
|
'detail' => $exception instanceof HttpExceptionInterface || !is_null($match)
|
||||||
? $exception->getMessage()
|
? $exception->getMessage()
|
||||||
: 'An unexpected error was encountered while processing this request, please try again.',
|
: 'An unexpected error was encountered while processing this request, please try again.',
|
||||||
];
|
];
|
||||||
|
|
|
@ -19,19 +19,19 @@ class AccountController extends ClientApiController
|
||||||
private $updateService;
|
private $updateService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Auth\SessionGuard
|
* @var \Illuminate\Auth\AuthManager
|
||||||
*/
|
*/
|
||||||
private $sessionGuard;
|
private $manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthManager $sessionGuard, UserUpdateService $updateService)
|
public function __construct(AuthManager $manager, UserUpdateService $updateService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->updateService = $updateService;
|
$this->updateService = $updateService;
|
||||||
$this->sessionGuard = $sessionGuard;
|
$this->manager = $manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request): array
|
public function index(Request $request): array
|
||||||
|
@ -64,13 +64,17 @@ class AccountController extends ClientApiController
|
||||||
{
|
{
|
||||||
$user = $this->updateService->handle($request->user(), $request->validated());
|
$user = $this->updateService->handle($request->user(), $request->validated());
|
||||||
|
|
||||||
|
$guard = $this->manager->guard();
|
||||||
// If you do not update the user in the session you'll end up working with a
|
// If you do not update the user in the session you'll end up working with a
|
||||||
// cached copy of the user that does not include the updated password. Do this
|
// cached copy of the user that does not include the updated password. Do this
|
||||||
// to correctly store the new user details in the guard and allow the logout
|
// to correctly store the new user details in the guard and allow the logout
|
||||||
// other devices functionality to work.
|
// other devices functionality to work.
|
||||||
$this->sessionGuard->setUser($user);
|
$guard->setUser($user);
|
||||||
|
|
||||||
$this->sessionGuard->logoutOtherDevices($request->input('password'));
|
// This method doesn't exist in the stateless Sanctum world.
|
||||||
|
if (method_exists($guard, 'logoutOtherDevices')) {
|
||||||
|
$guard->logoutOtherDevices($request->input('password'));
|
||||||
|
}
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,9 +195,13 @@ class ApiKey extends Model
|
||||||
public static function findToken($token)
|
public static function findToken($token)
|
||||||
{
|
{
|
||||||
$id = Str::substr($token, 0, self::IDENTIFIER_LENGTH);
|
$id = Str::substr($token, 0, self::IDENTIFIER_LENGTH);
|
||||||
$token = Str::substr($token, strlen($id));
|
|
||||||
|
|
||||||
return static::where('identifier', $id)->where('token', encrypt($token))->first();
|
$model = static::where('identifier', $id)->first();
|
||||||
|
if (!is_null($model) && decrypt($model->token) === Str::substr($token, strlen($id))) {
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ApiKeyFactory extends Factory
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'key_type' => ApiKey::TYPE_APPLICATION,
|
'key_type' => ApiKey::TYPE_APPLICATION,
|
||||||
'identifier' => Str::random(ApiKey::IDENTIFIER_LENGTH),
|
'identifier' => ApiKey::generateTokenIdentifier(),
|
||||||
'token' => $token ?: $token = encrypt(Str::random(ApiKey::KEY_LENGTH)),
|
'token' => $token ?: $token = encrypt(Str::random(ApiKey::KEY_LENGTH)),
|
||||||
'allowed_ips' => null,
|
'allowed_ips' => null,
|
||||||
'memo' => 'Test Function Key',
|
'memo' => 'Test Function Key',
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Tests\Integration\Api\Application;
|
namespace Pterodactyl\Tests\Integration\Api\Application;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
use PHPUnit\Framework\Assert;
|
use PHPUnit\Framework\Assert;
|
||||||
use Pterodactyl\Models\ApiKey;
|
use Pterodactyl\Models\ApiKey;
|
||||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||||
|
@ -41,10 +41,9 @@ abstract class ApplicationApiIntegrationTestCase extends IntegrationTestCase
|
||||||
$this->user = $this->createApiUser();
|
$this->user = $this->createApiUser();
|
||||||
$this->key = $this->createApiKey($this->user);
|
$this->key = $this->createApiKey($this->user);
|
||||||
|
|
||||||
$this->withHeader('Accept', 'application/vnd.pterodactyl.v1+json');
|
$this
|
||||||
$this->withHeader('Authorization', 'Bearer ' . $this->getApiKey()->identifier . decrypt($this->getApiKey()->token));
|
->withHeader('Accept', 'application/vnd.pterodactyl.v1+json')
|
||||||
|
->withHeader('Authorization', 'Bearer ' . $this->key->identifier . decrypt($this->key->token));
|
||||||
$this->withMiddleware('api..key:' . ApiKey::TYPE_APPLICATION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getApiUser(): User
|
public function getApiUser(): User
|
||||||
|
@ -63,19 +62,12 @@ abstract class ApplicationApiIntegrationTestCase extends IntegrationTestCase
|
||||||
protected function createNewDefaultApiKey(User $user, array $permissions = []): ApiKey
|
protected function createNewDefaultApiKey(User $user, array $permissions = []): ApiKey
|
||||||
{
|
{
|
||||||
$this->key = $this->createApiKey($user, $permissions);
|
$this->key = $this->createApiKey($user, $permissions);
|
||||||
$this->refreshHeaders($this->key);
|
|
||||||
|
$this->withHeader('Authorization', 'Bearer ' . $this->key->identifier . decrypt($this->key->token));
|
||||||
|
|
||||||
return $this->key;
|
return $this->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh the authorization header for a request to use a different API key.
|
|
||||||
*/
|
|
||||||
protected function refreshHeaders(ApiKey $key)
|
|
||||||
{
|
|
||||||
$this->withHeader('Authorization', 'Bearer ' . $key->identifier . decrypt($key->token));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an administrative user.
|
* Create an administrative user.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue