Upgrade project to PHP 8.3, add PHPStan, upgrade almost every dependency (#36)

* start updating to PHP 8.3

* taking off!

Co-authored-by: ErickSkrauch <erickskrauch@yandex.ru>
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* dropped this

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* migrate to symfonymailer

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* this is so stupid 😭

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* ah, free, at last.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* oh, Gabriel.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* now dawns thy reckoning.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* and thy gore shall GLISTEN before the temples of man.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* creature of steel.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* my gratitude upon thee for my freedom.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* but the crimes thy kind has committed against humanity

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* Upgrade PHP-CS-Fixer and do fix the codebase

* First review round (maybe I have broken something)

* are NOT forgotten.

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>

* Enable parallel PHP-CS-Fixer runner

* PHPStan level 1

* PHPStan level 2

* PHPStan level 3

* PHPStan level 4

* PHPStan level 5

* Levels 6 and 7 takes too much effort. Generate a baseline and fix them eventually

* Resolve TODO's related to the php-mock

* Drastically reduce baseline size with the Rector

* More code modernization with help of the Rector

* Update GitLab CI

---------

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
Co-authored-by: ErickSkrauch <erickskrauch@yandex.ru>
This commit is contained in:
Octol1ttle
2024-12-02 15:10:55 +05:00
committed by GitHub
parent 625250b367
commit 57d492da8a
356 changed files with 10531 additions and 4761 deletions

View File

@@ -9,7 +9,7 @@ use common\models\Account;
class IdentityInfo extends BaseAccountForm {
private $model;
private readonly AccountInfo $model;
public function __construct(Account $account, array $config = []) {
parent::__construct($account, $config);

View File

@@ -12,10 +12,7 @@ use yii\helpers\Inflector;
class OauthClientForm {
/**
* @var OauthClient
*/
private $client;
private readonly OauthClient $client;
public function __construct(OauthClient $client) {
if ($client->type === null) {

View File

@@ -15,23 +15,20 @@ class OauthClientFormFactory {
* @throws UnsupportedOauthClientType
*/
public static function create(OauthClient $client): OauthClientTypeForm {
switch ($client->type) {
case OauthClient::TYPE_APPLICATION:
return new ApplicationType([
'name' => $client->name,
'websiteUrl' => $client->website_url,
'description' => $client->description,
'redirectUri' => $client->redirect_uri,
]);
case OauthClient::TYPE_MINECRAFT_SERVER:
return new MinecraftServerType([
'name' => $client->name,
'websiteUrl' => $client->website_url,
'minecraftServerIp' => $client->minecraft_server_ip,
]);
}
throw new UnsupportedOauthClientType($client->type);
return match ($client->type) {
OauthClient::TYPE_APPLICATION => new ApplicationType([
'name' => $client->name,
'websiteUrl' => $client->website_url,
'description' => $client->description,
'redirectUri' => $client->redirect_uri,
]),
OauthClient::TYPE_MINECRAFT_SERVER => new MinecraftServerType([
'name' => $client->name,
'websiteUrl' => $client->website_url,
'minecraftServerIp' => $client->minecraft_server_ip,
]),
default => throw new UnsupportedOauthClientType($client->type),
};
}
}

View File

@@ -13,22 +13,19 @@ use GuzzleHttp\Psr7\Response;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Entities\ScopeEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Webmozart\Assert\Assert;
use Yii;
class OauthProcess {
private const INTERNAL_PERMISSIONS_TO_PUBLIC_SCOPES = [
private const array INTERNAL_PERMISSIONS_TO_PUBLIC_SCOPES = [
P::OBTAIN_OWN_ACCOUNT_INFO => 'account_info',
P::OBTAIN_ACCOUNT_EMAIL => 'account_email',
];
private AuthorizationServer $server;
public function __construct(AuthorizationServer $server) {
$this->server = $server;
public function __construct(private readonly AuthorizationServer $server) {
}
/**
@@ -96,17 +93,12 @@ class OauthProcess {
$canBeAutoApproved = $this->canBeAutoApproved($account, $client, $authRequest);
$acceptParam = ((array)$request->getParsedBody())['accept'] ?? null;
if ($acceptParam === null && !$canBeAutoApproved) {
Yii::$app->statsd->inc('oauth.complete.approve_required');
throw $this->createAcceptRequiredException();
}
Yii::$app->statsd->inc('oauth.complete.approve_required');
if ($acceptParam === null && $canBeAutoApproved) {
$approved = true;
} else {
$approved = in_array($acceptParam, [1, '1', true, 'true'], true);
}
// At this point if the $acceptParam is an empty, then the application can be auto approved
$approved = $acceptParam === null || in_array($acceptParam, [1, '1', true, 'true'], true);
if ($approved) {
$this->storeOauthSession($account, $client, $authRequest);
}
@@ -163,7 +155,7 @@ class OauthProcess {
Yii::$app->statsd->inc("oauth.issueToken_{$grantType}.attempt");
$shouldIssueRefreshToken = false;
$this->server->getEmitter()->addOneTimeListener(RequestedRefreshToken::class, function() use (&$shouldIssueRefreshToken) {
$this->server->getEmitter()->subscribeOnceTo(RequestedRefreshToken::class, function() use (&$shouldIssueRefreshToken): void {
$shouldIssueRefreshToken = true;
});
@@ -207,14 +199,8 @@ class OauthProcess {
/**
* The method checks whether the current user can be automatically authorized for the specified client
* without requesting access to the necessary list of scopes
*
* @param Account $account
* @param OauthClient $client
* @param AuthorizationRequest $request
*
* @return bool
*/
private function canBeAutoApproved(Account $account, OauthClient $client, AuthorizationRequest $request): bool {
private function canBeAutoApproved(Account $account, OauthClient $client, AuthorizationRequestInterface $request): bool {
if ($client->is_trusted) {
return true;
}
@@ -231,7 +217,7 @@ class OauthProcess {
return empty(array_diff($this->getScopesList($request), $session->getScopes()));
}
private function storeOauthSession(Account $account, OauthClient $client, AuthorizationRequest $request): void {
private function storeOauthSession(Account $account, OauthClient $client, AuthorizationRequestInterface $request): void {
$session = $this->findOauthSession($account, $client);
if ($session === null) {
$session = new OauthSession();
@@ -301,7 +287,7 @@ class OauthProcess {
];
if ($e->hasRedirect()) {
$response['redirectUri'] = $e->getRedirectUri();
$response['redirectUri'] = $e->getRedirectUri() . http_build_query($e->getPayload());
}
if ($e->getHttpStatusCode() !== 200) {
@@ -345,12 +331,11 @@ class OauthProcess {
return new OAuthServerException('Client must accept authentication request.', 0, 'accept_required', 401);
}
private function getScopesList(AuthorizationRequest $request): array {
return array_values(array_map(function(ScopeEntityInterface $scope): string {
return $scope->getIdentifier();
}, $request->getScopes()));
private function getScopesList(AuthorizationRequestInterface $request): array {
return array_values(array_map(fn(ScopeEntityInterface $scope): string => $scope->getIdentifier(), $request->getScopes()));
}
/** @noinspection PhpIncompatibleReturnTypeInspection */
private function findOauthSession(Account $account, OauthClient $client): ?OauthSession {
return $account->getOauthSessions()->andWhere(['client_id' => $client->id])->one();
}