├── 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 = Html::encode($user->username) ?>,
10 | Follow the link below to reset your password:
11 |
12 | = Html::a(Html::encode($resetLink), $resetLink) ?>
--------------------------------------------------------------------------------
/views/mail/es/passwordResetToken.php:
--------------------------------------------------------------------------------
1 | urlManager->createAbsoluteUrl(['auth/default/reset-password', 'token' => $user->password_reset_token]);
8 | ?>
9 | Hola = Html::encode($user->username) ?>,
10 | Siga el siguiente vínculo para restaurar su clave:
11 |
12 | = Html::a(Html::encode($resetLink), $resetLink) ?>
--------------------------------------------------------------------------------
/views/mail/de/passwordResetToken.php:
--------------------------------------------------------------------------------
1 | urlManager->createAbsoluteUrl(['auth/default/reset-password', 'token' => $user->password_reset_token]);
8 | ?>
9 | Hallo = Html::encode($user->username) ?>,
10 | Über den folgenden Link kannst du dein Passwort zurücksetzen:
11 |
12 | = Html::a(Html::encode($resetLink), $resetLink) ?>
--------------------------------------------------------------------------------
/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 |
= Html::encode($this->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 |
= Html::encode($this->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 | = Html::encode($this->title) ?>
18 | = Html::a('', ['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 |
= Html::encode($this->title) ?>
14 |
15 |
= \Yii::t('auth.reset-password', 'Please choose your new password') ?>:
16 |
17 |
18 |
19 | 'reset-password-form']); ?>
20 | = $form->field($model, 'password')->passwordInput() ?>
21 |
22 | = Html::submitButton(\Yii::t('auth.reset-password', 'Save'), ['class' => '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 |
= Html::encode($this->title) ?>
14 |
15 |
= Yii::t('auth.reset-password', 'Please fill out your email. A link to reset password will be sent there.') ?>
16 |
17 |
18 |
19 | 'request-password-reset-form']); ?>
20 | = $form->field($model, 'email') ?>
21 |
22 | = Html::submitButton(Yii::t('auth.reset-password','Send'), ['class' => 'btn btn-primary']) ?>
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/views/user/_form.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
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 |
14 |
15 | ['index'],
17 | 'method' => 'get',
18 | ]); ?>
19 |
20 | = $form->field($model, 'id') ?>
21 |
22 | = $form->field($model, 'username') ?>
23 |
24 | = $form->field($model, 'email') ?>
25 |
26 | = $form->field($model, 'password_hash') ?>
27 |
28 | = $form->field($model, 'password_reset_token') ?>
29 |
30 | field($model, 'auth_key') ?>
31 |
32 | field($model, 'status') ?>
33 |
34 | field($model, 'last_visit_time') ?>
35 |
36 | field($model, 'create_time') ?>
37 |
38 | field($model, 'update_time') ?>
39 |
40 | field($model, 'delete_time') ?>
41 |
42 |
43 | = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
44 | = Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
45 |
46 |
47 |
48 |
49 |
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: '= Html::encode($this->title) ?>'
18 |
19 |
20 | = Html::a(Yii::t('auth.user', 'Update'), ['update', 'id' => $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 |
= Html::encode($this->title) ?>
13 |
14 |
15 | 'registration-form',
17 | ]); ?>
18 |
19 | getModule('auth')->signupWithEmailOnly): ?>
20 | = $form->field($model, 'username') ?>
21 |
22 |
23 | = $form->field($model, 'email') ?>
24 |
25 | = $form->field($model, 'password')->passwordInput() ?>
26 |
27 | = Html::submitButton('Sign up', ['class' => 'btn btn-success btn-block']) ?>
28 |
29 |
30 |
31 |
32 |
33 | = Html::a('Already registered? Sign in!', ['/auth/default/login']) ?>
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 |
= Html::encode($this->title) ?>
18 |
19 | render('_search', ['model' => $searchModel]); ?>
20 |
21 |
22 | = Html::a(' ' . 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 | = Html::encode($this->title) ?>
22 |
23 |
24 |
25 | = $form->field($model, 'username')->textInput(['maxlength' => 64]) ?>
26 |
27 | = $form->field($model, 'email')->textInput(['maxlength' => 128, 'type' => 'email']) ?>
28 |
29 | = $form->field($model, 'password')->passwordInput() ?>
30 |
31 | getIsSuperAdmin()): // ToDo: Allow admins too ?>
32 | =
33 | $form->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 |
16 |
= Html::encode($this->title) ?>
17 |
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 | = $form->field($model, 'username', ['options' => ['class' => 'form-group input-group input-group-lg'], 'template' => '
{input}'])->textInput(['placeholder' => $model->getAttributeLabel('username')]) ?>
29 |
30 | = $form->field($model, 'password', ['options' => ['class' => 'form-group input-group input-group-lg'], 'template' => '
{input}'])->passwordInput(['placeholder' => $model->getAttributeLabel('password')]) ?>
31 | scenario == 'withCaptcha'): ?>
32 | =
33 | $form->field($model, 'verifyCode')->widget(Captcha::className(), ['captchaAction' => 'default/captcha', 'options' => ['class' => 'form-control'],]) ?>
34 |
35 |
36 | = $form->field($model, 'rememberMe')->checkbox() ?>
37 |
38 |
43 |
44 |
45 |
= Html::a(\Yii::t('auth.user', 'Forgot password?'), ['default/request-password-reset']) ?>
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 | [](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 |
--------------------------------------------------------------------------------