From 8a1d7148d04349c4dc7263d627882ac3b2253003 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 13 Sep 2019 01:19:03 +0300 Subject: [PATCH] Implemented public scopes repository. Fix some auth cases [skip ci] --- api/components/OAuth2/Component.php | 2 + .../Repositories/PublicScopeRepository.php | 54 +++++++++++++++++++ api/modules/oauth/models/OauthProcess.php | 8 ++- api/tests/functional/oauth/AuthCodeCest.php | 2 +- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 api/components/OAuth2/Repositories/PublicScopeRepository.php diff --git a/api/components/OAuth2/Component.php b/api/components/OAuth2/Component.php index c09f939..178adce 100644 --- a/api/components/OAuth2/Component.php +++ b/api/components/OAuth2/Component.php @@ -25,6 +25,7 @@ class Component extends BaseComponent { $clientsRepo = new Repositories\ClientRepository(); $accessTokensRepo = new Repositories\AccessTokenRepository(); $scopesRepo = new Repositories\ScopeRepository(); + $publicScopesRepo = new Repositories\PublicScopeRepository(); $authCodesRepo = new Repositories\AuthCodeRepository(); $refreshTokensRepo = new Repositories\RefreshTokenRepository(); @@ -41,6 +42,7 @@ class Component extends BaseComponent { $authCodeGrant = new Grant\AuthCodeGrant($authCodesRepo, $refreshTokensRepo, new DateInterval('PT10M')); $authCodeGrant->disableRequireCodeChallengeForPublicClients(); $authServer->enableGrantType($authCodeGrant, $accessTokenTTL); + $authCodeGrant->setScopeRepository($publicScopesRepo); // Change repository after enabling $authServer->enableGrantType(new Grant\RefreshTokenGrant($refreshTokensRepo), $accessTokenTTL); $authServer->enableGrantType(new Grant\ClientCredentialsGrant(), $accessTokenTTL); diff --git a/api/components/OAuth2/Repositories/PublicScopeRepository.php b/api/components/OAuth2/Repositories/PublicScopeRepository.php new file mode 100644 index 0000000..fe5297e --- /dev/null +++ b/api/components/OAuth2/Repositories/PublicScopeRepository.php @@ -0,0 +1,54 @@ + P::OBTAIN_OWN_ACCOUNT_INFO, + self::ACCOUNT_EMAIL => P::OBTAIN_ACCOUNT_EMAIL, + ]; + + private const ALLOWED_SCOPES = [ + P::OBTAIN_OWN_ACCOUNT_INFO, + P::OBTAIN_ACCOUNT_EMAIL, + P::MINECRAFT_SERVER_SESSION, + self::OFFLINE_ACCESS, + self::CHANGE_SKIN, + ]; + + public function getScopeEntityByIdentifier($identifier): ?ScopeEntityInterface { + $identifier = $this->convertToInternalPermission($identifier); + if (!in_array($identifier, self::ALLOWED_SCOPES, true)) { + return null; + } + + return new ScopeEntity($identifier); + } + + public function finalizeScopes( + array $scopes, + $grantType, + ClientEntityInterface $clientEntity, + $userIdentifier = null + ): array { + return $scopes; + } + + private function convertToInternalPermission(string $publicScope): string { + return self::PUBLIC_SCOPES_TO_INTERNAL_PERMISSIONS[$publicScope] ?? $publicScope; + } + +} diff --git a/api/modules/oauth/models/OauthProcess.php b/api/modules/oauth/models/OauthProcess.php index 5ed5c89..984c72e 100644 --- a/api/modules/oauth/models/OauthProcess.php +++ b/api/modules/oauth/models/OauthProcess.php @@ -107,6 +107,7 @@ class OauthProcess { } $authRequest->setUser(new UserEntity($account->id)); + $authRequest->setAuthorizationApproved(true); $responseObj = $this->server->completeAuthorizationRequest($authRequest, new Response(200)); $response = [ @@ -250,10 +251,15 @@ class OauthProcess { } private function buildErrorResponse(OAuthServerException $e): array { + $hint = $e->getPayload()['hint'] ?? ''; + if (preg_match('/the `(\w+)` scope/', $hint, $matches)) { + $parameter = $matches[1]; + } + $response = [ 'success' => false, 'error' => $e->getErrorType(), - // 'parameter' => $e->parameter, // TODO: if this is necessary, the parameter can be extracted from the hint + 'parameter' => $parameter ?? null, 'statusCode' => $e->getHttpStatusCode(), ]; diff --git a/api/tests/functional/oauth/AuthCodeCest.php b/api/tests/functional/oauth/AuthCodeCest.php index cdbae07..fba1dd7 100644 --- a/api/tests/functional/oauth/AuthCodeCest.php +++ b/api/tests/functional/oauth/AuthCodeCest.php @@ -132,7 +132,7 @@ class AuthCodeCest { $I->canSeeResponseContainsJson([ 'success' => false, 'error' => 'access_denied', - 'parameter' => '', + 'parameter' => null, 'statusCode' => 401, ]); $I->canSeeResponseJsonMatchesJsonPath('$.redirectUri');