From 01028cf378e4fb35e7db3e1d6fc31e07288d94d5 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Mon, 2 Dec 2019 22:15:52 +0300 Subject: [PATCH] Fixes ACCOUNTS-5VC. Handle the case when there is missing session for access or refresh token --- .../OAuth2/Entities/AccessTokenEntity.php | 2 +- .../OAuth2/Grants/RefreshTokenGrant.php | 4 ++ .../OAuth2/Storage/SessionStorage.php | 37 ++++++++++++------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/api/components/OAuth2/Entities/AccessTokenEntity.php b/api/components/OAuth2/Entities/AccessTokenEntity.php index 183704d..c489281 100644 --- a/api/components/OAuth2/Entities/AccessTokenEntity.php +++ b/api/components/OAuth2/Entities/AccessTokenEntity.php @@ -28,7 +28,7 @@ class AccessTokenEntity extends \League\OAuth2\Server\Entity\AccessTokenEntity { return $this; } - public function getSession() { + public function getSession(): ?OriginalSessionEntity { if ($this->session instanceof OriginalSessionEntity) { return $this->session; } diff --git a/api/components/OAuth2/Grants/RefreshTokenGrant.php b/api/components/OAuth2/Grants/RefreshTokenGrant.php index 4f20ad9..71b265b 100644 --- a/api/components/OAuth2/Grants/RefreshTokenGrant.php +++ b/api/components/OAuth2/Grants/RefreshTokenGrant.php @@ -121,6 +121,10 @@ class RefreshTokenGrant extends AbstractGrant { $session = $oldRefreshToken->getSession(); } + if ($session === null) { + throw new Exception\InvalidRefreshException(); + } + $scopes = $this->formatScopes($session->getScopes()); // Get and validate any requested scopes diff --git a/api/components/OAuth2/Storage/SessionStorage.php b/api/components/OAuth2/Storage/SessionStorage.php index 11e89d9..02ac0ba 100644 --- a/api/components/OAuth2/Storage/SessionStorage.php +++ b/api/components/OAuth2/Storage/SessionStorage.php @@ -3,6 +3,7 @@ namespace api\components\OAuth2\Storage; use api\components\OAuth2\Entities\AuthCodeEntity; use api\components\OAuth2\Entities\SessionEntity; +use api\exceptions\ThisShouldNotHappenException; use common\models\OauthSession; use ErrorException; use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity; @@ -19,8 +20,13 @@ class SessionStorage extends AbstractStorage implements SessionInterface { * @param string $sessionId * @return SessionEntity|null */ - public function getById($sessionId) { - return $this->hydrate($this->getSessionModel($sessionId)); + public function getById($sessionId): ?SessionEntity { + $session = $this->getSessionModel($sessionId); + if ($session === null) { + return null; + } + + return $this->hydrate($session); } public function getByAccessToken(OriginalAccessTokenEntity $accessToken) { @@ -35,9 +41,14 @@ class SessionStorage extends AbstractStorage implements SessionInterface { return $this->getById($authCode->getSessionId()); } - public function getScopes(OriginalSessionEntity $session) { + public function getScopes(OriginalSessionEntity $entity) { + $session = $this->getSessionModel($entity->getId()); + if ($session === null) { + return []; + } + $result = []; - foreach ($this->getSessionModel($session->getId())->getScopes() as $scope) { + foreach ($session->getScopes() as $scope) { if ($this->server->getScopeStorage()->get($scope) !== null) { $result[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]); } @@ -72,20 +83,20 @@ class SessionStorage extends AbstractStorage implements SessionInterface { return $sessionId; } - public function associateScope(OriginalSessionEntity $session, ScopeEntity $scope) { - $this->getSessionModel($session->getId())->getScopes()->add($scope->getId()); - } - - private function getSessionModel(string $sessionId): OauthSession { - $session = OauthSession::findOne($sessionId); + public function associateScope(OriginalSessionEntity $sessionEntity, ScopeEntity $scopeEntity): void { + $session = $this->getSessionModel($sessionEntity->getId()); if ($session === null) { - throw new ErrorException('Cannot find oauth session'); + throw new ThisShouldNotHappenException('Cannot find oauth session'); } - return $session; + $session->getScopes()->add($scopeEntity->getId()); } - private function hydrate(OauthSession $sessionModel) { + private function getSessionModel(string $sessionId): ?OauthSession { + return OauthSession::findOne(['id' => $sessionId]); + } + + private function hydrate(OauthSession $sessionModel): SessionEntity { $entity = new SessionEntity($this->server); $entity->setId($sessionModel->id); $entity->setClientId($sessionModel->client_id);