mirror of
https://github.com/elyby/accounts.git
synced 2024-11-30 02:32:26 +05:30
Все классы, отвечающие за oAuth передвинуты в компоненты API, освежён код, поправлены неймспейсы
This commit is contained in:
parent
e6fa0fe6f3
commit
20286f1744
@ -1,13 +1,13 @@
|
||||
<?php
|
||||
namespace common\components\oauth;
|
||||
namespace api\components\OAuth2;
|
||||
|
||||
use common\components\oauth\Storage\Redis\AuthCodeStorage;
|
||||
use common\components\oauth\Storage\Redis\RefreshTokenStorage;
|
||||
use common\components\oauth\Storage\Yii2\AccessTokenStorage;
|
||||
use common\components\oauth\Storage\Yii2\ClientStorage;
|
||||
use common\components\oauth\Storage\Yii2\ScopeStorage;
|
||||
use common\components\oauth\Storage\Yii2\SessionStorage;
|
||||
use common\components\oauth\Util\KeyAlgorithm\UuidAlgorithm;
|
||||
use api\components\OAuth2\Storage\AuthCodeStorage;
|
||||
use api\components\OAuth2\Storage\RefreshTokenStorage;
|
||||
use api\components\OAuth2\Storage\AccessTokenStorage;
|
||||
use api\components\OAuth2\Storage\ClientStorage;
|
||||
use api\components\OAuth2\Storage\ScopeStorage;
|
||||
use api\components\OAuth2\Storage\SessionStorage;
|
||||
use api\components\OAuth2\Utils\KeyAlgorithm\UuidAlgorithm;
|
||||
use League\OAuth2\Server\AuthorizationServer;
|
||||
use League\OAuth2\Server\Grant;
|
||||
use League\OAuth2\Server\Util\SecureKey;
|
||||
@ -41,22 +41,22 @@ class Component extends \yii\base\Component {
|
||||
public function getAuthServer() {
|
||||
if ($this->_authServer === null) {
|
||||
$authServer = new AuthorizationServer();
|
||||
$authServer
|
||||
->setAccessTokenStorage(new AccessTokenStorage())
|
||||
->setClientStorage(new ClientStorage())
|
||||
->setScopeStorage(new ScopeStorage())
|
||||
->setSessionStorage(new SessionStorage())
|
||||
->setAuthCodeStorage(new AuthCodeStorage())
|
||||
->setRefreshTokenStorage(new RefreshTokenStorage())
|
||||
->setScopeDelimiter(',');
|
||||
$authServer->setAccessTokenStorage(new AccessTokenStorage());
|
||||
$authServer->setClientStorage(new ClientStorage());
|
||||
$authServer->setScopeStorage(new ScopeStorage());
|
||||
$authServer->setSessionStorage(new SessionStorage());
|
||||
$authServer->setAuthCodeStorage(new AuthCodeStorage());
|
||||
$authServer->setRefreshTokenStorage(new RefreshTokenStorage());
|
||||
$authServer->setScopeDelimiter(',');
|
||||
|
||||
$this->_authServer = $authServer;
|
||||
|
||||
foreach ($this->grantTypes as $grantType) {
|
||||
if (!array_key_exists($grantType, $this->grantMap)) {
|
||||
if (!isset($this->grantMap[$grantType])) {
|
||||
throw new InvalidConfigException('Invalid grant type');
|
||||
}
|
||||
|
||||
/** @var Grant\GrantTypeInterface $grant */
|
||||
$grant = new $this->grantMap[$grantType]();
|
||||
$this->_authServer->addGrantType($grant);
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
namespace api\components\OAuth2\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
use League\OAuth2\Server\Entity\SessionEntity as OriginalSessionEntity;
|
||||
|
||||
class AccessTokenEntity extends \League\OAuth2\Server\Entity\AccessTokenEntity {
|
||||
use EntityTrait;
|
||||
|
||||
protected $sessionId;
|
||||
|
@ -1,11 +1,9 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
namespace api\components\OAuth2\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
use League\OAuth2\Server\Entity\SessionEntity;
|
||||
|
||||
class AuthCodeEntity extends \League\OAuth2\Server\Entity\AuthCodeEntity {
|
||||
use EntityTrait;
|
||||
|
||||
protected $sessionId;
|
||||
|
22
api/components/OAuth2/Entities/ClientEntity.php
Normal file
22
api/components/OAuth2/Entities/ClientEntity.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace api\components\OAuth2\Entities;
|
||||
|
||||
class ClientEntity extends \League\OAuth2\Server\Entity\ClientEntity {
|
||||
|
||||
public function setId(string $id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function setName(string $name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function setSecret(string $secret) {
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
public function setRedirectUri(string $redirectUri) {
|
||||
$this->redirectUri = $redirectUri;
|
||||
}
|
||||
|
||||
}
|
10
api/components/OAuth2/Entities/ScopeEntity.php
Normal file
10
api/components/OAuth2/Entities/ScopeEntity.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace api\components\OAuth2\Entities;
|
||||
|
||||
class ScopeEntity extends \League\OAuth2\Server\Entity\ScopeEntity {
|
||||
|
||||
public function setId(string $id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
namespace api\components\OAuth2\Entities;
|
||||
|
||||
use League\OAuth2\Server\Entity\ClientEntity;
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
@ -24,4 +24,8 @@ class SessionEntity extends \League\OAuth2\Server\Entity\SessionEntity {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClientId(string $clientId) {
|
||||
$this->clientId = $clientId;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Exception;
|
||||
namespace api\components\OAuth2\Exceptions;
|
||||
|
||||
use League\OAuth2\Server\Exception\OAuthException;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Exception;
|
||||
namespace api\components\OAuth2\Exceptions;
|
||||
|
||||
class AccessDeniedException extends \League\OAuth2\Server\Exception\AccessDeniedException {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use common\components\oauth\Entity\AccessTokenEntity;
|
||||
use api\components\OAuth2\Entities\AccessTokenEntity;
|
||||
use common\models\OauthAccessToken;
|
||||
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
@ -34,11 +34,15 @@ class AccessTokenStorage extends AbstractStorage implements AccessTokenInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new AccessTokenEntity($this->server))->hydrate([
|
||||
'id' => $model->access_token,
|
||||
'expireTime' => $model->expire_time,
|
||||
'sessionId' => $model->session_id,
|
||||
]);
|
||||
/** @var SessionStorage $sessionStorage */
|
||||
$sessionStorage = $this->server->getSessionStorage();
|
||||
|
||||
$token = new AccessTokenEntity($this->server);
|
||||
$token->setId($model->access_token);
|
||||
$token->setExpireTime($model->expire_time);
|
||||
$token->setSession($sessionStorage->getById($model->session_id));
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Redis;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use common\components\oauth\Entity\AuthCodeEntity;
|
||||
use api\components\OAuth2\Entities\AuthCodeEntity;
|
||||
use common\components\redis\Key;
|
||||
use common\components\redis\Set;
|
||||
use League\OAuth2\Server\Entity\AuthCodeEntity as OriginalAuthCodeEntity;
|
||||
@ -28,12 +28,16 @@ class AuthCodeStorage extends AbstractStorage implements AuthCodeInterface {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new AuthCodeEntity($this->server))->hydrate([
|
||||
'id' => $result['id'],
|
||||
'redirectUri' => $result['client_redirect_uri'],
|
||||
'expireTime' => $result['expire_time'],
|
||||
'sessionId' => $result['session_id'],
|
||||
]);
|
||||
/** @var SessionStorage $sessionStorage */
|
||||
$sessionStorage = $this->server->getSessionStorage();
|
||||
|
||||
$entity = new AuthCodeEntity($this->server);
|
||||
$entity->setId($result['id']);
|
||||
$entity->setRedirectUri($result['client_redirect_uri']);
|
||||
$entity->setExpireTime($result['expire_time']);
|
||||
$entity->setSession($sessionStorage->getById($result['session_id']));
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use common\components\oauth\Entity\SessionEntity;
|
||||
use api\components\OAuth2\Entities\ClientEntity;
|
||||
use api\components\OAuth2\Entities\SessionEntity;
|
||||
use common\models\OauthClient;
|
||||
use League\OAuth2\Server\Entity\ClientEntity;
|
||||
use League\OAuth2\Server\Entity\SessionEntity as OriginalSessionEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\ClientInterface;
|
||||
@ -18,15 +18,13 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($clientId, $clientSecret = null, $redirectUri = null, $grantType = null) {
|
||||
$query = OauthClient::find()
|
||||
->select(['id', 'name', 'secret', 'redirect_uri'])
|
||||
->where([OauthClient::tableName() . '.id' => $clientId]);
|
||||
|
||||
$query = OauthClient::find()->andWhere(['id' => $clientId]);
|
||||
if ($clientSecret !== null) {
|
||||
$query->andWhere(['secret' => $clientSecret]);
|
||||
}
|
||||
|
||||
$model = $query->asArray()->one();
|
||||
/** @var OauthClient|null $model */
|
||||
$model = $query->one();
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
@ -39,22 +37,17 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
* Короче это нужно учесть
|
||||
*/
|
||||
if ($redirectUri !== null) {
|
||||
if ($redirectUri === self::REDIRECT_STATIC_PAGE || $redirectUri === self::REDIRECT_STATIC_PAGE_WITH_CODE) {
|
||||
if (in_array($redirectUri, [self::REDIRECT_STATIC_PAGE, self::REDIRECT_STATIC_PAGE_WITH_CODE], true)) {
|
||||
// Тут, наверное, нужно проверить тип приложения
|
||||
} else {
|
||||
if (!StringHelper::startsWith($redirectUri, $model['redirect_uri'], false)) {
|
||||
if (!StringHelper::startsWith($redirectUri, $model->redirect_uri, false)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entity = new ClientEntity($this->server);
|
||||
$entity->hydrate([
|
||||
'id' => $model['id'],
|
||||
'name' => $model['name'],
|
||||
'secret' => $model['secret'],
|
||||
'redirectUri' => $redirectUri,
|
||||
]);
|
||||
$entity = $this->hydrate($model);
|
||||
$entity->setRedirectUri($redirectUri);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
@ -67,17 +60,23 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
throw new \ErrorException('This module assumes that $session typeof ' . SessionEntity::class);
|
||||
}
|
||||
|
||||
$model = OauthClient::find()
|
||||
->select(['id', 'name'])
|
||||
->andWhere(['id' => $session->getClientId()])
|
||||
->asArray()
|
||||
->one();
|
||||
|
||||
/** @var OauthClient|null $model */
|
||||
$model = OauthClient::findOne($session->getClientId());
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new ClientEntity($this->server))->hydrate($model);
|
||||
return $this->hydrate($model);
|
||||
}
|
||||
|
||||
private function hydrate(OauthClient $model) : ClientEntity {
|
||||
$entity = new ClientEntity($this->server);
|
||||
$entity->setId($model->id);
|
||||
$entity->setName($model->name);
|
||||
$entity->setSecret($model->secret);
|
||||
$entity->setRedirectUri($model->redirect_uri);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Redis;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use common\components\redis\Key;
|
||||
use League\OAuth2\Server\Entity\RefreshTokenEntity;
|
||||
@ -19,10 +19,12 @@ class RefreshTokenStorage extends AbstractStorage implements RefreshTokenInterfa
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new RefreshTokenEntity($this->server))
|
||||
->setId($result['id'])
|
||||
->setExpireTime($result['expire_time'])
|
||||
->setAccessTokenId($result['access_token_id']);
|
||||
$entity = new RefreshTokenEntity($this->server);
|
||||
$entity->setId($result['id']);
|
||||
$entity->setExpireTime($result['expire_time']);
|
||||
$entity->setAccessTokenId($result['access_token_id']);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use api\components\OAuth2\Entities\ScopeEntity;
|
||||
use common\models\OauthScope;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\ScopeInterface;
|
||||
|
||||
@ -12,13 +12,14 @@ class ScopeStorage extends AbstractStorage implements ScopeInterface {
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($scope, $grantType = null, $clientId = null) {
|
||||
$row = OauthScope::find()->andWhere(['id' => $scope])->asArray()->one();
|
||||
/** @var OauthScope|null $row */
|
||||
$row = OauthScope::findOne($scope);
|
||||
if ($row === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$entity = new ScopeEntity($this->server);
|
||||
$entity->hydrate($row);
|
||||
$entity->setId($row->id);
|
||||
|
||||
return $entity;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
namespace api\components\OAuth2\Storage;
|
||||
|
||||
use common\components\oauth\Entity\AuthCodeEntity;
|
||||
use common\components\oauth\Entity\SessionEntity;
|
||||
use api\components\OAuth2\Entities\AuthCodeEntity;
|
||||
use api\components\OAuth2\Entities\SessionEntity;
|
||||
use common\models\OauthSession;
|
||||
use ErrorException;
|
||||
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
|
||||
@ -18,35 +18,12 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
|
||||
private $cache = [];
|
||||
|
||||
/**
|
||||
* @param string $sessionId
|
||||
* @return OauthSession|null
|
||||
*/
|
||||
private function getSessionModel($sessionId) {
|
||||
if (!isset($this->cache[$sessionId])) {
|
||||
$this->cache[$sessionId] = OauthSession::findOne($sessionId);
|
||||
}
|
||||
|
||||
return $this->cache[$sessionId];
|
||||
}
|
||||
|
||||
private function hydrateEntity($sessionModel) {
|
||||
if (!$sessionModel instanceof OauthSession) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new SessionEntity($this->server))->hydrate([
|
||||
'id' => $sessionModel->id,
|
||||
'client_id' => $sessionModel->client_id,
|
||||
])->setOwner($sessionModel->owner_type, $sessionModel->owner_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sessionId
|
||||
* @return SessionEntity|null
|
||||
*/
|
||||
public function getSession($sessionId) {
|
||||
return $this->hydrateEntity($this->getSessionModel($sessionId));
|
||||
public function getById($sessionId) {
|
||||
return $this->hydrate($this->getSessionModel($sessionId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +37,7 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
},
|
||||
])->one();
|
||||
|
||||
return $this->hydrateEntity($model);
|
||||
return $this->hydrate($model);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +48,7 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
throw new ErrorException('This module assumes that $authCode typeof ' . AuthCodeEntity::class);
|
||||
}
|
||||
|
||||
return $this->getSession($authCode->getSessionId());
|
||||
return $this->getById($authCode->getSessionId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,4 +100,21 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
$this->getSessionModel($session->getId())->getScopes()->add($scope->getId());
|
||||
}
|
||||
|
||||
private function getSessionModel(string $sessionId) : OauthSession {
|
||||
if (!isset($this->cache[$sessionId])) {
|
||||
$this->cache[$sessionId] = OauthSession::findOne($sessionId);
|
||||
}
|
||||
|
||||
return $this->cache[$sessionId];
|
||||
}
|
||||
|
||||
private function hydrate(OauthSession $sessionModel) {
|
||||
$entity = new SessionEntity($this->server);
|
||||
$entity->setId($sessionModel->id);
|
||||
$entity->setClientId($sessionModel->client_id);
|
||||
$entity->setOwner($sessionModel->owner_type, $sessionModel->owner_id);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
}
|
16
api/components/OAuth2/Utils/KeyAlgorithm/UuidAlgorithm.php
Normal file
16
api/components/OAuth2/Utils/KeyAlgorithm/UuidAlgorithm.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace api\components\OAuth2\Utils\KeyAlgorithm;
|
||||
|
||||
use League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class UuidAlgorithm implements KeyAlgorithmInterface {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function generate($len = 40) : string {
|
||||
return Uuid::uuid4()->toString();
|
||||
}
|
||||
|
||||
}
|
@ -63,7 +63,7 @@ return [
|
||||
'format' => yii\web\Response::FORMAT_JSON,
|
||||
],
|
||||
'oauth' => [
|
||||
'class' => common\components\oauth\Component::class,
|
||||
'class' => api\components\OAuth2\Component::class,
|
||||
'grantTypes' => ['authorization_code'],
|
||||
],
|
||||
'errorHandler' => [
|
||||
|
@ -2,8 +2,8 @@
|
||||
namespace api\controllers;
|
||||
|
||||
use api\filters\ActiveUserRule;
|
||||
use common\components\oauth\Exception\AcceptRequiredException;
|
||||
use common\components\oauth\Exception\AccessDeniedException;
|
||||
use api\components\OAuth2\Exceptions\AcceptRequiredException;
|
||||
use api\components\OAuth2\Exceptions\AccessDeniedException;
|
||||
use common\models\Account;
|
||||
use common\models\OauthClient;
|
||||
use common\models\OauthScope;
|
||||
@ -186,7 +186,7 @@ class OauthController extends Controller {
|
||||
}
|
||||
|
||||
$scopes = $codeModel->getScopes();
|
||||
if (array_search(OauthScope::OFFLINE_ACCESS, array_keys($scopes)) === false) {
|
||||
if (array_search(OauthScope::OFFLINE_ACCESS, array_keys($scopes), true) === false) {
|
||||
return;
|
||||
}
|
||||
} elseif ($grantType === 'refresh_token') {
|
||||
|
@ -29,10 +29,10 @@ abstract class BaseApplication extends yii\base\Application {
|
||||
* Class WebApplication
|
||||
* Include only Web application related components here
|
||||
*
|
||||
* @property \api\components\User\Component $user User component.
|
||||
* @property \api\components\ApiUser\Component $apiUser Api User component.
|
||||
* @property \api\components\User\Component $user User component.
|
||||
* @property \api\components\ApiUser\Component $apiUser Api User component.
|
||||
* @property \api\components\ReCaptcha\Component $reCaptcha
|
||||
* @property \common\components\oauth\Component $oauth
|
||||
* @property \api\components\OAuth2\Component $oauth
|
||||
*
|
||||
* @method \api\components\User\Component getUser()
|
||||
*/
|
||||
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Util\KeyAlgorithm;
|
||||
|
||||
use League\OAuth2\Server\Util\KeyAlgorithm\DefaultAlgorithm;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class UuidAlgorithm extends DefaultAlgorithm {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function generate($len = 40) : string {
|
||||
return Uuid::uuid4()->toString();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user