add Telegram bot tokens table and API methods
This commit is contained in:
parent
3c9204f61a
commit
da08bcf1b2
@ -6,4 +6,6 @@ return [
|
|||||||
'senderName' => 'Chancellery ITguild mailer',
|
'senderName' => 'Chancellery ITguild mailer',
|
||||||
'user.passwordResetTokenExpire' => 3600,
|
'user.passwordResetTokenExpire' => 3600,
|
||||||
'user.passwordMinLength' => 8,
|
'user.passwordMinLength' => 8,
|
||||||
|
'tgBotTokenLength' => 6,
|
||||||
|
'tgBotTokenValidityTime' => 180,
|
||||||
];
|
];
|
||||||
|
75
common/models/UserTgBotToken.php
Normal file
75
common/models/UserTgBotToken.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\models;
|
||||||
|
|
||||||
|
use yii\db\ActiveQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the model class for table "user_tg_bot_token".
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int $user_id
|
||||||
|
* @property string $token
|
||||||
|
* @property string $created_at
|
||||||
|
* @property string $updated_at
|
||||||
|
* @property string $expired_at
|
||||||
|
*
|
||||||
|
* @property User $user
|
||||||
|
*/
|
||||||
|
class UserTgBotToken extends \yii\db\ActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function tableName()
|
||||||
|
{
|
||||||
|
return 'user_tg_bot_token';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['user_id'], 'integer'],
|
||||||
|
[['token'], 'required'],
|
||||||
|
[['created_at', 'updated_at', 'expired_at'], 'safe'],
|
||||||
|
[['token'], 'string', 'max' => 255],
|
||||||
|
[['token'], 'unique'],
|
||||||
|
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => 'ID',
|
||||||
|
'user_id' => 'User ID',
|
||||||
|
'token' => 'Token',
|
||||||
|
'created_at' => 'Created At',
|
||||||
|
'updated_at' => 'Updated At',
|
||||||
|
'expired_at' => 'Expired At',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ActiveQuery
|
||||||
|
*/
|
||||||
|
public function getUser()
|
||||||
|
{
|
||||||
|
return $this->hasOne(User::className(), ['id' => 'user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tokenValue
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function checkExistsByToken(string $tokenValue): bool
|
||||||
|
{
|
||||||
|
return self::find()->where(['token' => $tokenValue])->exists();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class m231023_122338_create_user_tg_bot_token
|
||||||
|
*/
|
||||||
|
class m231023_122338_create_user_tg_bot_token extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeUp()
|
||||||
|
{
|
||||||
|
$this->createTable('{{%user_tg_bot_token}}', [
|
||||||
|
'id' => $this->primaryKey(),
|
||||||
|
'user_id' => $this->integer(),
|
||||||
|
'token' => $this->string()->notNull()->unique(),
|
||||||
|
'created_at' => $this->dateTime(),
|
||||||
|
'updated_at' => $this->dateTime(),
|
||||||
|
'expired_at' => $this->dateTime(),
|
||||||
|
]);
|
||||||
|
$this->addForeignKey('user_user_tg_bot_token', 'user_tg_bot_token', 'user_id', 'user', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeDown()
|
||||||
|
{
|
||||||
|
$this->dropTable('user_tg_bot_token');
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,6 @@ class UserController extends ApiController
|
|||||||
return $behaviors;
|
return $behaviors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private UserService $userService;
|
private UserService $userService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
107
frontend/modules/api/controllers/UserTgBotController.php
Normal file
107
frontend/modules/api/controllers/UserTgBotController.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace frontend\modules\api\controllers;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use frontend\modules\api\models\profile\User;
|
||||||
|
use frontend\modules\api\models\UserTgBotToken;
|
||||||
|
use frontend\modules\api\services\UserTgBotTokenService;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
|
class UserTgBotController extends ApiController
|
||||||
|
{
|
||||||
|
public function behaviors(): array
|
||||||
|
{
|
||||||
|
return ArrayHelper::merge(parent::behaviors(), [
|
||||||
|
|
||||||
|
'verbs' => [
|
||||||
|
'class' => \yii\filters\VerbFilter::class,
|
||||||
|
'actions' => [
|
||||||
|
'get-token' => ['get'],
|
||||||
|
'get-user-by-token' => ['get'],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UserTgBotTokenService
|
||||||
|
*/
|
||||||
|
private UserTgBotTokenService $userTgBotTokenService;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$id,
|
||||||
|
$module,
|
||||||
|
UserTgBotTokenService $userTgBotTokenService,
|
||||||
|
$config = []
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->userTgBotTokenService = $userTgBotTokenService;
|
||||||
|
parent::__construct($id, $module, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(path="/user-tg-bot/get-token",
|
||||||
|
* summary="Токен ТГ бота",
|
||||||
|
* description="Метод для возвращает токен для ТГ бота",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"UserTgBotToken"},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект токен ТГ бота",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/UserTgBotTokenExample"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return UserTgBotToken
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function actionGetToken()
|
||||||
|
{
|
||||||
|
return $this->userTgBotTokenService->getToken(Yii::$app->user->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Get(path="/user-tg-bot/get-user",
|
||||||
|
* summary="Получить данные пользователя",
|
||||||
|
* description="Метод для получения данныех пользователя по токену ТГ бота",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"UserTgBotToken"},
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="token",
|
||||||
|
* in="query",
|
||||||
|
* example="HDAS7J",
|
||||||
|
* required=true,
|
||||||
|
* description="Токен ТГ бота",
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает данные пользователя",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return User|string[]
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function actionGetUser(string $token)
|
||||||
|
{
|
||||||
|
return $this->userTgBotTokenService->getUserByToken($token);
|
||||||
|
}
|
||||||
|
}
|
69
frontend/modules/api/models/UserTgBotToken.php
Normal file
69
frontend/modules/api/models/UserTgBotToken.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace frontend\modules\api\models;
|
||||||
|
|
||||||
|
|
||||||
|
use frontend\modules\api\models\profile\User;
|
||||||
|
use yii\db\ActiveQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="UserTgBotToken",
|
||||||
|
* @OA\Property(
|
||||||
|
* property="token",
|
||||||
|
* type="string",
|
||||||
|
* example= "HDAS7J",
|
||||||
|
* description="Токен ТГ бота"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="expired_at",
|
||||||
|
* type="dateTime",
|
||||||
|
* example="2023-10-24 10:05:54",
|
||||||
|
* description="Время истечения активности токена"
|
||||||
|
* ),
|
||||||
|
*)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="UserTgBotTokenExample",
|
||||||
|
* @OA\Property(
|
||||||
|
* property="token",
|
||||||
|
* type="string",
|
||||||
|
* example="HDAS7J"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="expired_at",
|
||||||
|
* type="dateTime",
|
||||||
|
* example="2023-10-24 10:05:54"
|
||||||
|
* ),
|
||||||
|
*)
|
||||||
|
*
|
||||||
|
* @property User $user
|
||||||
|
*/
|
||||||
|
class UserTgBotToken extends \common\models\UserTgBotToken
|
||||||
|
{
|
||||||
|
public function fields(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'token',
|
||||||
|
'expired_at',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function extraFields(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ActiveQuery
|
||||||
|
*/
|
||||||
|
public function getUser()
|
||||||
|
{
|
||||||
|
return $this->hasOne(User::class, ['id' => 'user_id']);
|
||||||
|
}
|
||||||
|
}
|
131
frontend/modules/api/services/UserTgBotTokenService.php
Normal file
131
frontend/modules/api/services/UserTgBotTokenService.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace frontend\modules\api\services;
|
||||||
|
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Exception;
|
||||||
|
use frontend\modules\api\models\profile\User;
|
||||||
|
use frontend\modules\api\models\UserTgBotToken;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
class UserTgBotTokenService
|
||||||
|
{
|
||||||
|
const CHARACTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $userId
|
||||||
|
* @return UserTgBotToken
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function getToken(int $userId)
|
||||||
|
{
|
||||||
|
$model = UserTgBotToken::findOne(['user_id' => $userId]);
|
||||||
|
if (!empty($model)) {
|
||||||
|
return $this->checkExpiredAtTime($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createToken($userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return User|string[]
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function getUserByToken(string $token)
|
||||||
|
{
|
||||||
|
$model = UserTgBotToken::findOne(['token' => $token]);
|
||||||
|
if (!empty($model) ) {
|
||||||
|
|
||||||
|
$currentTime = new DateTime();
|
||||||
|
|
||||||
|
if ($currentTime < new DateTime($model->expired_at)) {
|
||||||
|
return $model->user;
|
||||||
|
} else {
|
||||||
|
return ['error' => 'The token is expired!'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['error' => 'Token not found!'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private function generateToken(): string
|
||||||
|
{
|
||||||
|
$length = Yii::$app->params['tgBotTokenLength'];
|
||||||
|
$charactersLength = strlen($this::CHARACTERS);
|
||||||
|
do {
|
||||||
|
$value = '';
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$value .= $this::CHARACTERS[random_int(0, $charactersLength - 1)];
|
||||||
|
}
|
||||||
|
} while ( UserTgBotToken::checkExistsByToken($value));
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $userId
|
||||||
|
* @return UserTgBotToken
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private function createToken(int $userId): UserTgBotToken
|
||||||
|
{
|
||||||
|
$model = new UserTgBotToken();
|
||||||
|
$model->user_id = $userId;
|
||||||
|
$model->token = $this->generateToken();
|
||||||
|
$model->expired_at = $this->generateExpiredAtTime();
|
||||||
|
|
||||||
|
if (!$model->save()) {
|
||||||
|
throw new \Exception('Токен не сохранен');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return false|string
|
||||||
|
*/
|
||||||
|
private function generateExpiredAtTime()
|
||||||
|
{
|
||||||
|
return date("Y-m-d H:i:s",strtotime(date("Y-m-d H:i:s")) + Yii::$app->params['tgBotTokenValidityTime']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param UserTgBotToken $model
|
||||||
|
* @return UserTgBotToken
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private function checkExpiredAtTime(UserTgBotToken $model)
|
||||||
|
{
|
||||||
|
$currentTime = new DateTime();
|
||||||
|
|
||||||
|
if ($currentTime > new DateTime($model->expired_at)) {
|
||||||
|
$this->updateExpiredAtTime($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param UserTgBotToken $model
|
||||||
|
* @return UserTgBotToken
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private function updateExpiredAtTime(UserTgBotToken $model)
|
||||||
|
{
|
||||||
|
$model->token = $this->generateToken();
|
||||||
|
$model->expired_at = $this->generateExpiredAtTime();
|
||||||
|
|
||||||
|
if (!$model->save()) {
|
||||||
|
throw new \Exception('Токен не сохранен');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user