mirror of
https://github.com/elyby/accounts.git
synced 2024-10-01 07:47:16 +05:30
Merge branch 'develop'
This commit is contained in:
commit
d3219ac7b1
@ -2,14 +2,20 @@
|
|||||||
namespace api\components\ReCaptcha;
|
namespace api\components\ReCaptcha;
|
||||||
|
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use GuzzleHttp\Client as GuzzleClient;
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use GuzzleHttp\Exception\ConnectException;
|
||||||
|
use GuzzleHttp\Exception\ServerException;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\Exception;
|
use yii\base\Exception;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\di\Instance;
|
||||||
|
|
||||||
class Validator extends \yii\validators\Validator {
|
class Validator extends \yii\validators\Validator {
|
||||||
|
|
||||||
const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
|
private const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
|
||||||
|
|
||||||
|
private const REPEAT_LIMIT = 3;
|
||||||
|
private const REPEAT_TIMEOUT = 1;
|
||||||
|
|
||||||
public $skipOnEmpty = false;
|
public $skipOnEmpty = false;
|
||||||
|
|
||||||
@ -17,15 +23,21 @@ class Validator extends \yii\validators\Validator {
|
|||||||
|
|
||||||
public $requiredMessage = E::CAPTCHA_REQUIRED;
|
public $requiredMessage = E::CAPTCHA_REQUIRED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Component|string
|
||||||
|
*/
|
||||||
|
public $component = 'reCaptcha';
|
||||||
|
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct(ClientInterface $client, array $config = []) {
|
||||||
|
parent::__construct($config);
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
|
||||||
public function init() {
|
public function init() {
|
||||||
parent::init();
|
parent::init();
|
||||||
if ($this->getComponent() === null) {
|
$this->component = Instance::ensure($this->component, Component::class);
|
||||||
throw new InvalidConfigException('Required "reCaptcha" component as instance of ' . Component::class . '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->when = function() {
|
|
||||||
return !YII_ENV_TEST;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,31 +48,47 @@ class Validator extends \yii\validators\Validator {
|
|||||||
return [$this->requiredMessage, []];
|
return [$this->requiredMessage, []];
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->createClient()->post(self::SITE_VERIFY_URL, [
|
$repeats = 0;
|
||||||
'form_params' => [
|
do {
|
||||||
'secret' => $this->getComponent()->secret,
|
$isSuccess = true;
|
||||||
'response' => $value,
|
try {
|
||||||
'remoteip' => Yii::$app->getRequest()->getUserIP(),
|
$response = $this->performRequest($value);
|
||||||
],
|
} catch (ConnectException | ServerException $e) {
|
||||||
]);
|
if (++$repeats >= self::REPEAT_LIMIT) {
|
||||||
$data = json_decode($response->getBody(), true);
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isSuccess = false;
|
||||||
|
sleep(self::REPEAT_TIMEOUT);
|
||||||
|
}
|
||||||
|
} while (!$isSuccess);
|
||||||
|
|
||||||
|
/** @noinspection PhpUndefinedVariableInspection */
|
||||||
|
$data = json_decode($response->getBody(), true);
|
||||||
if (!isset($data['success'])) {
|
if (!isset($data['success'])) {
|
||||||
throw new Exception('Invalid recaptcha verify response.');
|
throw new Exception('Invalid recaptcha verify response.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data['success'] ? null : [$this->message, []];
|
if (!$data['success']) {
|
||||||
|
return [$this->message, []];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Component
|
* @param string $value
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
|
* @return ResponseInterface
|
||||||
*/
|
*/
|
||||||
protected function getComponent() {
|
protected function performRequest(string $value): ResponseInterface {
|
||||||
return Yii::$app->reCaptcha;
|
return $this->client->request('POST', self::SITE_VERIFY_URL, [
|
||||||
}
|
'form_params' => [
|
||||||
|
'secret' => $this->component->secret,
|
||||||
protected function createClient() {
|
'response' => $value,
|
||||||
return new GuzzleClient();
|
'remoteip' => Yii::$app->getRequest()->getUserIP(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,9 @@ return [
|
|||||||
],
|
],
|
||||||
'request' => [
|
'request' => [
|
||||||
'baseUrl' => '/api',
|
'baseUrl' => '/api',
|
||||||
|
'parsers' => [
|
||||||
|
'*' => api\request\RequestParser::class,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'urlManager' => [
|
'urlManager' => [
|
||||||
'enablePrettyUrl' => true,
|
'enablePrettyUrl' => true,
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @var \common\models\Account $account
|
|
||||||
* @var string $key
|
|
||||||
*/
|
|
||||||
?>
|
|
||||||
|
|
||||||
This E-mail was specified as new for account <?= $account->username ?>. To confirm this E-mail, pass code below into form on site.
|
|
||||||
|
|
||||||
Code: <?= $key ?>
|
|
||||||
|
|
||||||
// P.S. yes, this is E-mail is not designed yet :)
|
|
@ -42,7 +42,7 @@ class FeedbackForm extends ApiForm {
|
|||||||
|
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
/** @var \yii\swiftmailer\Message $message */
|
/** @var \yii\swiftmailer\Message $message */
|
||||||
$message = $mailer->compose('@app/mails/feedback', [
|
$message = $mailer->compose('@common/emails/views/feedback', [
|
||||||
'model' => $this,
|
'model' => $this,
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
]);
|
]);
|
||||||
|
@ -1,26 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\TotpValidator;
|
use api\validators\TotpValidator;
|
||||||
|
use common\emails\EmailHelper;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use api\traits\AccountFinder;
|
use api\traits\AccountFinder;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\confirmations\ForgotPassword;
|
use common\models\confirmations\ForgotPassword;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
use Yii;
|
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\base\InvalidConfigException;
|
|
||||||
|
|
||||||
class ForgotPasswordForm extends ApiForm {
|
class ForgotPasswordForm extends ApiForm {
|
||||||
use AccountFinder;
|
use AccountFinder;
|
||||||
|
|
||||||
|
public $captcha;
|
||||||
|
|
||||||
public $login;
|
public $login;
|
||||||
|
|
||||||
public $token;
|
public $token;
|
||||||
|
|
||||||
public function rules() {
|
public function rules() {
|
||||||
return [
|
return [
|
||||||
|
['captcha', ReCaptchaValidator::class],
|
||||||
['login', 'required', 'message' => E::LOGIN_REQUIRED],
|
['login', 'required', 'message' => E::LOGIN_REQUIRED],
|
||||||
['login', 'validateLogin'],
|
['login', 'validateLogin'],
|
||||||
['token', 'required', 'when' => function(self $model) {
|
['token', 'required', 'when' => function(self $model) {
|
||||||
@ -92,41 +96,11 @@ class ForgotPasswordForm extends ApiForm {
|
|||||||
throw new ErrorException('Cannot create email activation for forgot password form');
|
throw new ErrorException('Cannot create email activation for forgot password form');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sendMail($emailActivation);
|
EmailHelper::forgotPassword($emailActivation);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendMail(EmailActivation $emailActivation) {
|
|
||||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
|
||||||
$mailer = Yii::$app->mailer;
|
|
||||||
$fromEmail = Yii::$app->params['fromEmail'];
|
|
||||||
if (!$fromEmail) {
|
|
||||||
throw new InvalidConfigException('Please specify fromEmail app in app params');
|
|
||||||
}
|
|
||||||
|
|
||||||
$account = $emailActivation->account;
|
|
||||||
$htmlBody = Yii::$app->emailRenderer->getTemplate('forgotPassword')
|
|
||||||
->setLocale($account->lang)
|
|
||||||
->setParams([
|
|
||||||
'username' => $account->username,
|
|
||||||
'code' => $emailActivation->key,
|
|
||||||
'link' => Yii::$app->request->getHostInfo() . '/recover-password/' . $emailActivation->key,
|
|
||||||
])
|
|
||||||
->render();
|
|
||||||
|
|
||||||
/** @var \yii\swiftmailer\Message $message */
|
|
||||||
$message = $mailer->compose()
|
|
||||||
->setHtmlBody($htmlBody)
|
|
||||||
->setTo([$account->email => $account->username])
|
|
||||||
->setFrom([$fromEmail => 'Ely.by Accounts'])
|
|
||||||
->setSubject('Ely.by Account forgot password');
|
|
||||||
|
|
||||||
if (!$message->send()) {
|
|
||||||
throw new ErrorException('Unable send email with activation code.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLogin() {
|
public function getLogin() {
|
||||||
return $this->login;
|
return $this->login;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
|
use common\emails\EmailHelper;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\confirmations\RegistrationConfirmation;
|
use common\models\confirmations\RegistrationConfirmation;
|
||||||
use common\models\EmailActivation;
|
|
||||||
use common\models\UsernameHistory;
|
use common\models\UsernameHistory;
|
||||||
use common\validators\EmailValidator;
|
use common\validators\EmailValidator;
|
||||||
use common\validators\LanguageValidator;
|
use common\validators\LanguageValidator;
|
||||||
@ -17,7 +17,6 @@ use Exception;
|
|||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\base\InvalidConfigException;
|
|
||||||
use yii\helpers\ArrayHelper;
|
use yii\helpers\ArrayHelper;
|
||||||
use const common\LATEST_RULES_VERSION;
|
use const common\LATEST_RULES_VERSION;
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ class RegistrationForm extends ApiForm {
|
|||||||
throw new ErrorException('Cannot save username history record');
|
throw new ErrorException('Cannot save username history record');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sendMail($emailActivation, $account);
|
EmailHelper::registration($emailActivation);
|
||||||
|
|
||||||
$transaction->commit();
|
$transaction->commit();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@ -114,37 +113,6 @@ class RegistrationForm extends ApiForm {
|
|||||||
return $account;
|
return $account;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: подумать, чтобы вынести этот метод в какую-то отдельную конструкцию, т.к. используется и внутри NewAccountActivationForm
|
|
||||||
public function sendMail(EmailActivation $emailActivation, Account $account) {
|
|
||||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
|
||||||
$mailer = Yii::$app->mailer;
|
|
||||||
$fromEmail = Yii::$app->params['fromEmail'];
|
|
||||||
|
|
||||||
if (!$fromEmail) {
|
|
||||||
throw new InvalidConfigException('Please specify fromEmail app in app params');
|
|
||||||
}
|
|
||||||
|
|
||||||
$htmlBody = Yii::$app->emailRenderer->getTemplate('register')
|
|
||||||
->setLocale($account->lang)
|
|
||||||
->setParams([
|
|
||||||
'username' => $account->username,
|
|
||||||
'code' => $emailActivation->key,
|
|
||||||
'link' => Yii::$app->request->getHostInfo() . '/activation/' . $emailActivation->key,
|
|
||||||
])
|
|
||||||
->render();
|
|
||||||
|
|
||||||
/** @var \yii\swiftmailer\Message $message */
|
|
||||||
$message = $mailer->compose()
|
|
||||||
->setHtmlBody($htmlBody)
|
|
||||||
->setTo([$account->email => $account->username])
|
|
||||||
->setFrom([$fromEmail => 'Ely.by Accounts'])
|
|
||||||
->setSubject('Ely.by Account registration');
|
|
||||||
|
|
||||||
if (!$message->send()) {
|
|
||||||
throw new ErrorException('Unable send email with activation code.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается,
|
* Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается,
|
||||||
* что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь
|
* что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
|
use common\emails\EmailHelper;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
@ -72,8 +73,7 @@ class RepeatAccountActivationForm extends ApiForm {
|
|||||||
throw new ErrorException('Unable save email-activation model.');
|
throw new ErrorException('Unable save email-activation model.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$regForm = new RegistrationForm();
|
EmailHelper::registration($activation);
|
||||||
$regForm->sendMail($activation, $account);
|
|
||||||
|
|
||||||
$transaction->commit();
|
$transaction->commit();
|
||||||
} catch (ErrorException $e) {
|
} catch (ErrorException $e) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\models\profile\ChangeEmail;
|
namespace api\models\profile\ChangeEmail;
|
||||||
|
|
||||||
|
use common\emails\EmailHelper;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
@ -10,7 +11,6 @@ use common\models\EmailActivation;
|
|||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\base\Exception;
|
use yii\base\Exception;
|
||||||
use yii\base\InvalidConfigException;
|
|
||||||
|
|
||||||
class InitStateForm extends ApiForm {
|
class InitStateForm extends ApiForm {
|
||||||
|
|
||||||
@ -55,7 +55,8 @@ class InitStateForm extends ApiForm {
|
|||||||
try {
|
try {
|
||||||
$this->removeOldCode();
|
$this->removeOldCode();
|
||||||
$activation = $this->createCode();
|
$activation = $this->createCode();
|
||||||
$this->sendCode($activation);
|
|
||||||
|
EmailHelper::changeEmailConfirmCurrent($activation);
|
||||||
|
|
||||||
$transaction->commit();
|
$transaction->commit();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@ -93,29 +94,6 @@ class InitStateForm extends ApiForm {
|
|||||||
$emailActivation->delete();
|
$emailActivation->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendCode(EmailActivation $code) {
|
|
||||||
$mailer = Yii::$app->mailer;
|
|
||||||
$fromEmail = Yii::$app->params['fromEmail'];
|
|
||||||
if (!$fromEmail) {
|
|
||||||
throw new InvalidConfigException('Please specify fromEmail app in app params');
|
|
||||||
}
|
|
||||||
|
|
||||||
$acceptor = $code->account;
|
|
||||||
$message = $mailer->compose([
|
|
||||||
'html' => '@app/mails/current-email-confirmation-html',
|
|
||||||
'text' => '@app/mails/current-email-confirmation-text',
|
|
||||||
], [
|
|
||||||
'key' => $code->key,
|
|
||||||
])
|
|
||||||
->setTo([$acceptor->email => $acceptor->username])
|
|
||||||
->setFrom([$fromEmail => 'Ely.by Accounts'])
|
|
||||||
->setSubject('Ely.by Account change E-mail confirmation');
|
|
||||||
|
|
||||||
if (!$message->send()) {
|
|
||||||
throw new ErrorException('Unable send email with activation code.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает E-mail активацию, которая использовалась внутри процесса для перехода на следующий шаг.
|
* Возвращает E-mail активацию, которая использовалась внутри процесса для перехода на следующий шаг.
|
||||||
* Метод предназначен для проверки, не слишком ли часто отправляются письма о смене E-mail.
|
* Метод предназначен для проверки, не слишком ли часто отправляются письма о смене E-mail.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\models\profile\ChangeEmail;
|
namespace api\models\profile\ChangeEmail;
|
||||||
|
|
||||||
|
use common\emails\EmailHelper;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\EmailActivationKeyValidator;
|
use api\validators\EmailActivationKeyValidator;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
@ -9,7 +10,6 @@ use common\models\EmailActivation;
|
|||||||
use common\validators\EmailValidator;
|
use common\validators\EmailValidator;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\base\InvalidConfigException;
|
|
||||||
|
|
||||||
class NewEmailForm extends ApiForm {
|
class NewEmailForm extends ApiForm {
|
||||||
|
|
||||||
@ -45,7 +45,8 @@ class NewEmailForm extends ApiForm {
|
|||||||
$previousActivation->delete();
|
$previousActivation->delete();
|
||||||
|
|
||||||
$activation = $this->createCode();
|
$activation = $this->createCode();
|
||||||
$this->sendCode($activation);
|
|
||||||
|
EmailHelper::changeEmailConfirmNew($activation);
|
||||||
|
|
||||||
$transaction->commit();
|
$transaction->commit();
|
||||||
|
|
||||||
@ -67,32 +68,6 @@ class NewEmailForm extends ApiForm {
|
|||||||
return $emailActivation;
|
return $emailActivation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendCode(EmailActivation $code) {
|
|
||||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
|
||||||
$mailer = Yii::$app->mailer;
|
|
||||||
$fromEmail = Yii::$app->params['fromEmail'];
|
|
||||||
if (!$fromEmail) {
|
|
||||||
throw new InvalidConfigException('Please specify fromEmail app in app params');
|
|
||||||
}
|
|
||||||
|
|
||||||
$acceptor = $code->account;
|
|
||||||
/** @var \yii\swiftmailer\Message $message */
|
|
||||||
$message = $mailer->compose([
|
|
||||||
'html' => '@app/mails/new-email-confirmation-html',
|
|
||||||
'text' => '@app/mails/new-email-confirmation-text',
|
|
||||||
], [
|
|
||||||
'key' => $code->key,
|
|
||||||
'account' => $acceptor,
|
|
||||||
])
|
|
||||||
->setTo([$this->email => $acceptor->username])
|
|
||||||
->setFrom([$fromEmail => 'Ely.by Accounts'])
|
|
||||||
->setSubject('Ely.by Account new E-mail confirmation');
|
|
||||||
|
|
||||||
if (!$message->send()) {
|
|
||||||
throw new ErrorException('Unable send email with activation code.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct(Account $account, array $config = []) {
|
public function __construct(Account $account, array $config = []) {
|
||||||
$this->account = $account;
|
$this->account = $account;
|
||||||
parent::__construct($config);
|
parent::__construct($config);
|
||||||
|
@ -3,6 +3,7 @@ namespace api\modules\authserver\controllers;
|
|||||||
|
|
||||||
use api\controllers\Controller;
|
use api\controllers\Controller;
|
||||||
use api\modules\authserver\models;
|
use api\modules\authserver\models;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
class AuthenticationController extends Controller {
|
class AuthenticationController extends Controller {
|
||||||
|
|
||||||
@ -25,21 +26,21 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionAuthenticate() {
|
public function actionAuthenticate() {
|
||||||
$model = new models\AuthenticationForm();
|
$model = new models\AuthenticationForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
|
|
||||||
return $model->authenticate()->getResponseData(true);
|
return $model->authenticate()->getResponseData(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionRefresh() {
|
public function actionRefresh() {
|
||||||
$model = new models\RefreshTokenForm();
|
$model = new models\RefreshTokenForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
|
|
||||||
return $model->refresh()->getResponseData(false);
|
return $model->refresh()->getResponseData(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionValidate() {
|
public function actionValidate() {
|
||||||
$model = new models\ValidateForm();
|
$model = new models\ValidateForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->validateToken();
|
$model->validateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
@ -47,7 +48,7 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionSignout() {
|
public function actionSignout() {
|
||||||
$model = new models\SignoutForm();
|
$model = new models\SignoutForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->signout();
|
$model->signout();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
@ -55,7 +56,7 @@ class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
public function actionInvalidate() {
|
public function actionInvalidate() {
|
||||||
$model = new models\InvalidateForm();
|
$model = new models\InvalidateForm();
|
||||||
$model->loadByPost();
|
$model->load(Yii::$app->request->post());
|
||||||
$model->invalidateToken();
|
$model->invalidateToken();
|
||||||
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
// В случае успеха ожидается пустой ответ. В случае ошибки же бросается исключение,
|
||||||
// которое обработает ErrorHandler
|
// которое обработает ErrorHandler
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
use api\models\authentication\LoginForm;
|
use api\models\authentication\LoginForm;
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\Module as Authserver;
|
use api\modules\authserver\Module as Authserver;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
@ -9,7 +10,7 @@ use common\helpers\Error as E;
|
|||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class AuthenticationForm extends Form {
|
class AuthenticationForm extends ApiForm {
|
||||||
|
|
||||||
public $username;
|
public $username;
|
||||||
public $password;
|
public $password;
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace api\modules\authserver\models;
|
|
||||||
|
|
||||||
use Yii;
|
|
||||||
use yii\base\Model;
|
|
||||||
|
|
||||||
abstract class Form extends Model {
|
|
||||||
|
|
||||||
public function formName() {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadByGet() {
|
|
||||||
return $this->load(Yii::$app->request->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadByPost() {
|
|
||||||
$data = Yii::$app->request->post();
|
|
||||||
if (empty($data)) {
|
|
||||||
// TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там
|
|
||||||
$data = json_decode(Yii::$app->request->getRawBody(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->load($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class InvalidateForm extends Form {
|
class InvalidateForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
public $clientToken;
|
public $clientToken;
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class RefreshTokenForm extends Form {
|
class RefreshTokenForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
public $clientToken;
|
public $clientToken;
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
use api\models\authentication\LoginForm;
|
use api\models\authentication\LoginForm;
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
class SignoutForm extends Form {
|
class SignoutForm extends ApiForm {
|
||||||
|
|
||||||
public $username;
|
public $username;
|
||||||
public $password;
|
public $password;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\authserver\models;
|
namespace api\modules\authserver\models;
|
||||||
|
|
||||||
|
use api\models\base\ApiForm;
|
||||||
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
use api\modules\authserver\exceptions\ForbiddenOperationException;
|
||||||
use api\modules\authserver\validators\RequiredValidator;
|
use api\modules\authserver\validators\RequiredValidator;
|
||||||
use common\models\MinecraftAccessKey;
|
use common\models\MinecraftAccessKey;
|
||||||
|
|
||||||
class ValidateForm extends Form {
|
class ValidateForm extends ApiForm {
|
||||||
|
|
||||||
public $accessToken;
|
public $accessToken;
|
||||||
|
|
||||||
|
@ -86,10 +86,7 @@ class ApiController extends Controller {
|
|||||||
public function actionUuidsByUsernames() {
|
public function actionUuidsByUsernames() {
|
||||||
$usernames = Yii::$app->request->post();
|
$usernames = Yii::$app->request->post();
|
||||||
if (empty($usernames)) {
|
if (empty($usernames)) {
|
||||||
$usernames = json_decode(Yii::$app->request->getRawBody());
|
return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.');
|
||||||
if (empty($usernames)) {
|
|
||||||
return $this->illegalArgumentResponse('Passed array of profile names is an invalid JSON string.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$usernames = array_unique($usernames);
|
$usernames = array_unique($usernames);
|
||||||
|
@ -35,11 +35,6 @@ class SessionController extends ApiController {
|
|||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
$data = Yii::$app->request->post();
|
$data = Yii::$app->request->post();
|
||||||
if (empty($data)) {
|
|
||||||
// TODO: помнится у Yii2 есть механизм парсинга данных входящего запроса. Лучше будет сделать это там
|
|
||||||
$data = json_decode(Yii::$app->request->getRawBody(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$protocol = new ModernJoin($data['accessToken'] ?? '', $data['selectedProfile'] ?? '', $data['serverId'] ?? '');
|
$protocol = new ModernJoin($data['accessToken'] ?? '', $data['selectedProfile'] ?? '', $data['serverId'] ?? '');
|
||||||
$joinForm = new JoinForm($protocol);
|
$joinForm = new JoinForm($protocol);
|
||||||
$joinForm->join();
|
$joinForm->join();
|
||||||
|
43
api/request/RequestParser.php
Normal file
43
api/request/RequestParser.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
namespace api\request;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use yii\web\JsonParser;
|
||||||
|
use yii\web\RequestParserInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Т.к. Yii2 не предоставляет возможности сделать fallback для неспаршенного
|
||||||
|
* request, нужно полностью реимплементировать логику парсинга запроса.
|
||||||
|
*
|
||||||
|
* Код взят из \yii\web\Request::getBodyParams() и вывернут таким образом,
|
||||||
|
* чтобы по нисходящей пытаться спарсить запрос:
|
||||||
|
* - сначала проверяем, если PHP справился сам, то возвращаем его значение
|
||||||
|
* - дальше пробуем спарсить JSON, который закодирован в теле
|
||||||
|
* - если не вышло, то предположим, что это PUT, DELETE или иной другой запрос,
|
||||||
|
* который PHP автоматически не осиливает спарсить, так что пытаемся его спарсить
|
||||||
|
* самостоятельно
|
||||||
|
*/
|
||||||
|
class RequestParser implements RequestParserInterface {
|
||||||
|
|
||||||
|
public function parse($rawBody, $contentType) {
|
||||||
|
if (!empty($_POST)) {
|
||||||
|
return $_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var JsonParser $parser */
|
||||||
|
$parser = Yii::createObject(JsonParser::class);
|
||||||
|
$parser->throwException = false;
|
||||||
|
$result = $parser->parse($rawBody, $contentType);
|
||||||
|
if (!empty($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
mb_parse_str($rawBody, $bodyParams);
|
||||||
|
if (!empty($bodyParams)) {
|
||||||
|
return $bodyParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
'version' => '1.1.12',
|
'version' => '1.1.13',
|
||||||
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
|
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
|
||||||
'components' => [
|
'components' => [
|
||||||
'cache' => [
|
'cache' => [
|
||||||
|
56
common/emails/EmailHelper.php
Normal file
56
common/emails/EmailHelper.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails;
|
||||||
|
|
||||||
|
use common\emails\templates\ChangeEmailConfirmCurrentEmail;
|
||||||
|
use common\emails\templates\ChangeEmailConfirmNewEmail;
|
||||||
|
use common\emails\templates\ForgotPasswordEmail;
|
||||||
|
use common\emails\templates\ForgotPasswordParams;
|
||||||
|
use common\emails\templates\RegistrationEmail;
|
||||||
|
use common\emails\templates\RegistrationEmailParams;
|
||||||
|
use common\models\Account;
|
||||||
|
use common\models\confirmations\CurrentEmailConfirmation;
|
||||||
|
use common\models\confirmations\ForgotPassword;
|
||||||
|
use common\models\confirmations\NewEmailConfirmation;
|
||||||
|
use common\models\confirmations\RegistrationConfirmation;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
class EmailHelper {
|
||||||
|
|
||||||
|
public static function registration(RegistrationConfirmation $emailActivation): void {
|
||||||
|
$account = $emailActivation->account;
|
||||||
|
$locale = $account->lang;
|
||||||
|
$params = new RegistrationEmailParams(
|
||||||
|
$account->username,
|
||||||
|
$emailActivation->key,
|
||||||
|
Yii::$app->request->getHostInfo() . '/activation/' . $emailActivation->key
|
||||||
|
);
|
||||||
|
|
||||||
|
(new RegistrationEmail(self::buildTo($account), $locale, $params))->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forgotPassword(ForgotPassword $emailActivation): void {
|
||||||
|
$account = $emailActivation->account;
|
||||||
|
$locale = $account->lang;
|
||||||
|
$params = new ForgotPasswordParams(
|
||||||
|
$account->username,
|
||||||
|
$emailActivation->key,
|
||||||
|
Yii::$app->request->getHostInfo() . '/recover-password/' . $emailActivation->key
|
||||||
|
);
|
||||||
|
|
||||||
|
(new ForgotPasswordEmail(self::buildTo($account), $locale, $params))->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function changeEmailConfirmCurrent(CurrentEmailConfirmation $emailActivation): void {
|
||||||
|
(new ChangeEmailConfirmCurrentEmail(self::buildTo($emailActivation->account), $emailActivation->key))->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function changeEmailConfirmNew(NewEmailConfirmation $emailActivation): void {
|
||||||
|
$account = $emailActivation->account;
|
||||||
|
(new ChangeEmailConfirmNewEmail(self::buildTo($account), $account->username, $emailActivation->key))->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function buildTo(Account $account): array {
|
||||||
|
return [$account->email => $account->username];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
79
common/emails/Template.php
Normal file
79
common/emails/Template.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails;
|
||||||
|
|
||||||
|
use common\emails\exceptions\CannotSendEmailException;
|
||||||
|
use Yii;
|
||||||
|
use yii\base\InvalidConfigException;
|
||||||
|
use yii\mail\MailerInterface;
|
||||||
|
use yii\mail\MessageInterface;
|
||||||
|
|
||||||
|
abstract class Template {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \yii\swiftmailer\Mailer
|
||||||
|
*/
|
||||||
|
private $mailer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|array
|
||||||
|
*/
|
||||||
|
private $to;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array $to получатель письма. Задаётся как Email или как массив [email => name]
|
||||||
|
*/
|
||||||
|
public function __construct($to) {
|
||||||
|
$this->mailer = Yii::$app->mailer;
|
||||||
|
$this->to = $to;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
public function getTo() {
|
||||||
|
return $this->to;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function getSubject(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|string
|
||||||
|
* @throws InvalidConfigException
|
||||||
|
*/
|
||||||
|
public function getFrom() {
|
||||||
|
$fromEmail = Yii::$app->params['fromEmail'];
|
||||||
|
if (!$fromEmail) {
|
||||||
|
throw new InvalidConfigException('Please specify fromEmail app in app params');
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$fromEmail => 'Ely.by Accounts'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams(): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMailer(): MailerInterface {
|
||||||
|
return $this->mailer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send(): void {
|
||||||
|
if (!$this->createMessage()->send()) {
|
||||||
|
throw new CannotSendEmailException('Unable send email.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|array
|
||||||
|
*/
|
||||||
|
abstract protected function getView();
|
||||||
|
|
||||||
|
protected function createMessage(): MessageInterface {
|
||||||
|
return $this->getMailer()
|
||||||
|
->compose($this->getView(), $this->getParams())
|
||||||
|
->setTo($this->getTo())
|
||||||
|
->setFrom($this->getFrom())
|
||||||
|
->setSubject($this->getSubject());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
common/emails/TemplateWithRenderer.php
Normal file
66
common/emails/TemplateWithRenderer.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails;
|
||||||
|
|
||||||
|
use common\components\EmailRenderer;
|
||||||
|
use Yii;
|
||||||
|
use yii\mail\MessageInterface;
|
||||||
|
|
||||||
|
abstract class TemplateWithRenderer extends Template {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EmailRenderer
|
||||||
|
*/
|
||||||
|
private $emailRenderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct($to, string $locale) {
|
||||||
|
parent::__construct($to);
|
||||||
|
$this->emailRenderer = Yii::$app->emailRenderer;
|
||||||
|
$this->locale = $locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocale(): string {
|
||||||
|
return $this->locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEmailRenderer(): EmailRenderer {
|
||||||
|
return $this->emailRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод должен возвращать имя шаблона, который должен быть использован.
|
||||||
|
* Имена можно взять в репозитории elyby/email-renderer
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function getTemplateName(): string;
|
||||||
|
|
||||||
|
protected final function getView() {
|
||||||
|
return $this->getTemplateName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createMessage(): MessageInterface {
|
||||||
|
return $this->getMailer()
|
||||||
|
->compose()
|
||||||
|
->setHtmlBody($this->render())
|
||||||
|
->setTo($this->getTo())
|
||||||
|
->setFrom($this->getFrom())
|
||||||
|
->setSubject($this->getSubject());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function render(): string {
|
||||||
|
return $this->getEmailRenderer()
|
||||||
|
->getTemplate($this->getTemplateName())
|
||||||
|
->setLocale($this->getLocale())
|
||||||
|
->setParams($this->getParams())
|
||||||
|
->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
common/emails/exceptions/CannotSendEmailException.php
Normal file
8
common/emails/exceptions/CannotSendEmailException.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class CannotSendEmailException extends Exception {
|
||||||
|
|
||||||
|
}
|
35
common/emails/templates/ChangeEmailConfirmCurrentEmail.php
Normal file
35
common/emails/templates/ChangeEmailConfirmCurrentEmail.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
use common\emails\Template;
|
||||||
|
|
||||||
|
class ChangeEmailConfirmCurrentEmail extends Template {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function __construct($to, string $key) {
|
||||||
|
parent::__construct($to);
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubject(): string {
|
||||||
|
return 'Ely.by Account change E-mail confirmation';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|array
|
||||||
|
*/
|
||||||
|
protected function getView() {
|
||||||
|
return [
|
||||||
|
'html' => '@common/emails/views/current-email-confirmation-html',
|
||||||
|
'text' => '@common/emails/views/current-email-confirmation-text',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams(): array {
|
||||||
|
return [
|
||||||
|
'key' => $this->key,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
common/emails/templates/ChangeEmailConfirmNewEmail.php
Normal file
39
common/emails/templates/ChangeEmailConfirmNewEmail.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
use common\emails\Template;
|
||||||
|
|
||||||
|
class ChangeEmailConfirmNewEmail extends Template {
|
||||||
|
|
||||||
|
private $username;
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function __construct($to, string $username, string $key) {
|
||||||
|
parent::__construct($to);
|
||||||
|
$this->username = $username;
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubject(): string {
|
||||||
|
return 'Ely.by Account new E-mail confirmation';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|array
|
||||||
|
*/
|
||||||
|
protected function getView() {
|
||||||
|
return [
|
||||||
|
'html' => '@common/emails/views/new-email-confirmation-html',
|
||||||
|
'text' => '@common/emails/views/new-email-confirmation-text',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams(): array {
|
||||||
|
return [
|
||||||
|
'key' => $this->key,
|
||||||
|
'username' => $this->username,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
common/emails/templates/ForgotPasswordEmail.php
Normal file
34
common/emails/templates/ForgotPasswordEmail.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
use common\emails\TemplateWithRenderer;
|
||||||
|
|
||||||
|
class ForgotPasswordEmail extends TemplateWithRenderer {
|
||||||
|
|
||||||
|
private $params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct($to, string $locale, ForgotPasswordParams $params) {
|
||||||
|
TemplateWithRenderer::__construct($to, $locale);
|
||||||
|
$this->params = $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubject(): string {
|
||||||
|
return 'Ely.by Account forgot password';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplateName(): string {
|
||||||
|
return 'forgotPassword';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams(): array {
|
||||||
|
return [
|
||||||
|
'username' => $this->params->getUsername(),
|
||||||
|
'code' => $this->params->getCode(),
|
||||||
|
'link' => $this->params->getLink(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
common/emails/templates/ForgotPasswordParams.php
Normal file
30
common/emails/templates/ForgotPasswordParams.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
class ForgotPasswordParams {
|
||||||
|
|
||||||
|
private $username;
|
||||||
|
|
||||||
|
private $code;
|
||||||
|
|
||||||
|
private $link;
|
||||||
|
|
||||||
|
public function __construct(string $username, string $code, string $link) {
|
||||||
|
$this->username = $username;
|
||||||
|
$this->code = $code;
|
||||||
|
$this->link = $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsername(): string {
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): string {
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLink(): string {
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
common/emails/templates/RegistrationEmail.php
Normal file
34
common/emails/templates/RegistrationEmail.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
use common\emails\TemplateWithRenderer;
|
||||||
|
|
||||||
|
class RegistrationEmail extends TemplateWithRenderer {
|
||||||
|
|
||||||
|
private $params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct($to, string $locale, RegistrationEmailParams $params) {
|
||||||
|
TemplateWithRenderer::__construct($to, $locale);
|
||||||
|
$this->params = $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubject(): string {
|
||||||
|
return 'Ely.by Account registration';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplateName(): string {
|
||||||
|
return 'register';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams(): array {
|
||||||
|
return [
|
||||||
|
'username' => $this->params->getUsername(),
|
||||||
|
'code' => $this->params->getCode(),
|
||||||
|
'link' => $this->params->getLink(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
common/emails/templates/RegistrationEmailParams.php
Normal file
30
common/emails/templates/RegistrationEmailParams.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\emails\templates;
|
||||||
|
|
||||||
|
class RegistrationEmailParams {
|
||||||
|
|
||||||
|
private $username;
|
||||||
|
|
||||||
|
private $code;
|
||||||
|
|
||||||
|
private $link;
|
||||||
|
|
||||||
|
public function __construct(string $username, string $code, string $link) {
|
||||||
|
$this->username = $username;
|
||||||
|
$this->code = $code;
|
||||||
|
$this->link = $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsername(): string {
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): string {
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLink(): string {
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @var \common\models\Account $account
|
* @var string $username
|
||||||
* @var string $key
|
* @var string $key
|
||||||
*/
|
*/
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This E-mail was specified as new for account <?= $account->username ?>. To confirm this E-mail, pass code
|
This E-mail was specified as new for account <?= $username ?>. To confirm this E-mail, pass code
|
||||||
below into form on site.
|
below into form on site.
|
||||||
</p>
|
</p>
|
||||||
<p>Code: <?= $key ?></p>
|
<p>Code: <?= $key ?></p>
|
12
common/emails/views/new-email-confirmation-text.php
Normal file
12
common/emails/views/new-email-confirmation-text.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @var string $username
|
||||||
|
* @var string $key
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
|
||||||
|
This E-mail was specified as new for account <?= $username ?>. To confirm this E-mail, pass code below into form on site.
|
||||||
|
|
||||||
|
Code: <?= $key ?>
|
||||||
|
|
||||||
|
// P.S. yes, this is E-mail is not designed yet :)
|
@ -25,7 +25,7 @@
|
|||||||
"ely/yii2-tempmail-validator": "~1.0.0",
|
"ely/yii2-tempmail-validator": "~1.0.0",
|
||||||
"emarref/jwt": "~1.0.3",
|
"emarref/jwt": "~1.0.3",
|
||||||
"ely/amqp-controller": "dev-master#d7f8cdbc66c45e477c9c7d5d509bc0c1b11fd3ec",
|
"ely/amqp-controller": "dev-master#d7f8cdbc66c45e477c9c7d5d509bc0c1b11fd3ec",
|
||||||
"ely/email-renderer": "dev-master#d66ec82d2ebae59986ad5e009ae0c951d1cfcccb",
|
"ely/email-renderer": "dev-master#ecc044a00c87059be54bfbd0ed3b516383e3dcd5",
|
||||||
"predis/predis": "^1.0",
|
"predis/predis": "^1.0",
|
||||||
"mito/yii2-sentry": "^1.0",
|
"mito/yii2-sentry": "^1.0",
|
||||||
"minime/annotations": "~3.0",
|
"minime/annotations": "~3.0",
|
||||||
@ -37,10 +37,13 @@
|
|||||||
"yiisoft/yii2-debug": "*",
|
"yiisoft/yii2-debug": "*",
|
||||||
"yiisoft/yii2-faker": "*",
|
"yiisoft/yii2-faker": "*",
|
||||||
"flow/jsonpath": "^0.3.1",
|
"flow/jsonpath": "^0.3.1",
|
||||||
"codeception/codeception": "~2.2.4",
|
"phpunit/phpunit": "^5.7",
|
||||||
|
"codeception/codeception": "~2.3",
|
||||||
"codeception/specify": "*",
|
"codeception/specify": "*",
|
||||||
"codeception/verify": "*",
|
"codeception/verify": "*",
|
||||||
"phploc/phploc": "^3.0.1"
|
"phploc/phploc": "^3.0.1",
|
||||||
|
"mockery/mockery": "1.0.0-alpha1",
|
||||||
|
"php-mock/php-mock-mockery": "dev-mockery-1.0.0#03956ed4b34ae25bc20a0677500f4f4b416f976c"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"process-timeout": 1800
|
"process-timeout": 1800
|
||||||
@ -61,6 +64,10 @@
|
|||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@gitlab.ely.by:elyby/oauth2-server.git"
|
"url": "git@gitlab.ely.by:elyby/oauth2-server.git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:erickskrauch/php-mock-mockery.git"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -12,8 +12,9 @@ modules:
|
|||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/api/functional.php'
|
configFile: '../config/api/functional.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
Redis:
|
Redis:
|
||||||
host: "%REDIS_HOST%"
|
host: "%REDIS_HOST%"
|
||||||
port: 6379
|
port: 6379
|
||||||
database: 0
|
database: 0
|
||||||
|
cleanupBefore: 'test'
|
||||||
|
@ -38,6 +38,17 @@ class AuthorizationCest {
|
|||||||
$this->testSuccessResponse($I);
|
$this->testSuccessResponse($I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function byNamePassedViaPOSTBody(FunctionalTester $I) {
|
||||||
|
$I->wantTo('authenticate by username and password sent via post body');
|
||||||
|
$this->route->authenticate(json_encode([
|
||||||
|
'username' => 'admin',
|
||||||
|
'password' => 'password_0',
|
||||||
|
'clientToken' => Uuid::uuid4()->toString(),
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->testSuccessResponse($I);
|
||||||
|
}
|
||||||
|
|
||||||
public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) {
|
public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) {
|
||||||
$I->wantTo('get valid error by authenticate account with enabled two factor auth');
|
$I->wantTo('get valid error by authenticate account with enabled two factor auth');
|
||||||
$this->route->authenticate([
|
$this->route->authenticate([
|
||||||
|
@ -98,17 +98,6 @@ class UsernamesToUuidsCest {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function passWrongPostBody(FunctionalTester $I) {
|
|
||||||
$I->wantTo('get specific response when pass invalid json string');
|
|
||||||
$this->route->uuidsByUsernames('wrong-json');
|
|
||||||
$I->canSeeResponseCodeIs(400);
|
|
||||||
$I->canSeeResponseIsJson();
|
|
||||||
$I->canSeeResponseContainsJson([
|
|
||||||
'error' => 'IllegalArgumentException',
|
|
||||||
'errorMessage' => 'Passed array of profile names is an invalid JSON string.',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function validateFewValidUsernames(FunctionalTester $I) {
|
private function validateFewValidUsernames(FunctionalTester $I) {
|
||||||
$I->canSeeResponseCodeIs(200);
|
$I->canSeeResponseCodeIs(200);
|
||||||
$I->canSeeResponseIsJson();
|
$I->canSeeResponseIsJson();
|
||||||
|
@ -4,7 +4,8 @@ modules:
|
|||||||
- Yii2:
|
- Yii2:
|
||||||
part: [orm, email, fixtures]
|
part: [orm, email, fixtures]
|
||||||
- tests\codeception\common\_support\amqp\Helper
|
- tests\codeception\common\_support\amqp\Helper
|
||||||
|
- tests\codeception\common\_support\Mockery
|
||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/api/unit.php'
|
configFile: '../config/api/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace tests\codeception\api\unit;
|
namespace tests\codeception\api\unit;
|
||||||
|
|
||||||
|
use Mockery;
|
||||||
|
|
||||||
class TestCase extends \Codeception\Test\Unit {
|
class TestCase extends \Codeception\Test\Unit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,4 +21,9 @@ class TestCase extends \Codeception\Test\Unit {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
Mockery::close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,64 +2,73 @@
|
|||||||
namespace codeception\api\unit\components\ReCaptcha;
|
namespace codeception\api\unit\components\ReCaptcha;
|
||||||
|
|
||||||
use api\components\ReCaptcha\Validator;
|
use api\components\ReCaptcha\Validator;
|
||||||
use Codeception\Specify;
|
use GuzzleHttp\ClientInterface;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Exception\ConnectException;
|
||||||
use GuzzleHttp\Handler\MockHandler;
|
|
||||||
use GuzzleHttp\HandlerStack;
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
use GuzzleHttp\Psr7\Response;
|
||||||
|
use phpmock\mockery\PHPMockery;
|
||||||
|
use ReflectionClass;
|
||||||
use tests\codeception\api\unit\TestCase;
|
use tests\codeception\api\unit\TestCase;
|
||||||
|
|
||||||
class ValidatorTest extends TestCase {
|
class ValidatorTest extends TestCase {
|
||||||
use Specify;
|
|
||||||
|
|
||||||
public function testValidateValue() {
|
public function testValidateEmptyValue() {
|
||||||
$this->specify('Get error.captcha_required, if passed empty value', function() {
|
$validator = new Validator(mock(ClientInterface::class));
|
||||||
$validator = new Validator();
|
$this->assertFalse($validator->validate('', $error));
|
||||||
expect($validator->validate('', $error))->false();
|
$this->assertEquals('error.captcha_required', $error, 'Get error.captcha_required, if passed empty value');
|
||||||
expect($error)->equals('error.captcha_required');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('Get error.captcha_invalid, if passed wrong value', function() {
|
|
||||||
/** @var \PHPUnit_Framework_MockObject_MockObject|Validator $validator */
|
|
||||||
$validator = $this->getMockBuilder(Validator::class)
|
|
||||||
->setMethods(['createClient'])
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$validator->expects($this->once())
|
|
||||||
->method('createClient')
|
|
||||||
->will($this->returnValue($this->createMockGuzzleClient([
|
|
||||||
'success' => false,
|
|
||||||
'error-codes' => [
|
|
||||||
'invalid-input-response', // The response parameter is invalid or malformed.
|
|
||||||
],
|
|
||||||
])));
|
|
||||||
|
|
||||||
expect($validator->validate('12341234', $error))->false();
|
|
||||||
expect($error)->equals('error.captcha_invalid');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('Get error.captcha_invalid, if passed wrong value', function() {
|
|
||||||
/** @var \PHPUnit_Framework_MockObject_MockObject|Validator $validator */
|
|
||||||
$validator = $this->getMockBuilder(Validator::class)
|
|
||||||
->setMethods(['createClient'])
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$validator->expects($this->once())
|
|
||||||
->method('createClient')
|
|
||||||
->will($this->returnValue($this->createMockGuzzleClient(['success' => true])));
|
|
||||||
|
|
||||||
expect($validator->validate('12341234', $error))->true();
|
|
||||||
expect($error)->null();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createMockGuzzleClient(array $response) {
|
public function testValidateInvalidValue() {
|
||||||
$mock = new MockHandler([
|
$mockClient = mock(ClientInterface::class);
|
||||||
new Response(200, [], json_encode($response)),
|
$mockClient->shouldReceive('request')->andReturn(new Response(200, [], json_encode([
|
||||||
]);
|
'success' => false,
|
||||||
$handler = HandlerStack::create($mock);
|
'error-codes' => [
|
||||||
|
'invalid-input-response', // The response parameter is invalid or malformed.
|
||||||
|
],
|
||||||
|
])));
|
||||||
|
|
||||||
return new Client(['handler' => $handler]);
|
$validator = new Validator($mockClient);
|
||||||
|
$this->assertFalse($validator->validate('12341234', $error));
|
||||||
|
$this->assertEquals('error.captcha_invalid', $error, 'Get error.captcha_invalid, if passed wrong value');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateWithNetworkTroubles() {
|
||||||
|
$mockClient = mock(ClientInterface::class);
|
||||||
|
$mockClient->shouldReceive('request')->andThrow(mock(ConnectException::class))->once();
|
||||||
|
$mockClient->shouldReceive('request')->andReturn(new Response(200, [], json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'error-codes' => [
|
||||||
|
'invalid-input-response', // The response parameter is invalid or malformed.
|
||||||
|
],
|
||||||
|
])))->once();
|
||||||
|
PHPMockery::mock($this->getClassNamespace(Validator::class), 'sleep')->once();
|
||||||
|
|
||||||
|
$validator = new Validator($mockClient);
|
||||||
|
$this->assertTrue($validator->validate('12341234', $error));
|
||||||
|
$this->assertNull($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateWithHugeNetworkTroubles() {
|
||||||
|
$mockClient = mock(ClientInterface::class);
|
||||||
|
$mockClient->shouldReceive('request')->andThrow(mock(ConnectException::class))->times(3);
|
||||||
|
PHPMockery::mock($this->getClassNamespace(Validator::class), 'sleep')->times(2);
|
||||||
|
|
||||||
|
$validator = new Validator($mockClient);
|
||||||
|
$this->expectException(ConnectException::class);
|
||||||
|
$validator->validate('12341234', $error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateValidValue() {
|
||||||
|
$mockClient = mock(ClientInterface::class);
|
||||||
|
$mockClient->shouldReceive('request')->andReturn(new Response(200, [], json_encode([
|
||||||
|
'success' => true,
|
||||||
|
])));
|
||||||
|
$validator = new Validator($mockClient);
|
||||||
|
$this->assertTrue($validator->validate('12341234', $error));
|
||||||
|
$this->assertNull($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClassNamespace(string $className): string {
|
||||||
|
return (new ReflectionClass($className))->getNamespaceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace codeception\api\unit\models\authentication;
|
namespace codeception\api\unit\models\authentication;
|
||||||
|
|
||||||
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
use api\models\authentication\ForgotPasswordForm;
|
use api\models\authentication\ForgotPasswordForm;
|
||||||
use Codeception\Specify;
|
use Codeception\Specify;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
use OTPHP\TOTP;
|
use OTPHP\TOTP;
|
||||||
use tests\codeception\api\unit\TestCase;
|
use tests\codeception\api\unit\TestCase;
|
||||||
use tests\codeception\common\fixtures\AccountFixture;
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
class ForgotPasswordFormTest extends TestCase {
|
class ForgotPasswordFormTest extends TestCase {
|
||||||
use Specify;
|
use Specify;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
Yii::$container->set(ReCaptchaValidator::class, new class(mock(ClientInterface::class)) extends ReCaptchaValidator {
|
||||||
|
public function validateValue($value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function _fixtures() {
|
public function _fixtures() {
|
||||||
return [
|
return [
|
||||||
'accounts' => AccountFixture::class,
|
'accounts' => AccountFixture::class,
|
||||||
@ -20,17 +32,13 @@ class ForgotPasswordFormTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateLogin() {
|
public function testValidateLogin() {
|
||||||
$this->specify('error.login_not_exist if login is invalid', function() {
|
$model = new ForgotPasswordForm(['login' => 'unexist']);
|
||||||
$model = new ForgotPasswordForm(['login' => 'unexist']);
|
$model->validateLogin('login');
|
||||||
$model->validateLogin('login');
|
$this->assertEquals(['error.login_not_exist'], $model->getErrors('login'), 'error.login_not_exist if login is invalid');
|
||||||
expect($model->getErrors('login'))->equals(['error.login_not_exist']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('empty errors if login is exists', function() {
|
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
||||||
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
$model->validateLogin('login');
|
||||||
$model->validateLogin('login');
|
$this->assertEmpty($model->getErrors('login'), 'empty errors if login is exists');
|
||||||
expect($model->getErrors('login'))->isEmpty();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateTotpToken() {
|
public function testValidateTotpToken() {
|
||||||
@ -49,77 +57,66 @@ class ForgotPasswordFormTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateActivity() {
|
public function testValidateActivity() {
|
||||||
$this->specify('error.account_not_activated if account is not confirmed', function() {
|
$model = new ForgotPasswordForm([
|
||||||
$model = new ForgotPasswordForm([
|
'login' => $this->tester->grabFixture('accounts', 'not-activated-account')['username'],
|
||||||
'login' => $this->tester->grabFixture('accounts', 'not-activated-account')['username'],
|
]);
|
||||||
]);
|
$model->validateActivity('login');
|
||||||
$model->validateActivity('login');
|
$this->assertEquals(['error.account_not_activated'], $model->getErrors('login'), 'expected error if account is not confirmed');
|
||||||
expect($model->getErrors('login'))->equals(['error.account_not_activated']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('empty errors if login is exists', function() {
|
$model = new ForgotPasswordForm([
|
||||||
$model = new ForgotPasswordForm([
|
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
]);
|
||||||
]);
|
$model->validateLogin('login');
|
||||||
$model->validateLogin('login');
|
$this->assertEmpty($model->getErrors('login'), 'empty errors if login is exists');
|
||||||
expect($model->getErrors('login'))->isEmpty();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateFrequency() {
|
public function testValidateFrequency() {
|
||||||
$this->specify('error.account_not_activated if recently was message', function() {
|
$model = $this->createModel([
|
||||||
$model = $this->createModel([
|
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
'key' => $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery')['key'],
|
||||||
'key' => $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery')['key'],
|
]);
|
||||||
]);
|
$model->validateFrequency('login');
|
||||||
|
$this->assertEquals(['error.recently_sent_message'], $model->getErrors('login'), 'error.account_not_activated if recently was message');
|
||||||
|
|
||||||
$model->validateFrequency('login');
|
$model = $this->createModel([
|
||||||
expect($model->getErrors('login'))->equals(['error.recently_sent_message']);
|
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||||
});
|
'key' => $this->tester->grabFixture('emailActivations', 'oldPasswordRecovery')['key'],
|
||||||
|
]);
|
||||||
|
$model->validateFrequency('login');
|
||||||
|
$this->assertEmpty($model->getErrors('login'), 'empty errors if email was sent a long time ago');
|
||||||
|
|
||||||
$this->specify('empty errors if email was sent a long time ago', function() {
|
$model = $this->createModel([
|
||||||
$model = $this->createModel([
|
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
'key' => 'invalid-key',
|
||||||
'key' => $this->tester->grabFixture('emailActivations', 'oldPasswordRecovery')['key'],
|
]);
|
||||||
]);
|
$model->validateFrequency('login');
|
||||||
|
$this->assertEmpty($model->getErrors('login'), 'empty errors if previous confirmation model not founded');
|
||||||
$model->validateFrequency('login');
|
|
||||||
expect($model->getErrors('login'))->isEmpty();
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('empty errors if previous confirmation model not founded', function() {
|
|
||||||
$model = $this->createModel([
|
|
||||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
|
||||||
'key' => 'invalid-key',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model->validateFrequency('login');
|
|
||||||
expect($model->getErrors('login'))->isEmpty();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testForgotPassword() {
|
public function testForgotPassword() {
|
||||||
$this->specify('successfully send message with restore password key', function() {
|
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
||||||
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
$this->assertTrue($model->forgotPassword(), 'form should be successfully processed');
|
||||||
expect($model->forgotPassword())->true();
|
$activation = $model->getEmailActivation();
|
||||||
expect($model->getEmailActivation())->notNull();
|
$this->assertInstanceOf(EmailActivation::class, $activation, 'getEmailActivation should return valid object instance');
|
||||||
$this->tester->canSeeEmailIsSent(1);
|
$this->tester->canSeeEmailIsSent(1);
|
||||||
});
|
/** @var \yii\swiftmailer\Message $email */
|
||||||
|
$email = $this->tester->grabSentEmails()[0];
|
||||||
|
$body = $email->getSwiftMessage()->getBody();
|
||||||
|
$this->assertContains($activation->key, $body);
|
||||||
|
$this->assertContains('/recover-password/' . $activation->key, $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testForgotPasswordResend() {
|
public function testForgotPasswordResend() {
|
||||||
$this->specify('successfully renew and send message with restore password key', function() {
|
$fixture = $this->tester->grabFixture('accounts', 'account-with-expired-forgot-password-message');
|
||||||
$fixture = $this->tester->grabFixture('accounts', 'account-with-expired-forgot-password-message');
|
$model = new ForgotPasswordForm([
|
||||||
$model = new ForgotPasswordForm([
|
'login' => $fixture['username'],
|
||||||
'login' => $fixture['username'],
|
]);
|
||||||
]);
|
$callTime = time();
|
||||||
$callTime = time();
|
$this->assertTrue($model->forgotPassword(), 'form should be successfully processed');
|
||||||
expect($model->forgotPassword())->true();
|
$emailActivation = $model->getEmailActivation();
|
||||||
$emailActivation = $model->getEmailActivation();
|
$this->assertInstanceOf(EmailActivation::class, $emailActivation);
|
||||||
expect($emailActivation)->notNull();
|
$this->assertGreaterThanOrEqual($callTime, $emailActivation->created_at);
|
||||||
expect($emailActivation->created_at)->greaterOrEquals($callTime);
|
$this->tester->canSeeEmailIsSent(1);
|
||||||
$this->tester->canSeeEmailIsSent(1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ use Codeception\Specify;
|
|||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
use common\models\UsernameHistory;
|
use common\models\UsernameHistory;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
use tests\codeception\api\unit\TestCase;
|
use tests\codeception\api\unit\TestCase;
|
||||||
use tests\codeception\common\fixtures\AccountFixture;
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
use Yii;
|
use Yii;
|
||||||
@ -19,7 +20,7 @@ class RegistrationFormTest extends TestCase {
|
|||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->mockRequest();
|
$this->mockRequest();
|
||||||
Yii::$container->set(ReCaptchaValidator::class, new class extends ReCaptchaValidator {
|
Yii::$container->set(ReCaptchaValidator::class, new class(mock(ClientInterface::class)) extends ReCaptchaValidator {
|
||||||
public function validateValue($value) {
|
public function validateValue($value) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -96,20 +97,27 @@ class RegistrationFormTest extends TestCase {
|
|||||||
'username' => 'some_username',
|
'username' => 'some_username',
|
||||||
'email' => 'some_email@example.com',
|
'email' => 'some_email@example.com',
|
||||||
])->exists(), 'user model exists in database');
|
])->exists(), 'user model exists in database');
|
||||||
$this->assertTrue(EmailActivation::find()->andWhere([
|
/** @var EmailActivation $activation */
|
||||||
'account_id' => $account->id,
|
$activation = EmailActivation::find()
|
||||||
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
|
->andWhere([
|
||||||
])->exists(), 'email activation code exists in database');
|
'account_id' => $account->id,
|
||||||
|
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
|
||||||
|
])
|
||||||
|
->one();
|
||||||
|
$this->assertInstanceOf(EmailActivation::class, $activation, 'email activation code exists in database');
|
||||||
$this->assertTrue(UsernameHistory::find()->andWhere([
|
$this->assertTrue(UsernameHistory::find()->andWhere([
|
||||||
'username' => $account->username,
|
'username' => $account->username,
|
||||||
'account_id' => $account->id,
|
'account_id' => $account->id,
|
||||||
'applied_in' => $account->created_at,
|
'applied_in' => $account->created_at,
|
||||||
])->exists(), 'username history record exists in database');
|
])->exists(), 'username history record exists in database');
|
||||||
$this->tester->canSeeEmailIsSent(1);
|
$this->tester->canSeeEmailIsSent(1);
|
||||||
|
/** @var \yii\swiftmailer\Message $email */
|
||||||
|
$email = $this->tester->grabSentEmails()[0];
|
||||||
|
$body = $email->getSwiftMessage()->getBody();
|
||||||
|
$this->assertContains($activation->key, $body);
|
||||||
|
$this->assertContains('/activation/' . $activation->key, $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: там в самой форме есть метод sendMail(), который рано или поздно должен переехать. К нему нужны будут тоже тесты
|
|
||||||
|
|
||||||
private function mockRequest($ip = '88.225.20.236') {
|
private function mockRequest($ip = '88.225.20.236') {
|
||||||
$request = $this->getMockBuilder(Request::class)
|
$request = $this->getMockBuilder(Request::class)
|
||||||
->setMethods(['getUserIP'])
|
->setMethods(['getUserIP'])
|
||||||
|
@ -5,6 +5,7 @@ use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
|||||||
use api\models\authentication\RepeatAccountActivationForm;
|
use api\models\authentication\RepeatAccountActivationForm;
|
||||||
use Codeception\Specify;
|
use Codeception\Specify;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
use tests\codeception\api\unit\TestCase;
|
use tests\codeception\api\unit\TestCase;
|
||||||
use tests\codeception\common\fixtures\AccountFixture;
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||||
@ -15,7 +16,7 @@ class RepeatAccountActivationFormTest extends TestCase {
|
|||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
Yii::$container->set(ReCaptchaValidator::class, new class extends ReCaptchaValidator {
|
Yii::$container->set(ReCaptchaValidator::class, new class(mock(ClientInterface::class)) extends ReCaptchaValidator {
|
||||||
public function validateValue($value) {
|
public function validateValue($value) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
20
tests/codeception/api/unit/request/RequestParserTest.php
Normal file
20
tests/codeception/api/unit/request/RequestParserTest.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\api\unit\request;
|
||||||
|
|
||||||
|
use api\request\RequestParser;
|
||||||
|
use tests\codeception\api\unit\TestCase;
|
||||||
|
|
||||||
|
class RequestParserTest extends TestCase {
|
||||||
|
|
||||||
|
public function testParse() {
|
||||||
|
$parser = new RequestParser();
|
||||||
|
$_POST = ['from' => 'post'];
|
||||||
|
$this->assertEquals(['from' => 'post'], $parser->parse('from=post', ''));
|
||||||
|
$this->assertEquals(['from' => 'post'], $parser->parse('', ''));
|
||||||
|
$_POST = [];
|
||||||
|
$this->assertEquals(['from' => 'json'], $parser->parse('{"from":"json"}', ''));
|
||||||
|
$this->assertEquals(['from' => 'body'], $parser->parse('from=body', ''));
|
||||||
|
$this->assertEquals(['onlykey' => ''], $parser->parse('onlykey', ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
tests/codeception/common/_support/Mockery.php
Normal file
31
tests/codeception/common/_support/Mockery.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\common\_support;
|
||||||
|
|
||||||
|
use Codeception\Module;
|
||||||
|
use Codeception\TestInterface;
|
||||||
|
|
||||||
|
class Mockery extends Module {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Run mockery expectations after test or not
|
||||||
|
*/
|
||||||
|
private $assert_mocks = true;
|
||||||
|
|
||||||
|
public function _before(TestInterface $test) {
|
||||||
|
\Mockery::globalHelpers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _after(TestInterface $test) {
|
||||||
|
if ($this->assert_mocks) {
|
||||||
|
\Mockery::close();
|
||||||
|
} else {
|
||||||
|
\Mockery::getContainer()->mockery_close();
|
||||||
|
\Mockery::resetContainer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _failed(TestInterface $test, $fail) {
|
||||||
|
$this->assert_mocks = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -28,12 +28,9 @@ class Helper extends Module {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: заменить на assertCount() после релиза Codeception 2.2.7
|
$this->assertCount(
|
||||||
// https://github.com/Codeception/Codeception/pull/3802
|
|
||||||
/** @noinspection PhpUnitTestsInspection */
|
|
||||||
$this->assertEquals(
|
|
||||||
$num,
|
$num,
|
||||||
count($this->grabSentAmqpMessages($exchange)),
|
$this->grabSentAmqpMessages($exchange),
|
||||||
'number of created messages is equal to ' . $num
|
'number of created messages is equal to ' . $num
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -43,16 +43,16 @@ class TestComponent extends Component {
|
|||||||
public function getSentMessages(string $exchangeName = null) : array {
|
public function getSentMessages(string $exchangeName = null) : array {
|
||||||
if ($exchangeName !== null) {
|
if ($exchangeName !== null) {
|
||||||
return $this->sentMessages[$exchangeName] ?? [];
|
return $this->sentMessages[$exchangeName] ?? [];
|
||||||
} else {
|
|
||||||
$messages = [];
|
|
||||||
foreach($this->sentMessages as $exchangeGroup) {
|
|
||||||
foreach ($exchangeGroup as $message) {
|
|
||||||
$messages[] = $message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $messages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$messages = [];
|
||||||
|
foreach($this->sentMessages as $exchangeGroup) {
|
||||||
|
foreach ($exchangeGroup as $message) {
|
||||||
|
$messages[] = $message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ modules:
|
|||||||
enabled:
|
enabled:
|
||||||
- Yii2:
|
- Yii2:
|
||||||
part: [orm, email, fixtures]
|
part: [orm, email, fixtures]
|
||||||
|
- tests\codeception\common\_support\Mockery
|
||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/common/unit.php'
|
configFile: '../config/common/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace tests\codeception\common\unit;
|
namespace tests\codeception\common\unit;
|
||||||
|
|
||||||
|
use Mockery;
|
||||||
|
|
||||||
class TestCase extends \Codeception\Test\Unit {
|
class TestCase extends \Codeception\Test\Unit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,4 +21,9 @@ class TestCase extends \Codeception\Test\Unit {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
Mockery::close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
18
tests/codeception/common/unit/emails/EmailHelperTest.php
Normal file
18
tests/codeception/common/unit/emails/EmailHelperTest.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\common\unit\emails;
|
||||||
|
|
||||||
|
use common\emails\EmailHelper;
|
||||||
|
use common\models\Account;
|
||||||
|
use tests\codeception\common\unit\TestCase;
|
||||||
|
|
||||||
|
class EmailHelperTest extends TestCase {
|
||||||
|
|
||||||
|
public function testBuildTo() {
|
||||||
|
/** @var Account|\Mockery\MockInterface $account */
|
||||||
|
$account = mock(Account::class)->makePartial();
|
||||||
|
$account->username = 'mock-username';
|
||||||
|
$account->email = 'mock@ely.by';
|
||||||
|
$this->assertEquals(['mock@ely.by' => 'mock-username'], EmailHelper::buildTo($account));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
tests/codeception/common/unit/emails/TemplateTest.php
Normal file
47
tests/codeception/common/unit/emails/TemplateTest.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\common\unit\emails;
|
||||||
|
|
||||||
|
use common\emails\Template;
|
||||||
|
use tests\codeception\common\_support\ProtectedCaller;
|
||||||
|
use tests\codeception\common\unit\TestCase;
|
||||||
|
use Yii;
|
||||||
|
use yii\mail\MailerInterface;
|
||||||
|
use yii\mail\MessageInterface;
|
||||||
|
|
||||||
|
class TemplateTest extends TestCase {
|
||||||
|
use ProtectedCaller;
|
||||||
|
|
||||||
|
public function testConstructor() {
|
||||||
|
/** @var Template|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(Template::class, ['find-me'])->makePartial();
|
||||||
|
$this->assertEquals('find-me', $template->getTo());
|
||||||
|
$this->assertInstanceOf(MailerInterface::class, $template->getMailer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetFrom() {
|
||||||
|
Yii::$app->params['fromEmail'] = 'find-me';
|
||||||
|
/** @var Template|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(Template::class)->makePartial();
|
||||||
|
$this->assertEquals(['find-me' => 'Ely.by Accounts'], $template->getFrom());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetParams() {
|
||||||
|
/** @var Template|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(Template::class)->makePartial();
|
||||||
|
$this->assertEquals([], $template->getParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateMessage() {
|
||||||
|
Yii::$app->params['fromEmail'] = 'from@ely.by';
|
||||||
|
/** @var Template|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(Template::class, [['to@ely.by' => 'To']])->makePartial();
|
||||||
|
$template->shouldReceive('getSubject')->andReturn('mock-subject');
|
||||||
|
/** @var MessageInterface $message */
|
||||||
|
$message = $this->callProtected($template, 'createMessage');
|
||||||
|
$this->assertInstanceOf(MessageInterface::class, $message);
|
||||||
|
$this->assertEquals(['to@ely.by' => 'To'], $message->getTo());
|
||||||
|
$this->assertEquals(['from@ely.by' => 'Ely.by Accounts'], $message->getFrom());
|
||||||
|
$this->assertEquals('mock-subject', $message->getSubject());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
namespace tests\codeception\common\unit\emails;
|
||||||
|
|
||||||
|
use common\components\EmailRenderer;
|
||||||
|
use common\emails\TemplateWithRenderer;
|
||||||
|
use Ely\Email\TemplateBuilder;
|
||||||
|
use tests\codeception\common\_support\ProtectedCaller;
|
||||||
|
use tests\codeception\common\unit\TestCase;
|
||||||
|
use yii\mail\MailerInterface;
|
||||||
|
use yii\mail\MessageInterface;
|
||||||
|
|
||||||
|
class TemplateWithRendererTest extends TestCase {
|
||||||
|
use ProtectedCaller;
|
||||||
|
|
||||||
|
public function testConstructor() {
|
||||||
|
/** @var TemplateWithRenderer|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(TemplateWithRenderer::class, ['mock-to', 'mock-locale'])->makePartial();
|
||||||
|
$this->assertEquals('mock-to', $template->getTo());
|
||||||
|
$this->assertEquals('mock-locale', $template->getLocale());
|
||||||
|
$this->assertInstanceOf(MailerInterface::class, $template->getMailer());
|
||||||
|
$this->assertInstanceOf(EmailRenderer::class, $template->getEmailRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateMessage() {
|
||||||
|
/** @var TemplateBuilder|\Mockery\MockInterface $templateBuilder */
|
||||||
|
$templateBuilder = mock(TemplateBuilder::class)->makePartial();
|
||||||
|
$templateBuilder->shouldReceive('render')->andReturn('mock-html');
|
||||||
|
|
||||||
|
/** @var EmailRenderer|\Mockery\MockInterface $renderer */
|
||||||
|
$renderer = mock(EmailRenderer::class)->makePartial();
|
||||||
|
$renderer->shouldReceive('getTemplate')->with('mock-template')->andReturn($templateBuilder);
|
||||||
|
|
||||||
|
/** @var TemplateWithRenderer|\Mockery\MockInterface $template */
|
||||||
|
$template = mock(TemplateWithRenderer::class, [['to@ely.by' => 'To'], 'mock-locale']);
|
||||||
|
$template->makePartial();
|
||||||
|
$template->shouldReceive('getEmailRenderer')->andReturn($renderer);
|
||||||
|
$template->shouldReceive('getFrom')->andReturn(['from@ely.by' => 'From']);
|
||||||
|
$template->shouldReceive('getSubject')->andReturn('mock-subject');
|
||||||
|
$template->shouldReceive('getTemplateName')->andReturn('mock-template');
|
||||||
|
/** @var \yii\swiftmailer\Message $message */
|
||||||
|
$message = $this->callProtected($template, 'createMessage');
|
||||||
|
$this->assertInstanceOf(MessageInterface::class, $message);
|
||||||
|
$this->assertEquals(['to@ely.by' => 'To'], $message->getTo());
|
||||||
|
$this->assertEquals(['from@ely.by' => 'From'], $message->getFrom());
|
||||||
|
$this->assertEquals('mock-subject', $message->getSubject());
|
||||||
|
$this->assertEquals('mock-html', $message->getSwiftMessage()->getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
use api\components\ReCaptcha\Validator;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'components' => [
|
'components' => [
|
||||||
'user' => [
|
'user' => [
|
||||||
@ -17,4 +20,15 @@ return [
|
|||||||
'params' => [
|
'params' => [
|
||||||
'authserverHost' => 'authserver.ely.by',
|
'authserverHost' => 'authserver.ely.by',
|
||||||
],
|
],
|
||||||
|
'container' => [
|
||||||
|
'definitions' => [
|
||||||
|
Validator::class => function() {
|
||||||
|
return new class(new Client()) extends Validator {
|
||||||
|
protected function validateValue($value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
@ -3,7 +3,8 @@ modules:
|
|||||||
enabled:
|
enabled:
|
||||||
- Yii2:
|
- Yii2:
|
||||||
part: [orm, email, fixtures]
|
part: [orm, email, fixtures]
|
||||||
|
- tests\codeception\common\_support\Mockery
|
||||||
config:
|
config:
|
||||||
Yii2:
|
Yii2:
|
||||||
configFile: '../config/console/unit.php'
|
configFile: '../config/console/unit.php'
|
||||||
cleanup: false
|
cleanup: true
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace tests\codeception\console\unit;
|
namespace tests\codeception\console\unit;
|
||||||
|
|
||||||
use Codeception\Test\Unit;
|
use Codeception\Test\Unit;
|
||||||
|
use Mockery;
|
||||||
|
|
||||||
class TestCase extends Unit {
|
class TestCase extends Unit {
|
||||||
|
|
||||||
@ -21,4 +22,9 @@ class TestCase extends Unit {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
Mockery::close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user