mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Merge branch 'extract_account_validators' into develop
This commit is contained in:
@@ -31,7 +31,7 @@ class ConfirmEmailForm extends KeyConfirmationForm {
|
|||||||
throw new ErrorException('Unable remove activation key.');
|
throw new ErrorException('Unable remove activation key.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Unable activate user account.');
|
throw new ErrorException('Unable activate user account.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -77,7 +77,7 @@ class LoginForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
if ($account->password_hash_strategy === Account::PASS_HASH_STRATEGY_OLD_ELY) {
|
if ($account->password_hash_strategy !== Account::PASS_HASH_STRATEGY_YII2) {
|
||||||
$account->setPassword($this->password);
|
$account->setPassword($this->password);
|
||||||
$account->save();
|
$account->save();
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ use api\models\AccountIdentity;
|
|||||||
use api\models\base\KeyConfirmationForm;
|
use api\models\base\KeyConfirmationForm;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
use common\validators\PasswordValidate;
|
use common\validators\PasswordValidator;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ class RecoverPasswordForm extends KeyConfirmationForm {
|
|||||||
return array_merge(parent::rules(), [
|
return array_merge(parent::rules(), [
|
||||||
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
||||||
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
||||||
['newPassword', PasswordValidate::class],
|
['newPassword', PasswordValidator::class],
|
||||||
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,10 @@ use common\models\Account;
|
|||||||
use common\models\confirmations\RegistrationConfirmation;
|
use common\models\confirmations\RegistrationConfirmation;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
use common\models\UsernameHistory;
|
use common\models\UsernameHistory;
|
||||||
|
use common\validators\EmailValidator;
|
||||||
use common\validators\LanguageValidator;
|
use common\validators\LanguageValidator;
|
||||||
use common\validators\PasswordValidate;
|
use common\validators\PasswordValidator;
|
||||||
|
use common\validators\UsernameValidator;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Yii;
|
use Yii;
|
||||||
@@ -40,12 +42,12 @@ class RegistrationForm extends ApiForm {
|
|||||||
['captcha', ReCaptchaValidator::class],
|
['captcha', ReCaptchaValidator::class],
|
||||||
['rulesAgreement', 'required', 'message' => E::RULES_AGREEMENT_REQUIRED],
|
['rulesAgreement', 'required', 'message' => E::RULES_AGREEMENT_REQUIRED],
|
||||||
|
|
||||||
['username', 'validateUsername', 'skipOnEmpty' => false],
|
['username', UsernameValidator::class],
|
||||||
['email', 'validateEmail', 'skipOnEmpty' => false],
|
['email', EmailValidator::class],
|
||||||
|
|
||||||
['password', 'required', 'message' => E::PASSWORD_REQUIRED],
|
['password', 'required', 'message' => E::PASSWORD_REQUIRED],
|
||||||
['rePassword', 'required', 'message' => E::RE_PASSWORD_REQUIRED],
|
['rePassword', 'required', 'message' => E::RE_PASSWORD_REQUIRED],
|
||||||
['password', PasswordValidate::class],
|
['password', PasswordValidator::class],
|
||||||
['rePassword', 'validatePasswordAndRePasswordMatch'],
|
['rePassword', 'validatePasswordAndRePasswordMatch'],
|
||||||
|
|
||||||
['lang', LanguageValidator::class],
|
['lang', LanguageValidator::class],
|
||||||
@@ -53,22 +55,6 @@ class RegistrationForm extends ApiForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateUsername() {
|
|
||||||
$account = new Account();
|
|
||||||
$account->username = $this->username;
|
|
||||||
if (!$account->validate(['username'])) {
|
|
||||||
$this->addErrors($account->getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validateEmail() {
|
|
||||||
$account = new Account();
|
|
||||||
$account->email = $this->email;
|
|
||||||
if (!$account->validate(['email'])) {
|
|
||||||
$this->addErrors($account->getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validatePasswordAndRePasswordMatch($attribute) {
|
public function validatePasswordAndRePasswordMatch($attribute) {
|
||||||
if (!$this->hasErrors()) {
|
if (!$this->hasErrors()) {
|
||||||
if ($this->password !== $this->rePassword) {
|
if ($this->password !== $this->rePassword) {
|
||||||
@@ -97,7 +83,7 @@ class RegistrationForm extends ApiForm {
|
|||||||
$account->status = Account::STATUS_REGISTERED;
|
$account->status = Account::STATUS_REGISTERED;
|
||||||
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
||||||
$account->setRegistrationIp(Yii::$app->request->getUserIP());
|
$account->setRegistrationIp(Yii::$app->request->getUserIP());
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Account not created.');
|
throw new ErrorException('Account not created.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ class AcceptRulesForm extends ApiForm {
|
|||||||
public function agreeWithLatestRules() : bool {
|
public function agreeWithLatestRules() : bool {
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Cannot set user rules version');
|
throw new ErrorException('Cannot set user rules version');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,10 +2,10 @@
|
|||||||
namespace api\models\profile\ChangeEmail;
|
namespace api\models\profile\ChangeEmail;
|
||||||
|
|
||||||
use api\models\base\KeyConfirmationForm;
|
use api\models\base\KeyConfirmationForm;
|
||||||
use common\helpers\Error as E;
|
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\confirmations\NewEmailConfirmation;
|
use common\models\confirmations\NewEmailConfirmation;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
|
use common\validators\EmailValidator;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\base\Exception;
|
use yii\base\Exception;
|
||||||
@@ -25,26 +25,14 @@ class NewEmailForm extends KeyConfirmationForm {
|
|||||||
parent::__construct($config);
|
parent::__construct($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Account
|
|
||||||
*/
|
|
||||||
public function getAccount() {
|
|
||||||
return $this->account;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules() {
|
public function rules() {
|
||||||
return array_merge(parent::rules(), [
|
return array_merge(parent::rules(), [
|
||||||
['email', 'required', 'message' => E::EMAIL_REQUIRED],
|
['email', EmailValidator::class],
|
||||||
['email', 'validateEmail'],
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateEmail() {
|
public function getAccount() : Account {
|
||||||
$account = new Account();
|
return $this->account;
|
||||||
$account->email = $this->email;
|
|
||||||
if (!$account->validate(['email'])) {
|
|
||||||
$this->addErrors($account->getErrors());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendNewEmailConfirmation() {
|
public function sendNewEmailConfirmation() {
|
||||||
|
@@ -31,7 +31,7 @@ class ChangeLanguageForm extends ApiForm {
|
|||||||
|
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
$account->lang = $this->lang;
|
$account->lang = $this->lang;
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Cannot change user language');
|
throw new ErrorException('Cannot change user language');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ 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;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\validators\PasswordValidate;
|
use common\validators\PasswordValidator;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use yii\helpers\ArrayHelper;
|
use yii\helpers\ArrayHelper;
|
||||||
@@ -37,7 +37,7 @@ class ChangePasswordForm extends ApiForm {
|
|||||||
return ArrayHelper::merge(parent::rules(), [
|
return ArrayHelper::merge(parent::rules(), [
|
||||||
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
||||||
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
||||||
['newPassword', PasswordValidate::class],
|
['newPassword', PasswordValidator::class],
|
||||||
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
||||||
['logoutAll', 'boolean'],
|
['logoutAll', 'boolean'],
|
||||||
['password', PasswordRequiredValidator::class, 'account' => $this->_account],
|
['password', PasswordRequiredValidator::class, 'account' => $this->_account],
|
||||||
@@ -77,7 +77,7 @@ class ChangePasswordForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Cannot save user model');
|
throw new ErrorException('Cannot save user model');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,11 +4,10 @@ namespace api\models\profile;
|
|||||||
use api\models\AccountIdentity;
|
use api\models\AccountIdentity;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use common\helpers\Error;
|
|
||||||
use common\helpers\Amqp;
|
use common\helpers\Amqp;
|
||||||
use common\models\Account;
|
|
||||||
use common\models\amqp\UsernameChanged;
|
use common\models\amqp\UsernameChanged;
|
||||||
use common\models\UsernameHistory;
|
use common\models\UsernameHistory;
|
||||||
|
use common\validators\UsernameValidator;
|
||||||
use Exception;
|
use Exception;
|
||||||
use PhpAmqpLib\Message\AMQPMessage;
|
use PhpAmqpLib\Message\AMQPMessage;
|
||||||
use Yii;
|
use Yii;
|
||||||
@@ -22,23 +21,13 @@ class ChangeUsernameForm extends ApiForm {
|
|||||||
|
|
||||||
public function rules() {
|
public function rules() {
|
||||||
return [
|
return [
|
||||||
['username', 'required', 'message' => Error::USERNAME_REQUIRED],
|
['username', UsernameValidator::class, 'accountCallback' => function() {
|
||||||
['username', 'validateUsername'],
|
return $this->getAccount()->id;
|
||||||
|
}],
|
||||||
['password', PasswordRequiredValidator::class],
|
['password', PasswordRequiredValidator::class],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateUsername($attribute) {
|
|
||||||
$account = new Account();
|
|
||||||
$account->id = $this->getAccount()->id;
|
|
||||||
$account->username = $this->$attribute;
|
|
||||||
// Это чтобы unique validator учёл, что ник может быть забит на текущий аккаунт
|
|
||||||
$account->setIsNewRecord(false);
|
|
||||||
if (!$account->validate(['username'])) {
|
|
||||||
$this->addErrors($account->getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function change() {
|
public function change() {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -49,7 +38,7 @@ class ChangeUsernameForm extends ApiForm {
|
|||||||
$oldNickname = $account->username;
|
$oldNickname = $account->username;
|
||||||
try {
|
try {
|
||||||
$account->username = $this->username;
|
$account->username = $this->username;
|
||||||
if (!$account->save(false)) {
|
if (!$account->save()) {
|
||||||
throw new ErrorException('Cannot save account model with new username');
|
throw new ErrorException('Cannot save account model with new username');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace common\models;
|
namespace common\models;
|
||||||
|
|
||||||
use common\helpers\Error as E;
|
|
||||||
use common\components\UserPass;
|
use common\components\UserPass;
|
||||||
use Ely\Yii2\TempmailValidator;
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\base\InvalidConfigException;
|
||||||
use yii\behaviors\TimestampBehavior;
|
use yii\behaviors\TimestampBehavior;
|
||||||
@@ -59,28 +57,6 @@ class Account extends ActiveRecord {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules() {
|
|
||||||
return [
|
|
||||||
[['username'], 'filter', 'filter' => 'trim'],
|
|
||||||
[['username'], 'required', 'message' => E::USERNAME_REQUIRED],
|
|
||||||
[['username'], 'string', 'min' => 3, 'max' => 21,
|
|
||||||
'tooShort' => E::USERNAME_TOO_SHORT,
|
|
||||||
'tooLong' => E::USERNAME_TOO_LONG,
|
|
||||||
],
|
|
||||||
[['username'], 'match', 'pattern' => '/^[\p{L}\d-_\.!?#$%^&*()\[\]:;]+$/u',
|
|
||||||
'message' => E::USERNAME_INVALID,
|
|
||||||
],
|
|
||||||
[['username'], 'unique', 'message' => E::USERNAME_NOT_AVAILABLE],
|
|
||||||
|
|
||||||
[['email'], 'filter', 'filter' => 'trim'],
|
|
||||||
[['email'], 'required', 'message' => E::EMAIL_REQUIRED],
|
|
||||||
[['email'], 'string', 'max' => 255, 'tooLong' => E::EMAIL_TOO_LONG],
|
|
||||||
[['email'], 'email', 'checkDNS' => true, 'enableIDN' => true, 'message' => E::EMAIL_INVALID],
|
|
||||||
[['email'], TempmailValidator::class, 'message' => E::EMAIL_IS_TEMPMAIL],
|
|
||||||
[['email'], 'unique', 'message' => E::EMAIL_NOT_AVAILABLE],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates password
|
* Validates password
|
||||||
*
|
*
|
||||||
|
64
common/validators/EmailValidator.php
Normal file
64
common/validators/EmailValidator.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\validators;
|
||||||
|
|
||||||
|
use common\helpers\Error as E;
|
||||||
|
use common\models\Account;
|
||||||
|
use Ely\Yii2\TempmailValidator;
|
||||||
|
use yii\base\Model;
|
||||||
|
use yii\db\QueryInterface;
|
||||||
|
use yii\validators;
|
||||||
|
use yii\validators\Validator;
|
||||||
|
|
||||||
|
class EmailValidator extends Validator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
||||||
|
* текущая валидация. Позволяет пропустить проверку email для текущего аккаунта.
|
||||||
|
*/
|
||||||
|
public $accountCallback;
|
||||||
|
|
||||||
|
public $skipOnEmpty = false;
|
||||||
|
|
||||||
|
public function validateAttribute($model, $attribute) {
|
||||||
|
$filter = new validators\FilterValidator(['filter' => 'trim']);
|
||||||
|
|
||||||
|
$required = new validators\RequiredValidator();
|
||||||
|
$required->message = E::EMAIL_REQUIRED;
|
||||||
|
|
||||||
|
$length = new validators\StringValidator();
|
||||||
|
$length->max = 255;
|
||||||
|
$length->tooLong = E::EMAIL_TOO_LONG;
|
||||||
|
|
||||||
|
$email = new validators\EmailValidator();
|
||||||
|
$email->checkDNS = true;
|
||||||
|
$email->enableIDN = true;
|
||||||
|
$email->message = E::EMAIL_INVALID;
|
||||||
|
|
||||||
|
$tempmail = new TempmailValidator();
|
||||||
|
$tempmail->message = E::EMAIL_IS_TEMPMAIL;
|
||||||
|
|
||||||
|
$unique = new validators\UniqueValidator();
|
||||||
|
$unique->message = E::EMAIL_NOT_AVAILABLE;
|
||||||
|
$unique->targetClass = Account::class;
|
||||||
|
$unique->targetAttribute = 'email';
|
||||||
|
if ($this->accountCallback !== null) {
|
||||||
|
$unique->filter = function(QueryInterface $query) {
|
||||||
|
$query->andWhere(['NOT', ['id' => ($this->accountCallback)()]]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->executeValidation($filter, $model, $attribute) &&
|
||||||
|
$this->executeValidation($required, $model, $attribute) &&
|
||||||
|
$this->executeValidation($length, $model, $attribute) &&
|
||||||
|
$this->executeValidation($email, $model, $attribute) &&
|
||||||
|
$this->executeValidation($tempmail, $model, $attribute) &&
|
||||||
|
$this->executeValidation($unique, $model, $attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function executeValidation(Validator $validator, Model $model, string $attribute) {
|
||||||
|
$validator->validateAttribute($model, $attribute);
|
||||||
|
|
||||||
|
return !$model->hasErrors($attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,7 +7,7 @@ use yii\validators\StringValidator;
|
|||||||
/**
|
/**
|
||||||
* Класс должен реализовывать в себе все критерии валидации пароля пользователя
|
* Класс должен реализовывать в себе все критерии валидации пароля пользователя
|
||||||
*/
|
*/
|
||||||
class PasswordValidate extends StringValidator {
|
class PasswordValidator extends StringValidator {
|
||||||
|
|
||||||
public $min = 8;
|
public $min = 8;
|
||||||
|
|
59
common/validators/UsernameValidator.php
Normal file
59
common/validators/UsernameValidator.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\validators;
|
||||||
|
|
||||||
|
use common\helpers\Error as E;
|
||||||
|
use common\models\Account;
|
||||||
|
use yii\base\Model;
|
||||||
|
use yii\db\QueryInterface;
|
||||||
|
use yii\validators;
|
||||||
|
use yii\validators\Validator;
|
||||||
|
|
||||||
|
class UsernameValidator extends Validator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
||||||
|
* текущая валидация. Позволяет пропустить проверку ника для текущего аккаунта.
|
||||||
|
*/
|
||||||
|
public $accountCallback;
|
||||||
|
|
||||||
|
public $skipOnEmpty = false;
|
||||||
|
|
||||||
|
public function validateAttribute($model, $attribute) {
|
||||||
|
$filter = new validators\FilterValidator(['filter' => 'trim']);
|
||||||
|
|
||||||
|
$required = new validators\RequiredValidator();
|
||||||
|
$required->message = E::USERNAME_REQUIRED;
|
||||||
|
|
||||||
|
$length = new validators\StringValidator();
|
||||||
|
$length->min = 3;
|
||||||
|
$length->max = 21;
|
||||||
|
$length->tooShort = E::USERNAME_TOO_SHORT;
|
||||||
|
$length->tooLong = E::USERNAME_TOO_LONG;
|
||||||
|
|
||||||
|
$pattern = new validators\RegularExpressionValidator(['pattern' => '/^[\p{L}\d-_\.!?#$%^&*()\[\]:;]+$/u']);
|
||||||
|
$pattern->message = E::USERNAME_INVALID;
|
||||||
|
|
||||||
|
$unique = new validators\UniqueValidator();
|
||||||
|
$unique->message = E::USERNAME_NOT_AVAILABLE;
|
||||||
|
$unique->targetClass = Account::class;
|
||||||
|
$unique->targetAttribute = 'username';
|
||||||
|
if ($this->accountCallback !== null) {
|
||||||
|
$unique->filter = function(QueryInterface $query) {
|
||||||
|
$query->andWhere(['NOT', ['id' => ($this->accountCallback)()]]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->executeValidation($filter, $model, $attribute) &&
|
||||||
|
$this->executeValidation($required, $model, $attribute) &&
|
||||||
|
$this->executeValidation($length, $model, $attribute) &&
|
||||||
|
$this->executeValidation($pattern, $model, $attribute) &&
|
||||||
|
$this->executeValidation($unique, $model, $attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function executeValidation(Validator $validator, Model $model, string $attribute) {
|
||||||
|
$validator->validateAttribute($model, $attribute);
|
||||||
|
|
||||||
|
return !$model->hasErrors($attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -67,26 +67,6 @@ class ChangeUsernameFormTest extends TestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateUsername() {
|
|
||||||
$this->specify('error.username_not_available expected if username is already taken', function() {
|
|
||||||
$model = new ChangeUsernameForm([
|
|
||||||
'password' => 'password_0',
|
|
||||||
'username' => 'Jon',
|
|
||||||
]);
|
|
||||||
$model->validateUsername('username');
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_not_available']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('error.username_not_available is NOT expected if username is already taken by CURRENT user', function() {
|
|
||||||
$model = new ChangeUsernameForm([
|
|
||||||
'password' => 'password_0',
|
|
||||||
'username' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
|
||||||
]);
|
|
||||||
$model->validateUsername('username');
|
|
||||||
expect($model->getErrors('username'))->isEmpty();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCreateTask() {
|
public function testCreateTask() {
|
||||||
$model = new ChangeUsernameForm();
|
$model = new ChangeUsernameForm();
|
||||||
$model->createEventTask('1', 'test1', 'test');
|
$model->createEventTask('1', 'test1', 'test');
|
||||||
|
@@ -4,8 +4,6 @@ namespace tests\codeception\common\unit\models;
|
|||||||
use Codeception\Specify;
|
use Codeception\Specify;
|
||||||
use common\components\UserPass;
|
use common\components\UserPass;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use tests\codeception\common\fixtures\AccountFixture;
|
|
||||||
use tests\codeception\common\fixtures\MojangUsernameFixture;
|
|
||||||
use tests\codeception\common\unit\TestCase;
|
use tests\codeception\common\unit\TestCase;
|
||||||
use Yii;
|
use Yii;
|
||||||
use const common\LATEST_RULES_VERSION;
|
use const common\LATEST_RULES_VERSION;
|
||||||
@@ -13,109 +11,12 @@ use const common\LATEST_RULES_VERSION;
|
|||||||
class AccountTest extends TestCase {
|
class AccountTest extends TestCase {
|
||||||
use Specify;
|
use Specify;
|
||||||
|
|
||||||
public function _fixtures() {
|
|
||||||
return [
|
|
||||||
'accounts' => AccountFixture::class,
|
|
||||||
'mojangAccounts' => MojangUsernameFixture::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testValidateUsername() {
|
|
||||||
$this->specify('username required', function() {
|
|
||||||
$model = new Account(['username' => null]);
|
|
||||||
expect($model->validate(['username']))->false();
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_required']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('username should be at least 3 symbols length', function() {
|
|
||||||
$model = new Account(['username' => 'at']);
|
|
||||||
expect($model->validate(['username']))->false();
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_too_short']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('username should be not more than 21 symbols length', function() {
|
|
||||||
$model = new Account(['username' => 'erickskrauch_erickskrauch']);
|
|
||||||
expect($model->validate(['username']))->false();
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_too_long']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('username can contain many cool symbols', function() {
|
|
||||||
$shouldBeValid = [
|
|
||||||
'русский_ник', 'русский_ник_на_грани!', 'numbers1132', '*__*-Stars-*__*', '1-_.!?#$%^&*()[]',
|
|
||||||
'[ESP]Эрик', 'Свят_помидор;', 'зроблена_ў_беларусі:)',
|
|
||||||
];
|
|
||||||
foreach($shouldBeValid as $nickname) {
|
|
||||||
$model = new Account(['username' => $nickname]);
|
|
||||||
expect($nickname . ' passed validation', $model->validate(['username']))->true();
|
|
||||||
expect($model->getErrors('username'))->isEmpty();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('username cannot contain some symbols', function() {
|
|
||||||
$shouldBeInvalid = [
|
|
||||||
'nick@name', 'spaced nick',
|
|
||||||
];
|
|
||||||
foreach($shouldBeInvalid as $nickname) {
|
|
||||||
$model = new Account(['username' => $nickname]);
|
|
||||||
expect($nickname . ' fail validation', $model->validate('username'))->false();
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_invalid']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('username should be unique', function() {
|
|
||||||
$model = new Account();
|
|
||||||
$model->username = $this->tester->grabFixture('accounts', 'admin')['username'];
|
|
||||||
expect($model->validate('username'))->false();
|
|
||||||
expect($model->getErrors('username'))->equals(['error.username_not_available']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testValidateEmail() {
|
|
||||||
// TODO: пропускать этот тест, если падает ошибка с недостпуностью интернет соединения
|
|
||||||
$this->specify('email required', function() {
|
|
||||||
$model = new Account(['email' => null]);
|
|
||||||
expect($model->validate(['email']))->false();
|
|
||||||
expect($model->getErrors('email'))->equals(['error.email_required']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('email should be not more 255 symbols (I hope it\'s impossible to register)', function() {
|
|
||||||
$model = new Account([
|
|
||||||
'email' => 'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
|
||||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
|
||||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
|
||||||
'emailemail', // = 256 symbols
|
|
||||||
]);
|
|
||||||
expect($model->validate(['email']))->false();
|
|
||||||
expect($model->getErrors('email'))->equals(['error.email_too_long']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('email should be email (it test can fail, if you don\'t have internet connection)', function() {
|
|
||||||
$model = new Account(['email' => 'invalid_email']);
|
|
||||||
expect($model->validate(['email']))->false();
|
|
||||||
expect($model->getErrors('email'))->equals(['error.email_invalid']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('email should be not tempmail', function() {
|
|
||||||
$model = new Account(['email' => 'ibrpycwyjdnt@dropmail.me']);
|
|
||||||
expect($model->validate(['email']))->false();
|
|
||||||
expect($model->getErrors('email'))->equals(['error.email_is_tempmail']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->specify('email should be unique', function() {
|
|
||||||
$model = new Account(['email' => $this->tester->grabFixture('accounts', 'admin')['email']]);
|
|
||||||
expect($model->validate('email'))->false();
|
|
||||||
expect($model->getErrors('email'))->equals(['error.email_not_available']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSetPassword() {
|
public function testSetPassword() {
|
||||||
$this->specify('calling method should change password and set latest password hash algorithm', function() {
|
$model = new Account();
|
||||||
$model = new Account();
|
$model->setPassword('12345678');
|
||||||
$model->setPassword('12345678');
|
$this->assertNotEmpty($model->password_hash, 'hash should be set');
|
||||||
expect('hash should be set', $model->password_hash)->notEmpty();
|
$this->assertTrue($model->validatePassword('12345678'), 'validation should be passed');
|
||||||
expect('validation should be passed', $model->validatePassword('12345678'))->true();
|
$this->assertEquals(Account::PASS_HASH_STRATEGY_YII2, $model->password_hash_strategy, 'latest password hash should be used');
|
||||||
expect('latest password hash should be used', $model->password_hash_strategy)->equals(Account::PASS_HASH_STRATEGY_YII2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatePassword() {
|
public function testValidatePassword() {
|
||||||
|
109
tests/codeception/common/unit/validators/EmailValidatorTest.php
Normal file
109
tests/codeception/common/unit/validators/EmailValidatorTest.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
namespace codeception\common\unit\validators;
|
||||||
|
|
||||||
|
use common\validators\EmailValidator;
|
||||||
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
|
use tests\codeception\common\unit\TestCase;
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
class EmailValidatorTest extends TestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EmailValidator
|
||||||
|
*/
|
||||||
|
private $validator;
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$this->validator = new EmailValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeRequired() {
|
||||||
|
$model = $this->createModel('');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_required'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('email');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_required'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeLength() {
|
||||||
|
$model = $this->createModel(
|
||||||
|
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||||
|
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||||
|
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||||
|
'@gmail.com' // = 256 symbols
|
||||||
|
);
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_too_long'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('some-email@gmail.com');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_too_long'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeEmail() {
|
||||||
|
$model = $this->createModel('non-email');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('non-email@etot-domen-ne-suschestrvyet.de');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('valid-email@gmail.com');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeTempmail() {
|
||||||
|
$model = $this->createModel('ibrpycwyjdnt@dropmail.me');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_is_tempmail'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('valid-email@gmail.com');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_is_tempmail'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeUnique() {
|
||||||
|
$this->tester->haveFixtures([
|
||||||
|
'accounts' => AccountFixture::class,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** @var \common\models\Account $accountFixture */
|
||||||
|
$accountFixture = $this->tester->grabFixture('accounts', 'admin');
|
||||||
|
|
||||||
|
$model = $this->createModel($accountFixture->email);
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel($accountFixture->email);
|
||||||
|
$this->validator->accountCallback = function() use ($accountFixture) {
|
||||||
|
return $accountFixture->id;
|
||||||
|
};
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||||
|
$this->validator->accountCallback = null;
|
||||||
|
|
||||||
|
$model = $this->createModel('some-unique-email@gmail.com');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fieldValue
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
private function createModel(string $fieldValue) : Model {
|
||||||
|
$class = new class extends Model {
|
||||||
|
public $field;
|
||||||
|
};
|
||||||
|
|
||||||
|
$class->field = $fieldValue;
|
||||||
|
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
namespace codeception\common\unit\validators;
|
||||||
|
|
||||||
|
use common\validators\UsernameValidator;
|
||||||
|
use tests\codeception\common\fixtures\AccountFixture;
|
||||||
|
use tests\codeception\common\unit\TestCase;
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
class UsernameValidatorTest extends TestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UsernameValidator
|
||||||
|
*/
|
||||||
|
private $validator;
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$this->validator = new UsernameValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeRequired() {
|
||||||
|
$model = $this->createModel('');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.username_required'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('username');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.username_required'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeLength() {
|
||||||
|
$model = $this->createModel('at');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.username_too_short'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('erickskrauch_erickskrauch');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.username_too_long'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel('username');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.username_too_short'], $model->getErrors('field'));
|
||||||
|
$this->assertNotEquals(['error.username_too_long'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributePattern() {
|
||||||
|
$shouldBeValid = [
|
||||||
|
'русский_ник', 'русский_ник_на_грани!', 'numbers1132', '*__*-Stars-*__*', '1-_.!?#$%^&*()[]',
|
||||||
|
'[ESP]Эрик', 'Свят_помидор;', 'зроблена_ў_беларусі:)',
|
||||||
|
];
|
||||||
|
foreach($shouldBeValid as $nickname) {
|
||||||
|
$model = $this->createModel($nickname);
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.username_invalid'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$shouldBeInvalid = [
|
||||||
|
'nick@name', 'spaced nick',
|
||||||
|
];
|
||||||
|
foreach($shouldBeInvalid as $nickname) {
|
||||||
|
$model = $this->createModel($nickname);
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.username_invalid'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValidateAttributeUnique() {
|
||||||
|
$this->tester->haveFixtures([
|
||||||
|
'accounts' => AccountFixture::class,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** @var \common\models\Account $accountFixture */
|
||||||
|
$accountFixture = $this->tester->grabFixture('accounts', 'admin');
|
||||||
|
|
||||||
|
$model = $this->createModel($accountFixture->username);
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||||
|
|
||||||
|
$model = $this->createModel($accountFixture->username);
|
||||||
|
$this->validator->accountCallback = function() use ($accountFixture) {
|
||||||
|
return $accountFixture->id;
|
||||||
|
};
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||||
|
$this->validator->accountCallback = null;
|
||||||
|
|
||||||
|
$model = $this->createModel('some-unique-username');
|
||||||
|
$this->validator->validateAttribute($model, 'field');
|
||||||
|
$this->assertNotEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fieldValue
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
private function createModel(string $fieldValue) : Model {
|
||||||
|
$class = new class extends Model {
|
||||||
|
public $field;
|
||||||
|
};
|
||||||
|
|
||||||
|
$class->field = $fieldValue;
|
||||||
|
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user