2fa by email and by sms

This commit is contained in:
Antonio Cordeddu
2022-07-09 19:10:00 +02:00
parent 69e4bb620e
commit 91d110e1e7
47 changed files with 1253 additions and 48 deletions

View File

@ -20,6 +20,9 @@ use Da\User\Service\SocialNetworkAccountConnectService;
use Da\User\Service\SocialNetworkAuthenticateService;
use Da\User\Traits\ContainerAwareTrait;
use Da\User\Traits\ModuleAwareTrait;
use Da\User\Validator\TwoFactorEmailValidator;
use Da\User\Validator\TwoFactorTextMessageValidator;
use Da\User\Model\User;
use Yii;
use yii\authclient\AuthAction;
use yii\base\InvalidConfigException;
@ -30,6 +33,7 @@ use yii\filters\VerbFilter;
use yii\web\Controller;
use yii\web\Response;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
class SecurityController extends Controller
{
@ -206,13 +210,30 @@ class SecurityController extends Controller
return $this->goBack();
}
}
}
else{
$module = Yii::$app->getModule('user');
$validators = $module->twoFactorAuthenticationValidators;
$credentials=Yii::$app->session->get('credentials');
$login= $credentials['login'];
$user = User::findOne(['email'=>$login]);
if( $user==null)
$user = User::findOne(['username'=>$login]);
$tfType = $user->getAuthTfType();
$class = ArrayHelper::getValue($validators,$tfType.'.class');
$object = $this
->make($class, [$user, null, $this->module->twoFactorAuthenticationCycles]);
$object->generateCode();
}
return $this->render(
'confirm',
[
'model' => $form,
'module' => $this->module,
'module' => $this->module
]
);
}

View File

@ -28,10 +28,14 @@ use Da\User\Query\SocialNetworkAccountQuery;
use Da\User\Query\UserQuery;
use Da\User\Service\EmailChangeService;
use Da\User\Service\TwoFactorQrCodeUriGeneratorService;
use Da\User\Service\TwoFactorEmailCodeGeneratorService;
use Da\User\Service\TwoFactorSmsCodeGeneratorService;
use Da\User\Traits\ContainerAwareTrait;
use Da\User\Traits\ModuleAwareTrait;
use Da\User\Validator\AjaxRequestModelValidator;
use Da\User\Validator\TwoFactorCodeValidator;
use Da\User\Validator\TwoFactorEmailValidator;
use Da\User\Validator\TwoFactorTextMessageValidator;
use Yii;
use yii\base\DynamicModel;
use yii\filters\AccessControl;
@ -111,7 +115,8 @@ class SettingsController extends Controller
'delete',
'two-factor',
'two-factor-enable',
'two-factor-disable'
'two-factor-disable',
'two-factor-mobile-phone'
],
'roles' => ['@'],
],
@ -348,7 +353,7 @@ class SettingsController extends Controller
public function actionConfirm($id, $code)
{
$user = $this->userQuery->whereId($id)->one();
if ($user === null || MailChangeStrategyInterface::TYPE_INSECURE === $this->module->emailChangeStrategy) {
throw new NotFoundHttpException();
}
@ -400,16 +405,31 @@ class SettingsController extends Controller
public function actionTwoFactor($id)
{
/** @var User $user */
$choice=Yii::$app->request->post('choice');
/**
* @var User $user
*/
$user = $this->userQuery->whereId($id)->one();
if (null === $user) {
throw new NotFoundHttpException();
}
$uri = $this->make(TwoFactorQrCodeUriGeneratorService::class, [$user])->run();
return $this->renderAjax('two-factor', ['id' => $id, 'uri' => $uri]);
switch($choice)
{
case 'google-authenticator':
$uri = $this->make(TwoFactorQrCodeUriGeneratorService::class, [$user])->run();
return $this->renderAjax('two-factor', ['id' => $id, 'uri' => $uri]);
case 'email':
$emailCode = $this->make(TwoFactorEmailCodeGeneratorService::class, [$user])->run();
return $this->renderAjax('two-factor-email', ['id' => $id, 'code' => $emailCode]);
case 'sms':
// get mobile phone, if exists
$mobilePhone=$user->getAuthTfMobilePhone();
$smsCode = $this->make(TwoFactorSmsCodeGeneratorService::class, [$user])->run();
return $this->renderAjax('two-factor-sms', ['id' => $id, 'code' => $smsCode, 'mobilePhone' => $mobilePhone] );
}
}
public function actionTwoFactorEnable($id)
@ -426,18 +446,22 @@ class SettingsController extends Controller
];
}
$code = Yii::$app->request->get('code');
$module = Yii::$app->getModule('user');
$validators = $module->twoFactorAuthenticationValidators;
$choice = Yii::$app->request->get('choice');
$codeDurationTime = ArrayHelper::getValue($validators,$choice.'.codeDurationTime', 0);
$class = ArrayHelper::getValue($validators,$choice.'.class');
$success = $this
->make(TwoFactorCodeValidator::class, [$user, $code, $this->module->twoFactorAuthenticationCycles])
->validate();
$success = $success && $user->updateAttributes(['auth_tf_enabled' => '1']);
$object = $this
->make($class, [$user, $code, $this->module->twoFactorAuthenticationCycles]);
$success = $object->validate();
$success = $success && $user->updateAttributes(['auth_tf_enabled' => '1','auth_tf_type' => $choice]);
$message = $success
? $object->getSuccessMessage():$object->getUnsuccessMessage($codeDurationTime);
return [
'success' => $success,
'message' => $success
? Yii::t('usuario', 'Two factor authentication successfully enabled.')
: Yii::t('usuario', 'Verification failed. Please, enter new code.')
'message' => $message
];
}
@ -488,4 +512,39 @@ class SettingsController extends Controller
$account->delete();
$this->trigger(SocialNetworkConnectEvent::EVENT_AFTER_DISCONNECT, $event);
}
public function actionTwoFactorMobilePhone($id)
{
Yii::$app->response->format = Response::FORMAT_JSON;
/**
*
*
* @var User $user
*/
$user = $this->userQuery->whereId($id)->one();
if (null === $user) {
return [
'success' => false,
'message' => Yii::t('usuario', 'User not found.')
];
}
$mobilePhone = Yii::$app->request->get('mobilephone');
$currentMobilePhone = $user->getAuthTfMobilePhone();
$success=false;
if($currentMobilePhone==$mobilePhone){
$success=true;
}else{
$success = $user->updateAttributes(['auth_tf_mobile_phone' => $mobilePhone]);
$this->make(TwoFactorSmsCodeGeneratorService::class, [$user])->run();
}
return [
'success' => $success,
'message' => $success
? Yii::t('usuario', 'Mobile phone number successfully enabled.')
: Yii::t('usuario', 'Mobile phone number not registered.'),
];
}
}