-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2fa with email driver enabled by default to all users
- Loading branch information
0 parents
commit f72717c
Showing
14 changed files
with
664 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa; | ||
|
||
use humhub\modules\twofa\helpers\TwofaHelper; | ||
use Yii; | ||
|
||
class Events | ||
{ | ||
/** | ||
* Check if current User has been verified by 2fa if it is required | ||
* | ||
* @param $event | ||
* @return false|\yii\console\Response|\yii\web\Response | ||
*/ | ||
public static function onBeforeAction($event) | ||
{ | ||
if (Yii::$app->request->isAjax) { | ||
// TODO: maybe it should be restricted better, but we don't need to call this for PollController from live module indeed | ||
return false; | ||
} | ||
|
||
if (TwofaHelper::isVerifyingRequired() && | ||
!Yii::$app->getModule('twofa')->isTwofaCheckUrl()) { | ||
return Yii::$app->getResponse()->redirect(Yii::$app->getModule('twofa')->checkRoute); | ||
} | ||
} | ||
|
||
/** | ||
* Set flag after login to user who need 2fa | ||
* | ||
* @param $event | ||
* @throws \Throwable | ||
*/ | ||
public static function onAfterLogin($event) | ||
{ | ||
TwofaHelper::enableVerifying(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa; | ||
|
||
use humhub\modules\twofa\drivers\EmailDriver; | ||
use Yii; | ||
|
||
class Module extends \humhub\components\Module | ||
{ | ||
/** | ||
* @var array Drivers | ||
*/ | ||
public $drivers = [ | ||
EmailDriver::class, | ||
]; | ||
|
||
/** | ||
* @var string Route to check user for two-factor authentication | ||
*/ | ||
public $checkRoute = '/twofa/check'; | ||
|
||
/** | ||
* @return bool Check if current page is already URL of 2fa | ||
*/ | ||
public function isTwofaCheckUrl() | ||
{ | ||
return Yii::$app->requestedRoute === trim($this->checkRoute, '/'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
use humhub\modules\twofa\Events; | ||
use humhub\modules\user\controllers\AuthController; | ||
use yii\web\Controller; | ||
|
||
return [ | ||
'id' => 'twofa', | ||
'class' => 'humhub\modules\twofa\Module', | ||
'namespace' => 'humhub\modules\twofa', | ||
'events' => [ | ||
[AuthController::class, AuthController::EVENT_AFTER_LOGIN, [Events::class, 'onAfterLogin']], | ||
[Controller::class, Controller::EVENT_BEFORE_ACTION, [Events::class, 'onBeforeAction']], | ||
], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa\controllers; | ||
|
||
use humhub\components\Controller; | ||
use humhub\modules\twofa\helpers\TwofaHelper; | ||
use humhub\modules\twofa\models\CheckCode; | ||
use Yii; | ||
|
||
class CheckController extends Controller | ||
{ | ||
|
||
public $layout = "@twofa/views/layouts/main"; | ||
|
||
/** | ||
* Renders a form to check user after log in by two-factor authentication | ||
* | ||
* @return string | ||
*/ | ||
public function actionIndex() | ||
{ | ||
Yii::$app->getModule('live')->isActive = false; | ||
|
||
$model = new CheckCode(); | ||
|
||
if ($model->load(Yii::$app->request->post()) && $model->validate()) { | ||
TwofaHelper::disableVerifying(); | ||
|
||
$this->view->success(Yii::t('TwofaModule.base', 'Two-factor authentication code is validated!')); | ||
return $this->goHome(); | ||
} | ||
|
||
return $this->render('index', ['model' => $model]); | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Changelog | ||
========= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa\drivers; | ||
|
||
use Yii; | ||
|
||
abstract class BaseDriver | ||
{ | ||
/** | ||
* @var string Last generated code | ||
*/ | ||
private $code; | ||
|
||
/** | ||
* Return driver name | ||
* | ||
* @return string | ||
*/ | ||
abstract public function getName(); | ||
|
||
/** | ||
* Send new generated code | ||
* | ||
* @return bool true on success sending | ||
*/ | ||
abstract public function send(); | ||
|
||
/** | ||
* Get code, Generate random code on first call | ||
* | ||
* @return string | ||
*/ | ||
public function getCode() | ||
{ | ||
if (!isset($this->code)) { | ||
$this->code = Yii::$app->security->generateRandomString(6); | ||
} | ||
|
||
return $this->code; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa\drivers; | ||
|
||
use humhub\modules\user\models\User; | ||
use yii\mail\BaseMessage; | ||
use Yii; | ||
|
||
class EmailDriver extends BaseDriver | ||
{ | ||
/** | ||
* @inheritdoc | ||
*/ | ||
public function getName() | ||
{ | ||
return Yii::t('TwofaModule.base', 'E-mail'); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function send() | ||
{ | ||
/** @var User $user */ | ||
$user = Yii::$app->user->getIdentity(); | ||
if (!$user) { | ||
return false; | ||
} | ||
|
||
// Switch to users language - if specified | ||
if ($user->language !== '') { | ||
Yii::$app->language = $user->language; | ||
} | ||
|
||
/** @var BaseMessage $mail */ | ||
$mail = Yii::$app->mailer->compose([ | ||
'html' => '@twofa/views/mails/VerifyingCode', | ||
'text' => '@twofa/views/mails/plaintext/VerifyingCode' | ||
], [ | ||
'user' => $user, | ||
'code' => $this->getCode(), | ||
]); | ||
$mail->setTo($user->email); | ||
$mail->setSubject(Yii::t('TwofaModule.base', 'Two-Factor Authentication')); | ||
|
||
return $mail->send(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
|
||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) 2020 HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\twofa\helpers; | ||
|
||
use humhub\modules\content\components\ContentContainerSettingsManager; | ||
use humhub\modules\twofa\drivers\BaseDriver; | ||
use humhub\modules\twofa\drivers\EmailDriver; | ||
use humhub\modules\user\models\User; | ||
use humhub\modules\user\Module; | ||
use Yii; | ||
|
||
class TwofaHelper | ||
{ | ||
const USER_SETTING = 'twofaDriver'; | ||
const CODE_SETTING = 'twofaCode'; | ||
|
||
/** | ||
* Get settings manager of current User | ||
* | ||
* @return ContentContainerSettingsManager|false | ||
*/ | ||
public static function getSettings() | ||
{ | ||
/** @var User $user */ | ||
$user = Yii::$app->user->getIdentity(); | ||
/** @var Module $module */ | ||
$module = Yii::$app->getModule('user'); | ||
|
||
return $user ? $module->settings->contentContainer($user) : false; | ||
} | ||
|
||
/** | ||
* Get 2fa Driver for current User | ||
* | ||
* @return BaseDriver|false | ||
*/ | ||
public static function getDriver() | ||
{ | ||
/** @var BaseDriver $driverClass */ | ||
// TODO: Implement new user setting who should be checked by 2fa | ||
// $driverClass = self::getSettings()->get(self::USER_SETTING); | ||
$driverClass = EmailDriver::class; // Use temporary Email Driver by default enabled for all users | ||
|
||
if (in_array($driverClass, Yii::$app->getModule('twofa')->drivers )) { | ||
$driverClass = '\\' . $driverClass; | ||
return new $driverClass(); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Get verifying code of current User | ||
* | ||
* @return string|null | ||
*/ | ||
public static function getCode() | ||
{ | ||
return ($settings = self::getSettings()) ? $settings->get(self::CODE_SETTING) : null; | ||
} | ||
|
||
/** | ||
* Enable verifying by 2fa for current User | ||
* | ||
* @return bool true on success enabling | ||
*/ | ||
public static function enableVerifying() | ||
{ | ||
$settings = self::getSettings(); | ||
$driver = self::getDriver(); | ||
|
||
if (!$settings || !$driver) { | ||
// Current User may be not logged in | ||
// OR Wrong driver OR current User has no enabled 2fa | ||
return false; | ||
} | ||
|
||
if (!$driver->send()) { | ||
// Impossible to send a verifying code by Driver | ||
return false; | ||
} | ||
|
||
// TODO: Inform user about way of sending the verifying code | ||
|
||
// Store the sending verifying code in DB to use this as flag to display a form to check the code | ||
$settings->set(self::CODE_SETTING, md5($driver->getCode())); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Disable verifying by 2fa for current User | ||
*/ | ||
public static function disableVerifying() | ||
{ | ||
if ($settings = self::getSettings()) { | ||
$settings->delete(self::CODE_SETTING); | ||
} | ||
} | ||
|
||
/** | ||
* Check if verifying by 2fa is required for current User | ||
*/ | ||
public static function isVerifyingRequired() | ||
{ | ||
return self::getCode() !== null; | ||
} | ||
|
||
/** | ||
* Check the requested code is valid for current User | ||
* | ||
* @param $code | ||
* @return bool | ||
*/ | ||
public static function isValidCode($code) | ||
{ | ||
return md5($code) === self::getCode(); | ||
} | ||
} |
Oops, something went wrong.