mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Implemented desktop application type
This commit is contained in:
@@ -31,7 +31,6 @@ final class AuthorizationServerFactory {
|
||||
);
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
$authCodeGrant = new Grants\AuthCodeGrant($authCodesRepo, $refreshTokensRepo, new DateInterval('PT10M'));
|
||||
$authCodeGrant->disableRequireCodeChallengeForPublicClients();
|
||||
$authServer->enableGrantType($authCodeGrant, $accessTokenTTL);
|
||||
$authCodeGrant->setScopeRepository($publicScopesRepo); // Change repository after enabling
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ final class ClientEntity implements ClientEntityInterface {
|
||||
string $id,
|
||||
string $name,
|
||||
string|array $redirectUri,
|
||||
private readonly bool $isTrusted,
|
||||
private readonly bool $isTrusted = false,
|
||||
public readonly ?OauthClient $model = null,
|
||||
) {
|
||||
$this->identifier = $id;
|
||||
$this->name = $name;
|
||||
@@ -29,15 +30,20 @@ final class ClientEntity implements ClientEntityInterface {
|
||||
|
||||
public static function fromModel(OauthClient $model): self {
|
||||
return new self(
|
||||
$model->id, // @phpstan-ignore argument.type
|
||||
$model->name,
|
||||
$model->redirect_uri ?: '',
|
||||
(bool)$model->is_trusted,
|
||||
id: $model->id, // @phpstan-ignore argument.type
|
||||
name: $model->name,
|
||||
redirectUri: $model->redirect_uri ?: '',
|
||||
isTrusted: (bool)$model->is_trusted,
|
||||
model: $model,
|
||||
);
|
||||
}
|
||||
|
||||
public function isConfidential(): bool {
|
||||
return true;
|
||||
return match ($this->model->type) {
|
||||
OauthClient::TYPE_WEB_APPLICATION => true,
|
||||
OauthClient::TYPE_DESKTOP_APPLICATION => false,
|
||||
OauthClient::TYPE_MINECRAFT_SERVER => true,
|
||||
};
|
||||
}
|
||||
|
||||
public function isTrusted(): bool {
|
||||
|
||||
@@ -3,6 +3,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace common\components\OAuth2\Grants;
|
||||
|
||||
use common\components\OAuth2\Entities\ClientEntity;
|
||||
use common\models\OauthClient;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\EventEmitting\EventEmitter;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
@@ -14,15 +16,35 @@ trait ValidateRedirectUriTrait {
|
||||
|
||||
abstract public function getEmitter(): EventEmitter;
|
||||
|
||||
/**
|
||||
* Override the original method since we need a custom validation logic based on the client type.
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function validateRedirectUri(
|
||||
string $redirectUri,
|
||||
ClientEntityInterface $client,
|
||||
ServerRequestInterface $request,
|
||||
): void {
|
||||
$allowedRedirectUris = (array)$client->getRedirectUri();
|
||||
foreach ($allowedRedirectUris as $allowedRedirectUri) {
|
||||
if (StringHelper::startsWith($redirectUri, $allowedRedirectUri)) {
|
||||
return;
|
||||
if ($client instanceof ClientEntity && $client->model?->type === OauthClient::TYPE_DESKTOP_APPLICATION) {
|
||||
$uri = parse_url($redirectUri);
|
||||
if ($uri) {
|
||||
// Allow any custom scheme, that is not http
|
||||
if ($uri['scheme'] !== 'http' && $uri['scheme'] !== 'https') {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's a http, than should allow only redirection to the local machine
|
||||
if (in_array($uri['host'], ['localhost', '127.0.0.1', '[::1]'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The original implementation checks url too strictly (port and path must exactly match).
|
||||
// It's nice to have, but we made it this way earlier and so we must keep the same behavior as long as possible
|
||||
foreach ((array)$client->getRedirectUri() as $allowedRedirectUri) {
|
||||
if (StringHelper::startsWith($redirectUri, $allowedRedirectUri)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ final class ClientRepository implements ClientRepositoryInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($client->type !== OauthClient::TYPE_APPLICATION) {
|
||||
if (!in_array($client->type, [OauthClient::TYPE_WEB_APPLICATION, OauthClient::TYPE_DESKTOP_APPLICATION], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($clientSecret) && $clientSecret !== $client->secret) {
|
||||
if ($client->type === OauthClient::TYPE_WEB_APPLICATION && !empty($clientSecret) && $clientSecret !== $client->secret) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,7 @@ final class ClientRepository implements ClientRepositoryInterface {
|
||||
}
|
||||
|
||||
private function findModel(string $id): ?OauthClient {
|
||||
$client = OauthClient::findOne(['id' => $id]);
|
||||
if ($client === null || $client->type !== OauthClient::TYPE_APPLICATION) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $client;
|
||||
return OauthClient::findOne(['id' => $id]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use yii\db\ActiveRecord;
|
||||
* Fields:
|
||||
* @property string $id
|
||||
* @property string $secret
|
||||
* @property string $type
|
||||
* @property self::TYPE_* $type
|
||||
* @property string $name
|
||||
* @property string $description
|
||||
* @property string|null $redirect_uri
|
||||
@@ -29,14 +29,14 @@ use yii\db\ActiveRecord;
|
||||
*/
|
||||
class OauthClient extends ActiveRecord {
|
||||
|
||||
public const TYPE_APPLICATION = 'application';
|
||||
public const TYPE_MINECRAFT_SERVER = 'minecraft-server';
|
||||
public const TYPE_MINECRAFT_GAME_LAUNCHER = 'minecraft-game-launcher';
|
||||
public const string TYPE_WEB_APPLICATION = 'application';
|
||||
public const string TYPE_DESKTOP_APPLICATION = 'desktop-application';
|
||||
public const string TYPE_MINECRAFT_SERVER = 'minecraft-server';
|
||||
|
||||
/**
|
||||
* Abstract oauth_client, used to
|
||||
*/
|
||||
public const UNAUTHORIZED_MINECRAFT_GAME_LAUNCHER = 'unauthorized_minecraft_game_launcher';
|
||||
public const string UNAUTHORIZED_MINECRAFT_GAME_LAUNCHER = 'unauthorized_minecraft_game_launcher';
|
||||
|
||||
public static function tableName(): string {
|
||||
return 'oauth_clients';
|
||||
@@ -55,10 +55,13 @@ class OauthClient extends ActiveRecord {
|
||||
$this->secret = Yii::$app->security->generateRandomString(64);
|
||||
}
|
||||
|
||||
public function getAccount(): ActiveQuery {
|
||||
public function getAccount(): AccountQuery {
|
||||
return $this->hasOne(Account::class, ['id' => 'account_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \yii\db\ActiveQuery<\common\models\OauthSession>
|
||||
*/
|
||||
public function getSessions(): ActiveQuery {
|
||||
return $this->hasMany(OauthSession::class, ['client_id' => 'id']);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user