diff --git a/Module.php b/Module.php index d325ee8ce..79f6ec606 100644 --- a/Module.php +++ b/Module.php @@ -84,6 +84,22 @@ class Module extends BaseModule /** @var array Model map */ public $modelMap = []; + /** @var array Ip configuration that determines if an administrator can log in. + * Defaults to null which means that no ip check is being performed. + * It uses the yii\validators\IpValidator for validation: + * @see http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html#ip + * @see http://www.yiiframework.com/doc-2.0/yii-validators-ipvalidator.html + * @example + 'ranges' => [ + '192.168.10.128' + '!192.168.10.0/24', + 'any' // allows any other IP addresses + ] + * In this example, access is allowed for all the IPv4 and IPv6 addresses excluding the 192.168.10.0/24 subnet. + * IPv4 address 192.168.10.128 is also allowed, because it is listed before the restriction. + */ + public $allowedIpConfiguration = null; + /** * @var string The prefix for user module URL. * diff --git a/models/LoginForm.php b/models/LoginForm.php index a3086e005..f1c923bce 100644 --- a/models/LoginForm.php +++ b/models/LoginForm.php @@ -14,10 +14,12 @@ use dektrium\user\Finder; use dektrium\user\helpers\Password; use dektrium\user\traits\ModuleTrait; +use yii\base\DynamicModel; use yii\helpers\ArrayHelper; use yii\helpers\Html; use Yii; use yii\base\Model; +use yii\validators\IpValidator; /** * LoginForm get user's login and password, validates them and logs the user in. If user has been blocked, it adds @@ -53,7 +55,7 @@ public function __construct(Finder $finder, $config = []) $this->finder = $finder; parent::__construct($config); } - + /** * Gets all users to generate the dropdown list when in debug mode. * @@ -145,6 +147,30 @@ public function login() } + /** + * Validates if an administrator is coming from the correct IP adress. + * + * @see Module $allowedIpConfiguration + * @see http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html#ip + * @see http://www.yiiframework.com/doc-2.0/yii-validators-ipvalidator.html + * @return mixed true if the check is correct, an array with the errors otherwise + */ + public function checkValidIpAddresses() + { + $config = $this->module->allowedIpConfiguration; + + if (!$this->user || !$this->user->isAdmin || !$config) { + return true; + } + + $rules = ArrayHelper::merge(['login', 'ip'], $config); + + $model = DynamicModel::validateData(['login' => Yii::$app->request->userIP], [$rules]); + + return $model->hasErrors() ? $model->getErrors() : true; + } + + /** @inheritdoc */ public function formName() { @@ -157,6 +183,14 @@ public function beforeValidate() if (parent::beforeValidate()) { $this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login)); + $valid = $this->checkValidIpAddresses(); + + if($valid !== true) { + foreach($valid as $error) { + $this->addError('login', $error); + } + } + return true; } else { return false;