Fixes ACCOUNTS-5VC. Handle the case when there is missing session for access or refresh token

This commit is contained in:
ErickSkrauch 2019-12-02 22:15:52 +03:00
parent 22ef41ac7c
commit 01028cf378
3 changed files with 29 additions and 14 deletions

View File

@ -28,7 +28,7 @@ class AccessTokenEntity extends \League\OAuth2\Server\Entity\AccessTokenEntity {
return $this; return $this;
} }
public function getSession() { public function getSession(): ?OriginalSessionEntity {
if ($this->session instanceof OriginalSessionEntity) { if ($this->session instanceof OriginalSessionEntity) {
return $this->session; return $this->session;
} }

View File

@ -121,6 +121,10 @@ class RefreshTokenGrant extends AbstractGrant {
$session = $oldRefreshToken->getSession(); $session = $oldRefreshToken->getSession();
} }
if ($session === null) {
throw new Exception\InvalidRefreshException();
}
$scopes = $this->formatScopes($session->getScopes()); $scopes = $this->formatScopes($session->getScopes());
// Get and validate any requested scopes // Get and validate any requested scopes

View File

@ -3,6 +3,7 @@ namespace api\components\OAuth2\Storage;
use api\components\OAuth2\Entities\AuthCodeEntity; use api\components\OAuth2\Entities\AuthCodeEntity;
use api\components\OAuth2\Entities\SessionEntity; use api\components\OAuth2\Entities\SessionEntity;
use api\exceptions\ThisShouldNotHappenException;
use common\models\OauthSession; use common\models\OauthSession;
use ErrorException; use ErrorException;
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity; use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
@ -19,8 +20,13 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
* @param string $sessionId * @param string $sessionId
* @return SessionEntity|null * @return SessionEntity|null
*/ */
public function getById($sessionId) { public function getById($sessionId): ?SessionEntity {
return $this->hydrate($this->getSessionModel($sessionId)); $session = $this->getSessionModel($sessionId);
if ($session === null) {
return null;
}
return $this->hydrate($session);
} }
public function getByAccessToken(OriginalAccessTokenEntity $accessToken) { public function getByAccessToken(OriginalAccessTokenEntity $accessToken) {
@ -35,9 +41,14 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
return $this->getById($authCode->getSessionId()); 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 = []; $result = [];
foreach ($this->getSessionModel($session->getId())->getScopes() as $scope) { foreach ($session->getScopes() as $scope) {
if ($this->server->getScopeStorage()->get($scope) !== null) { if ($this->server->getScopeStorage()->get($scope) !== null) {
$result[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]); $result[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]);
} }
@ -72,20 +83,20 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
return $sessionId; return $sessionId;
} }
public function associateScope(OriginalSessionEntity $session, ScopeEntity $scope) { public function associateScope(OriginalSessionEntity $sessionEntity, ScopeEntity $scopeEntity): void {
$this->getSessionModel($session->getId())->getScopes()->add($scope->getId()); $session = $this->getSessionModel($sessionEntity->getId());
}
private function getSessionModel(string $sessionId): OauthSession {
$session = OauthSession::findOne($sessionId);
if ($session === null) { 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 = new SessionEntity($this->server);
$entity->setId($sessionModel->id); $entity->setId($sessionModel->id);
$entity->setClientId($sessionModel->client_id); $entity->setClientId($sessionModel->client_id);