Merge branch 'account_reassignment' into develop

This commit is contained in:
ErickSkrauch 2016-10-27 01:35:58 +03:00
commit b2f75450be
6 changed files with 86 additions and 13 deletions

View File

@ -3,6 +3,7 @@ namespace api\models\authentication;
use api\models\AccountIdentity; use api\models\AccountIdentity;
use api\models\base\KeyConfirmationForm; use api\models\base\KeyConfirmationForm;
use api\models\profile\ChangeUsernameForm;
use common\models\Account; use common\models\Account;
use common\models\EmailActivation; use common\models\EmailActivation;
use Yii; use Yii;
@ -34,6 +35,9 @@ class ConfirmEmailForm extends KeyConfirmationForm {
throw new ErrorException('Unable activate user account.'); throw new ErrorException('Unable activate user account.');
} }
$changeUsernameForm = new ChangeUsernameForm();
$changeUsernameForm->createEventTask($account->id, $account->username, null);
$transaction->commit(); $transaction->commit();
} catch (ErrorException $e) { } catch (ErrorException $e) {
$transaction->rollBack(); $transaction->rollBack();

View File

@ -4,7 +4,6 @@ namespace api\models\authentication;
use api\components\ReCaptcha\Validator as ReCaptchaValidator; use api\components\ReCaptcha\Validator as ReCaptchaValidator;
use api\models\base\ApiForm; use api\models\base\ApiForm;
use common\helpers\Error as E; use common\helpers\Error as E;
use api\models\profile\ChangeUsernameForm;
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;
@ -17,6 +16,7 @@ use Ramsey\Uuid\Uuid;
use Yii; use Yii;
use yii\base\ErrorException; use yii\base\ErrorException;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use const common\LATEST_RULES_VERSION; use const common\LATEST_RULES_VERSION;
class RegistrationForm extends ApiForm { class RegistrationForm extends ApiForm {
@ -49,6 +49,7 @@ class RegistrationForm extends ApiForm {
['rePassword', 'validatePasswordAndRePasswordMatch'], ['rePassword', 'validatePasswordAndRePasswordMatch'],
['lang', LanguageValidator::class], ['lang', LanguageValidator::class],
['lang', 'default', 'value' => 'en'],
]; ];
} }
@ -81,7 +82,7 @@ class RegistrationForm extends ApiForm {
* @throws Exception * @throws Exception
*/ */
public function signup() { public function signup() {
if (!$this->validate()) { if (!$this->validate() && !$this->canContinue($this->getFirstErrors())) {
return null; return null;
} }
@ -96,7 +97,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()) { if (!$account->save(false)) {
throw new ErrorException('Account not created.'); throw new ErrorException('Account not created.');
} }
@ -118,9 +119,6 @@ class RegistrationForm extends ApiForm {
$this->sendMail($emailActivation, $account); $this->sendMail($emailActivation, $account);
$changeUsernameForm = new ChangeUsernameForm();
$changeUsernameForm->createEventTask($account->id, $account->username, null);
$transaction->commit(); $transaction->commit();
} catch (Exception $e) { } catch (Exception $e) {
$transaction->rollBack(); $transaction->rollBack();
@ -161,4 +159,43 @@ class RegistrationForm extends ApiForm {
} }
} }
/**
* Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается,
* что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь
* выпонить регистрацию. Мы не будем им мешать и просто удаляем существующие недозарегистрированные
* аккаунты, позволяя им зарегистрироваться.
*
* @param array $errors массив, где ключ - это поле, а значение - первая ошибка из нашего
* стандартного словаря ошибок
*
* @return bool
*/
protected function canContinue(array $errors) : bool {
if (ArrayHelper::getValue($errors, 'username') === E::USERNAME_NOT_AVAILABLE) {
$duplicatedUsername = Account::findOne([
'username' => $this->username,
'status' => Account::STATUS_REGISTERED,
]);
if ($duplicatedUsername !== null) {
$duplicatedUsername->delete();
unset($errors['username']);
}
}
if (ArrayHelper::getValue($errors, 'email') === E::EMAIL_NOT_AVAILABLE) {
$duplicatedEmail = Account::findOne([
'email' => $this->email,
'status' => Account::STATUS_REGISTERED,
]);
if ($duplicatedEmail !== null) {
$duplicatedEmail->delete();
unset($errors['email']);
}
}
return empty($errors);
}
} }

View File

@ -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()) { if (!$account->save(false)) {
throw new ErrorException('Cannot change user language'); throw new ErrorException('Cannot change user language');
} }

View File

@ -30,7 +30,10 @@ class ChangeUsernameForm extends ApiForm {
public function validateUsername($attribute) { public function validateUsername($attribute) {
$account = new Account(); $account = new Account();
$account->id = $this->getAccount()->id;
$account->username = $this->$attribute; $account->username = $this->$attribute;
// Это чтобы unique validator учёл, что ник может быть забит на текущий аккаунт
$account->setIsNewRecord(false);
if (!$account->validate(['username'])) { if (!$account->validate(['username'])) {
$this->addErrors($account->getErrors()); $this->addErrors($account->getErrors());
} }
@ -46,7 +49,7 @@ class ChangeUsernameForm extends ApiForm {
$oldNickname = $account->username; $oldNickname = $account->username;
try { try {
$account->username = $this->username; $account->username = $this->username;
if (!$account->save()) { if (!$account->save(false)) {
throw new ErrorException('Cannot save account model with new username'); throw new ErrorException('Cannot save account model with new username');
} }

View File

@ -3,7 +3,6 @@ namespace common\models;
use common\helpers\Error as E; use common\helpers\Error as E;
use common\components\UserPass; use common\components\UserPass;
use common\validators\LanguageValidator;
use Ely\Yii2\TempmailValidator; use Ely\Yii2\TempmailValidator;
use Yii; use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
@ -79,9 +78,6 @@ class Account extends ActiveRecord {
[['email'], 'email', 'checkDNS' => true, 'enableIDN' => true, 'message' => E::EMAIL_INVALID], [['email'], 'email', 'checkDNS' => true, 'enableIDN' => true, 'message' => E::EMAIL_INVALID],
[['email'], TempmailValidator::class, 'message' => E::EMAIL_IS_TEMPMAIL], [['email'], TempmailValidator::class, 'message' => E::EMAIL_IS_TEMPMAIL],
[['email'], 'unique', 'message' => E::EMAIL_NOT_AVAILABLE], [['email'], 'unique', 'message' => E::EMAIL_NOT_AVAILABLE],
[['lang'], LanguageValidator::class],
[['lang'], 'default', 'value' => 'en'],
]; ];
} }

View File

@ -1,7 +1,6 @@
<?php <?php
namespace tests\codeception\api\functional; namespace tests\codeception\api\functional;
use Codeception\Specify;
use common\models\Account; use common\models\Account;
use tests\codeception\api\_pages\SignupRoute; use tests\codeception\api\_pages\SignupRoute;
use tests\codeception\api\FunctionalTester; use tests\codeception\api\FunctionalTester;
@ -216,6 +215,40 @@ class RegisterCest {
'rulesAgreement' => true, 'rulesAgreement' => true,
'lang' => 'ru', 'lang' => 'ru',
]); ]);
$this->assertSuccessRegistration($I);
}
public function testUserCorrectRegistrationWithReassignUsername(FunctionalTester $I) {
$route = new SignupRoute($I);
$I->wantTo('ensure that signup allow reassign not finished registration username');
$route->register([
'username' => 'howe.garnett',
'email' => 'custom-email@gmail.com',
'password' => 'some_password',
'rePassword' => 'some_password',
'rulesAgreement' => true,
'lang' => 'ru',
]);
$this->assertSuccessRegistration($I);
}
public function testUserCorrectRegistrationWithReassignEmail(FunctionalTester $I) {
$route = new SignupRoute($I);
$I->wantTo('ensure that signup allow reassign not finished registration email');
$route->register([
'username' => 'CustomUsername',
'email' => 'achristiansen@gmail.com',
'password' => 'some_password',
'rePassword' => 'some_password',
'rulesAgreement' => true,
'lang' => 'ru',
]);
$this->assertSuccessRegistration($I);
}
private function assertSuccessRegistration(FunctionalTester $I) {
$I->canSeeResponseCodeIs(200); $I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson(); $I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson(['success' => true]); $I->canSeeResponseContainsJson(['success' => true]);