├── messages ├── de │ ├── auth.rbac.php │ ├── auth.reset-password.php │ └── auth.user.php ├── es │ ├── auth.rbac.php │ ├── auth.reset-password.php │ └── auth.user.php └── ru │ ├── auth.rbac.php │ ├── auth.reset-password.php │ └── auth.user.php ├── views ├── mail │ ├── passwordResetToken.php │ ├── es │ │ └── passwordResetToken.php │ └── de │ │ └── passwordResetToken.php ├── user │ ├── create.php │ ├── update.php │ ├── _form.php │ ├── _search.php │ ├── view.php │ └── index.php ├── profile │ ├── view.php │ └── update.php └── default │ ├── resetPassword.php │ ├── requestPasswordResetToken.php │ ├── signup.php │ └── login.php ├── migrations ├── m000000_000003_ChangeTokenColumn.php ├── m000000_000001_CreateRbacTables.php └── m000000_000002_CreateUserTables.php ├── composer.json ├── LICENSE ├── Module.php ├── models ├── PasswordResetRequestForm.php ├── ResetPasswordForm.php ├── UserSearch.php ├── LoginForm.php ├── SignupForm.php └── User.php ├── components ├── User.php └── AccessControl.php ├── controllers ├── ProfileController.php ├── UserController.php └── DefaultController.php └── README.md /messages/de/auth.rbac.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 28/11/13 01:48 PM 6 | */ -------------------------------------------------------------------------------- /messages/es/auth.rbac.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 28/11/13 01:48 PM 6 | */ -------------------------------------------------------------------------------- /messages/ru/auth.rbac.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 28/11/13 01:48 PM 6 | */ -------------------------------------------------------------------------------- /views/mail/passwordResetToken.php: -------------------------------------------------------------------------------- 1 | urlManager->createAbsoluteUrl(['auth/default/reset-password', 'token' => $user->password_reset_token]); 8 | ?> 9 |

Hello username) ?>,

10 |

Follow the link below to reset your password:

11 | 12 |

-------------------------------------------------------------------------------- /views/mail/es/passwordResetToken.php: -------------------------------------------------------------------------------- 1 | urlManager->createAbsoluteUrl(['auth/default/reset-password', 'token' => $user->password_reset_token]); 8 | ?> 9 |

Hola username) ?>,

10 |

Siga el siguiente vínculo para restaurar su clave:

11 | 12 |

-------------------------------------------------------------------------------- /views/mail/de/passwordResetToken.php: -------------------------------------------------------------------------------- 1 | urlManager->createAbsoluteUrl(['auth/default/reset-password', 'token' => $user->password_reset_token]); 8 | ?> 9 |

Hallo username) ?>,

10 |

Über den folgenden Link kannst du dein Passwort zurücksetzen:

11 | 12 |

-------------------------------------------------------------------------------- /views/user/create.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('auth.user', 'Create User'); 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('auth.user', 'Users'), 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 | render('_form', [ 19 | 'model' => $model, 20 | ]); ?> 21 | 22 |
23 | -------------------------------------------------------------------------------- /views/user/update.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('auth.user', 'Update User') . ': ' . $model->username; 11 | $this->params['breadcrumbs'][] = ['label' => 'Users', 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = ['label' => $model->username, 'url' => ['view', 'id' => $model->id]]; 13 | $this->params['breadcrumbs'][] = Yii::t('auth.user', 'Update'); 14 | ?> 15 |
16 | 17 |

title) ?>

18 | 19 | render('_form', [ 20 | 'model' => $model, 21 | ]); ?> 22 | 23 |
24 | -------------------------------------------------------------------------------- /migrations/m000000_000003_ChangeTokenColumn.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 25/08/14 07:26 PM 6 | */ 7 | 8 | use yii\db\Schema; 9 | 10 | class m000000_000003_ChangeTokenColumn extends \yii\db\Migration 11 | { 12 | public function safeUp() 13 | { 14 | $tableMap = Yii::$app->getModule('auth')->tableMap; 15 | $this->alterColumn($tableMap['User'], 'password_reset_token', Schema::TYPE_STRING . '(48)'); 16 | } 17 | 18 | public function safeDown() 19 | { 20 | $tableMap = Yii::$app->getModule('auth')->tableMap; 21 | $this->alterColumn($tableMap['User'], 'password_reset_token', Schema::TYPE_STRING . '(32)'); 22 | } 23 | } -------------------------------------------------------------------------------- /messages/ru/auth.reset-password.php: -------------------------------------------------------------------------------- 1 | 4 | * @created 2014-12-13 5 | */ 6 | return [ 7 | 'Request password reset' => 'Запрос на смену пароля', 8 | 'Please fill out your email. A link to reset password will be sent there.' => 'Пожалуйста введите почтовый ящик. На него будет выслана ссылка необходимая для смены пароля.', 9 | 'There is no user with such email.' => 'Нет пользователей с таким почтовым ящиком.', 10 | 'Password reset token cannot be blank.' => 'Токен не может быть пустым.', 11 | 'Wrong password reset token.' => 'Неверный токен.', 12 | 'Send' => 'Отправить', 13 | 'Password reset for {name}' => 'Сброс пароля для {name}', 14 | 'Reset password' => 'Сброс пароля', 15 | 'Please choose your new password' => 'Выберите новый пароль', 16 | 'Save' => 'Сохранить', 17 | ]; -------------------------------------------------------------------------------- /messages/es/auth.reset-password.php: -------------------------------------------------------------------------------- 1 | 'Solicitud de recuperación de contraseña', 4 | 'Please fill out your email. A link to reset password will be sent there.' => 'Por favor, ingrese su correo electrónico. Un vínculo para recuperar la contraseña le será enviado a esa dirección.', 5 | 'There is no user with such email.' => 'No existe ningún usuario con ese correo electrónico.', 6 | 'Password reset token cannot be blank.' => 'El identificador para recuperación de la contraseña no puede estar en blanco.', 7 | 'Wrong password reset token.' => 'El Identificador para recuperación de la contraseña es incorrecto.', 8 | 'Send' => 'Enviar', 9 | 'Password reset for {name}' => 'Restaurar contraseña en {name}', 10 | 'Reset password' => 'Restaurar contraseña', 11 | 'Please choose your new password' => 'Por favor, elija su nueva contraseña', 12 | 'Save' => 'Guardar', 13 | ]; -------------------------------------------------------------------------------- /messages/de/auth.reset-password.php: -------------------------------------------------------------------------------- 1 | 4 | * @created 2014-12-13 5 | */ 6 | return [ 7 | 'Request password reset' => 'Passwort zurücksetzen', 8 | 'Please fill out your email. A link to reset password will be sent there.' => 'Bitte gib deine Email ein. Ein Link zum Zurücksetzen des Passwortes wird dorthin gesendet.', 9 | 'There is no user with such email.' => 'Es konnte kein Benutzer mit der angegebenen Email gefunden werden.', 10 | 'Password reset token cannot be blank.' => 'Das Passwort-Reset-Token darf nicht leer sein.', 11 | 'Wrong password reset token.' => 'Falsches Passwort-Reset-Token.', 12 | 'Send' => 'Senden', 13 | 'Password reset for {name}' => 'Passwort für {name} zurückgesetzt', 14 | 'Reset password' => 'Passwort zurücksetzen', 15 | 'Please choose your new password' => 'Bitte vergib ein neues Passwort', 16 | 'Save' => 'Speichern', 17 | ]; -------------------------------------------------------------------------------- /views/profile/view.php: -------------------------------------------------------------------------------- 1 | title = \Yii::t('auth.user', 'View Profile'); 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 |
16 |

17 | title) ?> 18 | ', ['update'], ['class' => 'pull-right']) ?> 19 |

20 |
21 | $model, 23 | 'attributes' => [ 24 | //'id', 25 | 'username', 26 | 'email:email', 27 | [ 28 | 'attribute' => 'status', 29 | 'value' => $model->getStatus() 30 | ], 31 | 'last_visit_time', 32 | 'create_time', 33 | 'update_time', 34 | ], 35 | ]); ?> 36 |
37 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "robregonm/yii2-auth", 3 | "description": "Yii 2 User Authentication & Role Based Access Control (RBAC) Module", 4 | "keywords": ["yii", "yii2", "user", "auth", "authentication", "rbac", "access"], 5 | "type": "yii2-extension", 6 | "license": "BSD-3-Clause", 7 | "support": { 8 | "issues": "https://github.com/robregonm/yii2-auth/issues?state=open", 9 | "forum": "http://www.yiiframework.com/forum/", 10 | "wiki": "http://www.yiiframework.com/wiki/", 11 | "source": "https://github.com/robregonm/yii2-auth" 12 | }, 13 | "authors": [ 14 | { 15 | "name": "robregonm", 16 | "email": "robregonm@gmail.com", 17 | "homepage": "http://obregon.co", 18 | "role": "Author" 19 | } 20 | ], 21 | "require": { 22 | "php": ">=5.4.0", 23 | "yiisoft/yii2": "*", 24 | "yiisoft/yii2-bootstrap": "*", 25 | "yiisoft/yii2-composer": "*", 26 | "yiisoft/yii2-swiftmailer": "*", 27 | "himiklab/yii2-recaptcha-widget": "*" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "auth\\": "" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /views/default/resetPassword.php: -------------------------------------------------------------------------------- 1 | title = \Yii::t('auth.reset-password', 'Reset password'); 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 |

title) ?>

14 | 15 |

:

16 | 17 |
18 |
19 | 'reset-password-form']); ?> 20 | field($model, 'password')->passwordInput() ?> 21 |
22 | 'btn btn-primary']) ?> 23 |
24 | 25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /views/default/requestPasswordResetToken.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('auth.reset-password', 'Request password reset'); 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 |

title) ?>

14 | 15 |

16 | 17 |
18 |
19 | 'request-password-reset-form']); ?> 20 | field($model, 'email') ?> 21 |
22 | 'btn btn-primary']) ?> 23 |
24 | 25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /views/user/_form.php: -------------------------------------------------------------------------------- 1 | 13 | 14 |
15 | 16 | 17 | 18 | field($model, 'username')->textInput(['maxlength' => 64]) ?> 19 | 20 | field($model, 'email')->textInput(['maxlength' => 128, 'type' => 'email']) ?> 21 | 22 | field($model, 'password')->passwordInput(['maxlength' => 128]) ?> 23 | 24 | field($model, 'status')->dropDownList([ 25 | User::STATUS_INACTIVE => $model->getStatus(User::STATUS_INACTIVE), 26 | User::STATUS_ACTIVE => $model->getStatus(User::STATUS_ACTIVE), 27 | User::STATUS_SUSPENDED => $model->getStatus(User::STATUS_SUSPENDED), 28 | User::STATUS_DELETED => $model->getStatus(User::STATUS_DELETED), 29 | ]) ?> 30 | 31 |
32 | isNewRecord ? Yii::t('auth.user', 'Create') : Yii::t('auth.user', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> 33 |
34 | 35 | 36 | 37 |
38 | -------------------------------------------------------------------------------- /messages/de/auth.user.php: -------------------------------------------------------------------------------- 1 | 4 | * @created 2014-12-13 5 | */ 6 | return [ 7 | 'Username' => 'Benutzername', 8 | 'Email' => 'Email', 9 | 'Password' => 'Passwort', 10 | 'Status' => 'Status', 11 | 'Last Visit Time' => 'Letzter Besuch', 12 | 'Create Time' => 'Erstellt am', 13 | 'Update Time' => 'Zuletzt bearbeitet am', 14 | 'Delete Time' => 'Gelöscht am', 15 | 'Incorrect username or password.' => 'Falscher Benutzername oder falsches Passwort.', 16 | 'Profile' => 'Profil', 17 | 'View Profile' => 'Profil ansehen', 18 | 'Update Profile' => 'Profil bearbeiten', 19 | 'Login' => 'Anmelden', 20 | 'Logout' => 'Abmelden', 21 | 'Username or Email' => 'Benutzername oder Email', 22 | 'Remember Me' => 'Eingeloggt bleiben', 23 | 'Please fill out the following fields to login:' => 'Bitte fülle die folgenden Felder aus, um dich einzuloggen:', 24 | 'Create' => 'Erstellen', 25 | 'Create User' => 'Benutzer erstellen', 26 | 'Users' => 'Benutzer', 27 | 'Update' => 'Bearbeiten', 28 | 'Update User' => 'Benutzer bearbeiten', 29 | 'Delete' => 'Löschen', 30 | 'Deleted' => 'Gelöscht', 31 | 'Inactive' => 'Inaktiv', 32 | 'Active' => 'Aktiv', 33 | 'Suspended' => 'Gebannt', 34 | 'Forgot password?' => 'Passwort vergessen?' 35 | ]; -------------------------------------------------------------------------------- /views/user/_search.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 50 | -------------------------------------------------------------------------------- /views/user/view.php: -------------------------------------------------------------------------------- 1 | title = $model->username; 12 | $this->params['breadcrumbs'][] = ['label' => Yii::t('auth.user', 'Users'), 'url' => ['index']]; 13 | $this->params['breadcrumbs'][] = $this->title; 14 | ?> 15 |
16 | 17 |

View User: 'title) ?>'

18 | 19 |

20 | $model->id], ['class' => 'btn btn-primary']) ?> 21 | $model->id], [ 22 | 'class' => 'btn btn-danger', 23 | 'data-confirm' => Yii::t('app', 'Are you sure to delete this user?'), 24 | 'data-method' => 'post', 25 | ]); ?> 26 |

27 | 28 | $model, 30 | 'attributes' => [ 31 | //'id', 32 | 'username', 33 | 'email:email', 34 | 'password_hash', 35 | 'password_reset_token', 36 | 'auth_key', 37 | [ 38 | 'attribute' => 'status', 39 | 'value' => $model->getStatus() 40 | ], 41 | 'last_visit_time', 42 | 'create_time', 43 | 'update_time', 44 | 'delete_time', 45 | ], 46 | ]); ?> 47 | 48 |
49 | -------------------------------------------------------------------------------- /messages/es/auth.user.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 28/11/13 01:24 PM 6 | */ 7 | return [ 8 | 'Username' => 'Nombre de Usuario', 9 | 'Email' => 'Correo Electrónico', 10 | 'Password' => 'Contraseña', 11 | 'Status' => 'Estado', 12 | 'Last Visit Time' => 'Fecha Última Visita', 13 | 'Create Time' => 'Fecha Creación', 14 | 'Update Time' => 'Fecha Actualización', 15 | 'Delete Time' => 'Fecha de Eliminación', 16 | 'Incorrect username or password.' => 'Nombre de usuario o contraseña incorrectas.', 17 | 'Profile' => 'Perfil', 18 | 'View Profile' => 'Ver Perfil', 19 | 'Update Profile' => 'Actualizar Perfil', 20 | 'Login' => 'Iniciar Sesión', 21 | 'Logout' => 'Cerrar Sesión', 22 | 'Username or Email' => 'Usuario o Email', 23 | 'Remember Me' => 'Recordarme', 24 | 'Please fill out the following fields to login:' => 'Por favor, ingrese los siguientes datos para iniciar sesión:', 25 | 'Create' => 'Crear', 26 | 'Create User' => 'Crear Usuario', 27 | 'Users' => 'Usuarios', 28 | 'Update' => 'Actualizar', 29 | 'Update User' => 'Actualizar Usuario', 30 | 'Delete' => 'Eliminar', 31 | 'Deleted' => 'Eliminado', 32 | 'Inactive' => 'Inactivo', 33 | 'Active' => 'Activo', 34 | 'Suspended' => 'Suspendido', 35 | 'Forgot password?' => '¿Olvidó su contraseña?' 36 | ]; -------------------------------------------------------------------------------- /views/default/signup.php: -------------------------------------------------------------------------------- 1 | title = 'Sign up'; 6 | $this->params['breadcrumbs'][] = $this->title; 7 | ?> 8 |
9 |
10 |
11 |
12 |

title) ?>

13 |
14 |
15 | 'registration-form', 17 | ]); ?> 18 | 19 | getModule('auth')->signupWithEmailOnly): ?> 20 | field($model, 'username') ?> 21 | 22 | 23 | field($model, 'email') ?> 24 | 25 | field($model, 'password')->passwordInput() ?> 26 | 27 | 'btn btn-success btn-block']) ?> 28 | 29 | 30 |
31 |
32 |

33 | 34 |

35 |
36 |
37 | -------------------------------------------------------------------------------- /views/user/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('auth.user', 'Users'); 13 | $this->params['breadcrumbs'][] = $this->title; 14 | ?> 15 |
16 | 17 |

title) ?>

18 | 19 | render('_search', ['model' => $searchModel]); ?> 20 | 21 |

22 | ' . Yii::t('auth.user', 'Create User'), ['create'], ['class' => 'btn btn-success']) ?> 23 |

24 | 25 | $dataProvider, 27 | 'filterModel' => $searchModel, 28 | 'columns' => [ 29 | //['class' => 'yii\grid\SerialColumn'], 30 | //'id', 31 | 'username', 32 | 'email:email', 33 | //'password_hash', 34 | //'password_reset_token', 35 | // 'auth_key', 36 | [ 37 | 'attribute' => 'status', 38 | 'value' => function ($model) { 39 | return $model->getStatus(); 40 | } 41 | ], 42 | 'last_visit_time', 43 | // 'create_time', 44 | // 'update_time', 45 | // 'delete_time', 46 | 47 | ['class' => 'yii\grid\ActionColumn'], 48 | ], 49 | ]); ?> 50 | 51 |
52 | -------------------------------------------------------------------------------- /messages/ru/auth.user.php: -------------------------------------------------------------------------------- 1 | 4 | * @created 2014-12-13 5 | */ 6 | return [ 7 | 'Username' => 'Имя пользователя', 8 | 'Email' => 'Email', 9 | 'Password' => 'Пароль', 10 | 'Status' => 'Статус', 11 | 'Last Visit Time' => 'Время последнего визита', 12 | 'Create Time' => 'Время создания', 13 | 'Update Time' => 'Время последних изменений', 14 | 'Delete Time' => 'Время удаления', 15 | 'Incorrect username or password.' => 'Неверное имя пользователя или пароль.', 16 | 'Profile' => 'Профиль', 17 | 'View Profile' => 'Просмотр профиля', 18 | 'Update Profile' => 'Редактировать профиль', 19 | 'Login' => 'Войти', 20 | 'Sign up' => 'Регистрация', 21 | 'Logout' => 'Выйти', 22 | 'Username or Email' => 'Имя пользователя или Email', 23 | 'Remember Me' => 'Запомнить меня', 24 | 'Please fill out the following fields to login:' => 'Пожалуйста заполните следующие поля:', 25 | 'Create' => 'Создать', 26 | 'Create User' => 'Создать пользователя', 27 | 'Users' => 'Пользователи', 28 | 'Update' => 'Редактировать', 29 | 'Update User' => 'Редактировать пользователя', 30 | 'Delete' => 'Удалить', 31 | 'Deleted' => 'Удален', 32 | 'Inactive' => 'Не активен', 33 | 'Active' => 'Активен', 34 | 'Suspended' => 'Выключен', 35 | 'Forgot password?' => 'Забыли пароль?', 36 | 'Already registered? Sign in!' => 'Уже зарегистрированы? Входите!', 37 | ]; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Ricardo Obregón 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | 'User', 25 | 'UserStatus' => 'UserStatus', 26 | 'ProfileFieldValue' => 'ProfileFieldValue', 27 | 'ProfileField' => 'ProfileField', 28 | 'ProfileFieldType' => 'ProfileFieldType', 29 | ); 30 | 31 | public $layoutLogged; 32 | 33 | public $attemptsBeforeCaptcha = 3; // Unsuccessful Login Attempts before Captcha 34 | 35 | public $referralParam = 'ref'; 36 | 37 | /** 38 | * @var int Seconds for token expiration 39 | */ 40 | public $passwordResetTokenExpire = 3600; 41 | 42 | public $supportEmail; 43 | 44 | public $superAdmins = ['admin']; 45 | 46 | /** 47 | * @var boolean Use only email for signup 48 | */ 49 | public $signupWithEmailOnly = false; 50 | 51 | public function init() 52 | { 53 | parent::init(); 54 | 55 | \Yii::$app->getI18n()->translations['auth.*'] = [ 56 | 'class' => 'yii\i18n\PhpMessageSource', 57 | 'basePath' => __DIR__.'/messages', 58 | ]; 59 | $this->setAliases([ 60 | '@auth' => __DIR__ 61 | ]); } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /models/PasswordResetRequestForm.php: -------------------------------------------------------------------------------- 1 | 'trim'], 21 | ['email', 'required'], 22 | ['email', 'email'], 23 | ['email', 'exist', 24 | 'targetClass' => '\auth\models\User', 25 | 'filter' => ['status' => User::STATUS_ACTIVE], 26 | 'message' => Yii::t('auth.reset-password', 'There is no user with such email.') 27 | ], 28 | ]; 29 | } 30 | 31 | /** 32 | * Sends an email with a link, for resetting the password. 33 | * 34 | * @return boolean whether the email was send 35 | */ 36 | public function sendEmail() 37 | { 38 | /* @var $user User */ 39 | $user = User::findOne([ 40 | 'status' => User::STATUS_ACTIVE, 41 | 'email' => $this->email, 42 | ]); 43 | 44 | if ($user) { 45 | $user->generatePasswordResetToken(); 46 | if ($user->save()) { 47 | return \Yii::$app->mailer->compose('@auth/views/mail/passwordResetToken', ['user' => $user]) 48 | ->setFrom([\Yii::$app->getModule('auth')->supportEmail => \Yii::$app->name]) 49 | ->setTo($this->email) 50 | ->setSubject(Yii::t('auth.reset-password', 'Password reset for {name}', ['name' => \Yii::$app->name])) 51 | ->send(); 52 | } 53 | } 54 | 55 | return false; 56 | } 57 | 58 | /** 59 | * @inheritdoc 60 | */ 61 | public function attributeLabels() 62 | { 63 | return [ 64 | 'email' => Yii::t('auth.user', 'Email') 65 | ]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /views/profile/update.php: -------------------------------------------------------------------------------- 1 | title = \Yii::t('auth.user', 'Update Profile'); 14 | $this->params['breadcrumbs'][] = ['label' => Yii::t('auth.user', 'Profile'), 'url' => ['view']]; 15 | $this->params['breadcrumbs'][] = Yii::t('auth.user', 'Update'); 16 | ?> 17 | 18 |
19 |
20 |

21 | title) ?> 22 |

23 |
24 |
25 | field($model, 'username')->textInput(['maxlength' => 64]) ?> 26 | 27 | field($model, 'email')->textInput(['maxlength' => 128, 'type' => 'email']) ?> 28 | 29 | field($model, 'password')->passwordInput() ?> 30 | 31 | getIsSuperAdmin()): // ToDo: Allow admins too ?> 32 | field($model, 'status')->dropDownList([ 34 | User::STATUS_INACTIVE => $model->getStatus(User::STATUS_INACTIVE), 35 | User::STATUS_ACTIVE => $model->getStatus(User::STATUS_ACTIVE), 36 | User::STATUS_SUSPENDED => $model->getStatus(User::STATUS_SUSPENDED), 37 | User::STATUS_DELETED => $model->getStatus(User::STATUS_DELETED), 38 | ]) ?> 39 | 40 | 41 |
42 |
43 | 44 |
45 | 48 |
49 | 50 | -------------------------------------------------------------------------------- /models/ResetPasswordForm.php: -------------------------------------------------------------------------------- 1 | _user = User::findByPasswordResetToken($token); 33 | if (!$this->_user) { 34 | throw new InvalidParamException(Yii::t('auth.reset-password', 'Wrong password reset token.')); 35 | } 36 | parent::__construct($config); 37 | } 38 | 39 | /** 40 | * @inheritdoc 41 | */ 42 | public function rules() 43 | { 44 | return [ 45 | ['password', 'required'], 46 | ['password', 'string', 'min' => 6], 47 | ]; 48 | } 49 | 50 | /** 51 | * Resets password. 52 | * 53 | * @return boolean if password was reset. 54 | */ 55 | public function resetPassword() 56 | { 57 | $user = $this->_user; 58 | $user->setScenario('resetPassword'); 59 | $user->password = $this->password; 60 | $user->removePasswordResetToken(); 61 | 62 | return $user->save(); 63 | } 64 | 65 | /** 66 | * @inheritdoc 67 | */ 68 | public function attributeLabels() 69 | { 70 | return [ 71 | 'password' => \Yii::t('auth.user', 'Password'), 72 | ]; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /components/User.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 24/11/13 07:40 PM 6 | */ 7 | 8 | namespace auth\components; 9 | 10 | use yii\web\IdentityInterface; 11 | use yii\web\User as BaseUser; 12 | use yii\db\Expression; 13 | 14 | /** 15 | * User is the class for the "user" application component that manages the user authentication status. 16 | * 17 | * @property \auth\models\User $identity The identity object associated with the currently logged user. Null 18 | * is returned if the user is not logged in (not authenticated). 19 | * 20 | * @author Ricardo Obregón 21 | */ 22 | class User extends BaseUser 23 | { 24 | /** 25 | * @inheritdoc 26 | */ 27 | public $identityClass = '\auth\models\User'; 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | public $enableAutoLogin = true; 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | public $loginUrl = ['/auth/default/login']; 38 | 39 | /** 40 | * @inheritdoc 41 | */ 42 | protected function afterLogin($identity, $cookieBased, $duration) 43 | { 44 | parent::afterLogin($identity, $cookieBased, $duration); 45 | $this->identity->setScenario(self::EVENT_AFTER_LOGIN); 46 | $this->identity->setAttribute('last_visit_time', new Expression('CURRENT_TIMESTAMP')); 47 | // $this->identity->setAttribute('login_ip', ip2long(\Yii::$app->getRequest()->getUserIP())); 48 | $this->identity->save(false); 49 | } 50 | 51 | public function getIsSuperAdmin() 52 | { 53 | if ($this->isGuest) { 54 | return false; 55 | } 56 | return $this->identity->getIsSuperAdmin(); 57 | } 58 | 59 | public function checkAccess($operation, $params = [], $allowCaching = true) 60 | { 61 | // Always return true when SuperAdmin user 62 | if ($this->getIsSuperAdmin()) { 63 | return true; 64 | } 65 | return parent::can($operation, $params, $allowCaching); 66 | } 67 | } -------------------------------------------------------------------------------- /models/UserSearch.php: -------------------------------------------------------------------------------- 1 | $query, 34 | ]); 35 | 36 | if (!($this->load($params) && $this->validate())) { 37 | return $dataProvider; 38 | } 39 | 40 | $query->andFilterWhere([ 41 | 'id' => $this->id, 42 | 'status' => $this->status, 43 | ]); 44 | 45 | $query->andFilterWhere(['like', 'username', $this->username]) 46 | ->andFilterWhere(['like', 'email', $this->email]) 47 | ->andFilterWhere(['like', 'password_hash', $this->password_hash]) 48 | ->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token]) 49 | ->andFilterWhere(['like', 'auth_key', $this->auth_key]) 50 | ->andFilterWhere(['like', 'last_visit_time', $this->last_visit_time]) 51 | ->andFilterWhere(['like', 'create_time', $this->create_time]) 52 | ->andFilterWhere(['like', 'update_time', $this->update_time]) 53 | ->andFilterWhere(['like', 'delete_time', $this->delete_time]); 54 | 55 | return $dataProvider; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /views/default/login.php: -------------------------------------------------------------------------------- 1 | title = \Yii::t('auth.user', 'Login'); 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 18 | 19 | 'login-form', 21 | 'options' => ['class' => 'form-horizontal'], 22 | 'fieldConfig' => [ 23 | 'template' => "{input}", 24 | 'labelOptions' => ['class' => 'col-lg-1 control-label'], 25 | ], 26 | ]); ?> 27 | 28 | field($model, 'username', ['options' => ['class' => 'form-group input-group input-group-lg'], 'template' => '{input}'])->textInput(['placeholder' => $model->getAttributeLabel('username')]) ?> 29 | 30 | field($model, 'password', ['options' => ['class' => 'form-group input-group input-group-lg'], 'template' => '{input}'])->passwordInput(['placeholder' => $model->getAttributeLabel('password')]) ?> 31 | scenario == 'withCaptcha'): ?> 32 | field($model, 'verifyCode')->widget(Captcha::className(), ['captchaAction' => 'default/captcha', 'options' => ['class' => 'form-control'],]) ?> 34 | 35 | 36 | field($model, 'rememberMe')->checkbox() ?> 37 | 38 |
39 |
40 | 'btn btn-primary btn-lg btn-block']) ?> 41 |
42 |
43 | 44 | 45 |

46 |
47 | -------------------------------------------------------------------------------- /models/LoginForm.php: -------------------------------------------------------------------------------- 1 | Yii::t('auth.user', 'Username or Email'), 44 | 'password' => Yii::t('auth.user', 'Password'), 45 | 'rememberMe' => Yii::t('auth.user', 'Remember Me'), 46 | 'verifyCode' => Yii::t('auth.user', 'Verify Code'), 47 | ]; 48 | } 49 | 50 | 51 | /** 52 | * Validates the password. 53 | * This method serves as the inline validation for password. 54 | */ 55 | public function validatePassword() 56 | { 57 | $user = $this->getUser(); 58 | if (!$user || !$user->validatePassword($this->password)) { 59 | $this->addError('password', Yii::t('auth.user', 'Incorrect username or password.')); 60 | } 61 | } 62 | 63 | /** 64 | * Logs in a user using the provided username and password. 65 | * 66 | * @return boolean whether the user is logged in successfully 67 | */ 68 | public function login() 69 | { 70 | if ($this->validate()) { 71 | return $this->getUser()->login($this->rememberMe ? Yii::$app->getModule('auth')->rememberMeTime : 0); 72 | } else { 73 | return false; 74 | } 75 | } 76 | 77 | /** 78 | * Finds user by [[username]] 79 | * 80 | * @return User|null 81 | */ 82 | private function getUser() 83 | { 84 | if ($this->_user === false) { 85 | $this->_user = User::findByUsername($this->username); 86 | } 87 | return $this->_user; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /models/SignupForm.php: -------------------------------------------------------------------------------- 1 | 'trim'], 27 | ['username', 'required'], 28 | [ 29 | 'username', 30 | 'unique', 31 | 'targetClass' => '\auth\models\User', 32 | 'message' => Yii::t('auth.user', 'This username has already been taken.') 33 | ], 34 | ['username', 'string', 'min' => 2, 'max' => 255], 35 | ['email', 'filter', 'filter' => 'trim'], 36 | ['email', 'required'], 37 | ['email', 'email'], 38 | [ 39 | 'email', 40 | 'unique', 41 | 'targetClass' => '\auth\models\User', 42 | 'message' => Yii::t('auth.user', 'This email address has already been taken.') 43 | ], 44 | ['password', 'required'], 45 | ['password', 'string', 'min' => 6], 46 | ]; 47 | } 48 | 49 | public function beforeValidate() 50 | { 51 | if (parent::beforeValidate()) { 52 | if (Yii::$app->getModule('auth')->signupWithEmailOnly) { 53 | $this->username = $this->email; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | return false; 60 | } 61 | 62 | /** 63 | * Signs user up. 64 | * 65 | * @return User|null the saved model or null if saving fails 66 | */ 67 | public function signup() 68 | { 69 | if ($this->validate()) { 70 | $user = new User(); 71 | $user->username = $this->username; 72 | $user->email = $this->email; 73 | $user->setPassword($this->password); 74 | $user->generateAuthKey(); 75 | if ($user->save()) { 76 | return $user; 77 | } 78 | } 79 | 80 | return null; 81 | } 82 | } -------------------------------------------------------------------------------- /controllers/ProfileController.php: -------------------------------------------------------------------------------- 1 | 5 | * @created 28/11/13 11:27 AM 6 | */ 7 | 8 | namespace auth\controllers; 9 | 10 | 11 | use Yii; 12 | use yii\web\Controller; 13 | use yii\helpers\Security; 14 | use auth\models\User; 15 | use yii\web\NotFoundHttpException; 16 | 17 | class ProfileController extends Controller 18 | { 19 | /** 20 | * @var string the ID of the action that is used when the action ID is not specified 21 | * in the request. Defaults to 'index'. 22 | */ 23 | public $defaultAction = 'view'; 24 | 25 | public function init() 26 | { 27 | $layout = $this->module->layoutLogged; 28 | if (!empty($layout)) { 29 | $this->layout = $layout; 30 | } 31 | } 32 | 33 | /** 34 | * @var \auth\Module 35 | */ 36 | public $module; 37 | 38 | public function behaviors() 39 | { 40 | return [ 41 | 'access' => [ 42 | 'class' => \yii\filters\AccessControl::className(), 43 | 'rules' => [ 44 | [ 45 | 'allow' => true, 46 | 'roles' => ['@'], 47 | ], 48 | ], 49 | ], 50 | ]; 51 | } 52 | 53 | /** 54 | * Displays current User model. 55 | * 56 | * @return mixed 57 | */ 58 | public function actionView() 59 | { 60 | return $this->render('view', [ 61 | 'model' => $this->findModel(), 62 | ]); 63 | } 64 | 65 | /** 66 | * Updates the current User model. 67 | * If update is successful, the browser will be redirected to the 'view' page. 68 | * 69 | * @param integer $id 70 | * @return mixed 71 | */ 72 | public function actionUpdate() 73 | { 74 | $model = $this->findModel(); 75 | $model->setScenario('profile'); 76 | 77 | if ($model->load($_POST) && $model->save()) { 78 | return $this->redirect(['view', 'id' => $model->id]); 79 | } else { 80 | return $this->render('update', [ 81 | 'model' => $model, 82 | ]); 83 | } 84 | } 85 | 86 | /** 87 | * Finds the logged in User model based on its primary key value. 88 | * If the model is not found, a 404 HTTP exception will be thrown. 89 | * 90 | * @return User the loaded model 91 | * @throws HttpException if the model cannot be found 92 | */ 93 | protected function findModel() 94 | { 95 | if (($model = Yii::$app->user->getIdentity()) !== null) { 96 | return $model; 97 | } else { 98 | throw new NotFoundHttpException('The requested page does not exist.'); 99 | } 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /migrations/m000000_000001_CreateRbacTables.php: -------------------------------------------------------------------------------- 1 | get('authManager'); 12 | 13 | $this->createTable($authManager->ruleTable, [ 14 | 'name' => Schema::TYPE_STRING . '(64) NOT NULL', 15 | 'data' => Schema::TYPE_TEXT, 16 | 'created_at' => Schema::TYPE_INTEGER, 17 | 'updated_at' => Schema::TYPE_INTEGER, 18 | 'PRIMARY KEY (name)', 19 | ]); 20 | 21 | $this->createTable($authManager->itemTable, [ 22 | 'name' => Schema::TYPE_STRING . '(64) NOT NULL', 23 | 'type' => Schema::TYPE_INTEGER . ' NOT NULL', 24 | 'description' => Schema::TYPE_TEXT, 25 | 'rule_name' => Schema::TYPE_STRING . '(64)', 26 | 'data' => Schema::TYPE_TEXT, 27 | 'created_at' => Schema::TYPE_INTEGER, 28 | 'updated_at' => Schema::TYPE_INTEGER, 29 | 'PRIMARY KEY (name)', 30 | ]); 31 | 32 | $this->addForeignKey('AuthItem_rule_name_fk', $authManager->itemTable, 'rule_name', $authManager->ruleTable, 'name', 'SET NULL', 'CASCADE'); 33 | 34 | $this->createIndex('AuthItem_type_idx', $authManager->itemTable, 'type'); 35 | 36 | $this->createTable($authManager->itemChildTable, [ 37 | 'parent' => Schema::TYPE_STRING . '(64) NOT NULL', 38 | 'child' => Schema::TYPE_STRING . '(64) NOT NULL', 39 | 'PRIMARY KEY (parent,child)', 40 | ]); 41 | 42 | $this->addForeignKey('AuthItemChild_parent_fk', $authManager->itemChildTable, 'parent', $authManager->itemTable, 'name', 'CASCADE', 'CASCADE'); 43 | $this->addForeignKey('AuthItemChild_child_fk', $authManager->itemChildTable, 'child', $authManager->itemTable, 'name', 'CASCADE', 'CASCADE'); 44 | 45 | $this->createTable($authManager->assignmentTable, [ 46 | 'item_name' => Schema::TYPE_STRING . '(64) NOT NULL', 47 | 'user_id' => Schema::TYPE_INTEGER . ' NOT NULL', 48 | 'created_at' => Schema::TYPE_INTEGER, 49 | 'PRIMARY KEY (item_name,user_id)', 50 | ]); 51 | 52 | $this->addForeignKey('AuthAssignment_item_name_fk', $authManager->assignmentTable, 'item_name', $authManager->itemTable, 'name', 'CASCADE', 'CASCADE'); 53 | } 54 | 55 | public function safeDown() 56 | { 57 | /** @var \yii\rbac\DbManager $authManager */ 58 | $authManager = Yii::$app->get('authManager'); 59 | $this->dropTable($authManager->assignmentTable); 60 | $this->dropTable($authManager->itemChildTable); 61 | $this->dropTable($authManager->itemTable); 62 | $this->dropTable($authManager->ruleTable); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Auth Module 2 | =========== 3 | 4 | Auth Module is a flexible user registration, authentication & RBAC module for Yii2. It provides user authentication, registration and RBAC support to your Yii2 site. 5 | 6 | ## Installation 7 | 8 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 9 | 10 | Either run 11 | 12 | ``` 13 | $ php composer.phar require robregonm/yii2-auth "*" 14 | ``` 15 | 16 | or add 17 | 18 | ``` 19 | "robregonm/yii2-auth": "*" 20 | ``` 21 | 22 | to the require section of your `composer.json` file. 23 | 24 | ## Usage 25 | 26 | Once the extension is installed, modify your application configuration to include: 27 | 28 | ```php 29 | return [ 30 | 'modules' => [ 31 | ... 32 | 'auth' => [ 33 | 'class' => 'auth\Module', 34 | 'layout' => '//homepage', // Layout when not logged in yet 35 | 'layoutLogged' => '//main', // Layout for logged in users 36 | 'attemptsBeforeCaptcha' => 3, // Optional 37 | 'supportEmail' => 'support@mydomain.com', // Email for notifications 38 | 'passwordResetTokenExpire' => 3600, // Seconds for token expiration 39 | 'superAdmins' => ['admin'], // SuperAdmin users 40 | 'signupWithEmailOnly' => false, // false = signup with username + email, true = only email signup 41 | 'tableMap' => [ // Optional, but if defined, all must be declared 42 | 'User' => 'user', 43 | 'UserStatus' => 'user_status', 44 | 'ProfileFieldValue' => 'profile_field_value', 45 | 'ProfileField' => 'profile_field', 46 | 'ProfileFieldType' => 'profile_field_type', 47 | ], 48 | ], 49 | ... 50 | ], 51 | ... 52 | 'components' => [ 53 | ... 54 | 'authManager' => [ 55 | 'class' => '\yii\rbac\DbManager', 56 | 'ruleTable' => 'AuthRule', // Optional 57 | 'itemTable' => 'AuthItem', // Optional 58 | 'itemChildTable' => 'AuthItemChild', // Optional 59 | 'assignmentTable' => 'AuthAssignment', // Optional 60 | ], 61 | 'user' => [ 62 | 'class' => 'auth\components\User', 63 | 'identityClass' => 'auth\models\User', // or replace to your custom identityClass 64 | 'enableAutoLogin' => true, 65 | ], 66 | ... 67 | ] 68 | ]; 69 | ``` 70 | 71 | And run migrations: 72 | 73 | ```bash 74 | $ php yii migrate/up --migrationPath=@auth/migrations 75 | ``` 76 | 77 | ## License 78 | 79 | Auth module is released under the BSD-3 License. See the bundled `LICENSE.md` for details. 80 | 81 | #INSTALLATION 82 | 83 | ./yii migrate/up --migrationPath=@auth/migrations 84 | 85 | ## URLs 86 | 87 | * Login: `yourhost/auth/default/login` 88 | * Logout: `yourhost/auth/default/logout` 89 | * Sign-up: `yourhost/auth/default/signup` 90 | * Reset Password: `yourhost/auth/default/reset-password` 91 | * User management: `yourhost/auth/user/index` 92 | * User profile: `yourhost/auth/profile/view` 93 | 94 | [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=robregonm&url=https://github.com/robregonm/yii2-auth&title=Yii2-PDF&language=&tags=github&category=software) 95 | -------------------------------------------------------------------------------- /controllers/UserController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['post'], 24 | ], 25 | ], 26 | 'access' => [ 27 | 'class' => AccessControl::className(), 28 | 'rules' => [ 29 | [ 30 | 'allow' => true, 31 | 'matchCallback' => function () { 32 | return \Yii::$app->user->getIsSuperAdmin(); 33 | }, 34 | ], 35 | ], 36 | ], 37 | ]; 38 | } 39 | 40 | public function init() 41 | { 42 | $layout = $this->module->layoutLogged; 43 | if (!empty($layout)) { 44 | $this->layout = $layout; 45 | } 46 | } 47 | 48 | /** 49 | * Lists all User models. 50 | * 51 | * @return mixed 52 | */ 53 | public function actionIndex() 54 | { 55 | $searchModel = new UserSearch; 56 | $dataProvider = $searchModel->search($_GET); 57 | 58 | return $this->render('index', [ 59 | 'dataProvider' => $dataProvider, 60 | 'searchModel' => $searchModel, 61 | ]); 62 | } 63 | 64 | /** 65 | * Displays a single User model. 66 | * 67 | * @param integer $id 68 | * @return mixed 69 | */ 70 | public function actionView($id) 71 | { 72 | return $this->render('view', [ 73 | 'model' => $this->findModel($id), 74 | ]); 75 | } 76 | 77 | /** 78 | * Creates a new User model. 79 | * If creation is successful, the browser will be redirected to the 'view' page. 80 | * 81 | * @return mixed 82 | */ 83 | public function actionCreate() 84 | { 85 | $model = new User; 86 | 87 | if ($model->load($_POST) && $model->save()) { 88 | return $this->redirect(['view', 'id' => $model->id]); 89 | } else { 90 | return $this->render('create', [ 91 | 'model' => $model, 92 | ]); 93 | } 94 | } 95 | 96 | /** 97 | * Updates an existing User model. 98 | * If update is successful, the browser will be redirected to the 'view' page. 99 | * 100 | * @param integer $id 101 | * @return mixed 102 | */ 103 | public function actionUpdate($id) 104 | { 105 | $model = $this->findModel($id); 106 | $model->setScenario('profile'); 107 | 108 | if (isset($_POST['User']['password'])) { 109 | $model->setPassword($_POST['User']['password']); 110 | } 111 | 112 | if ($model->load($_POST) && $model->save()) { 113 | return $this->redirect(['view', 'id' => $model->id]); 114 | } else { 115 | return $this->render('update', [ 116 | 'model' => $model, 117 | ]); 118 | } 119 | } 120 | 121 | /** 122 | * Deletes an existing User model. 123 | * If deletion is successful, the browser will be redirected to the 'index' page. 124 | * 125 | * @param integer $id 126 | * @return mixed 127 | */ 128 | public function actionDelete($id) 129 | { 130 | $this->findModel($id)->delete(); 131 | return $this->redirect(['index']); 132 | } 133 | 134 | /** 135 | * Finds the User model based on its primary key value. 136 | * If the model is not found, a 404 HTTP exception will be thrown. 137 | * 138 | * @param integer $id 139 | * @return User the loaded model 140 | * @throws HttpException if the model cannot be found 141 | */ 142 | protected function findModel($id) 143 | { 144 | if (($model = User::findOne($id)) !== null) { 145 | return $model; 146 | } else { 147 | throw new NotFoundHttpException('The requested page does not exist.'); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /controllers/DefaultController.php: -------------------------------------------------------------------------------- 1 | [ 28 | 'class' => \yii\filters\AccessControl::class, 29 | 'only' => ['logout', 'signup'], 30 | 'rules' => [ 31 | [ 32 | 'actions' => ['signup'], 33 | 'allow' => true, 34 | 'roles' => ['?'], 35 | ], 36 | [ 37 | 'actions' => ['logout'], 38 | 'allow' => true, 39 | 'roles' => ['@'], 40 | ], 41 | ], 42 | ], 43 | ]; 44 | } 45 | 46 | public function actions() 47 | { 48 | return [ 49 | 'error' => [ 50 | 'class' => 'yii\web\ErrorAction', 51 | ], 52 | ]; 53 | } 54 | 55 | public function actionLogin() 56 | { 57 | if (!\Yii::$app->user->isGuest) { 58 | $this->goHome(); 59 | } 60 | 61 | $model = new LoginForm(); 62 | 63 | if ($this->module instanceof \auth\Module) { 64 | $module = $this->module; 65 | } else { 66 | $module = Yii::$app->getModule('auth'); 67 | } 68 | 69 | if ($model->load($_POST) and $model->login()) { 70 | $this->setLoginAttempts(0); //if login is successful, reset the attempts 71 | return $this->goBack(); 72 | } 73 | //if login is not successful, increase the attempts 74 | $this->setLoginAttempts($this->getLoginAttempts() + 1); 75 | 76 | return $this->render('login', [ 77 | 'model' => $model, 78 | ]); 79 | } 80 | 81 | protected function getLoginAttempts() 82 | { 83 | return Yii::$app->getSession()->get($this->loginAttemptsVar, 0); 84 | } 85 | 86 | protected function setLoginAttempts($value) 87 | { 88 | Yii::$app->getSession()->set($this->loginAttemptsVar, $value); 89 | } 90 | 91 | public function actionLogout() 92 | { 93 | Yii::$app->user->logout(); 94 | return $this->goHome(); 95 | } 96 | 97 | public function actionSignup() 98 | { 99 | $model = new SignupForm(); 100 | if ($model->load(Yii::$app->request->post())) { 101 | if ($user = $model->signup()) { 102 | if (Yii::$app->getUser()->login($user)) { 103 | return $this->goHome(); 104 | } 105 | } 106 | } 107 | return $this->render('signup', [ 108 | 'model' => $model, 109 | ]); 110 | } 111 | public function actionRequestPasswordReset() 112 | { 113 | $model = new PasswordResetRequestForm(); 114 | if ($model->load(Yii::$app->request->post()) && $model->validate()) { 115 | if ($model->sendEmail()) { 116 | Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.'); 117 | 118 | return $this->goHome(); 119 | } else { 120 | Yii::$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); 121 | } 122 | } 123 | 124 | return $this->render('requestPasswordResetToken', [ 125 | 'model' => $model, 126 | ]); 127 | } 128 | 129 | public function actionResetPassword($token) 130 | { 131 | try { 132 | $model = new ResetPasswordForm($token); 133 | } catch (InvalidParamException $e) { 134 | throw new BadRequestHttpException($e->getMessage()); 135 | } 136 | 137 | if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { 138 | Yii::$app->getSession()->setFlash('success', 'New password was saved.'); 139 | 140 | return $this->goHome(); 141 | } 142 | 143 | return $this->render('resetPassword', [ 144 | 'model' => $model, 145 | ]); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /components/AccessControl.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright Copyright © Ricardo Obregón 2012- 8 | * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 9 | * @package auth.components 10 | */ 11 | 12 | namespace auth\components; 13 | 14 | use Yii; 15 | use yii\base\Action; 16 | use yii\base\ActionFilter; 17 | 18 | /** 19 | * Auth AccessControl provides RBAC access control. 20 | * 21 | * Auth AccessControl is an action filter. It will check the item names to find 22 | * the first match that will dictate whether to allow or deny the access to the requested controller 23 | * action. If no matches, the access will be denied. 24 | * 25 | * To use Auth AccessControl, declare it in the `behaviors()` method of your controller class. 26 | * For example, the following declaration will enable rbac filtering in your controller. 27 | * 28 | * ~~~ 29 | * public function behaviors() 30 | * { 31 | * return [ 32 | * 'access' => [ 33 | * 'class' => \auth\AccessControl::className(), 34 | * ], 35 | * ]; 36 | * } 37 | * ~~~ 38 | * 39 | * @author Ricardo Obregón 40 | * @since 2.0 41 | */ 42 | class AccessControl extends ActionFilter 43 | { 44 | /** 45 | * @var array name-value pairs that would be passed to business rules associated 46 | * with the tasks and roles assigned to the user. 47 | */ 48 | public $params = []; 49 | 50 | /** 51 | * @var callback a callback that will be called if the access should be denied 52 | * to the current user. If not set, [[denyAccess()]] will be called. 53 | * 54 | * The signature of the callback should be as follows: 55 | * 56 | * ~~~ 57 | * function ($item, $action) 58 | * ~~~ 59 | * 60 | * where `$item` is this item name, and `$action` is the current [[Action|action]] object. 61 | */ 62 | public $denyCallback; 63 | 64 | private $separator = '.'; 65 | 66 | private function getItemName($component) 67 | { 68 | return strtr($component->getUniqueId(), '/', $this->separator); 69 | } 70 | 71 | /** 72 | * This method is invoked right before an action is to be executed (after all possible filters.) 73 | * You may override this method to do last-minute preparation for the action. 74 | * 75 | * @param Action $action the action to be executed. 76 | * @return boolean whether the action should continue to be executed. 77 | */ 78 | public function beforeAction($action) 79 | { 80 | $user = Yii::$app->getUser(); 81 | 82 | $controller = $action->controller; 83 | 84 | if ($controller->module !== null) { 85 | if ($user->checkAccess($this->getItemName($controller->module) . $this->separator . '*', $this->params)) { 86 | return true; 87 | } 88 | } 89 | 90 | if ($user->checkAccess($this->getItemName($controller) . $this->separator . '*', $this->params)) { 91 | return true; 92 | } 93 | 94 | if ($user->checkAccess($itemName = $this->getItemName($action), $this->params)) { 95 | return true; 96 | } 97 | 98 | if (isset($this->denyCallback)) { 99 | call_user_func($this->denyCallback, $itemName, $action); 100 | } else { 101 | $this->denyAccess($user); 102 | } 103 | return false; 104 | } 105 | 106 | /** 107 | * Denies the access of the user. 108 | * The default implementation will redirect the user to the login page if he is a guest; 109 | * if the user is already logged, a 403 HTTP exception will be thrown. 110 | * 111 | * @param User $user the current user 112 | * @throws HttpException if the user is already logged in. 113 | */ 114 | protected function denyAccess($user) 115 | { 116 | if ($user->getIsGuest()) { 117 | $user->loginRequired(); 118 | } else { 119 | throw new \yii\web\ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.')); 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /migrations/m000000_000002_CreateUserTables.php: -------------------------------------------------------------------------------- 1 | getModule('auth')->tableMap; 11 | 12 | $this->createTable( 13 | $tableMap['User'], 14 | array( 15 | 'id' => Schema::TYPE_PK, 16 | 'username' => Schema::TYPE_STRING . '(64) NOT NULL', 17 | 'email' => Schema::TYPE_STRING . '(128) NOT NULL', 18 | 'password_hash' => Schema::TYPE_STRING . '(128) NOT NULL', 19 | 'password_reset_token' => Schema::TYPE_STRING . '(32)', 20 | 'auth_key' => Schema::TYPE_STRING . '(128)', 21 | 'status' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT ' . \auth\models\User::STATUS_ACTIVE, 22 | 'last_visit_time' => Schema::TYPE_TIMESTAMP, 23 | 'create_time' => Schema::TYPE_TIMESTAMP . ' NOT NULL', 24 | 'update_time' => Schema::TYPE_TIMESTAMP, 25 | 'delete_time' => Schema::TYPE_TIMESTAMP, 26 | ) 27 | ); 28 | $this->createIndex('User_status_ix', $tableMap['User'], 'status'); 29 | 30 | $this->createTable( 31 | $tableMap['ProfileFieldType'], 32 | array( 33 | 'id' => Schema::TYPE_PK, 34 | 'name' => Schema::TYPE_STRING . ' NOT NULL', 35 | 'title' => Schema::TYPE_STRING . ' NOT NULL', 36 | ) 37 | ); 38 | $this->createIndex('ProfileFieldType_name_uk', $tableMap['ProfileFieldType'], 'name', true); 39 | 40 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'integer', 'title' => 'Integer')); //1 41 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'string', 'title' => 'String')); //2 42 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'text', 'title' => 'Text')); //3 43 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'boolean', 'title' => 'Boolean')); //4 44 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'decimal', 'title' => 'Decimal')); //5 45 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'money', 'title' => 'Money')); //6 46 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'date', 'title' => 'Date only')); //7 47 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'datetime', 'title' => 'Date and Time')); //8 48 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'time', 'title' => 'Time only')); //9 49 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'url', 'title' => 'Url Address')); //10 50 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'email', 'title' => 'Email')); //11 51 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'lookup', 'title' => 'Lookup')); //12 52 | $this->insert($tableMap['ProfileFieldType'], array('name' => 'list', 'title' => 'List')); //13 53 | 54 | $this->createTable( 55 | $tableMap['ProfileField'], 56 | array( 57 | 'id' => Schema::TYPE_PK, 58 | 'name' => Schema::TYPE_STRING . '(32) NOT NULL', 59 | 'title' => Schema::TYPE_STRING, 60 | 'type_id' => Schema::TYPE_INTEGER . ' NOT NULL', // Field Type 61 | 'position' => Schema::TYPE_INTEGER . ' NOT NULL', 62 | 'required' => Schema::TYPE_BOOLEAN . ' NOT NULL', 63 | 'configuration' => Schema::TYPE_TEXT, 64 | //'size' => 'integer', //Field Size 65 | /*'min_length' => 'integer', 66 | 'max_length' => 'integer', 67 | 'match' => 'text', 68 | 'range' => 'string',*/ 69 | 'error_message' => Schema::TYPE_STRING, 70 | 'default_value' => Schema::TYPE_STRING, 71 | 'read_only' => Schema::TYPE_BOOLEAN . ' NOT NULL', 72 | ) 73 | ); 74 | $this->createIndex('ProfileField_name_uk', $tableMap['ProfileField'], 'name', true); 75 | $this->createIndex('ProfileField_type_ix', $tableMap['ProfileField'], 'type_id'); 76 | $this->addForeignKey('ProfileField_type_fk', $tableMap['ProfileField'], 'type_id', $tableMap['ProfileFieldType'], 'id'); 77 | 78 | $this->insert( 79 | $tableMap['ProfileField'], 80 | array('name' => 'first_name', 'title' => 'First Name', 'type_id' => 2, 'position' => 1, 'required' => 0, 'read_only' => 0) 81 | ); 82 | $this->insert( 83 | $tableMap['ProfileField'], 84 | array('name' => 'last_name', 'title' => 'Last Name', 'type_id' => 2, 'position' => 2, 'required' => 0, 'read_only' => 0) 85 | ); 86 | $this->insert( 87 | $tableMap['ProfileField'], 88 | array('name' => 'website', 'title' => 'Website', 'type_id' => 2, 'position' => 3, 'required' => 0, 'read_only' => 0) 89 | ); 90 | 91 | 92 | $this->createTable( 93 | $tableMap['ProfileFieldValue'], 94 | array( 95 | 'id' => Schema::TYPE_PK, 96 | 'user_id' => Schema::TYPE_INTEGER . ' NOT NULL', 97 | 'field_id' => Schema::TYPE_INTEGER . ' NOT NULL', 98 | 'value' => Schema::TYPE_TEXT, 99 | ) 100 | ); 101 | $this->createIndex('Profile_field_ix', $tableMap['ProfileFieldValue'], 'field_id'); 102 | //$this->createIndex('Profile_value_ix', $tableMap['ProfileFieldValue'], 'value'); 103 | $this->addForeignKey('Profile_user_fk', $tableMap['ProfileFieldValue'], 'user_id', $tableMap['User'], 'id'); 104 | $this->addForeignKey('Profile_field_fk', $tableMap['ProfileFieldValue'], 'field_id', $tableMap['ProfileField'], 'id'); 105 | 106 | 107 | // Creates the default admin user 108 | $adminUser = new \auth\models\User(); 109 | 110 | echo 'Please type the admin user info: ' . PHP_EOL; 111 | $this->readStdinUser('Email (e.g. admin@mydomain.com)', $adminUser, 'email'); 112 | $this->readStdinUser('Type Username', $adminUser, 'username', $adminUser->email); 113 | $this->readStdinUser('Type Password', $adminUser, 'password', 'admin'); 114 | 115 | if (!$adminUser->save()) { 116 | throw new \yii\console\Exception('Error when creating admin user.'); 117 | } 118 | echo 'User created successfully.' . PHP_EOL; 119 | } 120 | 121 | private function readStdinUser($prompt, $model, $field, $default = '') 122 | { 123 | while (!isset($input) || !$model->validate(array($field))) { 124 | echo $prompt . (($default) ? " [$default]" : '') . ': '; 125 | $input = (trim(fgets(STDIN))); 126 | if (empty($input) && !empty($default)) { 127 | $input = $default; 128 | } 129 | $model->$field = $input; 130 | } 131 | return $input; 132 | } 133 | 134 | public function safeDown() 135 | { 136 | $tableMap = Yii::$app->getModule('auth')->tableMap; 137 | $this->dropTable($tableMap['ProfileFieldValue']); 138 | $this->dropTable($tableMap['ProfileField']); 139 | $this->dropTable($tableMap['ProfileFieldType']); 140 | $this->dropTable($tableMap['User']); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /models/User.php: -------------------------------------------------------------------------------- 1 | 'Deleted', 40 | self::STATUS_INACTIVE => 'Inactive', 41 | self::STATUS_ACTIVE => 'Active', 42 | self::STATUS_SUSPENDED => 'Suspended', 43 | ]; 44 | 45 | public function behaviors() 46 | { 47 | return [ 48 | 'timestamp' => [ 49 | 'class' => 'yii\behaviors\TimestampBehavior', 50 | 'attributes' => [ 51 | self::EVENT_BEFORE_INSERT => ['create_time', 'update_time'], 52 | self::EVENT_BEFORE_DELETE => 'delete_time', 53 | ], 54 | 'value' => function () { 55 | return new Expression('CURRENT_TIMESTAMP'); 56 | } 57 | ], 58 | ]; 59 | } 60 | 61 | public function getStatus($status = null) 62 | { 63 | if ($status === null) { 64 | return Yii::t('auth.user', $this->statuses[$this->status]); 65 | } 66 | return Yii::t('auth.user', $this->statuses[$status]); 67 | } 68 | 69 | /** 70 | * Finds an identity by the given ID. 71 | * 72 | * @param string|integer $id the ID to be looked for 73 | * @return IdentityInterface|null the identity object that matches the given ID. 74 | */ 75 | public static function findIdentity($id) 76 | { 77 | return static::findOne($id); 78 | } 79 | 80 | /** 81 | * Finds user by username 82 | * 83 | * @param string $username 84 | * @return null|User 85 | */ 86 | public static function findByUsername($username) 87 | { 88 | return static::find() 89 | ->andWhere(['and', ['or', ['username' => $username], ['email' => $username]], ['status' => static::STATUS_ACTIVE]]) 90 | ->one(); 91 | } 92 | 93 | /** 94 | * @inheritdoc 95 | */ 96 | public static function findIdentityByAccessToken($token, $type = null) 97 | { 98 | throw new \yii\base\NotSupportedException('"findIdentityByAccessToken" is not implemented.'); 99 | } 100 | 101 | /** 102 | * Finds user by password reset token 103 | * 104 | * @param string $token password reset token 105 | * @return static|null 106 | */ 107 | public static function findByPasswordResetToken($token) 108 | { 109 | $expire = Yii::$app->getModule('auth')->passwordResetTokenExpire; 110 | $parts = explode('_', $token); 111 | $timestamp = (int)end($parts); 112 | if ($timestamp + $expire < time()) { 113 | // token expired 114 | return null; 115 | } 116 | 117 | return static::findOne([ 118 | 'password_reset_token' => $token, 119 | 'status' => self::STATUS_ACTIVE, 120 | ]); 121 | } 122 | 123 | /** 124 | * @return int|string current user ID 125 | */ 126 | public function getId() 127 | { 128 | return $this->id; 129 | } 130 | 131 | /** 132 | * @return string current user auth key 133 | */ 134 | public function getAuthKey() 135 | { 136 | return $this->auth_key; 137 | } 138 | 139 | /** 140 | * @param string $authKey 141 | * @return boolean if auth key is valid for current user 142 | */ 143 | public function validateAuthKey($authKey) 144 | { 145 | return $this->auth_key === $authKey; 146 | } 147 | 148 | /** 149 | * Validates password 150 | * 151 | * @param string $password password to validate 152 | * @return boolean if password provided is valid for current user 153 | */ 154 | public function validatePassword($password) 155 | { 156 | return Yii::$app->security->validatePassword($password, $this->password_hash); 157 | } 158 | 159 | public function getPassword() 160 | { 161 | return $this->password_hash; 162 | } 163 | /** 164 | * Generates password hash from password and sets it to the model 165 | * 166 | * @param string $password 167 | */ 168 | public function setPassword($password) 169 | { 170 | if (!empty($password) and $password != $this->password_hash) { 171 | $this->password_hash = Yii::$app->security->generatePasswordHash($password); 172 | } 173 | } 174 | 175 | /** 176 | * Generates "remember me" authentication key 177 | */ 178 | public function generateAuthKey() 179 | { 180 | $this->auth_key = Yii::$app->security->generateRandomString(); 181 | } 182 | 183 | /** 184 | * @inheritdoc 185 | */ 186 | public static function tableName() 187 | { 188 | return Yii::$app->getModule('auth')->tableMap['User']; 189 | } 190 | 191 | /** 192 | * @inheritdoc 193 | */ 194 | public function rules() 195 | { 196 | return [ 197 | ['status', 'default', 'value' => self::STATUS_ACTIVE], 198 | [ 199 | 'status', 200 | 'in', 201 | 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED, self::STATUS_INACTIVE, self::STATUS_SUSPENDED] 202 | ], 203 | ['username', 'filter', 'filter' => 'trim'], 204 | ['username', 'required'], 205 | ['username', 'unique', 'message' => Yii::t('auth.user', 'This username has already been taken.')], 206 | ['username', 'string', 'min' => 2, 'max' => 255], 207 | 208 | ['email', 'filter', 'filter' => 'trim'], 209 | ['email', 'required'], 210 | ['email', 'email'], 211 | ['email', 'unique', 'message' => Yii::t('auth.user', 'This email address has already been taken.')], 212 | ['email', 'exist', 'message' => Yii::t('auth.user', 'There is no user with such email.'), 'on' => 'requestPasswordResetToken'], 213 | ]; 214 | } 215 | 216 | public function scenarios() 217 | { 218 | return [ 219 | 'profile' => ['username', 'email', 'password_hash', 'password'], 220 | 'resetPassword' => ['password_hash'], 221 | 'requestPasswordResetToken' => ['email'], 222 | 'login' => ['last_visit_time'], 223 | ] + parent::scenarios(); 224 | } 225 | 226 | /** 227 | * @inheritdoc 228 | */ 229 | public function attributeLabels() 230 | { 231 | return [ 232 | 'id' => 'ID', 233 | 'username' => Yii::t('auth.user', 'Username'), 234 | 'email' => Yii::t('auth.user', 'Email'), 235 | 'password_hash' => Yii::t('auth.user', 'Password Hash'), 236 | 'password_reset_token' => Yii::t('auth.user', 'Password Reset Token'), 237 | 'auth_key' => Yii::t('auth.user', 'Auth Key'), 238 | 'status' => Yii::t('auth.user', 'Status'), 239 | 'last_visit_time' => Yii::t('auth.user', 'Last Visit Time'), 240 | 'create_time' => Yii::t('auth.user', 'Create Time'), 241 | 'update_time' => Yii::t('auth.user', 'Update Time'), 242 | 'delete_time' => Yii::t('auth.user', 'Delete Time'), 243 | ]; 244 | } 245 | 246 | /** 247 | * @return \yii\db\ActiveRelation 248 | */ 249 | public function getProfileFieldValue() 250 | { 251 | return $this->hasOne(ProfileFieldValue::className(), ['id' => 'user_id']); 252 | } 253 | 254 | public function beforeValidate() 255 | { 256 | if (parent::beforeValidate()) { 257 | 258 | return true; 259 | } 260 | 261 | return false; 262 | } 263 | 264 | public function beforeSave($insert) 265 | { 266 | if (parent::beforeSave($insert)) { 267 | if ($this->isNewRecord) { 268 | $this->auth_key = Yii::$app->getSecurity()->generateRandomString(); 269 | } 270 | if ($this->getScenario() !== \yii\web\User::EVENT_AFTER_LOGIN) { 271 | $this->setAttribute('update_time', new Expression('CURRENT_TIMESTAMP')); 272 | } 273 | 274 | return true; 275 | } 276 | return false; 277 | } 278 | 279 | public function delete() 280 | { 281 | $db = static::getDb(); 282 | $transaction = $this->isTransactional(self::OP_DELETE) && $db->getTransaction() === null ? $db->beginTransaction() : null; 283 | try { 284 | $result = false; 285 | if ($this->beforeDelete()) { 286 | $this->setAttribute('status', static::STATUS_DELETED); 287 | $this->save(false); 288 | } 289 | if ($transaction !== null) { 290 | if ($result === false) { 291 | $transaction->rollback(); 292 | } else { 293 | $transaction->commit(); 294 | } 295 | } 296 | } catch (\Exception $e) { 297 | if ($transaction !== null) { 298 | $transaction->rollback(); 299 | } 300 | throw $e; 301 | } 302 | return $result; 303 | } 304 | 305 | /** 306 | * Returns whether the logged in user is an administrator. 307 | * 308 | * @return boolean the result. 309 | */ 310 | public function getIsSuperAdmin() 311 | { 312 | if ($this->_isSuperAdmin !== null) { 313 | return $this->_isSuperAdmin; 314 | } 315 | 316 | $this->_isSuperAdmin = in_array($this->username, Yii::$app->getModule('auth')->superAdmins); 317 | return $this->_isSuperAdmin; 318 | } 319 | 320 | public function login($duration = 0) 321 | { 322 | return Yii::$app->user->login($this, $duration); 323 | } 324 | 325 | /** 326 | * Generates new password reset token 327 | */ 328 | public function generatePasswordResetToken() 329 | { 330 | $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); 331 | } 332 | 333 | /** 334 | * Removes password reset token 335 | */ 336 | public function removePasswordResetToken() 337 | { 338 | $this->password_reset_token = null; 339 | } 340 | } 341 | --------------------------------------------------------------------------------