mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Реализована логика oAuth авторизации приложений, добавлен Redis, удалены лишние тесты, пофикшены старые.
This commit is contained in:
63
common/components/oauth/Component.php
Normal file
63
common/components/oauth/Component.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace common\components\oauth;
|
||||
|
||||
use common\components\oauth\Storage\Redis\AuthCodeStorage;
|
||||
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 League\OAuth2\Server\AuthorizationServer;
|
||||
use yii\base\InvalidConfigException;
|
||||
|
||||
/**
|
||||
* @property AuthorizationServer $authServer
|
||||
*/
|
||||
class Component extends \yii\base\Component {
|
||||
|
||||
/**
|
||||
* @var AuthorizationServer
|
||||
*/
|
||||
private $_authServer;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $grantTypes = [];
|
||||
|
||||
/**
|
||||
* @var array grant type => class
|
||||
*/
|
||||
public $grantMap = [
|
||||
'authorization_code' => 'League\OAuth2\Server\Grant\AuthCodeGrant',
|
||||
'client_credentials' => 'League\OAuth2\Server\Grant\ClientCredentialsGrant',
|
||||
'password' => 'League\OAuth2\Server\Grant\PasswordGrant',
|
||||
'refresh_token' => 'League\OAuth2\Server\Grant\RefreshTokenGrant'
|
||||
];
|
||||
|
||||
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())
|
||||
->setScopeDelimiter(',');
|
||||
|
||||
$this->_authServer = $authServer;
|
||||
|
||||
foreach ($this->grantTypes as $grantType) {
|
||||
if (!array_key_exists($grantType, $this->grantMap)) {
|
||||
throw new InvalidConfigException('Invalid grant type');
|
||||
}
|
||||
|
||||
$grant = new $this->grantMap[$grantType]();
|
||||
$this->_authServer->addGrantType($grant);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_authServer;
|
||||
}
|
||||
|
||||
}
|
27
common/components/oauth/Entity/AccessTokenEntity.php
Normal file
27
common/components/oauth/Entity/AccessTokenEntity.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
use League\OAuth2\Server\Entity\SessionEntity;
|
||||
|
||||
class AccessTokenEntity extends \League\OAuth2\Server\Entity\AccessTokenEntity {
|
||||
use EntityTrait;
|
||||
|
||||
protected $sessionId;
|
||||
|
||||
public function getSessionId() {
|
||||
return $this->sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @return static
|
||||
*/
|
||||
public function setSession(SessionEntity $session) {
|
||||
parent::setSession($session);
|
||||
$this->sessionId = $session->getId();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
27
common/components/oauth/Entity/AuthCodeEntity.php
Normal file
27
common/components/oauth/Entity/AuthCodeEntity.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
use League\OAuth2\Server\Entity\SessionEntity;
|
||||
|
||||
class AuthCodeEntity extends \League\OAuth2\Server\Entity\AuthCodeEntity {
|
||||
use EntityTrait;
|
||||
|
||||
protected $sessionId;
|
||||
|
||||
public function getSessionId() {
|
||||
return $this->sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @return static
|
||||
*/
|
||||
public function setSession(SessionEntity $session) {
|
||||
parent::setSession($session);
|
||||
$this->sessionId = $session->getId();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
27
common/components/oauth/Entity/SessionEntity.php
Normal file
27
common/components/oauth/Entity/SessionEntity.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Entity;
|
||||
|
||||
use League\OAuth2\Server\Entity\ClientEntity;
|
||||
use League\OAuth2\Server\Entity\EntityTrait;
|
||||
|
||||
class SessionEntity extends \League\OAuth2\Server\Entity\SessionEntity {
|
||||
use EntityTrait;
|
||||
|
||||
protected $clientId;
|
||||
|
||||
public function getClientId() {
|
||||
return $this->clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @return static
|
||||
*/
|
||||
public function associateClient(ClientEntity $client) {
|
||||
parent::associateClient($client);
|
||||
$this->clientId = $client->getId();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Exception;
|
||||
|
||||
use League\OAuth2\Server\Exception\OAuthException;
|
||||
|
||||
class AcceptRequiredException extends OAuthException {
|
||||
|
||||
public $httpStatusCode = 401;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $errorType = 'accept_required';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Client must accept authentication request.');
|
||||
}
|
||||
|
||||
}
|
11
common/components/oauth/Exception/AccessDeniedException.php
Normal file
11
common/components/oauth/Exception/AccessDeniedException.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Exception;
|
||||
|
||||
class AccessDeniedException extends \League\OAuth2\Server\Exception\AccessDeniedException {
|
||||
|
||||
public function __construct($redirectUri = null) {
|
||||
parent::__construct();
|
||||
$this->redirectUri = $redirectUri;
|
||||
}
|
||||
|
||||
}
|
84
common/components/oauth/Storage/Redis/AuthCodeStorage.php
Normal file
84
common/components/oauth/Storage/Redis/AuthCodeStorage.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Redis;
|
||||
|
||||
use common\components\oauth\Entity\AuthCodeEntity;
|
||||
use common\components\redis\Key;
|
||||
use common\components\redis\Set;
|
||||
use League\OAuth2\Server\Entity\AuthCodeEntity as OriginalAuthCodeEntity;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\AuthCodeInterface;
|
||||
|
||||
class AuthCodeStorage extends AbstractStorage implements AuthCodeInterface {
|
||||
|
||||
public $dataTable = 'oauth_auth_codes';
|
||||
|
||||
public $ttl = 3600; // 1h
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($code) {
|
||||
$result = (new Key($this->dataTable, $code))->getValue();
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($result['expire_time'] < time()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new AuthCodeEntity($this->server))->hydrate([
|
||||
'id' => $result['id'],
|
||||
'redirectUri' => $result['client_redirect_uri'],
|
||||
'expireTime' => $result['expire_time'],
|
||||
'sessionId' => $result['sessionId'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function create($token, $expireTime, $sessionId, $redirectUri) {
|
||||
$payload = [
|
||||
'id' => $token,
|
||||
'expire_time' => $expireTime,
|
||||
'session_id' => $sessionId,
|
||||
'client_redirect_uri' => $redirectUri,
|
||||
];
|
||||
|
||||
(new Key($this->dataTable, $token))->setValue($payload)->expire($this->ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getScopes(OriginalAuthCodeEntity $token) {
|
||||
$result = (new Set($this->dataTable, $token->getId(), 'scopes'));
|
||||
$response = [];
|
||||
foreach ($result as $scope) {
|
||||
// TODO: нужно проверить все выданные скоупы на их существование
|
||||
$response[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function associateScope(OriginalAuthCodeEntity $token, ScopeEntity $scope) {
|
||||
(new Set($this->dataTable, $token->getId(), 'scopes'))->add($scope->getId())->expire($this->ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete(OriginalAuthCodeEntity $token) {
|
||||
// Удаляем ключ
|
||||
(new Set($this->dataTable, $token->getId()))->delete();
|
||||
// Удаляем список скоупов для ключа
|
||||
(new Set($this->dataTable, $token->getId(), 'scopes'))->delete();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace Fahmiardi\OAuth2\Server\Storage\Redis;
|
||||
|
||||
use common\components\redis\Key;
|
||||
use League\OAuth2\Server\Entity\RefreshTokenEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\RefreshTokenInterface;
|
||||
|
||||
class RefreshTokenStorage extends AbstractStorage implements RefreshTokenInterface {
|
||||
|
||||
public $dataTable = 'oauth_refresh_tokens';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($token) {
|
||||
$result = (new Key($this->dataTable, $token))->getValue();
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new RefreshTokenEntity($this->server))
|
||||
->setId($result['id'])
|
||||
->setExpireTime($result['expire_time'])
|
||||
->setAccessTokenId($result['access_token_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function create($token, $expireTime, $accessToken) {
|
||||
$payload = [
|
||||
'id' => $token,
|
||||
'expire_time' => $expireTime,
|
||||
'access_token_id' => $accessToken,
|
||||
];
|
||||
|
||||
(new Key($this->dataTable, $token))->setValue($payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete(RefreshTokenEntity $token) {
|
||||
(new Key($this->dataTable, $token->getId()))->delete();
|
||||
}
|
||||
|
||||
}
|
85
common/components/oauth/Storage/Yii2/AccessTokenStorage.php
Normal file
85
common/components/oauth/Storage/Yii2/AccessTokenStorage.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
|
||||
use common\components\oauth\Entity\AccessTokenEntity;
|
||||
use common\models\OauthAccessToken;
|
||||
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\AccessTokenInterface;
|
||||
use yii\db\Exception;
|
||||
|
||||
class AccessTokenStorage extends AbstractStorage implements AccessTokenInterface {
|
||||
|
||||
private $cache = [];
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
* @return OauthAccessToken|null
|
||||
*/
|
||||
private function getTokenModel($token) {
|
||||
if (isset($this->cache[$token])) {
|
||||
$this->cache[$token] = OauthAccessToken::findOne($token);
|
||||
}
|
||||
|
||||
return $this->cache[$token];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($token) {
|
||||
$model = $this->getTokenModel($token);
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new AccessTokenEntity($this->server))->hydrate([
|
||||
'id' => $model->access_token,
|
||||
'expireTime' => $model->expire_time,
|
||||
'sessionId' => $model->session_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getScopes(OriginalAccessTokenEntity $token) {
|
||||
$entities = [];
|
||||
foreach($this->getTokenModel($token->getId())->getScopes() as $scope) {
|
||||
$entities[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]);
|
||||
}
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function create($token, $expireTime, $sessionId) {
|
||||
$model = new OauthAccessToken([
|
||||
'access_token' => $token,
|
||||
'expire_time' => $expireTime,
|
||||
'session_id' => $sessionId,
|
||||
]);
|
||||
|
||||
if (!$model->save()) {
|
||||
throw new Exception('Cannot save ' . OauthAccessToken::class . ' model.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function associateScope(OriginalAccessTokenEntity $token, ScopeEntity $scope) {
|
||||
$this->getTokenModel($token->getId())->getScopes()->add($scope->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete(OriginalAccessTokenEntity $token) {
|
||||
$this->getTokenModel($token->getId())->delete();
|
||||
}
|
||||
|
||||
}
|
73
common/components/oauth/Storage/Yii2/ClientStorage.php
Normal file
73
common/components/oauth/Storage/Yii2/ClientStorage.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
|
||||
use common\components\oauth\Entity\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;
|
||||
|
||||
class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($clientId, $clientSecret = null, $redirectUri = null, $grantType = null) {
|
||||
$query = OauthClient::find()
|
||||
->select(['id', 'name', 'secret'])
|
||||
->where([OauthClient::tableName() . '.id' => $clientId]);
|
||||
|
||||
if ($clientSecret !== null) {
|
||||
$query->andWhere(['secret' => $clientSecret]);
|
||||
}
|
||||
|
||||
if ($redirectUri !== null) {
|
||||
$query
|
||||
->addSelect(['redirect_uri'])
|
||||
->andWhere(['redirect_uri' => $redirectUri]);
|
||||
}
|
||||
|
||||
$model = $query->asArray()->one();
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$entity = new ClientEntity($this->server);
|
||||
$entity->hydrate([
|
||||
'id' => $model['id'],
|
||||
'name' => $model['name'],
|
||||
'secret' => $model['secret'],
|
||||
]);
|
||||
|
||||
if (isset($model['redirect_uri'])) {
|
||||
$entity->hydrate([
|
||||
'redirectUri' => $model['redirect_uri'],
|
||||
]);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getBySession(OriginalSessionEntity $session) {
|
||||
if (!$session instanceof SessionEntity) {
|
||||
throw new \ErrorException('This module assumes that $session typeof ' . SessionEntity::class);
|
||||
}
|
||||
|
||||
$model = OauthClient::find()
|
||||
->select(['id', 'name'])
|
||||
->andWhere(['id' => $session->getClientId()])
|
||||
->asArray()
|
||||
->one();
|
||||
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new ClientEntity($this->server))->hydrate($model);
|
||||
}
|
||||
|
||||
}
|
26
common/components/oauth/Storage/Yii2/ScopeStorage.php
Normal file
26
common/components/oauth/Storage/Yii2/ScopeStorage.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
|
||||
use common\models\OauthScope;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\ScopeInterface;
|
||||
|
||||
class ScopeStorage extends AbstractStorage implements ScopeInterface {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($scope, $grantType = null, $clientId = null) {
|
||||
$row = OauthScope::find()->andWhere(['id' => $scope])->asArray()->one();
|
||||
if ($row === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$entity = new ScopeEntity($this->server);
|
||||
$entity->hydrate($row);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
}
|
125
common/components/oauth/Storage/Yii2/SessionStorage.php
Normal file
125
common/components/oauth/Storage/Yii2/SessionStorage.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
namespace common\components\oauth\Storage\Yii2;
|
||||
|
||||
use common\components\oauth\Entity\AuthCodeEntity;
|
||||
use common\components\oauth\Entity\SessionEntity;
|
||||
use common\models\OauthSession;
|
||||
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
|
||||
use League\OAuth2\Server\Entity\AuthCodeEntity as OriginalAuthCodeEntity;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use League\OAuth2\Server\Entity\SessionEntity as OriginalSessionEntity;
|
||||
use League\OAuth2\Server\Storage\AbstractStorage;
|
||||
use League\OAuth2\Server\Storage\SessionInterface;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\db\Exception;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getByAccessToken(OriginalAccessTokenEntity $accessToken) {
|
||||
/** @var OauthSession|null $model */
|
||||
$model = OauthSession::find()->innerJoinWith([
|
||||
'accessTokens' => function(ActiveQuery $query) use ($accessToken) {
|
||||
$query->andWhere(['access_token' => $accessToken->getId()]);
|
||||
},
|
||||
])->one();
|
||||
|
||||
return $this->hydrateEntity($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getByAuthCode(OriginalAuthCodeEntity $authCode) {
|
||||
if (!$authCode instanceof AuthCodeEntity) {
|
||||
throw new \ErrorException('This module assumes that $authCode typeof ' . AuthCodeEntity::class);
|
||||
}
|
||||
|
||||
return $this->getSession($authCode->getSessionId());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getScopes(OriginalSessionEntity $session) {
|
||||
$result = [];
|
||||
foreach ($this->getSessionModel($session->getId())->getScopes() as $scope) {
|
||||
// TODO: нужно проверить все выданные скоупы на их существование
|
||||
$result[] = (new ScopeEntity($this->server))->hydrate(['id' => $scope]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function create($ownerType, $ownerId, $clientId, $clientRedirectUri = null) {
|
||||
$sessionId = OauthSession::find()
|
||||
->select('id')
|
||||
->andWhere([
|
||||
'client_id' => $clientId,
|
||||
'owner_type' => $ownerType,
|
||||
'owner_id' => $ownerId,
|
||||
])->scalar();
|
||||
|
||||
if ($sessionId === false) {
|
||||
$model = new OauthSession([
|
||||
'client_id' => $clientId,
|
||||
'owner_type' => $ownerType,
|
||||
'owner_id' => $ownerId,
|
||||
]);
|
||||
|
||||
if (!$model->save()) {
|
||||
throw new Exception('Cannot save ' . OauthSession::class . ' model.');
|
||||
}
|
||||
|
||||
$sessionId = $model->id;
|
||||
}
|
||||
|
||||
return $sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function associateScope(OriginalSessionEntity $session, ScopeEntity $scope) {
|
||||
$this->getSessionModel($session->getId())->getScopes()->add($scope->getId());
|
||||
}
|
||||
|
||||
}
|
58
common/components/redis/Key.php
Normal file
58
common/components/redis/Key.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace common\components\redis;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Yii;
|
||||
|
||||
class Key {
|
||||
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* @return \yii\redis\Connection
|
||||
*/
|
||||
public function getRedis() {
|
||||
return Yii::$app->get('redis');
|
||||
}
|
||||
|
||||
public function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
return $this->getRedis()->get(json_decode($this->key));
|
||||
}
|
||||
|
||||
public function setValue($value) {
|
||||
$this->getRedis()->set($this->key, json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
$this->getRedis()->executeCommand('DEL', [$this->key]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function expire($ttl) {
|
||||
$this->getRedis()->executeCommand('EXPIRE', [$this->key, $ttl]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function buildKey(array $parts) {
|
||||
$keyParts = [];
|
||||
foreach($parts as $part) {
|
||||
$keyParts[] = str_replace('_', ':', $part);
|
||||
}
|
||||
|
||||
return implode(':', $keyParts);
|
||||
}
|
||||
|
||||
public function __construct(...$key) {
|
||||
if (empty($key)) {
|
||||
throw new InvalidArgumentException('You must specify at least one key.');
|
||||
}
|
||||
|
||||
$this->key = $this->buildKey($key);
|
||||
}
|
||||
|
||||
}
|
49
common/components/redis/Set.php
Normal file
49
common/components/redis/Set.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace common\components\redis;
|
||||
|
||||
use IteratorAggregate;
|
||||
use Yii;
|
||||
|
||||
class Set extends Key implements IteratorAggregate {
|
||||
|
||||
/**
|
||||
* @return \yii\redis\Connection
|
||||
*/
|
||||
public static function getDb() {
|
||||
return Yii::$app->get('redis');
|
||||
}
|
||||
|
||||
public function add($value) {
|
||||
$this->getDb()->executeCommand('SADD', [$this->key, $value]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function remove($value) {
|
||||
$this->getDb()->executeCommand('SREM', [$this->key, $value]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function members() {
|
||||
return $this->getDb()->executeCommand('SMEMBERS', [$this->key]);
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
return $this->members();
|
||||
}
|
||||
|
||||
public function exists($value) {
|
||||
return !!$this->getDb()->executeCommand('SISMEMBER', [$this->key, $value]);
|
||||
}
|
||||
|
||||
public function diff(array $sets) {
|
||||
return $this->getDb()->executeCommand('SDIFF', [$this->key, implode(' ', $sets)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new \ArrayIterator($this->members());
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user