mirror of
https://github.com/elyby/accounts.git
synced 2024-11-22 21:23:19 +05:30
Translate all code comments from Russian to English [skip ci]
This commit is contained in:
parent
31069562b3
commit
3dbf29d34c
@ -1,8 +1,8 @@
|
|||||||
.git/*
|
.git/*
|
||||||
.env
|
.env
|
||||||
|
|
||||||
# vendor будет заполнен уже внутри контейнера
|
# vendor folder will be filled from the container
|
||||||
vendor
|
vendor
|
||||||
|
|
||||||
# Все временные файлы
|
# Runtime data from any app module
|
||||||
*/runtime
|
*/runtime
|
||||||
|
18
.env-dist
18
.env-dist
@ -1,42 +1,42 @@
|
|||||||
# Параметры приложения
|
# Application params
|
||||||
## Env приложения
|
## Application environment
|
||||||
YII_DEBUG=true
|
YII_DEBUG=true
|
||||||
YII_ENV=dev
|
YII_ENV=dev
|
||||||
DOMAIN=https://account.ely.by
|
DOMAIN=https://account.ely.by
|
||||||
EMAILS_RENDERER_HOST=http://emails-renderer:3000
|
EMAILS_RENDERER_HOST=http://emails-renderer:3000
|
||||||
|
|
||||||
## Параметры, отвечающие за безопасность
|
## Security params
|
||||||
JWT_USER_SECRET=
|
JWT_USER_SECRET=
|
||||||
|
|
||||||
## Внешние сервисы
|
## External services
|
||||||
RECAPTCHA_PUBLIC=
|
RECAPTCHA_PUBLIC=
|
||||||
RECAPTCHA_SECRET=
|
RECAPTCHA_SECRET=
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
|
|
||||||
## SMTP параметры
|
## SMTP params
|
||||||
SMTP_USER=
|
SMTP_USER=
|
||||||
SMTP_PASS=
|
SMTP_PASS=
|
||||||
SMTP_PORT=
|
SMTP_PORT=
|
||||||
|
|
||||||
## Параметры подключения к базе данных
|
## MariaDB connection params
|
||||||
DB_HOST=db
|
DB_HOST=db
|
||||||
DB_DATABASE=ely_accounts
|
DB_DATABASE=ely_accounts
|
||||||
DB_USER=ely_accounts_user
|
DB_USER=ely_accounts_user
|
||||||
DB_PASSWORD=ely_accounts_password
|
DB_PASSWORD=ely_accounts_password
|
||||||
|
|
||||||
## Параметры подключения к redis
|
## Redis connection params
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_DATABASE=0
|
REDIS_DATABASE=0
|
||||||
REDIS_PASSWORD=
|
REDIS_PASSWORD=
|
||||||
|
|
||||||
## Параметры Statsd
|
## StatsD metrics params
|
||||||
STATSD_HOST=statsd.ely.by
|
STATSD_HOST=statsd.ely.by
|
||||||
STATSD_PORT=8125
|
STATSD_PORT=8125
|
||||||
# This value can be blank
|
# This value can be blank
|
||||||
STATSD_NAMESPACE=
|
STATSD_NAMESPACE=
|
||||||
|
|
||||||
## Конфигурация для Dev.
|
## Dev-only params
|
||||||
XDEBUG_CONFIG=remote_host=10.254.254.254
|
XDEBUG_CONFIG=remote_host=10.254.254.254
|
||||||
PHP_IDE_CONFIG=serverName=docker
|
PHP_IDE_CONFIG=serverName=docker
|
||||||
|
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -10,11 +10,9 @@
|
|||||||
# npm debug
|
# npm debug
|
||||||
npm-debug*
|
npm-debug*
|
||||||
|
|
||||||
# Docker и его override файлы
|
# Docker and related files
|
||||||
/docker-compose.yml
|
/docker-compose.yml
|
||||||
/docker-compose.override.yml
|
/docker-compose.override.yml
|
||||||
|
|
||||||
# Локальный .env
|
|
||||||
/.env
|
/.env
|
||||||
|
|
||||||
# id_rsa
|
# id_rsa
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace api\aop\annotations;
|
namespace api\aop\annotations;
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\Annotation;
|
use Doctrine\Common\Annotations\Annotation;
|
||||||
@ -12,7 +14,7 @@ class CollectModelMetrics {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @Required()
|
* @Required()
|
||||||
* @var string задаёт префикс для отправки метрик. Задаётся без ведущей и без завершающей точки.
|
* @var string sets the prefix for collected metrics. Should be specified without trailing dots
|
||||||
*/
|
*/
|
||||||
public $prefix = '';
|
public $prefix = '';
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ class AuthCodeGrant extends AbstractGrant {
|
|||||||
$this->server->getTokenType()->setParam('access_token', $accessToken->getId());
|
$this->server->getTokenType()->setParam('access_token', $accessToken->getId());
|
||||||
$this->server->getTokenType()->setParam('expires_in', $this->getAccessTokenTTL());
|
$this->server->getTokenType()->setParam('expires_in', $this->getAccessTokenTTL());
|
||||||
|
|
||||||
// Выдаём refresh_token, если запрошен offline_access
|
// Set refresh_token param only in case when offline_access requested
|
||||||
if (isset($accessToken->getScopes()[ScopeStorage::OFFLINE_ACCESS])) {
|
if (isset($accessToken->getScopes()[ScopeStorage::OFFLINE_ACCESS])) {
|
||||||
/** @var RefreshTokenGrant $refreshTokenGrant */
|
/** @var RefreshTokenGrant $refreshTokenGrant */
|
||||||
$refreshTokenGrant = $this->server->getGrantType('refresh_token');
|
$refreshTokenGrant = $this->server->getGrantType('refresh_token');
|
||||||
@ -222,8 +222,9 @@ class AuthCodeGrant extends AbstractGrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* По стандарту OAuth2 scopes должны разделяться пробелом, а не запятой. Косяк.
|
* In the earlier versions of Accounts Ely.by backend we had a comma-separated scopes
|
||||||
* Так что оборачиваем функцию разбора скоупов, заменяя запятые на пробелы.
|
* list, while by OAuth2 standard it they should be separated by a space. Shit happens :)
|
||||||
|
* So override scopes validation function to reformat passed value.
|
||||||
*
|
*
|
||||||
* @param string $scopeParam
|
* @param string $scopeParam
|
||||||
* @param BaseClientEntity $client
|
* @param BaseClientEntity $client
|
||||||
|
@ -69,8 +69,9 @@ class ClientCredentialsGrant extends AbstractGrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* По стандарту OAuth2 scopes должны разделяться пробелом, а не запятой. Косяк.
|
* In the earlier versions of Accounts Ely.by backend we had a comma-separated scopes
|
||||||
* Так что оборачиваем функцию разбора скоупов, заменяя запятые на пробелы.
|
* list, while by OAuth2 standard it they should be separated by a space. Shit happens :)
|
||||||
|
* So override scopes validation function to reformat passed value.
|
||||||
*
|
*
|
||||||
* @param string $scopeParam
|
* @param string $scopeParam
|
||||||
* @param BaseClientEntity $client
|
* @param BaseClientEntity $client
|
||||||
|
@ -48,8 +48,9 @@ class RefreshTokenGrant extends AbstractGrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* По стандарту OAuth2 scopes должны разделяться пробелом, а не запятой. Косяк.
|
* In the earlier versions of Accounts Ely.by backend we had a comma-separated scopes
|
||||||
* Так что оборачиваем функцию разбора скоупов, заменяя запятые на пробелы.
|
* list, while by OAuth2 standard it they should be separated by a space. Shit happens :)
|
||||||
|
* So override scopes validation function to reformat passed value.
|
||||||
*
|
*
|
||||||
* @param string $scopeParam
|
* @param string $scopeParam
|
||||||
* @param BaseClientEntity $client
|
* @param BaseClientEntity $client
|
||||||
@ -62,9 +63,9 @@ class RefreshTokenGrant extends AbstractGrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод таки пришлось переписать по той причине, что нынче мы храним access_token в redis с expire значением,
|
* The method has been overridden because we stores access_tokens in Redis with expire value,
|
||||||
* так что он может банально несуществовать на тот момент, когда к нему через refresh_token попытаются обратиться.
|
* so they might not exists at the moment, when it will be requested via refresh_token.
|
||||||
* Поэтому мы расширили логику RefreshTokenEntity и она теперь знает о сессии, в рамках которой была создана
|
* That's why we extends RefreshTokenEntity to give it knowledge about related session.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
* @throws \League\OAuth2\Server\Exception\OAuthException
|
* @throws \League\OAuth2\Server\Exception\OAuthException
|
||||||
|
@ -27,16 +27,12 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: нужно учитывать тип приложения
|
// TODO: should check application type
|
||||||
/*
|
// For "desktop" app type redirect_uri is not required and should be by default set
|
||||||
* Для приложений типа "настольный" redirect_uri необязателем - он должен быть по умолчанию равен
|
// to the static redirect, but for "site" it's required always.
|
||||||
* статичному редиректу на страницу сайта
|
|
||||||
* А для приложений типа "сайт" редирект должен быть всегда.
|
|
||||||
* Короче это нужно учесть
|
|
||||||
*/
|
|
||||||
if ($redirectUri !== null) {
|
if ($redirectUri !== null) {
|
||||||
if (in_array($redirectUri, [self::REDIRECT_STATIC_PAGE, self::REDIRECT_STATIC_PAGE_WITH_CODE], true)) {
|
if (in_array($redirectUri, [self::REDIRECT_STATIC_PAGE, self::REDIRECT_STATIC_PAGE_WITH_CODE], true)) {
|
||||||
// Тут, наверное, нужно проверить тип приложения
|
// I think we should check the type of application here
|
||||||
} else {
|
} else {
|
||||||
if (!StringHelper::startsWith($redirectUri, $model->redirect_uri, false)) {
|
if (!StringHelper::startsWith($redirectUri, $model->redirect_uri, false)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -39,8 +39,8 @@ class ScopeStorage extends AbstractStorage implements ScopeInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $scope
|
* @param string $scope
|
||||||
* @param string $grantType передаётся, если запрос поступает из grant. В этом случае нужно отфильтровать
|
* @param string $grantType is passed on if called from the grant.
|
||||||
* только те права, которые можно получить на этом grant.
|
* In this case, you only need to filter out the rights that you can get on this grant.
|
||||||
* @param string $clientId
|
* @param string $clientId
|
||||||
*
|
*
|
||||||
* @return ScopeEntity|null
|
* @return ScopeEntity|null
|
||||||
|
@ -52,7 +52,7 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
|||||||
->andWhere([
|
->andWhere([
|
||||||
'client_id' => $clientId,
|
'client_id' => $clientId,
|
||||||
'owner_type' => $ownerType,
|
'owner_type' => $ownerType,
|
||||||
'owner_id' => (string)$ownerId, // Переводим в строку, чтобы работали индексы, т.к. поле varchar
|
'owner_id' => (string)$ownerId, // Casts as a string to make the indexes work, because the varchar field
|
||||||
])->scalar();
|
])->scalar();
|
||||||
|
|
||||||
if ($sessionId === false) {
|
if ($sessionId === false) {
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace api\components\OAuth2\Utils;
|
namespace api\components\OAuth2\Utils;
|
||||||
|
|
||||||
class Scopes {
|
class Scopes {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* По стандарту OAuth2 scopes должны разделяться пробелом, а не запятой. Косяк.
|
* In the earlier versions of Accounts Ely.by backend we had a comma-separated scopes
|
||||||
* Так что оборачиваем функцию разбора скоупов, заменяя запятые на пробелы.
|
* list, while by OAuth2 standard it they should be separated by a space. Shit happens :)
|
||||||
* Заодно учитываем возможность передать скоупы в виде массива.
|
* So override scopes validation function to reformat passed value.
|
||||||
*
|
*
|
||||||
* @param string|array $scopes
|
* @param string|array $scopes
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function format($scopes): string {
|
public static function format($scopes): string {
|
||||||
@ -21,7 +22,6 @@ class Scopes {
|
|||||||
return implode(' ', $scopes);
|
return implode(' ', $scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
|
||||||
return str_replace(',', ' ', $scopes);
|
return str_replace(',', ' ', $scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ class Component extends YiiUserComponent {
|
|||||||
$token->addClaim(new Claim\JwtId($session->id));
|
$token->addClaim(new Claim\JwtId($session->id));
|
||||||
} else {
|
} else {
|
||||||
$session = null;
|
$session = null;
|
||||||
// Если мы не сохраняем сессию, то токен должен жить подольше,
|
// If we don't remember a session, the token should live longer
|
||||||
// чтобы не прогорала сессия во время работы с аккаунтом
|
// so that the session doesn't end while working with the account
|
||||||
$token->addClaim(new Claim\Expiration((new DateTime())->add(new DateInterval($this->sessionTimeout))));
|
$token->addClaim(new Claim\Expiration((new DateTime())->add(new DateInterval($this->sessionTimeout))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +125,8 @@ class Component extends YiiUserComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $jwtString
|
* @param string $jwtString
|
||||||
* @return Token распаршенный токен
|
* @return Token
|
||||||
* @throws VerificationException если один из Claims не пройдёт проверку
|
* @throws VerificationException in case when some Claim not pass the validation
|
||||||
*/
|
*/
|
||||||
public function parseToken(string $jwtString): Token {
|
public function parseToken(string $jwtString): Token {
|
||||||
$token = &self::$parsedTokensCache[$jwtString];
|
$token = &self::$parsedTokensCache[$jwtString];
|
||||||
@ -149,13 +149,13 @@ class Component extends YiiUserComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод находит AccountSession модель, относительно которой был выдан текущий JWT токен.
|
* The method searches AccountSession model, which one has been used to create current JWT token.
|
||||||
* В случае, если на пути поиска встретится ошибка, будет возвращено значение null. Возможные кейсы:
|
* null will be returned in case when any of the following situations occurred:
|
||||||
* - Юзер не авторизован
|
* - The user isn't authorized
|
||||||
* - Почему-то нет заголовка с токеном
|
* - There is no header with a token
|
||||||
* - Во время проверки токена возникла ошибка, что привело к исключению
|
* - Token validation isn't passed and some exception has been thrown
|
||||||
* - В токене не найдено ключа сессии. Такое возможно, если юзер выбрал "не запоминать меня"
|
* - No session key found in the token. This is possible if the user chose not to remember me
|
||||||
* или просто старые токены, без поддержки сохранения используемой сессии
|
* or just some old tokens, without the support of saving the used session
|
||||||
*
|
*
|
||||||
* @return AccountSession|null
|
* @return AccountSession|null
|
||||||
*/
|
*/
|
||||||
|
@ -17,17 +17,17 @@ interface IdentityInterface extends \yii\web\IdentityInterface {
|
|||||||
public static function findIdentityByAccessToken($token, $type = null): IdentityInterface;
|
public static function findIdentityByAccessToken($token, $type = null): IdentityInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Этот метод используется для получения токена, к которому привязаны права.
|
* This method is used to obtain a token to which scopes are attached.
|
||||||
* У нас права привязываются к токенам, так что возвращаем именно его id.
|
* Our permissions are attached to tokens itself, so we return its id.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getId(): string;
|
public function getId(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод возвращает аккаунт, который привязан к текущему токену.
|
* The method returns an account that is attached to the current token.
|
||||||
* Но не исключено, что токен был выдан и без привязки к аккаунту, так что
|
* But it's possible that the token was issued without binding to the account,
|
||||||
* следует это учитывать.
|
* so you should handle it.
|
||||||
*
|
*
|
||||||
* @return Account|null
|
* @return Account|null
|
||||||
*/
|
*/
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace api\controllers;
|
namespace api\controllers;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\filters\auth\HttpBearerAuth;
|
use yii\filters\auth\HttpBearerAuth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin \yii\filters\ContentNegotiator
|
* @mixin \yii\filters\ContentNegotiator
|
||||||
* @mixin \yii\filters\VerbFilter
|
* @mixin \yii\filters\VerbFilter
|
||||||
* @mixin \yii\filters\auth\CompositeAuth
|
* @mixin \yii\filters\auth\CompositeAuth
|
||||||
@ -14,13 +16,13 @@ class Controller extends \yii\rest\Controller {
|
|||||||
|
|
||||||
public function behaviors(): array {
|
public function behaviors(): array {
|
||||||
$parentBehaviors = parent::behaviors();
|
$parentBehaviors = parent::behaviors();
|
||||||
// Добавляем авторизатор для входа по jwt токенам
|
// Add JWT authenticator
|
||||||
$parentBehaviors['authenticator'] = [
|
$parentBehaviors['authenticator'] = [
|
||||||
'class' => HttpBearerAuth::class,
|
'class' => HttpBearerAuth::class,
|
||||||
'user' => Yii::$app->getUser(),
|
'user' => Yii::$app->getUser(),
|
||||||
];
|
];
|
||||||
|
|
||||||
// xml и rate limiter нам не понадобятся
|
// XML and rate limiter is not necessary
|
||||||
unset(
|
unset(
|
||||||
$parentBehaviors['contentNegotiator']['formats']['application/xml'],
|
$parentBehaviors['contentNegotiator']['formats']['application/xml'],
|
||||||
$parentBehaviors['rateLimiter']
|
$parentBehaviors['rateLimiter']
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace api\exceptions;
|
namespace api\exceptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Исключение можно использовать для тех кейсов, где вроде указанных исход не продполагается,
|
* The exception can be used for cases where the outcome doesn't seem to be expected,
|
||||||
* но теоретически может произойти. Целью является отлавливание таких участков и доработка логики,
|
* but can theoretically happen. The goal is to capture these areas and refine the logic
|
||||||
* если такие ситуации всё же будут иметь место случаться.
|
* if such situations do occur.
|
||||||
*/
|
*/
|
||||||
class ThisShouldNotHappenException extends Exception {
|
class ThisShouldNotHappenException extends Exception {
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace api\filters;
|
namespace api\filters;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
@ -7,13 +9,13 @@ use yii\base\ActionFilter;
|
|||||||
class NginxCache extends ActionFilter {
|
class NginxCache extends ActionFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|callable массив или callback, содержащий пары роут -> сколько кэшировать.
|
* @var array|callable array or callback, contains pairs of route => cache duration.
|
||||||
*
|
*
|
||||||
* Период можно задавать 2-умя путями:
|
* Duration can be set in 2-ways:
|
||||||
* - если значение начинается с префикса @, оно задаёт абсолютное время в unix timestamp,
|
* - if the value starts with the @ prefix, it sets the absolute time
|
||||||
* до которого ответ может быть закэширован.
|
* in unix timestamp that the response can be cached to.
|
||||||
* - в ином случае значение интерпретируется как количество секунд, на которое необходимо
|
* - otherwise, the value is interpreted as the number of seconds
|
||||||
* закэшировать ответ
|
* for which the response must be cached
|
||||||
*/
|
*/
|
||||||
public $rules;
|
public $rules;
|
||||||
|
|
||||||
|
@ -116,14 +116,14 @@ class RegistrationForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается,
|
* The method checks whether the username or E-mail specified during registration
|
||||||
* что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь
|
* can be occupied. It happens that users enter the wrong E-mail or username,
|
||||||
* выпонить регистрацию. Мы не будем им мешать и просто удаляем существующие недозарегистрированные
|
* then notice it and try to re-register. We'll not interfere with them
|
||||||
* аккаунты, позволяя им зарегистрироваться.
|
* and simply delete existing not-finished-registration account,
|
||||||
*
|
* allowing them to take it.
|
||||||
* @param array $errors массив, где ключ - это поле, а значение - первая ошибка из нашего
|
|
||||||
* стандартного словаря ошибок
|
|
||||||
*
|
*
|
||||||
|
* @param array $errors an array where the key is a field and the value is
|
||||||
|
* the first error from our standard error dictionary
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function canContinue(array $errors): bool {
|
protected function canContinue(array $errors): bool {
|
||||||
|
@ -12,17 +12,16 @@ class BanAccountForm extends AccountActionForm {
|
|||||||
public const DURATION_FOREVER = -1;
|
public const DURATION_FOREVER = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Нереализованный функционал блокировки аккаунта на определённый период времени.
|
* Unimplemented account blocking functionality for a certain period of time.
|
||||||
* Сейчас установка этого параметра ничего не даст, аккаунт будет заблокирован навечно,
|
* Setting this parameter currently will do nothing, the account will be blocked forever,
|
||||||
* но, по задумке, здесь можно передать количество секунд, на которое будет
|
* but the idea is to pass the number of seconds for which the user's account will be blocked.
|
||||||
* заблокирован аккаунт пользователя.
|
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
public $duration = self::DURATION_FOREVER;
|
public $duration = self::DURATION_FOREVER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Нереализованный функционал указания причины блокировки аккаунта.
|
* Unimplemented functionality to indicate the reason for account blocking.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +15,7 @@ class SendEmailVerificationForm extends AccountActionForm {
|
|||||||
public $password;
|
public $password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var null meta-поле, чтобы заставить yii валидировать и публиковать ошибки, связанные с отправленными email
|
* @var null meta-field to force yii to validate and publish errors related to sent emails
|
||||||
*/
|
*/
|
||||||
public $email;
|
public $email;
|
||||||
|
|
||||||
@ -76,10 +76,10 @@ class SendEmailVerificationForm extends AccountActionForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает E-mail активацию, которая использовалась внутри процесса для перехода на следующий шаг.
|
* Returns the E-mail activation that was used within the process to move on to the next step.
|
||||||
* Метод предназначен для проверки, не слишком ли часто отправляются письма о смене E-mail.
|
* The method is designed to check if the E-mail change messages are sent too often.
|
||||||
* Проверяем тип подтверждения нового E-mail, поскольку при переходе на этот этап, активация предыдущего
|
* Including checking for the confirmation of the new E-mail type, because when you go to this step,
|
||||||
* шага удаляется.
|
* the activation of the previous step is removed.
|
||||||
*/
|
*/
|
||||||
public function getEmailActivation(): ?EmailActivation {
|
public function getEmailActivation(): ?EmailActivation {
|
||||||
return $this->getAccount()
|
return $this->getAccount()
|
||||||
|
@ -62,13 +62,14 @@ class TwoFactorAuthInfo extends BaseAccountForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* В используемой либе для рендеринга QR кода нет возможности указать QR code version.
|
* In the used library for rendering QR codes there is no possibility to specify a QR code version.
|
||||||
* http://www.qrcode.com/en/about/version.html
|
* http://www.qrcode.com/en/about/version.html
|
||||||
* По какой-то причине 7 и 8 версии не читаются вовсе, с логотипом или без.
|
*
|
||||||
* Поэтому нужно иначально привести строку к длинне 9 версии (91), добавляя к концу
|
* For some reason, generated versions 7 and 8 are not readable at all, with or without a logo.
|
||||||
* строки необходимое количество символов "#". Этот символ используется, т.к. нашим
|
* Therefore, it is necessary to initially append the string to the length of version 9 (91),
|
||||||
* контентом является ссылка и чтобы не вводить лишние параметры мы помечаем добавочную
|
* adding to the end of the string the necessary number of characters "#".
|
||||||
* часть как хеш часть и все программы для чтения QR кодов продолжают свою работу.
|
* This symbol is used because our content is a link and in order not to enter unnecessary parameters
|
||||||
|
* we mark the additional part as a hash part and all application for scanning QR codes continue their work.
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
* @return string
|
* @return string
|
||||||
@ -78,11 +79,11 @@ class TwoFactorAuthInfo extends BaseAccountForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* otp_secret кодируется в Base32, но после кодирования в результурющей строке есть символы,
|
* otp_secret is encoded in Base32, but after encoding there are characters in the result line
|
||||||
* которые можно перепутать (1 и l, O и 0, и т.д.). Т.к. целевая строка не предназначена для
|
* that can be mixed up (1 and l, O and 0, etc.). Since the target string isn't intended for
|
||||||
* обратной расшифровки, то мы можем безжалостно их удалить. Итоговая строка составляет 160%
|
* reverse decryption, we can safely delete them. The resulting string is 160% of the source line.
|
||||||
* от исходной. Поэтому, генерируя исходные случайные байты, мы должны обеспечить такую длину,
|
* That's why, when generating the initial random bytes, we should provide such a length that
|
||||||
* чтобы 160% её было равно запрошенному значению.
|
* 160% of it is equal to the requested length.
|
||||||
*
|
*
|
||||||
* @param int $length
|
* @param int $length
|
||||||
* @return string
|
* @return string
|
||||||
@ -91,6 +92,7 @@ class TwoFactorAuthInfo extends BaseAccountForm {
|
|||||||
$randomBytesLength = ceil($length / 1.6);
|
$randomBytesLength = ceil($length / 1.6);
|
||||||
$result = '';
|
$result = '';
|
||||||
while (strlen($result) < $length) {
|
while (strlen($result) < $length) {
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
$encoded = Base32::encodeUpper(random_bytes($randomBytesLength));
|
$encoded = Base32::encodeUpper(random_bytes($randomBytesLength));
|
||||||
$encoded = trim($encoded, '=');
|
$encoded = trim($encoded, '=');
|
||||||
$encoded = str_replace(['I', 'L', 'O', 'U', '1', '0'], '', $encoded);
|
$encoded = str_replace(['I', 'L', 'O', 'U', '1', '0'], '', $encoded);
|
||||||
|
@ -51,9 +51,8 @@ class Module extends \yii\base\Module implements BootstrapInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поскольку это legacy метод и документации в новой среде для него не будет,
|
* Since this is a legacy method and there will be no documentation for it in the new environment,
|
||||||
* нет смысла выставлять на показ внутренние url, так что ограничиваем доступ
|
* there is no point in displaying the internal API, so we are limiting access only to logons from the old domain.
|
||||||
* только для заходов по старому домену
|
|
||||||
*
|
*
|
||||||
* @throws NotFoundHttpException
|
* @throws NotFoundHttpException
|
||||||
*/
|
*/
|
||||||
|
@ -42,24 +42,24 @@ class AuthenticationController extends Controller {
|
|||||||
$model = new models\ValidateForm();
|
$model = new models\ValidateForm();
|
||||||
$model->load(Yii::$app->request->post());
|
$model->load(Yii::$app->request->post());
|
||||||
$model->validateToken();
|
$model->validateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// If successful, an empty answer is expected.
|
||||||
// которое обработает ErrorHandler
|
// In case of an error, an exception is thrown which will be processed by ErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionSignout() {
|
public function actionSignout() {
|
||||||
$model = new models\SignoutForm();
|
$model = new models\SignoutForm();
|
||||||
$model->load(Yii::$app->request->post());
|
$model->load(Yii::$app->request->post());
|
||||||
$model->signout();
|
$model->signout();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// If successful, an empty answer is expected.
|
||||||
// которое обработает ErrorHandler
|
// In case of an error, an exception is thrown which will be processed by ErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionInvalidate() {
|
public function actionInvalidate() {
|
||||||
$model = new models\InvalidateForm();
|
$model = new models\InvalidateForm();
|
||||||
$model->load(Yii::$app->request->post());
|
$model->load(Yii::$app->request->post());
|
||||||
$model->invalidateToken();
|
$model->invalidateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// If successful, an empty answer is expected.
|
||||||
// которое обработает ErrorHandler
|
// In case of an error, an exception is thrown which will be processed by ErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use yii\web\HttpException;
|
|||||||
class AuthserverException extends HttpException {
|
class AuthserverException extends HttpException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Рефлексия быстрее, как ни странно:
|
* Reflection is faster, weird as it may seem:
|
||||||
* @url https://coderwall.com/p/cpxxxw/php-get-class-name-without-namespace#comment_19313
|
* @url https://coderwall.com/p/cpxxxw/php-get-class-name-without-namespace#comment_19313
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -33,7 +33,7 @@ class AuthenticateData {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if ($includeAvailableProfiles) {
|
if ($includeAvailableProfiles) {
|
||||||
// Сами моянги ещё ничего не придумали с этими availableProfiles
|
// The Moiangs themselves haven't come up with anything yet with these availableProfiles
|
||||||
$availableProfiles[0] = $result['selectedProfile'];
|
$availableProfiles[0] = $result['selectedProfile'];
|
||||||
$result['availableProfiles'] = $availableProfiles;
|
$result['availableProfiles'] = $availableProfiles;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,8 @@ class AuthenticationForm extends ApiForm {
|
|||||||
Authserver::error("User with login = '{$this->username}' passed wrong password.");
|
Authserver::error("User with login = '{$this->username}' passed wrong password.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// На старом сервере авторизации использовалось поле nickname, а не username, так что сохраняем эту логику
|
// The previous authorization server implementation used the nickname field instead of username,
|
||||||
|
// so we keep such behavior
|
||||||
$attribute = $loginForm->getLoginAttribute();
|
$attribute = $loginForm->getLoginAttribute();
|
||||||
if ($attribute === 'username') {
|
if ($attribute === 'username') {
|
||||||
$attribute = 'nickname';
|
$attribute = 'nickname';
|
||||||
|
@ -30,11 +30,12 @@ class SignoutForm extends ApiForm {
|
|||||||
if (!$loginForm->validate()) {
|
if (!$loginForm->validate()) {
|
||||||
$errors = $loginForm->getFirstErrors();
|
$errors = $loginForm->getFirstErrors();
|
||||||
if (isset($errors['login']) && $errors['login'] === E::ACCOUNT_BANNED) {
|
if (isset($errors['login']) && $errors['login'] === E::ACCOUNT_BANNED) {
|
||||||
// Считаем, что заблокированный может безболезненно выйти
|
// We believe that a blocked one can get out painlessly
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// На старом сервере авторизации использовалось поле nickname, а не username, так что сохраняем эту логику
|
// The previous authorization server implementation used the nickname field instead of username,
|
||||||
|
// so we keep such behavior
|
||||||
$attribute = $loginForm->getLoginAttribute();
|
$attribute = $loginForm->getLoginAttribute();
|
||||||
if ($attribute === 'username') {
|
if ($attribute === 'username') {
|
||||||
$attribute = 'nickname';
|
$attribute = 'nickname';
|
||||||
|
@ -4,8 +4,8 @@ namespace api\modules\authserver\validators;
|
|||||||
use api\modules\authserver\exceptions\IllegalArgumentException;
|
use api\modules\authserver\exceptions\IllegalArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Максимальная длина clientToken для нашей базы данных составляет 255.
|
* The maximum length of clientToken for our database is 255.
|
||||||
* После этого мы не принимаем указанный токен
|
* If the token is longer, we do not accept the passed token at all.
|
||||||
*/
|
*/
|
||||||
class ClientTokenValidator extends \yii\validators\RequiredValidator {
|
class ClientTokenValidator extends \yii\validators\RequiredValidator {
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ namespace api\modules\authserver\validators;
|
|||||||
use api\modules\authserver\exceptions\IllegalArgumentException;
|
use api\modules\authserver\exceptions\IllegalArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Для данного модуля нам не принципиально, что там за ошибка: если не хватает хотя бы одного
|
* For this module, it is not important for us what the error is: if at least one parameter is missing,
|
||||||
* параметра - тут же отправляем исключение и дело с концом
|
* we immediately throw an exception and that's it.
|
||||||
*/
|
*/
|
||||||
class RequiredValidator extends \yii\validators\RequiredValidator {
|
class RequiredValidator extends \yii\validators\RequiredValidator {
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@ class ApiController extends Controller {
|
|||||||
->andWhere(['<=', 'applied_in', $at])
|
->andWhere(['<=', 'applied_in', $at])
|
||||||
->one();
|
->one();
|
||||||
|
|
||||||
// Запрос выше находит просто последний случай использования, не учитывая то, что ник
|
// The query above simply finds the latest case of usage, without taking into account the fact
|
||||||
// мог быть сменён с тех пор. Поэтому дополнительно проводим проверку, чтобы ник находился
|
// that the nickname may have been changed since then. Therefore, we additionally check
|
||||||
// в каком-либо периоде (т.е. существовала последующая запись) или последний использовавший
|
// that the nickname is in some period (i.e. there is a subsequent entry) or that the last user
|
||||||
// ник пользователь не сменил его на нечто иное
|
// who used the nickname has not changed it to something else
|
||||||
$account = null;
|
$account = null;
|
||||||
if ($record !== null) {
|
if ($record !== null) {
|
||||||
if ($record->account->username === $record->username || $record->findNext($at) !== null) {
|
if ($record->account->username === $record->username || $record->findNext($at) !== null) {
|
||||||
@ -76,8 +76,8 @@ class ApiController extends Controller {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// У первого элемента не должно быть времени, когда он был применён
|
// The first element shouldn't have time when it was applied.
|
||||||
// Хотя мы в принципе эту инфу знаем. А вот Mojang, вероятно, нет
|
// Although we know this information in fact. But Mojang probably doesn't.
|
||||||
unset($data[0]['changedToAt']);
|
unset($data[0]['changedToAt']);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
@ -32,10 +32,10 @@ class OauthProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запрос, который должен проверить переданные параметры oAuth авторизации
|
* A request that should check the passed OAuth2 authorization params and build a response
|
||||||
* и сформировать ответ для нашего приложения на фронте
|
* for our frontend application.
|
||||||
*
|
*
|
||||||
* Входными данными является стандартный список GET параметров по стандарту oAuth:
|
* The input data is the standard GET parameters list according to the OAuth2 standard:
|
||||||
* $_GET = [
|
* $_GET = [
|
||||||
* client_id,
|
* client_id,
|
||||||
* redirect_uri,
|
* redirect_uri,
|
||||||
@ -44,7 +44,7 @@ class OauthProcess {
|
|||||||
* state,
|
* state,
|
||||||
* ];
|
* ];
|
||||||
*
|
*
|
||||||
* Кроме того можно передать значения description для переопределения описания приложения.
|
* In addition, you can pass the description value to override the application's description.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -67,10 +67,10 @@ class OauthProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод выполняется генерацию авторизационного кода (authorization_code) и формирование
|
* This method generates authorization_code and a link
|
||||||
* ссылки для дальнейшнешл редиректа пользователя назад на сайт клиента
|
* for the user's further redirect to the client's site.
|
||||||
*
|
*
|
||||||
* Входными данными является всё те же параметры, что были необходимы для валидации:
|
* The input data are the same parameters that were necessary for validation request:
|
||||||
* $_GET = [
|
* $_GET = [
|
||||||
* client_id,
|
* client_id,
|
||||||
* redirect_uri,
|
* redirect_uri,
|
||||||
@ -79,9 +79,9 @@ class OauthProcess {
|
|||||||
* state,
|
* state,
|
||||||
* ];
|
* ];
|
||||||
*
|
*
|
||||||
* А также поле accept, которое показывает, что пользователь нажал на кнопку "Принять".
|
* Also, the accept field, which shows that the user has clicked on the "Accept" button.
|
||||||
* Если поле присутствует, то оно будет интерпретироваться как любое приводимое к false значение.
|
* If the field is present, it will be interpreted as any value resulting in false positives.
|
||||||
* В ином случае, значение будет интерпретировано, как положительный исход.
|
* Otherwise, the value will be interpreted as "true".
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -125,9 +125,9 @@ class OauthProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод выполняется сервером приложения, которому был выдан auth_token или refresh_token.
|
* The method is executed by the application server to which auth_token or refresh_token was given.
|
||||||
*
|
*
|
||||||
* Входными данными является стандартный список POST параметров по стандарту oAuth:
|
* Input data is a standard list of POST parameters according to the OAuth2 standard:
|
||||||
* $_POST = [
|
* $_POST = [
|
||||||
* client_id,
|
* client_id,
|
||||||
* client_secret,
|
* client_secret,
|
||||||
@ -135,7 +135,7 @@ class OauthProcess {
|
|||||||
* code,
|
* code,
|
||||||
* grant_type,
|
* grant_type,
|
||||||
* ]
|
* ]
|
||||||
* для запроса grant_type = authentication_code.
|
* for request with grant_type = authentication_code:
|
||||||
* $_POST = [
|
* $_POST = [
|
||||||
* client_id,
|
* client_id,
|
||||||
* client_secret,
|
* client_secret,
|
||||||
@ -170,8 +170,8 @@ class OauthProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод проверяет, может ли текущий пользователь быть автоматически авторизован
|
* The method checks whether the current user can be automatically authorized for the specified client
|
||||||
* для указанного клиента без запроса доступа к необходимому списку прав
|
* without requesting access to the necessary list of scopes
|
||||||
*
|
*
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param OauthClient $client
|
* @param OauthClient $client
|
||||||
@ -206,7 +206,7 @@ class OauthProcess {
|
|||||||
private function buildSuccessResponse(array $queryParams, OauthClient $client, array $scopes): array {
|
private function buildSuccessResponse(array $queryParams, OauthClient $client, array $scopes): array {
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
// Возвращаем только те ключи, которые имеют реальное отношение к oAuth параметрам
|
// We return only those keys which are related to the OAuth2 standard parameters
|
||||||
'oAuth' => array_intersect_key($queryParams, array_flip([
|
'oAuth' => array_intersect_key($queryParams, array_flip([
|
||||||
'client_id',
|
'client_id',
|
||||||
'redirect_uri',
|
'redirect_uri',
|
||||||
|
@ -7,7 +7,7 @@ use yii\web\HttpException;
|
|||||||
class SessionServerException extends HttpException {
|
class SessionServerException extends HttpException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Рефлексия быстрее, как ни странно:
|
* Reflection is faster, weird as it may seem:
|
||||||
* @url https://coderwall.com/p/cpxxxw/php-get-class-name-without-namespace#comment_19313
|
* @url https://coderwall.com/p/cpxxxw/php-get-class-name-without-namespace#comment_19313
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -41,11 +41,10 @@ class LegacyJoin extends BaseJoin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод проводит инициализацию значений полей для соотвествия общим канонам
|
* The method initializes field values to meet the general naming conventions in the project
|
||||||
* именования в проекте
|
|
||||||
*
|
*
|
||||||
* Бьём по ':' для учёта авторизации в современных лаунчерах и входе на более старую
|
* Split by ':' to take into account authorization in modern launchers and login to an legacy version of the game.
|
||||||
* версию игры. Там sessionId передаётся как "token:{accessToken}:{uuid}", так что это нужно обработать
|
* The sessionId is passed on as "token:{accessToken}:{uuid}", so it needs to be processed
|
||||||
*/
|
*/
|
||||||
private function parseSessionId(string $sessionId) {
|
private function parseSessionId(string $sessionId) {
|
||||||
$parts = explode(':', $sessionId);
|
$parts = explode(':', $sessionId);
|
||||||
|
@ -4,8 +4,8 @@ namespace api\modules\session\validators;
|
|||||||
use api\modules\session\exceptions\IllegalArgumentException;
|
use api\modules\session\exceptions\IllegalArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Для данного модуля нам не принципиально, что там за ошибка: если не хватает хотя бы одного
|
* For this module, it is not important for us what the error is: if at least one parameter is missing,
|
||||||
* параметра - тут же отправляем исключение и дело с концом
|
* we immediately throw an exception and that's it.
|
||||||
*/
|
*/
|
||||||
class RequiredValidator extends \yii\validators\RequiredValidator {
|
class RequiredValidator extends \yii\validators\RequiredValidator {
|
||||||
|
|
||||||
|
@ -6,16 +6,15 @@ use yii\web\JsonParser;
|
|||||||
use yii\web\RequestParserInterface;
|
use yii\web\RequestParserInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Т.к. Yii2 не предоставляет возможности сделать fallback для неспаршенного
|
* Since Yii2 doesn't provide an opportunity to make a fallback for an unparsed request,
|
||||||
* request, нужно полностью реимплементировать логику парсинга запроса.
|
* the query parsing logic must be fully reimplemented.
|
||||||
*
|
*
|
||||||
* Код взят из \yii\web\Request::getBodyParams() и вывернут таким образом,
|
* The code is taken from \yii\web\Request::getBodyParams() and reworked in such a way
|
||||||
* чтобы по нисходящей пытаться спарсить запрос:
|
* that it tries to parse the request by the next steps:
|
||||||
* - сначала проверяем, если PHP справился сам, то возвращаем его значение
|
* - first check if PHP has managed to do it by itself, then we return its value;
|
||||||
* - дальше пробуем спарсить JSON, который закодирован в теле
|
* - then we try to parse JSON, which is encoded in the body;
|
||||||
* - если не вышло, то предположим, что это PUT, DELETE или иной другой запрос,
|
* - if it doesn't work out, let's assume it's a PUT, DELETE or other request
|
||||||
* который PHP автоматически не осиливает спарсить, так что пытаемся его спарсить
|
* that PHP doesn't automatically overpower to parse, so we try to parse it ourselves.
|
||||||
* самостоятельно
|
|
||||||
*/
|
*/
|
||||||
class RequestParser implements RequestParserInterface {
|
class RequestParser implements RequestParserInterface {
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class GetCest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testGetInfoWithExpiredToken(FunctionalTester $I) {
|
public function testGetInfoWithExpiredToken(FunctionalTester $I) {
|
||||||
// Устанавливаем заведомо истёкший токен
|
// We're setting up a known expired token
|
||||||
$I->amBearerAuthenticated(
|
$I->amBearerAuthenticated(
|
||||||
'eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjQ2Mjc1NDUsImV4cCI6MTQ2NDYzMTE0NSwic3ViIjoiZWx5fDEiLCJlbHktc' .
|
'eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjQ2Mjc1NDUsImV4cCI6MTQ2NDYzMTE0NSwic3ViIjoiZWx5fDEiLCJlbHktc' .
|
||||||
'2NvcGVzIjoiYWNjb3VudHNfd2ViX3VzZXIifQ.v1u8V5wk2RkWmnZtH3jZvM3zO1Gpgbp2DQFfLfy8jHY'
|
'2NvcGVzIjoiYWNjb3VudHNfd2ViX3VzZXIifQ.v1u8V5wk2RkWmnZtH3jZvM3zO1Gpgbp2DQFfLfy8jHY'
|
||||||
|
@ -55,7 +55,7 @@ class ValidateCest {
|
|||||||
public function expiredAccessToken(AuthserverSteps $I) {
|
public function expiredAccessToken(AuthserverSteps $I) {
|
||||||
$I->wantTo('get error on expired accessToken');
|
$I->wantTo('get error on expired accessToken');
|
||||||
$this->route->validate([
|
$this->route->validate([
|
||||||
// Заведомо истёкший токен из дампа
|
// Knowingly expired token from the dump
|
||||||
'accessToken' => '6042634a-a1e2-4aed-866c-c661fe4e63e2',
|
'accessToken' => '6042634a-a1e2-4aed-866c-c661fe4e63e2',
|
||||||
]);
|
]);
|
||||||
$I->canSeeResponseCodeIs(401);
|
$I->canSeeResponseCodeIs(401);
|
||||||
|
@ -59,7 +59,7 @@ class ClientCredentialsCest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testIssueTokenWithPublicScopes(OauthSteps $I) {
|
public function testIssueTokenWithPublicScopes(OauthSteps $I) {
|
||||||
// TODO: у нас пока нет публичных скоупов, поэтому тест прогоняется с пустым набором
|
// TODO: we don't have any public scopes yet for this grant, so the test runs with an empty set
|
||||||
$this->route->issueToken($this->buildParams(
|
$this->route->issueToken($this->buildParams(
|
||||||
'ely',
|
'ely',
|
||||||
'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
|
'ZuM1vGchJz-9_UZ5HC3H3Z9Hg5PzdbkM',
|
||||||
|
@ -19,7 +19,7 @@ class TestCase extends Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Список фикстур, что будут загружены перед тестом, но после зачистки базы данных
|
* A list of fixtures that will be loaded before the test, but after the database is cleaned up
|
||||||
*
|
*
|
||||||
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
||||||
*
|
*
|
||||||
|
@ -6,13 +6,13 @@ use common\models\EmailActivation;
|
|||||||
use yii\validators\Validator;
|
use yii\validators\Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Валидатор для проверки полученного от пользователя кода активации.
|
* Validator to check the activation code received from the user.
|
||||||
* В случае успешной валидации подменяет значение поля на актуальную модель
|
* In case of success it replaces the field value with the corresponding model.
|
||||||
*/
|
*/
|
||||||
class EmailActivationKeyValidator extends Validator {
|
class EmailActivationKeyValidator extends Validator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int тип ключа. Если не указан, то валидирует по всем ключам.
|
* @var int the type of key. If not specified, it validates over all keys.
|
||||||
*/
|
*/
|
||||||
public $type;
|
public $type;
|
||||||
|
|
||||||
|
@ -17,17 +17,16 @@ class TotpValidator extends Validator {
|
|||||||
public $account;
|
public $account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int|null Задаёт окно, в промежуток которого будет проверяться код.
|
* @var int|null Specifies the window in the interval of which the code will be checked.
|
||||||
* Позволяет избежать ситуации, когда пользователь ввёл код в последнюю секунду
|
* Allows you to avoid the situation when the user entered the code in the last second of its existence
|
||||||
* его существования и пока шёл запрос, тот протух.
|
* and while the request was being sent, it has changed. The value is set in +- periods, not seconds.
|
||||||
* Значение задаётся в +- периодах, а не секундах.
|
|
||||||
*/
|
*/
|
||||||
public $window;
|
public $window;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int|callable|null Позволяет задать точное время, относительно которого будет
|
* @var int|callable|null Allows you to set the exact time against which the validation will be performed.
|
||||||
* выполняться проверка. Это может быть собственно время или функция, возвращающая значение.
|
* It may be the unix time or a function returning a unix time.
|
||||||
* Если не задано, то будет использовано текущее время.
|
* If not specified, the current time will be used.
|
||||||
*/
|
*/
|
||||||
public $timestamp;
|
public $timestamp;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use yii\helpers\ArrayHelper;
|
|||||||
class DataBehavior extends Behavior {
|
class DataBehavior extends Behavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string имя атрибута, к которому будет применяться поведение
|
* @var string attribute name to which this behavior will be applied
|
||||||
*/
|
*/
|
||||||
public $attribute = '_data';
|
public $attribute = '_data';
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ class DataBehavior extends Behavior {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \yii\base\ErrorException Yii2 подхватит Notice от неправильной десериализаци и превратит его
|
* @throws \yii\base\ErrorException Yii2 will catch Notice from the wrong deserialization and turn it
|
||||||
* в свой Exception, благодаря чему программа сможем продолжить нормально работать (вернее ловить Exception)
|
* into its own Exception, so that the program can continue to work normally (you still should catch an Exception)
|
||||||
*/
|
*/
|
||||||
private function getData() {
|
private function getData() {
|
||||||
$data = $this->owner->{$this->attribute};
|
$data = $this->owner->{$this->attribute};
|
||||||
|
@ -9,23 +9,23 @@ use yii\base\Behavior;
|
|||||||
class EmailActivationExpirationBehavior extends Behavior {
|
class EmailActivationExpirationBehavior extends Behavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int количество секунд, прежде чем можно будет повторить отправку кода
|
* @var int the number of seconds before the code can be sent again
|
||||||
* @see EmailActivation::canRepeat()
|
* @see EmailActivation::canRepeat()
|
||||||
*/
|
*/
|
||||||
public $repeatTimeout;
|
public $repeatTimeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int количество секунд, прежде чем это подтверждение истечёт
|
* @var int the number of seconds before this activation expires
|
||||||
* @see EmailActivation::isExpired()
|
* @see EmailActivation::isExpired()
|
||||||
*/
|
*/
|
||||||
public $expirationTimeout;
|
public $expirationTimeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Можно ли повторить отправку письма текущего типа?
|
* Is it allowed to resend a message of the current type?
|
||||||
* Для проверки используется значение EmailActivation::$repeatTimeout и интерпретируется как:
|
* The value of EmailActivation::$repeatTimeout is used for checking as follows:
|
||||||
* - <0 запретит повторную отправку этого кода
|
* - <0 will forbid you to resend this activation
|
||||||
* - =0 позволит отправлять сообщения в любой момент
|
* - =0 allows you to send messages at any time
|
||||||
* - >0 будет проверять, сколько секунд прошло с момента создания модели
|
* - >0 will check how many seconds have passed since the model was created
|
||||||
*
|
*
|
||||||
* @see EmailActivation::compareTime()
|
* @see EmailActivation::compareTime()
|
||||||
* @return bool
|
* @return bool
|
||||||
@ -35,11 +35,11 @@ class EmailActivationExpirationBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Истёк ли срок кода?
|
* Did the code expire?
|
||||||
* Для проверки используется значение EmailActivation::$expirationTimeout и интерпретируется как:
|
* The value of EmailActivation::$expirationTimeout is used for checking as follows:
|
||||||
* - <0 означает, что код никогда не истечёт
|
* - <0 means the code will never expire
|
||||||
* - =0 всегда будет говорить, что код истёк
|
* - =0 will always say that the code has expired
|
||||||
* - >0 будет проверять, сколько секунд прошло с момента создания модели
|
* - >0 will check how many seconds have passed since the model was created
|
||||||
*
|
*
|
||||||
* @see EmailActivation::compareTime()
|
* @see EmailActivation::compareTime()
|
||||||
* @return bool
|
* @return bool
|
||||||
@ -48,25 +48,15 @@ class EmailActivationExpirationBehavior extends Behavior {
|
|||||||
return $this->compareTime($this->expirationTimeout);
|
return $this->compareTime($this->expirationTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Вычисляет, во сколько можно будет выполнить повторную отправку кода
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function canRepeatIn(): int {
|
public function canRepeatIn(): int {
|
||||||
return $this->calculateTime($this->repeatTimeout);
|
return $this->calculateTime($this->repeatTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Вычисляет, во сколько код истечёт
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function expireIn(): int {
|
public function expireIn(): int {
|
||||||
return $this->calculateTime($this->expirationTimeout);
|
return $this->calculateTime($this->expirationTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function compareTime(int $value): bool {
|
private function compareTime(int $value): bool {
|
||||||
if ($value < 0) {
|
if ($value < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -78,7 +68,7 @@ class EmailActivationExpirationBehavior extends Behavior {
|
|||||||
return time() > $this->calculateTime($value);
|
return time() > $this->calculateTime($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function calculateTime(int $value): int {
|
private function calculateTime(int $value): int {
|
||||||
return $this->owner->created_at + $value;
|
return $this->owner->created_at + $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,11 @@ use yii\db\ActiveRecord;
|
|||||||
class PrimaryKeyValueBehavior extends Behavior {
|
class PrimaryKeyValueBehavior extends Behavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var callable Функция, что будет вызвана для генерации ключа.
|
* @var callable The function that will be called to generate the key.
|
||||||
* Должна возвращать случайное значение, подходящее для логики модели. Функция будет вызываться
|
* Must return a random value suitable for model logic.
|
||||||
* в цикле do-while с целью избежания дубликатов строк по первичному ключу, так что если функция
|
* The function will be called in the do-while loop to avoid duplicate strings by the primary key,
|
||||||
* станет возвращать статичное значение, то программа зациклится и что-нибудь здохнет. Не делайте так.
|
* so if the function returns a static value, the program will loop forever and something will die.
|
||||||
|
* Don't do so.
|
||||||
*/
|
*/
|
||||||
public $value;
|
public $value;
|
||||||
|
|
||||||
@ -60,7 +61,6 @@ class PrimaryKeyValueBehavior extends Behavior {
|
|||||||
throw new InvalidConfigException('Current behavior don\'t support models with more then one primary key.');
|
throw new InvalidConfigException('Current behavior don\'t support models with more then one primary key.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection PhpIncompatibleReturnTypeInspection да как бы оно всё нормально, но шторм мне не верит */
|
|
||||||
return $primaryKeys[0];
|
return $primaryKeys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
namespace common\components;
|
namespace common\components;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Этот класс был использован для изначальной генерации паролей на Ely.by и сейчас должен быть планомерно выпилен
|
* This class was used for the first generation of passwords on the Ely.by
|
||||||
* с проекта с целью заменить этот алгоритм каким-нибудь посерьёзнее.
|
* and should now be systematically cut from the project in order to replace this algorithm
|
||||||
|
* with a more secure one.
|
||||||
*/
|
*/
|
||||||
class UserPass {
|
class UserPass {
|
||||||
|
|
||||||
|
@ -24,31 +24,31 @@ class ConfigLoader {
|
|||||||
require __DIR__ . '/config.php',
|
require __DIR__ . '/config.php',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Общие окружение-зависимые настройки
|
// Common env-dependent configuration
|
||||||
$path = __DIR__ . '/config-' . YII_ENV . '.php';
|
$path = __DIR__ . '/config-' . YII_ENV . '.php';
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
$toMerge[] = require $path;
|
$toMerge[] = require $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Общие локальные настройки
|
// Common local configuration
|
||||||
$path = __DIR__ . '/config-local.php';
|
$path = __DIR__ . '/config-local.php';
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
$toMerge[] = require $path;
|
$toMerge[] = require $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Настройки конкретного приложения
|
// App-related base configuration
|
||||||
$path = self::ROOT_PATH . '/' . $this->application . '/config/config.php';
|
$path = self::ROOT_PATH . '/' . $this->application . '/config/config.php';
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
$toMerge[] = require $path;
|
$toMerge[] = require $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Настройки конкретного приложения для действующего окружения
|
// App-related env-dependent configuration
|
||||||
$path = self::ROOT_PATH . '/' . $this->application . '/config/config-' . YII_ENV . '.php';
|
$path = self::ROOT_PATH . '/' . $this->application . '/config/config-' . YII_ENV . '.php';
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
$toMerge[] = require $path;
|
$toMerge[] = require $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Локальные настройки конкретного приложения
|
// App-related local configuration
|
||||||
$path = self::ROOT_PATH . '/' . $this->application . '/config/config-local.php';
|
$path = self::ROOT_PATH . '/' . $this->application . '/config/config-local.php';
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
$toMerge[] = require $path;
|
$toMerge[] = require $path;
|
||||||
|
@ -24,12 +24,6 @@ class StringHelper {
|
|||||||
return $mask . mb_substr($email, $usernameLength);
|
return $mask . mb_substr($email, $usernameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Проверяет на то, что переданная строка является валидным UUID
|
|
||||||
*
|
|
||||||
* @param string $uuid
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isUuid(string $uuid): bool {
|
public static function isUuid(string $uuid): bool {
|
||||||
try {
|
try {
|
||||||
Uuid::fromString($uuid);
|
Uuid::fromString($uuid);
|
||||||
|
@ -13,7 +13,7 @@ use yii\db\ActiveRecord;
|
|||||||
use const common\LATEST_RULES_VERSION;
|
use const common\LATEST_RULES_VERSION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property string $uuid
|
* @property string $uuid
|
||||||
* @property string $username
|
* @property string $username
|
||||||
@ -30,11 +30,11 @@ use const common\LATEST_RULES_VERSION;
|
|||||||
* @property integer $updated_at
|
* @property integer $updated_at
|
||||||
* @property integer $password_changed_at
|
* @property integer $password_changed_at
|
||||||
*
|
*
|
||||||
* Геттеры-сеттеры:
|
* Getters-setters:
|
||||||
* @property string $password пароль пользователя (только для записи)
|
* @property-write string $password plain user's password
|
||||||
* @property string $profileLink ссылка на профиль на Ely без поддержки static url (только для записи)
|
* @property-read string $profileLink link to the user's Ely.by profile
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Relations:
|
||||||
* @property EmailActivation[] $emailActivations
|
* @property EmailActivation[] $emailActivations
|
||||||
* @property OauthSession[] $oauthSessions
|
* @property OauthSession[] $oauthSessions
|
||||||
* @property OauthClient[] $oauthClients
|
* @property OauthClient[] $oauthClients
|
||||||
@ -42,7 +42,7 @@ use const common\LATEST_RULES_VERSION;
|
|||||||
* @property AccountSession[] $sessions
|
* @property AccountSession[] $sessions
|
||||||
* @property MinecraftAccessKey[] $minecraftAccessKeys
|
* @property MinecraftAccessKey[] $minecraftAccessKeys
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
*/
|
*/
|
||||||
class Account extends ActiveRecord {
|
class Account extends ActiveRecord {
|
||||||
@ -113,11 +113,6 @@ class Account extends ActiveRecord {
|
|||||||
return $this->hasMany(MinecraftAccessKey::class, ['account_id' => 'id']);
|
return $this->hasMany(MinecraftAccessKey::class, ['account_id' => 'id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Выполняет проверку, принадлежит ли этому нику аккаунт у Mojang
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasMojangUsernameCollision(): bool {
|
public function hasMojangUsernameCollision(): bool {
|
||||||
return MojangUsername::find()
|
return MojangUsername::find()
|
||||||
->andWhere(['username' => $this->username])
|
->andWhere(['username' => $this->username])
|
||||||
@ -125,9 +120,8 @@ class Account extends ActiveRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Т.к. у нас нет инфы по static_url пользователя, то пока генерируем самый простой вариант
|
* Since we don't have info about the user's static_url, we still generate the simplest
|
||||||
* с ссылкой на профиль по id. На Ely он всё равно редиректнется на static, а мы так или
|
* version with a link to the profile by it's id. On Ely.by, it will be redirected to static url.
|
||||||
* иначе обеспечим отдачу этой инфы.
|
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -136,10 +130,10 @@ class Account extends ActiveRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* При создании структуры БД все аккаунты получают null значение в это поле, однако оно
|
* Initially, the table of users we got from the main site, where there were no rules.
|
||||||
* обязательно для заполнения. Все мигрировавшие с Ely аккаунты будут иметь null значение,
|
* All existing users at the time of migration received an empty value in this field.
|
||||||
* а актуальной версией будет 1 версия правил сайта (т.к. раньше их просто не было). Ну а
|
* They will have to confirm their agreement with the rules at the first login.
|
||||||
* дальше уже будем инкрементить.
|
* All new users automatically agree with the current version of the rules.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
@ -7,7 +7,7 @@ use yii\db\ActiveQuery;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property integer $account_id
|
* @property integer $account_id
|
||||||
* @property string $refresh_token
|
* @property string $refresh_token
|
||||||
@ -15,10 +15,10 @@ use yii\db\ActiveRecord;
|
|||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
* @property integer $last_refreshed_at
|
* @property integer $last_refreshed_at
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Relations:
|
||||||
* @property Account $account
|
* @property Account $account
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
*/
|
*/
|
||||||
class AccountSession extends ActiveRecord {
|
class AccountSession extends ActiveRecord {
|
||||||
|
@ -11,17 +11,17 @@ use yii\db\ActiveRecord;
|
|||||||
use yii\helpers\ArrayHelper;
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property string $key
|
* @property string $key
|
||||||
* @property integer $account_id
|
* @property integer $account_id
|
||||||
* @property integer $type
|
* @property integer $type
|
||||||
* @property string $_data
|
* @property string $_data
|
||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Relations:
|
||||||
* @property Account $account
|
* @property Account $account
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
* @mixin EmailActivationExpirationBehavior
|
* @mixin EmailActivationExpirationBehavior
|
||||||
* @mixin DataBehavior
|
* @mixin DataBehavior
|
||||||
|
@ -8,22 +8,21 @@ use yii\db\ActiveQuery;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Это временный класс, куда мигрирует вся логика ныне существующего authserver.ely.by.
|
* This is a temporary class where all the logic of the authserver.ely.by service.
|
||||||
* Поскольку там допускался вход по логину и паролю, а формат хранения выданных токенов был
|
* Since the login and password were allowed there, and the format of storage of the issued tokens was different,
|
||||||
* иным, то на период, пока мы окончательно не мигрируем, нужно сохранить старую логику
|
* we need to keep the legacy logic and structure under it for the period until we finally migrate.
|
||||||
* и структуру под неё.
|
|
||||||
*
|
*
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property string $access_token
|
* @property string $access_token
|
||||||
* @property string $client_token
|
* @property string $client_token
|
||||||
* @property integer $account_id
|
* @property integer $account_id
|
||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
* @property integer $updated_at
|
* @property integer $updated_at
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Relations:
|
||||||
* @property Account $account
|
* @property Account $account
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
* @mixin PrimaryKeyValueBehavior
|
* @mixin PrimaryKeyValueBehavior
|
||||||
*/
|
*/
|
||||||
|
@ -5,12 +5,12 @@ use yii\behaviors\TimestampBehavior;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property string $username
|
* @property string $username
|
||||||
* @property string $uuid
|
* @property string $uuid
|
||||||
* @property integer $last_pulled_at
|
* @property integer $last_pulled_at
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
*/
|
*/
|
||||||
class MojangUsername extends ActiveRecord {
|
class MojangUsername extends ActiveRecord {
|
||||||
|
@ -7,7 +7,7 @@ use yii\db\ActiveQuery;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property string $id
|
* @property string $id
|
||||||
* @property string $secret
|
* @property string $secret
|
||||||
* @property string $type
|
* @property string $type
|
||||||
@ -21,7 +21,7 @@ use yii\db\ActiveRecord;
|
|||||||
* @property bool $is_deleted
|
* @property bool $is_deleted
|
||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Behaviors:
|
||||||
* @property Account|null $account
|
* @property Account|null $account
|
||||||
* @property OauthSession[] $sessions
|
* @property OauthSession[] $sessions
|
||||||
*/
|
*/
|
||||||
|
@ -4,19 +4,19 @@ namespace common\models;
|
|||||||
final class OauthOwnerType {
|
final class OauthOwnerType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Используется для сессий, принадлежащих непосредственно пользователям account.ely.by,
|
* Used for sessions belonging directly to account.ely.by users
|
||||||
* выполнивших парольную авторизацию и использующих web интерфейс
|
* who have performed password authentication and are using the web interface
|
||||||
*/
|
*/
|
||||||
public const ACCOUNT = 'accounts';
|
public const ACCOUNT = 'accounts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Используется когда пользователь по протоколу oAuth2 authorization_code
|
* Used when a user uses OAuth2 authorization_code protocol to allow an application
|
||||||
* разрешает приложению получить доступ и выполнять действия от своего имени
|
* to access and perform actions on its own behalf
|
||||||
*/
|
*/
|
||||||
public const USER = 'user';
|
public const USER = 'user';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Используется для авторизованных по протоколу oAuth2 client_credentials
|
* Used for clients authorized via OAuth2 client_credentials protocol
|
||||||
*/
|
*/
|
||||||
public const CLIENT = 'client';
|
public const CLIENT = 'client';
|
||||||
|
|
||||||
|
@ -9,15 +9,15 @@ use yii\db\ActiveQuery;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля:
|
* Fields:
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property string $owner_type содержит одну из констант OauthOwnerType
|
* @property string $owner_type contains one of the OauthOwnerType constants
|
||||||
* @property string|null $owner_id
|
* @property string|null $owner_id
|
||||||
* @property string $client_id
|
* @property string $client_id
|
||||||
* @property string $client_redirect_uri
|
* @property string $client_redirect_uri
|
||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
*
|
*
|
||||||
* Отношения
|
* Relations:
|
||||||
* @property OauthClient $client
|
* @property OauthClient $client
|
||||||
* @property Account $account
|
* @property Account $account
|
||||||
* @property Set $scopes
|
* @property Set $scopes
|
||||||
|
@ -5,16 +5,16 @@ use yii\behaviors\TimestampBehavior;
|
|||||||
use yii\db\ActiveRecord;
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поля модели:
|
* Fields:
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property string $username
|
* @property string $username
|
||||||
* @property integer $account_id
|
* @property integer $account_id
|
||||||
* @property integer $applied_in
|
* @property integer $applied_in
|
||||||
*
|
*
|
||||||
* Отношения:
|
* Relations:
|
||||||
* @property Account $account
|
* @property Account $account
|
||||||
*
|
*
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin TimestampBehavior
|
* @mixin TimestampBehavior
|
||||||
*/
|
*/
|
||||||
class UsernameHistory extends ActiveRecord {
|
class UsernameHistory extends ActiveRecord {
|
||||||
|
@ -5,7 +5,7 @@ use common\models\EmailActivation;
|
|||||||
use yii\helpers\ArrayHelper;
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поведения:
|
* Behaviors:
|
||||||
* @mixin NewEmailConfirmationBehavior
|
* @mixin NewEmailConfirmationBehavior
|
||||||
*/
|
*/
|
||||||
class NewEmailConfirmation extends EmailActivation {
|
class NewEmailConfirmation extends EmailActivation {
|
||||||
|
@ -7,12 +7,11 @@ use yii\rbac\PhpManager;
|
|||||||
class Manager extends PhpManager {
|
class Manager extends PhpManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* В нашем приложении права выдаются не пользователям, а токенам, так что ожидаем
|
* In our application the permissions are given not to users but to tokens,
|
||||||
* здесь $accessToken и извлекаем из него все присвоенные права.
|
* so we receive $accessToken here and extract all the assigned scopes from it.
|
||||||
*
|
*
|
||||||
* По каким-то причинам, в Yii механизм рекурсивной проверки прав требует, чтобы
|
* In Yii2, the mechanism of recursive permissions checking requires that the array with permissions
|
||||||
* массив с правами был проиндексирован по ключам этих самых прав, так что в
|
* is indexed by the keys of these rights, so at the end we turn the array inside out.
|
||||||
* конце выворачиваем массив наизнанку.
|
|
||||||
*
|
*
|
||||||
* @param string $accessToken
|
* @param string $accessToken
|
||||||
* @return string[]
|
* @return string[]
|
||||||
|
@ -10,15 +10,15 @@ class AccountOwner extends Rule {
|
|||||||
public $name = 'account_owner';
|
public $name = 'account_owner';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* В нашем приложении права выдаются не пользователям, а токенам, так что ожидаем
|
* In our application the permissions are given not to users but to tokens,
|
||||||
* здесь $accessToken, по которому дальше восстанавливаем аккаунт, если это возможно.
|
* so we receive $accessToken here and extract all the assigned scopes from it.
|
||||||
*
|
*
|
||||||
* @param string|int $accessToken
|
* @param string|int $accessToken
|
||||||
* @param \yii\rbac\Item $item
|
* @param \yii\rbac\Item $item
|
||||||
* @param array $params параметр accountId нужно передать обязательно как id аккаунта,
|
* @param array $params the "accountId" parameter must be passed as the id of the account
|
||||||
* к которому выполняется запрос
|
* to which the request is made
|
||||||
* параметр optionalRules позволяет отключить обязательность
|
* the "optionalRules" parameter allows you to disable the mandatory acceptance
|
||||||
* принятия последней версии правил
|
* of the latest version of the rules
|
||||||
*
|
*
|
||||||
* @return bool a value indicating whether the rule permits the auth item it is associated with.
|
* @return bool a value indicating whether the rule permits the auth item it is associated with.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@ class TestCase extends Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Список фикстур, что будут загружены перед тестом, но после зачистки базы данных
|
* A list of fixtures that will be loaded before the test, but after the database is cleaned up
|
||||||
*
|
*
|
||||||
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
||||||
*
|
*
|
||||||
|
@ -13,8 +13,8 @@ use yii\validators\Validator;
|
|||||||
class EmailValidator extends Validator {
|
class EmailValidator extends Validator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
* @var \Closure the function must return the account id for which the current validation is being performed.
|
||||||
* текущая валидация. Позволяет пропустить проверку email для текущего аккаунта.
|
* Allows you to skip the email check for the current account.
|
||||||
*/
|
*/
|
||||||
public $accountCallback;
|
public $accountCallback;
|
||||||
|
|
||||||
|
@ -4,9 +4,6 @@ namespace common\validators;
|
|||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use yii\validators\StringValidator;
|
use yii\validators\StringValidator;
|
||||||
|
|
||||||
/**
|
|
||||||
* Класс должен реализовывать в себе все критерии валидации пароля пользователя
|
|
||||||
*/
|
|
||||||
class PasswordValidator extends StringValidator {
|
class PasswordValidator extends StringValidator {
|
||||||
|
|
||||||
public $min = 8;
|
public $min = 8;
|
||||||
|
@ -12,8 +12,8 @@ use yii\validators\Validator;
|
|||||||
class UsernameValidator extends Validator {
|
class UsernameValidator extends Validator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
* @var \Closure the function must return the account id for which the current validation is being performed.
|
||||||
* текущая валидация. Позволяет пропустить проверку ника для текущего аккаунта.
|
* Allows you to skip the username check for the current account.
|
||||||
*/
|
*/
|
||||||
public $accountCallback;
|
public $accountCallback;
|
||||||
|
|
||||||
|
@ -43,12 +43,12 @@ class CleanupController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Нужно удалить те сессии, которые не рефрешились 90 дней,
|
* Sessions that have not been refreshed for 90 days and those
|
||||||
* а также сессии, которые ни разу не рефрешились с момента своей выписки
|
* that have not been refreshed since they were issued more than 2 weeks ago
|
||||||
* более чем 2 недели назад.
|
* should be deleted.
|
||||||
*
|
*
|
||||||
* У модели AccountSession нет внешних связей, так что целевые записи
|
* The AccountSession model doesn't have any relations,
|
||||||
* могут быть удалены без использования циклов.
|
* so the records can be deleted just with mass delete operation.
|
||||||
*/
|
*/
|
||||||
public function actionWebSessions(): int {
|
public function actionWebSessions(): int {
|
||||||
AccountSession::deleteAll([
|
AccountSession::deleteAll([
|
||||||
@ -89,8 +89,8 @@ class CleanupController extends Controller {
|
|||||||
/** @var \common\behaviors\EmailActivationExpirationBehavior $behavior */
|
/** @var \common\behaviors\EmailActivationExpirationBehavior $behavior */
|
||||||
$behavior = $object->getBehavior('expirationBehavior');
|
$behavior = $object->getBehavior('expirationBehavior');
|
||||||
/** @noinspection NullPointerExceptionInspection */
|
/** @noinspection NullPointerExceptionInspection */
|
||||||
$expiration = $behavior->expirationTimeout ?? 1123200; // 13d по умолчанию
|
$expiration = $behavior->expirationTimeout ?? 1123200; // 13d by default
|
||||||
// Приращаем 1 день, чтобы пользователи ещё могли получать сообщения об истечении кода активации
|
// We increment 1 day so that users can still receive notifications about the expiry of the activation code
|
||||||
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */
|
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */
|
||||||
$durationsMap[$typeId] = $expiration + 86400;
|
$durationsMap[$typeId] = $expiration + 86400;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class TestCase extends Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Список фикстур, что будут загружены перед тестом, но после зачистки базы данных
|
* A list of fixtures that will be loaded before the test, but after the database is cleaned up
|
||||||
*
|
*
|
||||||
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user