diff --git a/README.md b/README.md index b1be3183..f9849251 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,13 @@ Perks * Visit log * Optimised (zero DB queries during usual user workflow) * Nice widgets like GhostMenu or GhostHtml::a where elements are visible only if user has access to route where they point +* LDAP support + +Features of this fork +~~~ + +* Correct maximum length of an email address +* Improved Spanish translation Installation @@ -17,20 +24,19 @@ Installation The preferred way to install this extension is through [composer](http://getcomposer.org/download/). -Either run - +Add the following lines to your `composer.json` file: ``` -composer require webvimark/module-user-management -``` - -or add - -``` -"webvimark/module-user-management": "^1" +"repositories": [ + { + "type": "vcs", + "url": "https://github.com/quique/user-management" + } +], +"require": { + "webvimark/module-user-management": "dev-dev", +}, ``` -to the require section of your `composer.json` file. - Configuration --- @@ -40,6 +46,8 @@ Configuration 'components'=>[ 'user' => [ + // 'identityClass' => 'app\models\User', + 'enableLdap' => false, // Change it to true to enable LDAP authentication 'class' => 'webvimark\modules\UserManagement\components\UserConfig', // Comment this if you don't want to record user logins @@ -65,7 +73,7 @@ Configuration // $: anchored to the end of the string //'passwordRegexp' => '^\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$', - + // Here you can set your handler to change layout for any controller or action // Tip: you can use this event in any module @@ -80,6 +88,22 @@ Configuration ``` +If needed, you can extend the base User class in app/models/User.php +(change the identityClass in the configuration accordingly): +```php + [ + 'host' => 'ldapserver.domain.net', + 'port' => 389, + 'base_dn' => 'ou=unit, dc=domain, dc=net', // Base Distinguished Name +], +``` + Where you can go ----- diff --git a/components/UserConfig.php b/components/UserConfig.php index 54de6e75..f814a5c5 100644 --- a/components/UserConfig.php +++ b/components/UserConfig.php @@ -6,57 +6,60 @@ use Yii; /** - * Class UserConfig - * @package webvimark\modules\UserManagement\components + * Class UserConfig. */ class UserConfig extends User { - /** - * @inheritdoc - */ - public $identityClass = 'webvimark\modules\UserManagement\models\User'; - - /** - * @inheritdoc - */ - public $enableAutoLogin = true; - - /** - * @inheritdoc - */ - public $cookieLifetime = 2592000; - - /** - * @inheritdoc - */ - public $loginUrl = ['/user-management/auth/login']; - - /** - * Allows to call Yii::$app->user->isSuperadmin - * - * @return bool - */ - public function getIsSuperadmin() - { - return @Yii::$app->user->identity->superadmin == 1; - } - - /** - * @return string - */ - public function getUsername() - { - return @Yii::$app->user->identity->username; - } - - /** - * @inheritdoc - */ - protected function afterLogin($identity, $cookieBased, $duration) - { - AuthHelper::updatePermissions($identity); - - parent::afterLogin($identity, $cookieBased, $duration); - } + /** + * {@inheritdoc} + */ + public $identityClass = 'webvimark\modules\UserManagement\models\User'; + /** + * {@inheritdoc} + */ + public $enableAutoLogin = true; + + /** + * {@inheritdoc} + */ + public $enableLdap = false; + + /** + * {@inheritdoc} + */ + public $cookieLifetime = 2592000; + + /** + * {@inheritdoc} + */ + public $loginUrl = ['/user-management/auth/login']; + + /** + * Allows to call Yii::$app->user->isSuperadmin. + * + * @return bool + */ + public function getIsSuperadmin() + { + return @Yii::$app->user->identity->superadmin == 1; + } + + /** + * @return string + */ + public function getUsername() + { + return @Yii::$app->user->identity->username; + } + + /** + * {@inheritdoc} + */ + protected function afterLogin($identity, $cookieBased, $duration) + { + AuthHelper::updatePermissions($identity); + + parent::afterLogin($identity, $cookieBased, $duration); + } } diff --git a/components/UserIdentity.php b/components/UserIdentity.php index 75fd6583..0006151f 100644 --- a/components/UserIdentity.php +++ b/components/UserIdentity.php @@ -1,186 +1,278 @@ $token, 'status' => User::STATUS_ACTIVE]); - } - - /** - * Finds user by username - * - * @param string $username - * @return static|null - */ - public static function findByUsername($username) - { - return static::findOne(['username' => $username, 'status' => User::STATUS_ACTIVE]); - } - - /** - * Finds user by confirmation token - * - * @param string $token confirmation token - * @return static|null|User - */ - public static function findByConfirmationToken($token) - { - $expire = Yii::$app->getModule('user-management')->confirmationTokenExpire; - - $parts = explode('_', $token); - $timestamp = (int)end($parts); - - if ( $timestamp + $expire < time() ) - { - // token expired - return null; - } - - return static::findOne([ - 'confirmation_token' => $token, - 'status' => User::STATUS_ACTIVE, - ]); - } - - /** - * Finds user by confirmation token - * - * @param string $token confirmation token - * @return static|null|User - */ - public static function findInactiveByConfirmationToken($token) - { - $expire = Yii::$app->getModule('user-management')->confirmationTokenExpire; - - $parts = explode('_', $token); - $timestamp = (int)end($parts); - - if ( $timestamp + $expire < time() ) - { - // token expired - return null; - } - - return static::findOne([ - 'confirmation_token' => $token, - 'status' => User::STATUS_INACTIVE, - ]); - } - - /** - * @inheritdoc - */ - public function getId() - { - return $this->getPrimaryKey(); - } - - /** - * @inheritdoc - */ - public function getAuthKey() - { - return $this->auth_key; - } - - /** - * @inheritdoc - */ - public function validateAuthKey($authKey) - { - return $this->getAuthKey() === $authKey; - } - - /** - * Validates password - * - * @param string $password password to validate - * @return boolean if password provided is valid for current user - */ - public function validatePassword($password) - { - return Yii::$app->security->validatePassword($password, $this->password_hash); - } - - /** - * Generates password hash from password and sets it to the model - * - * @param string $password - */ - public function setPassword($password) - { - if ( php_sapi_name() == 'cli' ) - { - $security = new Security(); - $this->password_hash = $security->generatePasswordHash($password); - } - else - { - $this->password_hash = Yii::$app->security->generatePasswordHash($password); - } - } - - /** - * Generates "remember me" authentication key - */ - public function generateAuthKey() - { - if ( php_sapi_name() == 'cli' ) - { - $security = new Security(); - $this->auth_key = $security->generateRandomString(); - } - else - { - $this->auth_key = Yii::$app->security->generateRandomString(); - } - } - - /** - * Generates new confirmation token - */ - public function generateConfirmationToken() - { - $this->confirmation_token = Yii::$app->security->generateRandomString() . '_' . time(); - } - - /** - * Removes confirmation token - */ - public function removeConfirmationToken() - { - $this->confirmation_token = null; - } -} \ No newline at end of file + /** + * {@inheritdoc} + */ + public static function findIdentity($id) + { + return static::findOne($id); + } + + /** + * {@inheritdoc} + */ + public static function findIdentityByAccessToken($token, $type = null) + { + return static::findOne(['auth_key' => $token, 'status' => User::STATUS_ACTIVE]); + } + + /** + * Finds user by username. + * + * @param string $username + * + * @return static|null + */ + public static function findByUsername($username) + { + return static::findOne(['username' => $username, 'status' => User::STATUS_ACTIVE]); + } + + /** + * Finds user by confirmation token. + * + * @param string $token confirmation token + * + * @return static|null|User + */ + public static function findByConfirmationToken($token) + { + $expire = Yii::$app->getModule('user-management')->confirmationTokenExpire; + + $parts = explode('_', $token); + $timestamp = (int) end($parts); + + if ($timestamp + $expire < time()) { + // token expired + return null; + } + + return static::findOne([ + 'confirmation_token' => $token, + 'status' => User::STATUS_ACTIVE, + ]); + } + + /** + * Finds user by confirmation token. + * + * @param string $token confirmation token + * + * @return static|null|User + */ + public static function findInactiveByConfirmationToken($token) + { + $expire = Yii::$app->getModule('user-management')->confirmationTokenExpire; + + $parts = explode('_', $token); + $timestamp = (int) end($parts); + + if ($timestamp + $expire < time()) { + // token expired + return null; + } + + return static::findOne([ + 'confirmation_token' => $token, + 'status' => User::STATUS_INACTIVE, + ]); + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->getPrimaryKey(); + } + + /** + * {@inheritdoc} + */ + public function getAuthKey() + { + return $this->auth_key; + } + + /** + * {@inheritdoc} + */ + public function validateAuthKey($authKey) + { + return $this->getAuthKey() === $authKey; + } + + /** + * Validates password, locally or via LDAP. + * + * @param string $password password to validate + * + * @return bool if password provided is valid for current user + */ + public function validatePassword($password) + { + // Local user + if ($this->auth_type === 'local') { + return Yii::$app->security->validatePassword($password, $this->password_hash); + } + + // LDAP user + if ($this->auth_type === 'ldap') { + $user = $this->username; + $ldap_host = Yii::$app->params['ldap']['host']; + $ldap_port = Yii::$app->params['ldap']['port']; + $base_dn = Yii::$app->params['ldap']['base_dn']; // Active Directory base DN + $dn = "uid=$user, $base_dn"; // Distinguised Name + + // Connecting to LDAP server + // The "@" will silence any php errors and warnings the function could raise. + // See http://php.net/manual/en/language.operators.errorcontrol.php + if (!$ds = @ldap_connect($ldap_host, $ldap_port)) { + throw new ServerErrorHttpException(UserManagementModule::t('back', 'The provided LDAP parameters are syntactically wrong.')); + } + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + + // ldap_connect() does not actually test the connection to the + // specified LDAP server, it is just a syntactic check. + // The only way to test the connection is to actually call + // ldap_bind($ds, $username, $password). + // But if that fails, is it because credentials were wrong, + // or is it because the app could not reach the LDAP server? + // + // One possible workaround is to try an anonymous bind first. + // Note that this workaround relies on anonymous login being enabled. + // TODO: Explore ldap_error($ds) and LDAP_OPT_DIAGNOSTIC_MESSAGE. + if (!($anon = @ldap_bind($ds))) { + throw new ServerErrorHttpException(UserManagementModule::t('back', 'Could not bind to the LDAP server.')); + } else { + // Test passed. Unbind anonymous. + ldap_unbind($ds); + } + + // Reconnect and try a real login. + if (!$ldapconn = @ldap_connect($ldap_host, $ldap_port)) { + throw new ServerErrorHttpException(UserManagementModule::t('back', 'The provided LDAP parameters are syntactically wrong.')); + } + ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0); // We need this for doing an LDAP search on Windows 2003 Server Active Directory. + if (!($bind = @ldap_bind($ldapconn, $dn, $password))) { + // Authentication failed + ldap_unbind($ldapconn); + + return false; + } + + // Successfully authenticated! + // If it is the first the user logs in, let's add it to the database. + if (!$this->id) { + $this->getUserAttributes($ldapconn, $base_dn); + $this->save(); + } + + ldap_unbind($ldapconn); + + return true; + } + + throw new ServerErrorHttpException(UserManagementModule::t('back', 'Unknown auth type.')); + } + + /** + * Search user attributes in the LDAP server, and add them to the User object. + * + * You may want to override this function in your custom User class. + * This is just a placeholder and example. + * + * @param resource $ldapconn An LDAP link identifier, returned by ldap_connect() + * @param string $base_dn The base DN for the directory + */ + protected function getUserAttributes($ldapconn, $base_dn) + { + /* + $filter = "(uid=$this->username)"; + // RFC specifications define many standard LDAP attributes, including + // RFC 2256: cn (Common Name) + // RFC 2798: mail (primary e-mail address) + // RFC 2307: uidNumber (user's integer identification number) + $attributes = ['mail']; + $results = @ldap_search($ldapconn, $base_dn, $filter, $attributes); + if (!$results) { + throw new ServerErrorHttpException(Yii::t('app', 'Unable to search LDAP server')); + } + // $number_returned = ldap_count_entries($ldapconn, $results); + $entries = ldap_get_entries($ldapconn, $results); + $mail = $entries[0]['mail'][0]; + + $this->email = $mail; + */ + } + + /** + * Generates password hash from password and sets it to the model. + * + * @param string $password + */ + public function setPassword($password) + { + if (php_sapi_name() == 'cli') { + $security = new Security(); + $this->password_hash = $security->generatePasswordHash($password); + } else { + $this->password_hash = Yii::$app->security->generatePasswordHash($password); + } + } + + /** + * Generates "remember me" authentication key. + */ + public function generateAuthKey() + { + if (php_sapi_name() == 'cli') { + $security = new Security(); + $this->auth_key = $security->generateRandomString(); + } else { + $this->auth_key = Yii::$app->security->generateRandomString(); + } + } + + /** + * Generates new confirmation token. + */ + public function generateConfirmationToken() + { + $this->confirmation_token = Yii::$app->security->generateRandomString().'_'.time(); + } + + /** + * Removes confirmation token. + */ + public function removeConfirmationToken() + { + $this->confirmation_token = null; + } +} diff --git a/messages/cs/back.php b/messages/cs/back.php index dd7fd4b7..4fe3857d 100644 --- a/messages/cs/back.php +++ b/messages/cs/back.php @@ -2,7 +2,7 @@ /** * Message translations. * - * This file is automatically generated by 'yii message' command. + * This file is automatically generated by 'yii message/extract' command. * It contains the localizable messages extracted from source code. * You may modify this file by translating the extracted messages. * @@ -19,6 +19,7 @@ return [ 'Active' => '', 'Are you sure you want to delete this user?' => '', + 'Authentication type' => '', 'Banned' => '', 'Bind to IP' => '', 'Browser' => '', @@ -30,6 +31,7 @@ 'Child roles' => '', 'Code' => '', 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', 'Create' => '', 'Created' => '', 'Creating permission group' => '', @@ -49,10 +51,9 @@ 'For example: 123.34.56.78, 168.111.192.12' => '', 'Group' => '', 'ID' => '', - 'Inactive' => '', 'IP' => '', + 'Inactive' => '', 'Language' => '', - 'Login' => '', 'Name' => '', 'OS' => '', 'Password' => '', @@ -81,9 +82,11 @@ 'Show only selected' => '', 'Status' => '', 'Superadmin' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', 'Token' => '', 'Too many attempts' => '', 'Type' => '', + 'Unknown auth type.' => '', 'Updated' => '', 'User' => '', 'User agent' => '', @@ -94,4 +97,5 @@ 'Wrong format. Enter valid IPs separated by comma' => '', 'Wrong password' => '', 'You can not change own permissions' => '', + 'Login' => '@@@@', ]; diff --git a/messages/de/back.php b/messages/de/back.php index 16965e3f..25d3d4d5 100644 --- a/messages/de/back.php +++ b/messages/de/back.php @@ -17,19 +17,37 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Banned' => '', + 'Browser' => '', + 'Code' => '', + 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', + 'E-mail' => '', + 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => '', + 'ID' => '', + 'IP' => '', + 'Name' => '', + 'Refresh routes' => '', + 'Refresh routes (and delete unused)' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'Search route' => '', + 'Show all' => '', + 'Show only selected' => '', + 'Status' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Token' => '', + 'Unknown auth type.' => '', + 'Login' => '@@@@', 'Active' => 'Aktiv', 'Are you sure you want to delete this user?' => 'Wollen Sie diesen Benutzer wirklich löschen?', - 'Banned' => '', 'Bind to IP' => 'An IP binden', - 'Browser' => '', 'Change own password' => 'Eigenes Passwort ändern', 'Change password' => 'Passwort ändern', 'Changing password' => 'Ändere Passwort', 'Changing password for user: ' => 'Ändere Passwort von Benutzer: ', 'Child permissions' => 'Kind-Berechtigungen', 'Child roles' => 'Kind-Rollen', - 'Code' => '', - 'Confirmation Token' => '', 'Create' => 'Erstellen', 'Created' => 'Erstellt', 'Creating permission group' => 'Erstelle Berechtigungs-Gruppe', @@ -37,9 +55,7 @@ 'Data' => 'Daten', 'Delete' => 'Löschen', 'Description' => 'Beschreibung', - 'E-mail' => '', 'E-mail confirmed' => 'E-Mail bestätigt', - 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => '', 'Edit' => 'Bearbeiten', 'Editing' => 'Bearbeite', 'Editing permission group' => 'Bearbeite Berechtigungs-Gruppe', @@ -48,12 +64,8 @@ 'Editing user: ' => 'Bearbeite Benutzer', 'For example: 123.34.56.78, 168.111.192.12' => 'Zum Beispiel: 123.34.56.78, 168.111.192.12', 'Group' => 'Gruppe', - 'ID' => '', 'Inactive' => 'Inaktiv', - 'IP' => '', 'Language' => 'Sprache', - 'Login' => '', - 'Name' => '', 'OS' => 'Betriebssystem', 'Password' => 'Passwort', 'Password has been changed' => 'Passwort wurde geändert', @@ -61,8 +73,6 @@ 'Permission groups' => 'Berechtigungs-Gruppen', 'Permissions' => 'Berechtigungen', 'Permissions for role:' => 'Berechtigungen für Rolle', - 'Refresh routes' => '', - 'Refresh routes (and delete unused)' => '', 'Registration IP' => 'Registrierung IP', 'Repeat password' => 'Passwort wiederholen', 'Reset' => 'Zurücksetzen', @@ -70,18 +80,12 @@ 'Roles' => 'Rollen', 'Roles and permissions' => 'Rollen und Berechtigungen', 'Roles and permissions for user:' => 'Rollen und Berechtigungen von Benutzer:', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => 'Rolle', 'Save' => 'Speichern', 'Saved' => 'Gespeichert', 'Search' => 'Suchen', - 'Search route' => '', 'Settings for permission' => 'Einstellungen für Berechtigung', - 'Show all' => '', - 'Show only selected' => '', - 'Status' => '', 'Superadmin' => 'Super-Administrator', - 'Token' => '', 'Too many attempts' => 'Zu viele Versuche', 'Type' => 'Typ', 'Updated' => 'Aktualisiert', diff --git a/messages/es/back.php b/messages/es/back.php index c254af93..3ef3d942 100644 --- a/messages/es/back.php +++ b/messages/es/back.php @@ -17,15 +17,19 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => 'Tipo de autenticación', + 'Could not bind to the LDAP server.' => 'No fue posible conectarse al servidor LDAP', + 'The provided LDAP parameters are syntactically wrong.' => 'Los parámetros de LDAP proporcionados no son sintácticamente correctos.', + 'Unknown auth type.' => 'Tipo de autenticación desconocido', 'Active' => 'Activo', - 'Are you sure you want to delete this user?' => '¿Está seguro que desea eliminar este usuario?', + 'Are you sure you want to delete this user?' => '¿Seguro que desea borrar este usuario?', 'Banned' => 'Bloqueado', - 'Bind to IP' => 'Casar a IP', + 'Bind to IP' => 'Asociar a la IP', 'Browser' => 'Navegador', - 'Change own password' => 'Cambiar propia contraseña', - 'Change password' => 'Cambiar contraseña de usuario', - 'Changing password' => 'Cambiando contraseña', - 'Changing password for user: ' => 'Cambiando contraseña para usuario: ', + 'Change own password' => 'Cambiar la contraseña propia', + 'Change password' => 'Cambiar la contraseña', + 'Changing password' => 'Cambio de la contraseña', + 'Changing password for user: ' => 'Cambiando la contraseña del usuario: ', 'Child permissions' => 'Permisos hijos', 'Child roles' => 'Roles hijos', 'Code' => 'Código', @@ -33,65 +37,64 @@ 'Create' => 'Crear', 'Created' => 'Creado', 'Creating permission group' => 'Creación de grupo de permisos', - 'Current password' => 'Actual contraseña', + 'Current password' => 'Contraseña actual', 'Data' => 'Dato', - 'Delete' => 'Eliminar', + 'Delete' => 'Borrar', 'Description' => 'Descripción', 'E-mail' => 'Correo electrónico', 'E-mail confirmed' => 'Correo confirmado', - 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => 'Un correo electrónico con un enlace de activación ha sido enviado a {email}. El enlace expirara en {minutes} minutos.', + 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => 'Se ha enviado un correo electrónico con un enlace de activación a {email}. El enlace expirará en {minutes} minutos.', 'Edit' => 'Editar', - 'Editing' => 'Editando', - 'Editing permission group' => 'Editando grupo de permiso', + 'Editing' => 'Edición', + 'Editing permission group' => 'Edición de grupo de permisos', 'Editing permission: ' => 'Editando permiso:', 'Editing role: ' => 'Editando rol:', 'Editing user: ' => 'Editando usuario:', 'For example: 123.34.56.78, 168.111.192.12' => 'Por ejemplo: 123.34.56.78, 168.111.192.12', 'Group' => 'Grupo', 'ID' => 'Id', - 'Inactive' => 'Inactivo', 'IP' => 'IP', + 'Inactive' => 'Inactivo', 'Language' => 'Idioma', - 'Login' => 'Inicio de sesión', 'Name' => 'Nombre', 'OS' => 'Sistema Operativo', 'Password' => 'Contraseña', - 'Password has been changed' => 'Contraseña ha sido cambiada', + 'Password has been changed' => 'Se ha cambiado la contraseña', 'Permission creation' => 'Creación de permisos', 'Permission groups' => 'Grupos de permisos', 'Permissions' => 'Permisos', - 'Permissions for role:' => 'Permisos de role:', - 'Refresh routes' => 'Refrescar rutas', - 'Refresh routes (and delete unused)' => 'Refrescar rutas (y eliminar sin uso)', - 'Registration IP' => 'IP Registrada', - 'Repeat password' => 'Repetir contraseña', - 'Reset' => 'Reestablecer', - 'Role creation' => 'Creación de Rol', + 'Permissions for role:' => 'Permisos del rol:', + 'Refresh routes' => 'Refrescar las rutas', + 'Refresh routes (and delete unused)' => 'Refrescar las rutas (y borrar las que no se usan)', + 'Registration IP' => 'IP de registro', + 'Repeat password' => 'Repita la contraseña', + 'Reset' => 'Restablecer', + 'Role creation' => 'Creación de rol', 'Roles' => 'Roles', 'Roles and permissions' => 'Roles y permisos', - 'Roles and permissions for user:' => 'Roles y permisos para el usuario', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => 'Se eliminarán rutas que no existan en esta aplicación. No se recomienda para aplicaciones con estructura de "avanzada", porque frontend y backend tienen que propio conjunto de rutas.', + 'Roles and permissions for user:' => 'Roles y permisos para el usuario:', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => 'Se eliminarán rutas que no existan en esta aplicación. No se recomienda para aplicaciones con estructura «avanzada», porque frontend y backend tienen su propio conjunto de rutas.', 'Rule' => 'Regla', 'Save' => 'Guardar', 'Saved' => 'Guardado', 'Search' => 'Buscar', - 'Search route' => 'Buscar ruta', + 'Search route' => 'Buscar una ruta', 'Settings for permission' => 'Configuración de permiso', 'Show all' => 'Mostrar todos', - 'Show only selected' => 'Mostrar solo seleccionados', - 'Status' => 'Estatus', - 'Superadmin' => 'Super admin', + 'Show only selected' => 'Mostrar sólo los seleccionados', + 'Status' => 'Estado', + 'Superadmin' => 'Superadmin', 'Token' => 'Código Token', 'Too many attempts' => 'Demasiados intentos', 'Type' => 'Tipo', 'Updated' => 'Actualizado', 'User' => 'Usuario', - 'User agent' => 'Agente de Usuario', - 'User creation' => 'Creación de Usuario', + 'User agent' => 'Agente de usuario', + 'User creation' => 'Creación de usuario', 'Users' => 'Usuarios', 'Visit Time' => 'Fecha de visita', 'Visit log' => 'Registro de visita', - 'Wrong format. Enter valid IPs separated by comma' => 'Formato incorrecto. Ingrese IPs valida separada por coma', + 'Wrong format. Enter valid IPs separated by comma' => 'Formato incorrecto. Introduzca IPs válidas separadas por comas', 'Wrong password' => 'Contraseña incorrecta', 'You can not change own permissions' => 'Usted no puede cambiar sus propios permisos', ]; diff --git a/messages/es/front.php b/messages/es/front.php index 45c34b9c..b60f88ab 100644 --- a/messages/es/front.php +++ b/messages/es/front.php @@ -20,33 +20,33 @@ 'Username' => 'Nombre de usuario', 'Authorization' => 'Autorización', 'Captcha' => 'Código Captcha', - 'Check your E-mail for further instructions' => 'Verifique su correo electrónico para futura instrucciones', - 'Check your e-mail {email} for instructions to activate account' => 'Verifique su correo electrónico {mail} para obtener las instrucciones para activar la cuenta', + 'Check your E-mail for further instructions' => 'Verifique su correo electrónico para más instrucciones', + 'Check your e-mail {email} for instructions to activate account' => 'Verifique su correo electrónico {email} para obtener las instrucciones para activar la cuenta', 'Confirm' => 'Confirmar', 'Confirm E-mail' => 'Confirmar correo electrónico', 'Continue' => 'Continuar', - 'Could not send confirmation email' => 'No fue posible enviar correo electrónico de confirmación', + 'Could not send confirmation email' => 'No fue posible enviar el correo electrónico de confirmación', 'E-mail' => 'Correo electrónico', - 'E-mail confirmation for' => 'Correo electrónico para confirmación', + 'E-mail confirmation for' => 'Confirmación del correo electrónico de', 'E-mail confirmed' => 'Correo electrónico confirmado', - 'E-mail is invalid' => 'Correo electrónico inválido', - 'Forgot password ?' => '¿Olvido la contraseña?', + 'E-mail is invalid' => 'Correo electrónico no válido', + 'Forgot password ?' => '¿Olvidó la contraseña?', 'Incorrect username or password.' => 'Nombre de usuario o contraseña incorrecta.', - 'Login' => 'Inicio de sesión', - 'Login has been taken' => 'Este login ya existe', + 'Login' => 'Iniciar sesión', + 'Login has been taken' => 'Este usuario ya existe', 'Password' => 'Contraseña', - 'Password recovery' => 'Recuperación de contraseña', - 'Password reset for' => 'Contraseña a definir de nuevo', + 'Password recovery' => 'Recuperación de la contraseña', + 'Password reset for' => 'Restablecer la contraseña de', 'Recover' => 'Recuperar', 'Register' => 'Registrar', 'Registration' => 'Registro', - 'Registration - confirm your e-mail' => 'Registro - Confirmar su correo electrónico', + 'Registration - confirm your e-mail' => 'Registro - Confirme su correo electrónico', 'Remember me' => 'Recordarme', - 'Repeat password' => 'Repita a contraseña', + 'Repeat password' => 'Repita la contraseña', 'This E-mail already exists' => 'Este correo electrónico ya existe', - 'Token not found. It may be expired' => 'Token no encontrado. Pode haber expirado', - 'Token not found. It may be expired. Try reset password once more' => 'Token no encontrado. Pode haber expirado. Trate de redefinir a contraseña una vez mas', + 'Token not found. It may be expired' => 'Token no encontrado. Puede haber expirado', + 'Token not found. It may be expired. Try reset password once more' => 'Token no encontrado. Puede haber expirado. Trate de restablecer la contraseña una vez más', 'Too many attempts' => 'Demasiados intentos', - 'Unable to send message for email provided' => 'Deshabilitado para enviar mensaje por correo electrónico proveído', - 'You could not login from this IP' => 'Usted no puede iniciar sesión desde esta dirección IP', + 'Unable to send message for email provided' => 'No fue posible enviar mensaje al correo electrónico indicado', + 'You could not login from this IP' => 'No pudo iniciar sesión desde esta dirección IP', ]; diff --git a/messages/fr/back.php b/messages/fr/back.php index 27a4be20..767ed67a 100644 --- a/messages/fr/back.php +++ b/messages/fr/back.php @@ -17,6 +17,12 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Could not bind to the LDAP server.' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Unknown auth type.' => '', + 'Login' => '@@Identifiant@@', 'Active' => 'Actif', 'Are you sure you want to delete this user?' => 'Etes-vous sûre de vouloir supprimer cet utilisateur ?', 'Banned' => 'Banni', @@ -49,10 +55,9 @@ 'For example: 123.34.56.78, 168.111.192.12' => 'Par exemple: 123.34.56.78, 168.111.192.12', 'Group' => 'Groupe', 'ID' => 'ID', - 'Inactive' => 'Inactif', 'IP' => 'Adresse IP', + 'Inactive' => 'Inactif', 'Language' => 'Langage', - 'Login' => 'Identifiant', 'Name' => 'Nom', 'OS' => 'OS', 'Password' => 'Mot de passe', @@ -70,7 +75,6 @@ 'Roles' => 'Rôles', 'Roles and permissions' => 'Rôles et permissions', 'Roles and permissions for user:' => 'Rôles et permissions pour l\'utilisateur:', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => 'Rêgle', 'Save' => 'Enregistrer', 'Saved' => 'Enregistrement', diff --git a/messages/ko-KR/back.php b/messages/ko-KR/back.php index 22aa9fdb..1fc32a98 100644 --- a/messages/ko-KR/back.php +++ b/messages/ko-KR/back.php @@ -17,9 +17,25 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Banned' => '', + 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', + 'E-mail' => '', + 'ID' => '', + 'IP' => '', + 'Refresh routes' => '', + 'Refresh routes (and delete unused)' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'Search route' => '', + 'Show all' => '', + 'Show only selected' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Token' => '', + 'Unknown auth type.' => '', + 'Login' => '@@로그인@@', 'Active' => '활성', 'Are you sure you want to delete this user?' => '이 사용자를 삭제하시겠습니까?', - 'Banned' => '', 'Bind to IP' => '아이피에 바인드', 'Browser' => '브라우져', 'Change own password' => '자신의 암호를 변경', @@ -29,7 +45,6 @@ 'Child permissions' => '자식 권한', 'Child roles' => '자식 역할', 'Code' => '코드', - 'Confirmation Token' => '', 'Create' => '생성', 'Created' => '성됨', 'Creating permission group' => '권한 그룹 생성중', @@ -37,7 +52,6 @@ 'Data' => '데이터', 'Delete' => '삭제', 'Description' => '설명', - 'E-mail' => '', 'E-mail confirmed' => 'E-Mail 승인됨', 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => '{email} 로 계정 활성화 링크를 보냈습니다. 이 메일은 {minutes}분 동안 유효합니다', 'Edit' => '편집', @@ -48,11 +62,8 @@ 'Editing user: ' => '사용자 편집중', 'For example: 123.34.56.78, 168.111.192.12' => '예시 : 123.34.56.78, 168.111.192.12', 'Group' => '그룹', - 'ID' => '', 'Inactive' => '비활성화', - 'IP' => '', 'Language' => '언어', - 'Login' => '로그인', 'Name' => '이름', 'OS' => '운영체제', 'Password' => '암호', @@ -61,8 +72,6 @@ 'Permission groups' => '권한 그룹들', 'Permissions' => '권한들', 'Permissions for role:' => '역할을 위한 권한', - 'Refresh routes' => '', - 'Refresh routes (and delete unused)' => '', 'Registration IP' => '등록 IP', 'Repeat password' => '암호 반복', 'Reset' => '재설정', @@ -70,18 +79,13 @@ 'Roles' => '역할들', 'Roles and permissions' => '역할과 권한', 'Roles and permissions for user:' => '사용자를 위한역할과 권한:', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => '규칙', 'Save' => '저장', 'Saved' => '저장됨', 'Search' => '검색', - 'Search route' => '', 'Settings for permission' => '권한을 위한설정', - 'Show all' => '', - 'Show only selected' => '', 'Status' => '상태', 'Superadmin' => '슈퍼 관리자', - 'Token' => '', 'Too many attempts' => '너무 많은 시도들', 'Type' => '유형', 'Updated' => '수정됨', diff --git a/messages/pl/back.php b/messages/pl/back.php index 884e9d34..4c0feefb 100644 --- a/messages/pl/back.php +++ b/messages/pl/back.php @@ -17,6 +17,26 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', + 'E-mail' => '', + 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => '', + 'ID' => '', + 'IP' => '', + 'Permission creation' => '', + 'Refresh routes' => '', + 'Refresh routes (and delete unused)' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'Search route' => '', + 'Show all' => '', + 'Show only selected' => '', + 'Status' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Token' => '', + 'Unknown auth type.' => '', + 'User agent' => '', + 'Login' => '@@Login@@', 'Active' => 'Aktywny', 'Are you sure you want to delete this user?' => 'Czy na pewno chcesz usunąć tego użytkownika?', 'Banned' => 'Zbanowany', @@ -29,7 +49,6 @@ 'Child permissions' => 'Podrzędne uprawnienia', 'Child roles' => 'Podrzędne role', 'Code' => 'Kod', - 'Confirmation Token' => '', 'Create' => 'Utwórz', 'Created' => 'Utworzone', 'Creating permission group' => 'Tworzenie grupy uprawnień', @@ -37,9 +56,7 @@ 'Data' => 'Dane', 'Delete' => 'Usuń', 'Description' => 'Opis', - 'E-mail' => '', 'E-mail confirmed' => 'E-mail potwierdzony', - 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => '', 'Edit' => 'Edytuj', 'Editing' => 'Edytowanie', 'Editing permission group' => 'Edytowanie grupy uprawnień: ', @@ -48,21 +65,15 @@ 'Editing user: ' => 'Edycja użytkownika: ', 'For example: 123.34.56.78, 168.111.192.12' => 'Przykładowo: 123.34.56.78, 168.111.192.12', 'Group' => 'Grupa', - 'ID' => '', 'Inactive' => 'Nieaktywny', - 'IP' => '', 'Language' => 'Język', - 'Login' => 'Login', 'Name' => 'Nazwa', 'OS' => 'System', 'Password' => 'Hasło', 'Password has been changed' => 'Hasło zostało zmienione', - 'Permission creation' => '', 'Permission groups' => 'Grupy uprawnień', 'Permissions' => 'Uprawnienia', 'Permissions for role:' => 'Uprawnienia roli: ', - 'Refresh routes' => '', - 'Refresh routes (and delete unused)' => '', 'Registration IP' => 'Adres IP rejestracji', 'Repeat password' => 'Powtórz hasło', 'Reset' => 'Resetuj', @@ -70,23 +81,16 @@ 'Roles' => 'Role', 'Roles and permissions' => 'Role i uprawnienia', 'Roles and permissions for user:' => 'Role i uprawnienia użytkownika: ', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => 'Reguła', 'Save' => 'Zapisz', 'Saved' => 'Zapisano', 'Search' => 'Szukaj', - 'Search route' => '', 'Settings for permission' => 'Ustawienia uprawnień', - 'Show all' => '', - 'Show only selected' => '', - 'Status' => '', 'Superadmin' => 'Superadministrator', - 'Token' => '', 'Too many attempts' => 'Zbyt wiele prób', 'Type' => 'Typ', 'Updated' => 'Zaktualizowano', 'User' => 'Użytkownik', - 'User agent' => '', 'User creation' => 'Dodawanie użytkownika', 'Users' => 'Użytkownicy', 'Visit Time' => 'Ostatnia wizyta', diff --git a/messages/pt-BR/back.php b/messages/pt-BR/back.php index a4fd7689..da2ded6e 100644 --- a/messages/pt-BR/back.php +++ b/messages/pt-BR/back.php @@ -17,7 +17,9 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', 'E-mail' => '', 'ID' => '', 'IP' => '', @@ -28,7 +30,10 @@ 'Show all' => '', 'Show only selected' => '', 'Superadmin' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', 'Token' => '', + 'Unknown auth type.' => '', + 'Login' => '@@Login@@', 'Permissions for role - "{role}"' => '@@Permissões da função - "{role}"@@', 'Active' => 'Ativo', 'Are you sure you want to delete this user?' => 'Você tem certeza de que deseja excluir este usuário?', @@ -61,7 +66,6 @@ 'Group' => 'Grupo', 'Inactive' => 'Inativo', 'Language' => 'Idioma', - 'Login' => 'Login', 'Name' => 'Nome', 'OS' => 'Sistema operacional', 'Password' => 'Senha', diff --git a/messages/pt-PT/back.php b/messages/pt-PT/back.php index 467d5711..49199426 100644 --- a/messages/pt-PT/back.php +++ b/messages/pt-PT/back.php @@ -17,9 +17,25 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Banned' => '', + 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', + 'E-mail' => '', + 'ID' => '', + 'IP' => '', + 'Refresh routes' => '', + 'Refresh routes (and delete unused)' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'Search route' => '', + 'Show all' => '', + 'Show only selected' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Token' => '', + 'Unknown auth type.' => '', + 'Login' => '@@Nome de utilizador@@', 'Active' => 'Ativo', 'Are you sure you want to delete this user?' => 'Você tem certeza de que deseja excluir este utilizador?', - 'Banned' => '', 'Bind to IP' => 'Víncular ao IP', 'Browser' => 'Navegador', 'Change own password' => 'Alterar a própria senha', @@ -29,7 +45,6 @@ 'Child permissions' => 'Permissões filhas', 'Child roles' => 'Regras filhas', 'Code' => 'Código', - 'Confirmation Token' => '', 'Create' => 'Criar', 'Created' => 'Criado', 'Creating permission group' => 'Criando grupo de permissões', @@ -37,9 +52,8 @@ 'Data' => 'Dados', 'Delete' => 'Excluir', 'Description' => 'Descrição', - 'E-mail' => '', 'E-mail confirmed' => 'E-mail confirmado', - 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' =>'Um e-mail com o link de ativação foi enviado para {email}. Este link irá expirar dentro de {minutes} minutos.', + 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => 'Um e-mail com o link de ativação foi enviado para {email}. Este link irá expirar dentro de {minutes} minutos.', 'Edit' => 'Editar', 'Editing' => 'Editando', 'Editing permission group' => 'Editando grupo de permissões', @@ -48,11 +62,8 @@ 'Editing user: ' => 'Editando utilizador: ', 'For example: 123.34.56.78, 168.111.192.12' => 'Por exemplo: 123.34.56.78, 168.111.192.12', 'Group' => 'Grupo', - 'ID' => '', 'Inactive' => 'Inativo', - 'IP' => '', 'Language' => 'Idioma', - 'Login' => 'Nome de utilizador', 'Name' => 'Nome', 'OS' => 'SO', 'Password' => 'Senha', @@ -61,8 +72,6 @@ 'Permission groups' => 'Grupos de permissão', 'Permissions' => 'Permissões', 'Permissions for role:' => 'Permissões da função:', - 'Refresh routes' => '', - 'Refresh routes (and delete unused)' => '', 'Registration IP' => 'Registo do IP', 'Repeat password' => 'Repetir senha', 'Reset' => 'Redefinir', @@ -70,18 +79,13 @@ 'Roles' => 'Funções', 'Roles and permissions' => 'Funções e permissões', 'Roles and permissions for user:' => 'Funções e permissões do utilizador:', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => 'Regra', 'Save' => 'Salvar', 'Saved' => 'Salvo', 'Search' => 'Buscar', - 'Search route' => '', 'Settings for permission' => 'Configurações de permissões', - 'Show all' => '', - 'Show only selected' => '', 'Status' => 'Estado', 'Superadmin' => 'Superadmin', - 'Token' => '', 'Too many attempts' => 'Demasiadas tentativas', 'Type' => 'Tipo', 'Updated' => 'Atualizado', diff --git a/messages/ru/back.php b/messages/ru/back.php index 42e083ea..2675f72b 100644 --- a/messages/ru/back.php +++ b/messages/ru/back.php @@ -17,9 +17,25 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Authentication type' => '', + 'Banned' => '', + 'Confirmation Token' => '', + 'Could not bind to the LDAP server.' => '', + 'E-mail' => '', + 'ID' => '', + 'IP' => '', + 'Refresh routes' => '', + 'Refresh routes (and delete unused)' => '', + 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', + 'Search route' => '', + 'Show all' => '', + 'Show only selected' => '', + 'The provided LDAP parameters are syntactically wrong.' => '', + 'Token' => '', + 'Unknown auth type.' => '', + 'Login' => '@@Логин@@', 'Active' => 'Активен', 'Are you sure you want to delete this user?' => 'Вы уверены, что хотите удалить этого пользователя ?', - 'Banned' => '', 'Bind to IP' => 'Привязать к IP', 'Browser' => 'Браузер', 'Change own password' => 'Смена пароля', @@ -29,7 +45,6 @@ 'Child permissions' => 'Дочерние права', 'Child roles' => 'Дочерние роли', 'Code' => 'Код', - 'Confirmation Token' => '', 'Create' => 'Создать', 'Created' => 'Создано', 'Creating permission group' => 'Создание группы прав', @@ -37,7 +52,6 @@ 'Data' => 'Данные', 'Delete' => 'Удалить', 'Description' => 'Описание', - 'E-mail' => '', 'E-mail confirmed' => 'E-mail подтверждён', 'E-mail with activation link has been sent to {email}. This link will expire in {minutes} min.' => 'Ссылка активации была отправлена на {email}>. Срок действия ссылки {minutes} мин.', 'Edit' => 'Редактировать', @@ -48,11 +62,8 @@ 'Editing user: ' => 'Редактирование пользователя: ', 'For example: 123.34.56.78, 168.111.192.12' => 'Напрмиер: 123.34.56.78, 168.111.192.12', 'Group' => 'Группа', - 'ID' => '', 'Inactive' => 'Неактивен', - 'IP' => '', 'Language' => 'Язык', - 'Login' => 'Логин', 'Name' => 'Название', 'OS' => 'ОС', 'Password' => 'Пароль', @@ -61,8 +72,6 @@ 'Permission groups' => 'Группы прав', 'Permissions' => 'Права', 'Permissions for role:' => 'Права для роли:', - 'Refresh routes' => '', - 'Refresh routes (and delete unused)' => '', 'Registration IP' => 'IP регистрации', 'Repeat password' => 'Повторите пароль', 'Reset' => 'Сбросить', @@ -70,18 +79,13 @@ 'Roles' => 'Роли', 'Roles and permissions' => 'Роли и права', 'Roles and permissions for user:' => 'Роли и права для пользователя', - 'Routes that are not exists in this application will be deleted. Do not recommended for application with "advanced" structure, because frontend and backend have they own set of routes.' => '', 'Rule' => 'Правило', 'Save' => 'Сохранить', 'Saved' => 'Сохранено', 'Search' => 'Поиск', - 'Search route' => '', 'Settings for permission' => 'Настройки для права', - 'Show all' => '', - 'Show only selected' => '', 'Status' => 'Статус', 'Superadmin' => 'Суперадмин', - 'Token' => '', 'Too many attempts' => 'Лимит попыток превышен', 'Type' => 'Тип', 'Updated' => 'Обновлено', diff --git a/migrations/m170307_100221_update_email_type.php b/migrations/m170307_100221_update_email_type.php new file mode 100644 index 00000000..9acbab96 --- /dev/null +++ b/migrations/m170307_100221_update_email_type.php @@ -0,0 +1,29 @@ +alterColumn('user', 'email', 'varchar(254)'); + } + + public function down() + { + echo "m170307_100221_update_email_type cannot be reverted.\n"; + + return false; + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/migrations/m170315_110029_add_auth_type_column_to_user_table.php b/migrations/m170315_110029_add_auth_type_column_to_user_table.php new file mode 100644 index 00000000..0b757232 --- /dev/null +++ b/migrations/m170315_110029_add_auth_type_column_to_user_table.php @@ -0,0 +1,25 @@ +addColumn('user', 'auth_type', $this->string(15)->defaultValue('local')); + } + + /** + * {@inheritdoc} + */ + public function down() + { + $this->dropColumn('user', 'auth_type'); + } +} diff --git a/migrations/mysql.schema.sql b/migrations/mysql.schema.sql index 1e83df31..98b5ee1f 100644 --- a/migrations/mysql.schema.sql +++ b/migrations/mysql.schema.sql @@ -280,7 +280,7 @@ CREATE TABLE IF NOT EXISTS `user` ( `updated_at` int(11) NOT NULL, `registration_ip` varchar(15) DEFAULT NULL, `bind_to_ip` varchar(255) DEFAULT NULL, - `email` varchar(128) DEFAULT NULL, + `email` varchar(254) DEFAULT NULL, `email_confirmed` smallint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; diff --git a/models/User.php b/models/User.php index 51002567..3e0b8361 100644 --- a/models/User.php +++ b/models/User.php @@ -15,406 +15,380 @@ /** * This is the model class for table "user". * - * @property integer $id + * @property int $id * @property string $username * @property string $email - * @property integer $email_confirmed + * @property int $email_confirmed * @property string $auth_key * @property string $password_hash * @property string $confirmation_token * @property string $bind_to_ip * @property string $registration_ip - * @property integer $status - * @property integer $superadmin - * @property integer $created_at - * @property integer $updated_at + * @property int $status + * @property int $superadmin + * @property int $created_at + * @property int $updated_at */ class User extends UserIdentity { - const STATUS_ACTIVE = 1; - const STATUS_INACTIVE = 0; - const STATUS_BANNED = -1; - - /** - * @var string - */ - public $gridRoleSearch; - - /** - * @var string - */ - public $password; - - /** - * @var string - */ - public $repeat_password; - - /** - * Store result in singleton to prevent multiple db requests with multiple calls - * - * @param bool $fromSingleton - * - * @return static - */ - public static function getCurrentUser($fromSingleton = true) - { - if ( !$fromSingleton ) - { - return static::findOne(Yii::$app->user->id); - } - - $user = Singleton::getData('__currentUser'); - - if ( !$user ) - { - $user = static::findOne(Yii::$app->user->id); - - Singleton::setData('__currentUser', $user); - } - - return $user; - } - - /** - * Assign role to user - * - * @param int $userId - * @param string $roleName - * - * @return bool - */ - public static function assignRole($userId, $roleName) - { - try - { - Yii::$app->db->createCommand() - ->insert(Yii::$app->getModule('user-management')->auth_assignment_table, [ - 'user_id' => $userId, - 'item_name' => $roleName, - 'created_at' => time(), - ])->execute(); - - AuthHelper::invalidatePermissions(); - - return true; - } - catch (\Exception $e) - { - return false; - } - } - - /** - * Revoke role from user - * - * @param int $userId - * @param string $roleName - * - * @return bool - */ - public static function revokeRole($userId, $roleName) - { - $result = Yii::$app->db->createCommand() - ->delete(Yii::$app->getModule('user-management')->auth_assignment_table, ['user_id' => $userId, 'item_name' => $roleName]) - ->execute() > 0; - - if ( $result ) - { - AuthHelper::invalidatePermissions(); - } - - return $result; - } - - /** - * @param string|array $roles - * @param bool $superAdminAllowed - * - * @return bool - */ - public static function hasRole($roles, $superAdminAllowed = true) - { - if ( $superAdminAllowed AND Yii::$app->user->isSuperadmin ) - { - return true; - } - $roles = (array)$roles; - - AuthHelper::ensurePermissionsUpToDate(); - - return array_intersect($roles, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_ROLES,[])) !== []; - } - - /** - * @param string $permission - * @param bool $superAdminAllowed - * - * @return bool - */ - public static function hasPermission($permission, $superAdminAllowed = true) - { - if ( $superAdminAllowed AND Yii::$app->user->isSuperadmin ) - { - return true; - } - - AuthHelper::ensurePermissionsUpToDate(); - - return in_array($permission, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_PERMISSIONS,[])); - } - - /** - * Useful for Menu widget - * - * - * ... - * [ 'label'=>'Some label', 'url'=>['/site/index'], 'visible'=>User::canRoute(['/site/index']) ] - * ... - * - * - * @param string|array $route - * @param bool $superAdminAllowed - * - * @return bool - */ - public static function canRoute($route, $superAdminAllowed = true) - { - if ( $superAdminAllowed AND Yii::$app->user->isSuperadmin ) - { - return true; - } - - $baseRoute = AuthHelper::unifyRoute($route); - - if ( Route::isFreeAccess($baseRoute) ) - { - return true; - } - - AuthHelper::ensurePermissionsUpToDate(); - - return Route::isRouteAllowed($baseRoute, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_ROUTES,[])); - } - - /** - * getStatusList - * @return array - */ - public static function getStatusList() - { - return array( - self::STATUS_ACTIVE => UserManagementModule::t('back', 'Active'), - self::STATUS_INACTIVE => UserManagementModule::t('back', 'Inactive'), - self::STATUS_BANNED => UserManagementModule::t('back', 'Banned'), - ); - } - - /** - * getStatusValue - * - * @param string $val - * - * @return string - */ - public static function getStatusValue($val) - { - $ar = self::getStatusList(); - - return isset( $ar[$val] ) ? $ar[$val] : $val; - } - - /** - * @inheritdoc - */ - public static function tableName() - { - return Yii::$app->getModule('user-management')->user_table; - } - - /** - * @inheritdoc - */ - public function behaviors() - { - return [ - TimestampBehavior::className(), - ]; - } - - /** - * @inheritdoc - */ - public function rules() - { - return [ - ['username', 'required'], - ['username', 'unique'], - ['username', 'trim'], - - [['status', 'email_confirmed'], 'integer'], - - ['email', 'email'], - ['email', 'validateEmailConfirmedUnique'], - - ['bind_to_ip', 'validateBindToIp'], - ['bind_to_ip', 'trim'], - ['bind_to_ip', 'string', 'max' => 255], - - ['password', 'required', 'on'=>['newUser', 'changePassword']], - ['password', 'string', 'max' => 255, 'on'=>['newUser', 'changePassword']], - ['password', 'trim', 'on'=>['newUser', 'changePassword']], - ['password', 'match', 'pattern' => Yii::$app->getModule('user-management')->passwordRegexp], - - ['repeat_password', 'required', 'on'=>['newUser', 'changePassword']], - ['repeat_password', 'compare', 'compareAttribute'=>'password'], - ]; - } - - /** - * Check that there is no such confirmed E-mail in the system - */ - public function validateEmailConfirmedUnique() - { - if ( $this->email ) - { - $exists = User::findOne([ - 'email' => $this->email, - 'email_confirmed' => 1, - ]); - - if ( $exists AND $exists->id != $this->id ) - { - $this->addError('email', UserManagementModule::t('front', 'This E-mail already exists')); - } - } - } - - /** - * Validate bind_to_ip attr to be in correct format - */ - public function validateBindToIp() - { - if ( $this->bind_to_ip ) - { - $ips = explode(',', $this->bind_to_ip); - - foreach ($ips as $ip) - { - if ( !filter_var(trim($ip), FILTER_VALIDATE_IP) ) - { - $this->addError('bind_to_ip', UserManagementModule::t('back', "Wrong format. Enter valid IPs separated by comma")); - } - } - } - } - - /** - * @return array - */ - public function attributeLabels() - { - return [ - 'id' => 'ID', - 'username' => UserManagementModule::t('back', 'Login'), - 'superadmin' => UserManagementModule::t('back', 'Superadmin'), - 'confirmation_token' => UserManagementModule::t('back', 'Confirmation Token'), - 'registration_ip' => UserManagementModule::t('back', 'Registration IP'), - 'bind_to_ip' => UserManagementModule::t('back', 'Bind to IP'), - 'status' => UserManagementModule::t('back', 'Status'), - 'gridRoleSearch' => UserManagementModule::t('back', 'Roles'), - 'created_at' => UserManagementModule::t('back', 'Created'), - 'updated_at' => UserManagementModule::t('back', 'Updated'), - 'password' => UserManagementModule::t('back', 'Password'), - 'repeat_password' => UserManagementModule::t('back', 'Repeat password'), - 'email_confirmed' => UserManagementModule::t('back', 'E-mail confirmed'), - 'email' => UserManagementModule::t('back', 'E-mail'), - ]; - } - - /** - * @return \yii\db\ActiveQuery - */ - public function getRoles() - { - return $this->hasMany(Role::className(), ['name' => 'item_name']) - ->viaTable(Yii::$app->getModule('user-management')->auth_assignment_table, ['user_id'=>'id']); - } - - - /** - * Make sure user will not deactivate himself and superadmin could not demote himself - * Also don't let non-superadmin edit superadmin - * - * @inheritdoc - */ - public function beforeSave($insert) - { - if ( $insert ) - { - if ( php_sapi_name() != 'cli' ) - { - $this->registration_ip = LittleBigHelper::getRealIp(); - } - $this->generateAuthKey(); - } - else - { - // Console doesn't have Yii::$app->user, so we skip it for console - if ( php_sapi_name() != 'cli' ) - { - if ( Yii::$app->user->id == $this->id ) - { - // Make sure user will not deactivate himself - $this->status = static::STATUS_ACTIVE; - - // Superadmin could not demote himself - if ( Yii::$app->user->isSuperadmin AND $this->superadmin != 1 ) - { - $this->superadmin = 1; - } - } - - // Don't let non-superadmin edit superadmin - if ( isset($this->oldAttributes['superadmin']) && !Yii::$app->user->isSuperadmin && $this->oldAttributes['superadmin'] == 1 ) - { - return false; - } - } - } - - // If password has been set, than create password hash - if ( $this->password ) - { - $this->setPassword($this->password); - } - - return parent::beforeSave($insert); - } - - /** - * Don't let delete yourself and don't let non-superadmin delete superadmin - * - * @inheritdoc - */ - public function beforeDelete() - { - // Console doesn't have Yii::$app->user, so we skip it for console - if ( php_sapi_name() != 'cli' ) - { - // Don't let delete yourself - if ( Yii::$app->user->id == $this->id ) - { - return false; - } - - // Don't let non-superadmin delete superadmin - if ( !Yii::$app->user->isSuperadmin AND $this->superadmin == 1 ) - { - return false; - } - } - - return parent::beforeDelete(); - } + const STATUS_ACTIVE = 1; + const STATUS_INACTIVE = 0; + const STATUS_BANNED = -1; + + /** + * @var string + */ + public $gridRoleSearch; + + /** + * @var string + */ + public $password; + + /** + * @var string + */ + public $repeat_password; + + /** + * Store result in singleton to prevent multiple db requests with multiple calls. + * + * @param bool $fromSingleton + * + * @return static + */ + public static function getCurrentUser($fromSingleton = true) + { + if (!$fromSingleton) { + return static::findOne(Yii::$app->user->id); + } + + $user = Singleton::getData('__currentUser'); + + if (!$user) { + $user = static::findOne(Yii::$app->user->id); + + Singleton::setData('__currentUser', $user); + } + + return $user; + } + + /** + * Assign role to user. + * + * @param int $userId + * @param string $roleName + * + * @return bool + */ + public static function assignRole($userId, $roleName) + { + try { + Yii::$app->db->createCommand() + ->insert(Yii::$app->getModule('user-management')->auth_assignment_table, [ + 'user_id' => $userId, + 'item_name' => $roleName, + 'created_at' => time(), + ])->execute(); + + AuthHelper::invalidatePermissions(); + + return true; + } catch (\Exception $e) { + return false; + } + } + + /** + * Revoke role from user. + * + * @param int $userId + * @param string $roleName + * + * @return bool + */ + public static function revokeRole($userId, $roleName) + { + $result = Yii::$app->db->createCommand() + ->delete(Yii::$app->getModule('user-management')->auth_assignment_table, ['user_id' => $userId, 'item_name' => $roleName]) + ->execute() > 0; + + if ($result) { + AuthHelper::invalidatePermissions(); + } + + return $result; + } + + /** + * @param string|array $roles + * @param bool $superAdminAllowed + * + * @return bool + */ + public static function hasRole($roles, $superAdminAllowed = true) + { + if ($superAdminAllowed and Yii::$app->user->isSuperadmin) { + return true; + } + $roles = (array) $roles; + + AuthHelper::ensurePermissionsUpToDate(); + + return array_intersect($roles, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_ROLES, [])) !== []; + } + + /** + * @param string $permission + * @param bool $superAdminAllowed + * + * @return bool + */ + public static function hasPermission($permission, $superAdminAllowed = true) + { + if ($superAdminAllowed and Yii::$app->user->isSuperadmin) { + return true; + } + + AuthHelper::ensurePermissionsUpToDate(); + + return in_array($permission, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_PERMISSIONS, [])); + } + + /** + * Useful for Menu widget. + * + * + * ... + * [ 'label'=>'Some label', 'url'=>['/site/index'], 'visible'=>User::canRoute(['/site/index']) ] + * ... + * + * + * @param string|array $route + * @param bool $superAdminAllowed + * + * @return bool + */ + public static function canRoute($route, $superAdminAllowed = true) + { + if ($superAdminAllowed and Yii::$app->user->isSuperadmin) { + return true; + } + + $baseRoute = AuthHelper::unifyRoute($route); + + if (Route::isFreeAccess($baseRoute)) { + return true; + } + + AuthHelper::ensurePermissionsUpToDate(); + + return Route::isRouteAllowed($baseRoute, Yii::$app->session->get(AuthHelper::SESSION_PREFIX_ROUTES, [])); + } + + /** + * getStatusList. + * + * @return array + */ + public static function getStatusList() + { + return array( + self::STATUS_ACTIVE => UserManagementModule::t('back', 'Active'), + self::STATUS_INACTIVE => UserManagementModule::t('back', 'Inactive'), + self::STATUS_BANNED => UserManagementModule::t('back', 'Banned'), + ); + } + + /** + * getStatusValue. + * + * @param string $val + * + * @return string + */ + public static function getStatusValue($val) + { + $ar = self::getStatusList(); + + return isset($ar[$val]) ? $ar[$val] : $val; + } + + /** + * {@inheritdoc} + */ + public static function tableName() + { + return Yii::$app->getModule('user-management')->user_table; + } + + /** + * {@inheritdoc} + */ + public function behaviors() + { + return [ + TimestampBehavior::className(), + ]; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + ['username', 'required'], + ['username', 'unique'], + ['username', 'trim'], + + [['status', 'email_confirmed'], 'integer'], + + ['email', 'email'], + ['email', 'validateEmailConfirmedUnique'], + + ['bind_to_ip', 'validateBindToIp'], + ['bind_to_ip', 'trim'], + ['bind_to_ip', 'string', 'max' => 255], + + ['password', 'required', 'on' => ['newUser', 'changePassword']], + ['password', 'string', 'max' => 255, 'on' => ['newUser', 'changePassword']], + ['password', 'trim', 'on' => ['newUser', 'changePassword']], + ['password', 'match', 'pattern' => Yii::$app->getModule('user-management')->passwordRegexp], + + ['repeat_password', 'required', 'on' => ['newUser', 'changePassword']], + ['repeat_password', 'compare', 'compareAttribute' => 'password'], + ]; + } + + /** + * Check that there is no such confirmed E-mail in the system. + */ + public function validateEmailConfirmedUnique() + { + if ($this->email) { + $exists = self::findOne([ + 'email' => $this->email, + 'email_confirmed' => 1, + ]); + + if ($exists and $exists->id != $this->id) { + $this->addError('email', UserManagementModule::t('front', 'This E-mail already exists')); + } + } + } + + /** + * Validate bind_to_ip attr to be in correct format. + */ + public function validateBindToIp() + { + if ($this->bind_to_ip) { + $ips = explode(',', $this->bind_to_ip); + + foreach ($ips as $ip) { + if (!filter_var(trim($ip), FILTER_VALIDATE_IP)) { + $this->addError('bind_to_ip', UserManagementModule::t('back', 'Wrong format. Enter valid IPs separated by comma')); + } + } + } + } + + /** + * @return array + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'username' => UserManagementModule::t('back', 'User'), + 'superadmin' => UserManagementModule::t('back', 'Superadmin'), + 'confirmation_token' => UserManagementModule::t('back', 'Confirmation Token'), + 'registration_ip' => UserManagementModule::t('back', 'Registration IP'), + 'bind_to_ip' => UserManagementModule::t('back', 'Bind to IP'), + 'status' => UserManagementModule::t('back', 'Status'), + 'gridRoleSearch' => UserManagementModule::t('back', 'Roles'), + 'created_at' => UserManagementModule::t('back', 'Created'), + 'updated_at' => UserManagementModule::t('back', 'Updated'), + 'password' => UserManagementModule::t('back', 'Password'), + 'repeat_password' => UserManagementModule::t('back', 'Repeat password'), + 'email_confirmed' => UserManagementModule::t('back', 'E-mail confirmed'), + 'email' => UserManagementModule::t('back', 'E-mail'), + 'auth_type' => UserManagementModule::t('back', 'Authentication type'), + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getRoles() + { + return $this->hasMany(Role::className(), ['name' => 'item_name']) + ->viaTable(Yii::$app->getModule('user-management')->auth_assignment_table, ['user_id' => 'id']); + } + + /** + * Make sure user will not deactivate himself and superadmin could not demote himself + * Also don't let non-superadmin edit superadmin. + * + * {@inheritdoc} + */ + public function beforeSave($insert) + { + if ($insert) { + if (php_sapi_name() != 'cli') { + $this->registration_ip = LittleBigHelper::getRealIp(); + } + $this->generateAuthKey(); + } else { + // Console doesn't have Yii::$app->user, so we skip it for console + if (php_sapi_name() != 'cli') { + if (Yii::$app->user->id == $this->id) { + // Make sure user will not deactivate himself + $this->status = static::STATUS_ACTIVE; + + // Superadmin could not demote himself + if (Yii::$app->user->isSuperadmin and $this->superadmin != 1) { + $this->superadmin = 1; + } + } + + // Don't let non-superadmin edit superadmin + if (isset($this->oldAttributes['superadmin']) && !Yii::$app->user->isSuperadmin && $this->oldAttributes['superadmin'] == 1) { + return false; + } + } + } + + // If password has been set, than create password hash + if ($this->password) { + $this->setPassword($this->password); + } + + return parent::beforeSave($insert); + } + + /** + * Don't let delete yourself and don't let non-superadmin delete superadmin. + * + * {@inheritdoc} + */ + public function beforeDelete() + { + // Console doesn't have Yii::$app->user, so we skip it for console + if (php_sapi_name() != 'cli') { + // Don't let delete yourself + if (Yii::$app->user->id == $this->id) { + return false; + } + + // Don't let non-superadmin delete superadmin + if (!Yii::$app->user->isSuperadmin and $this->superadmin == 1) { + return false; + } + } + + return parent::beforeDelete(); + } } diff --git a/models/forms/LoginForm.php b/models/forms/LoginForm.php index ee6cc9d2..a4589995 100644 --- a/models/forms/LoginForm.php +++ b/models/forms/LoginForm.php @@ -1,4 +1,5 @@ UserManagementModule::t('front', 'Username'), - 'password' => UserManagementModule::t('front', 'Password'), - 'rememberMe' => UserManagementModule::t('front', 'Remember me'), - ]; - } - - /** - * Validates the password. - * This method serves as the inline validation for password. - */ - public function validatePassword() - { - if ( !Yii::$app->getModule('user-management')->checkAttempts() ) - { - $this->addError('password', UserManagementModule::t('front', 'Too many attempts')); - - return false; - } - - if ( !$this->hasErrors() ) - { - $user = $this->getUser(); - if ( !$user || !$user->validatePassword($this->password) ) - { - $this->addError('password', UserManagementModule::t('front', 'Incorrect username or password.')); - } - } - } - - /** - * Check if user is binded to IP and compare it with his actual IP - */ - public function validateIP() - { - $user = $this->getUser(); - - if ( $user AND $user->bind_to_ip ) - { - $ips = explode(',', $user->bind_to_ip); - - $ips = array_map('trim', $ips); - - if ( !in_array(LittleBigHelper::getRealIp(), $ips) ) - { - $this->addError('password', UserManagementModule::t('front', "You could not login from this IP")); - } - } - } - - /** - * Logs in a user using the provided username and password. - * @return boolean whether the user is logged in successfully - */ - public function login() - { - if ( $this->validate() ) - { - return Yii::$app->user->login($this->getUser(), $this->rememberMe ? Yii::$app->user->cookieLifetime : 0); - } - else - { - return false; - } - } - - /** - * Finds user by [[username]] - * @return User|null - */ - public function getUser() - { - if ( $this->_user === false ) - { - $u = new \Yii::$app->user->identityClass; - $this->_user = ($u instanceof User ? $u->findByUsername($this->username) : User::findByUsername($this->username)); - } - - return $this->_user; - } + public $username; + public $password; + public $rememberMe = false; + + private $_user = false; + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['username', 'password'], 'required'], + ['rememberMe', 'boolean'], + ['password', 'validatePassword'], + + ['username', 'validateIP'], + ]; + } + + public function attributeLabels() + { + return [ + 'username' => UserManagementModule::t('front', 'Username'), + 'password' => UserManagementModule::t('front', 'Password'), + 'rememberMe' => UserManagementModule::t('front', 'Remember me'), + ]; + } + + /** + * Validates the password. + * This method serves as the inline validation for password. + */ + public function validatePassword() + { + if (!Yii::$app->getModule('user-management')->checkAttempts()) { + $this->addError('password', UserManagementModule::t('front', 'Too many attempts')); + + return false; + } + + if (!$this->hasErrors()) { + $user = $this->getUser(); + if (!$user || !$user->validatePassword($this->password)) { + $this->addError('password', UserManagementModule::t('front', 'Incorrect username or password.')); + } + } + } + + /** + * Check if user is binded to IP and compare it with his actual IP. + */ + public function validateIP() + { + $user = $this->getUser(); + + if ($user and $user->bind_to_ip) { + $ips = explode(',', $user->bind_to_ip); + + $ips = array_map('trim', $ips); + + if (!in_array(LittleBigHelper::getRealIp(), $ips)) { + $this->addError('password', UserManagementModule::t('front', 'You could not login from this IP')); + } + } + } + + /** + * Logs in a user using the provided username and password. + * + * @return bool whether the user is logged in successfully + */ + public function login() + { + if ($this->validate()) { + return Yii::$app->user->login($this->getUser(), $this->rememberMe ? Yii::$app->user->cookieLifetime : 0); + } else { + return false; + } + } + + /** + * Finds user by [[username]]. + * + * @return User|null + */ + public function getUser() + { + if ($this->_user === false) { + $u = new \Yii::$app->user->identityClass(); + $this->_user = ($u instanceof User ? $u->findByUsername($this->username) : User::findByUsername($this->username)); + } + + if (!$this->_user and Yii::$app->user->enableLdap) { + // If the user doesn't exist in the database, + // it might be the first login of a LDAP user. + $new_user = new \Yii::$app->user->identityClass(); + $new_user->id = null; + $new_user->username = $this->username; + $new_user->password_hash = Yii::$app->getSecurity()->generatePasswordHash(Yii::$app->getSecurity()->generateRandomString()); + $new_user->auth_type = 'ldap'; + $this->_user = $new_user; + } + + return $this->_user; + } } diff --git a/views/auth/confirmEmail.php b/views/auth/confirmEmail.php index c21d1978..42d1a23d 100644 --- a/views/auth/confirmEmail.php +++ b/views/auth/confirmEmail.php @@ -34,7 +34,7 @@ 'validateOnBlur'=>false, ]); ?> - field($model, 'email')->textInput(['maxlength' => 255, 'autofocus'=>true]) ?> + field($model, 'email')->textInput(['maxlength' => 254, 'autofocus'=>true]) ?>
diff --git a/views/auth/passwordRecovery.php b/views/auth/passwordRecovery.php index b834c6d0..c68b7818 100644 --- a/views/auth/passwordRecovery.php +++ b/views/auth/passwordRecovery.php @@ -30,7 +30,7 @@ 'validateOnBlur'=>false, ]); ?> - field($model, 'email')->textInput(['maxlength' => 255, 'autofocus'=>true]) ?> + field($model, 'email')->textInput(['maxlength' => 254, 'autofocus'=>true]) ?> field($model, 'captcha')->widget(Captcha::className(), [ 'template' => '
{image}
{input}
', diff --git a/views/user/_form.php b/views/user/_form.php index e828d60f..4736ff75 100644 --- a/views/user/_form.php +++ b/views/user/_form.php @@ -44,7 +44,7 @@ - field($model, 'email')->textInput(['maxlength' => 255]) ?> + field($model, 'email')->textInput(['maxlength' => 254]) ?> field($model, 'email_confirmed')->checkbox() ?> @@ -70,4 +70,4 @@
- \ No newline at end of file + diff --git a/views/user/view.php b/views/user/view.php index 5623a29b..86211054 100644 --- a/views/user/view.php +++ b/views/user/view.php @@ -8,7 +8,7 @@ use yii\helpers\Html; use yii\widgets\DetailView; -/** +/* * @var yii\web\View $this * @var webvimark\modules\UserManagement\models\User $model */ @@ -19,71 +19,72 @@ ?>
-

title ?>

+

title ?>

-
-
+
+
-

- $model->id], ['class' => 'btn btn-sm btn-primary']) ?> - 'btn btn-sm btn-success']) ?> - $model->id], - ['class' => 'btn btn-sm btn-default'] - ) ?> +

+ $model->id], ['class' => 'btn btn-sm btn-primary']) ?> + 'btn btn-sm btn-success']) ?> + $model->id], + ['class' => 'btn btn-sm btn-default'] + ) ?> - $model->id], [ - 'class' => 'btn btn-sm btn-danger pull-right', - 'data' => [ - 'confirm' => UserManagementModule::t('back', 'Are you sure you want to delete this user?'), - 'method' => 'post', - ], - ]) ?> -

+ $model->id], [ + 'class' => 'btn btn-sm btn-danger pull-right', + 'data' => [ + 'confirm' => UserManagementModule::t('back', 'Are you sure you want to delete this user?'), + 'method' => 'post', + ], + ]) ?> +

- $model, - 'attributes' => [ - 'id', - [ - 'attribute'=>'status', - 'value'=>User::getStatusValue($model->status), - ], - 'username', - [ - 'attribute'=>'email', - 'value'=>$model->email, - 'format'=>'email', - 'visible'=>User::hasPermission('viewUserEmail'), - ], - [ - 'attribute'=>'email_confirmed', - 'value'=>$model->email_confirmed, - 'format'=>'boolean', - 'visible'=>User::hasPermission('viewUserEmail'), - ], - [ - 'label'=>UserManagementModule::t('back', 'Roles'), - 'value'=>implode('
', ArrayHelper::map(Role::getUserRoles($model->id), 'name', 'description')), - 'visible'=>User::hasPermission('viewUserRoles'), - 'format'=>'raw', - ], - [ - 'attribute'=>'bind_to_ip', - 'visible'=>User::hasPermission('bindUserToIp'), - ], - array( - 'attribute'=>'registration_ip', - 'value'=>Html::a($model->registration_ip, "http://ipinfo.io/" . $model->registration_ip, ["target"=>"_blank"]), - 'format'=>'raw', - 'visible'=>User::hasPermission('viewRegistrationIp'), - ), - 'created_at:datetime', - 'updated_at:datetime', - ], - ]) ?> + $model, + 'attributes' => [ + 'id', + [ + 'attribute' => 'status', + 'value' => User::getStatusValue($model->status), + ], + 'username', + [ + 'attribute' => 'email', + 'value' => $model->email, + 'format' => 'email', + 'visible' => User::hasPermission('viewUserEmail'), + ], + [ + 'attribute' => 'email_confirmed', + 'value' => $model->email_confirmed, + 'format' => 'boolean', + 'visible' => User::hasPermission('viewUserEmail'), + ], + 'auth_type', + [ + 'label' => UserManagementModule::t('back', 'Roles'), + 'value' => implode('
', ArrayHelper::map(Role::getUserRoles($model->id), 'name', 'description')), + 'visible' => User::hasPermission('viewUserRoles'), + 'format' => 'raw', + ], + [ + 'attribute' => 'bind_to_ip', + 'visible' => User::hasPermission('bindUserToIp'), + ], + array( + 'attribute' => 'registration_ip', + 'value' => Html::a($model->registration_ip, 'http://ipinfo.io/'.$model->registration_ip, ['target' => '_blank']), + 'format' => 'raw', + 'visible' => User::hasPermission('viewRegistrationIp'), + ), + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> -
-
+
+