File: //home/aliazzsr/api.crm.vqode.com/models/UserIdentity.php
<?php
namespace app\models;
use app\components\helpers\AppHelper;
use app\components\helpers\ValueHelper;
use app\models\core\Permission;
use app\models\core\RolePermission;
use app\models\core\User;
use app\models\enums\PermissionEnum;
use yii\caching\CacheInterface;
use yii\helpers\ArrayHelper;
use yii\web\ForbiddenHttpException;
use yii\web\IdentityInterface;
use yii\web\ServerErrorHttpException;
/**
* Class UserIdentity
* @package app\models
* @property AuthToken $authToken
*/
class UserIdentity extends User implements IdentityInterface
{
use \damirka\JWT\UserTrait {
findIdentityByAccessToken as protected traitGetIdentity;
}
/** @var bool */
public $eulaAcceptanceRequired;
/** @var RolePermission[] */
protected $_permissions;
/** @var CacheInterface */
protected $cache;
/** @var boolean */
public $hasStartedSession;
public function init()
{
$this->eulaAcceptanceRequired = AppHelper::getParam('eulaAcceptanceRequired', false);
$this->cache = \Yii::$app->cache;
$this->hasStartedSession = false;
}
public function afterFind()
{
$cacheKey = 'userPermissions_' . $this->id;
$this->cache->delete($cacheKey);
$this->_permissions = $this->cache->getOrSet($cacheKey, function() {
/** @var RolePermission[] $permissions */
$permissions = $this->getRolePermissions()->all();
$result = [];
foreach ($permissions as $permission) {
$result[$permission->permission_name] = $permission;
}
return $result;
});
}
/**
* @inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
/** @var UserIdentity $user */
$user = self::traitGetIdentity($token, $type);
if (!$user) {
return null;
}
$isTokenValid = $user && $user->authToken && $token === $user->authToken->token;
if ($isTokenValid) {
if (!$user->hasAcceptedEula()) {
throw new ForbiddenHttpException('EULA not accepted');
}
$user->authToken->save();
$user->hasStartedSession = true;
return $user;
}
return null;
}
/**
* @inheritdoc
*/
protected static function getSecretKey()
{
return ArrayHelper::getValue(\Yii::$app->params, 'jwt-key', 'jwt-secret-key');
}
/**
* @inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne($id);
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* @inheritdoc
*/
public function getAuthKey()
{
return null;
}
/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return false;
}
/**
* Finds user by email
* @param string $username user's email
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['email' => $username]);
}
/**
*
* @param $password
* @return bool
*/
public function validatePassword($password)
{
return password_verify($password, $this->password);
}
public function getUser()
{
return User::findOne($this->getId());
}
/**
* Returns valid authToken
* @return null|\yii\db\ActiveRecord
*/
public function getAuthToken()
{
$query = $this
->hasOne(AuthToken::className(), ['user_id' => 'id'])
->andWhere(['>', 'expires_at', ValueHelper::now()]);
return $query->one();
}
public function hasAcceptedEula()
{
return !$this->eulaAcceptanceRequired || !is_null($this->eula_accepted_at);
}
/**
* @return bool
*/
public function isBlocked()
{
return !$this->can(PermissionEnum::LOGIN)->read;
}
/**
*
* @param $permissionName
* @return RolePermission
*/
public function can($permissionName)
{
return ArrayHelper::getValue($this->_permissions, $permissionName, new RolePermission());
}
public function getPermissionsAsArray()
{
/** @var Permission[] $permissions */
$cacheKey = 'rolePermissions_' . $this->role_id;
$permissions = $this->cache->getOrSet($cacheKey, function() {
return Permission::find()->all();
});
$result = [];
foreach ($permissions as $perm) {
$result[] = $this->can($perm->name)->toArray([
'permission_name', 'create', 'read', 'update', 'delete',
]);
}
return $result;
}
public function getActiveSession()
{
return $this->hasOne(Session::className(), ['user_id' => 'id'])
->andWhere([
'logout_at' => null,
]);
}
/**
* @throws ServerErrorHttpException
*/
public function startSession()
{
if ($this->hasStartedSession) {
return $this->continueSession();
}
return $this->startNewSession();
}
/**
* Starts a new session and issues a new identity token
*
* @throws ServerErrorHttpException
*/
protected function startNewSession()
{
$this->stopAllSessions();
$newSession = Session::start(['user_id' => $this->id]);
if (!$newSession) {
throw new ServerErrorHttpException('Can\'t start new session');
}
$token = new AuthToken([
'token' => $this->getJWT(),
'user_id' => $this->id,
]);
if (!$token->save()) {
$error = $token->getFirstErrors();
throw new ServerErrorHttpException('Can\'t create new token: ' . reset($error));
}
}
/**
* Prolongs session
*/
protected function continueSession()
{
/** @var Session $activeSession */
$activeSession = $this->getActiveSession()->one();
$activeSession->save();
$this->getAuthToken()->save();
}
protected function stopThisSession()
{
/** @var AuthToken $token */
$token = $this->getAuthToken();
if ($token) {
$token->delete();
}
/** @var Session $activeSession */
$activeSession = $this->getActiveSession()->one();
if ($activeSession) {
$activeSession->stop();
}
}
public function stopAllSessions()
{
$this->stopThisSession();
AuthToken::deleteExpired();
Session::stopExpired();
}
}