diff --git a/apps/advanced/common/config/params.php b/apps/advanced/common/config/params.php
index c381cb0..abb8873 100644
--- a/apps/advanced/common/config/params.php
+++ b/apps/advanced/common/config/params.php
@@ -6,6 +6,7 @@ Yii::setAlias('backend', __DIR__ . '/../../backend');
 
 return array(
 	'adminEmail' => 'admin@example.com',
+	'supportEmail' => 'support@example.com',
 
 	'components.cache' => array(
 		'class' => 'yii\caching\FileCache',
diff --git a/apps/advanced/common/models/User.php b/apps/advanced/common/models/User.php
index 25be085..df1d6b0 100644
--- a/apps/advanced/common/models/User.php
+++ b/apps/advanced/common/models/User.php
@@ -12,6 +12,7 @@ use yii\web\Identity;
  * @property integer $id
  * @property string $username
  * @property string $password_hash
+ * @property string $password_reset_token
  * @property string $email
  * @property string $auth_key
  * @property integer $role
@@ -66,7 +67,7 @@ class User extends ActiveRecord implements Identity
 
 	public function validateAuthKey($authKey)
 	{
-		return $this->auth_key === $authKey;
+		return $this->getAuthKey() === $authKey;
 	}
 
 	public function validatePassword($password)
@@ -84,7 +85,7 @@ class User extends ActiveRecord implements Identity
 			array('email', 'filter', 'filter' => 'trim'),
 			array('email', 'required'),
 			array('email', 'email'),
-			array('email', 'unique', 'message' => 'This email address has already been taken.'),
+			array('email', 'unique', 'message' => 'This email address has already been taken.', 'on' => 'signup'),
 
 			array('password', 'required'),
 			array('password', 'string', 'min' => 6),
@@ -96,16 +97,17 @@ class User extends ActiveRecord implements Identity
 		return array(
 			'signup' => array('username', 'email', 'password'),
 			'login' => array('username', 'password'),
+			'resetPassword' => array('password'),
 		);
 	}
 
 	public function beforeSave($insert)
 	{
 		if (parent::beforeSave($insert)) {
+			if (($this->isNewRecord || $this->getScenario() === 'resetPassword') && !empty($this->password)) {
+				$this->password_hash = SecurityHelper::generatePasswordHash($this->password);
+			}
 			if ($this->isNewRecord) {
-				if (!empty($this->password)) {
-					$this->password_hash = SecurityHelper::generatePasswordHash($this->password);
-				}
 				$this->auth_key = SecurityHelper::generateRandomKey();
 			}
 			return true;
diff --git a/apps/advanced/console/migrations/m130524_201442_init.php b/apps/advanced/console/migrations/m130524_201442_init.php
index a5e9d30..e7b9e84 100644
--- a/apps/advanced/console/migrations/m130524_201442_init.php
+++ b/apps/advanced/console/migrations/m130524_201442_init.php
@@ -12,7 +12,9 @@ class m130524_201442_init extends \yii\db\Migration
 		$this->createTable('tbl_user', array(
 			'id' => Schema::TYPE_PK,
 			'username' => Schema::TYPE_STRING.' NOT NULL',
+			'auth_key' => Schema::TYPE_STRING.'(32) NOT NULL',
 			'password_hash' => Schema::TYPE_STRING.' NOT NULL',
+			'password_reset_token' => Schema::TYPE_STRING.'(32)',
 			'email' => Schema::TYPE_STRING.' NOT NULL',
 			'role' => 'tinyint NOT NULL DEFAULT 10',
 
diff --git a/apps/advanced/frontend/controllers/SiteController.php b/apps/advanced/frontend/controllers/SiteController.php
index 7fce71c..44a7fd9 100644
--- a/apps/advanced/frontend/controllers/SiteController.php
+++ b/apps/advanced/frontend/controllers/SiteController.php
@@ -7,6 +7,8 @@ use yii\web\Controller;
 use common\models\LoginForm;
 use frontend\models\ContactForm;
 use common\models\User;
+use yii\web\HttpException;
+use frontend\models\SendPasswordResetTokenForm;
 
 class SiteController extends Controller
 {
@@ -74,4 +76,38 @@ class SiteController extends Controller
 			'model' => $model,
 		));
 	}
+
+	public function actionResetPassword($token = null)
+	{
+		if ($token) {
+			$model = User::find(array(
+				'password_reset_token' => $token,
+				'status' => User::STATUS_ACTIVE,
+			));
+
+			if (!$model) {
+				throw new HttpException(400, 'Wrong password reset token.');
+			}
+
+			$model->scenario = 'resetPassword';
+			if ($model->load($_POST) && $model->save()) {
+				// TODO: confirm that password was successfully saved
+				$this->redirect('index');
+			}
+
+			$this->render('resetPassword', array(
+				'model' => $model,
+			));
+		}
+		else {
+			$model = new SendPasswordResetTokenForm();
+			if ($model->load($_POST) && $model->sendEmail()) {
+				// TODO: confirm that password reset token was sent
+				$this->redirect('index');
+			}
+			$this->render('sendPasswordResetTokenForm', array(
+				'model' => $model,
+			));
+		}
+	}
 }
diff --git a/apps/advanced/frontend/models/SendPasswordResetTokenForm.php b/apps/advanced/frontend/models/SendPasswordResetTokenForm.php
new file mode 100644
index 0000000..05c8f99
--- /dev/null
+++ b/apps/advanced/frontend/models/SendPasswordResetTokenForm.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace frontend\models;
+use yii\base\Model;
+use common\models\User;
+use yii\base\View;
+use yii\helpers\SecurityHelper;
+
+/**
+ * SendPasswordResetTokenForm is the model behind requesting password reset token form.
+ */
+class SendPasswordResetTokenForm extends Model
+{
+	public $email;
+
+	/**
+	 * @return array the validation rules.
+	 */
+	public function rules()
+	{
+		return array(
+			array('email', 'required'),
+			array('email', 'email'),
+		);
+	}
+
+	public function sendEmail()
+	{
+		if($this->validate()) {
+			/** @var User $user */
+			$user = User::find(array(
+				'email' => $this->email,
+				'status' => User::STATUS_ACTIVE,
+			));
+			if ($user) {
+				$user->password_reset_token = SecurityHelper::generateRandomKey();
+				if ($user->save(false)) {
+					$view = new View(array(
+						'context' => \Yii::$app->controller,
+					));
+
+					$fromEmail = \Yii::$app->params['supportEmail'];
+					$name = '=?UTF-8?B?' . base64_encode(\Yii::$app->name . ' robot') . '?=';
+					$subject = '=?UTF-8?B?' . base64_encode('Password reset for ' . \Yii::$app->name) . '?=';
+					$body = $view->render('/emails/passwordResetToken', array(
+						'user' => $user,
+					));
+					$headers = "From: $name <{$fromEmail}>\r\n" .
+						"MIME-Version: 1.0\r\n" .
+						"Content-type: text/plain; charset=UTF-8";
+					mail($fromEmail, $subject, $body, $headers);
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+}
diff --git a/apps/advanced/frontend/views/emails/passwordResetToken.php b/apps/advanced/frontend/views/emails/passwordResetToken.php
new file mode 100644
index 0000000..110bfbf
--- /dev/null
+++ b/apps/advanced/frontend/views/emails/passwordResetToken.php
@@ -0,0 +1,16 @@
+<?php
+use yii\helpers\Html;
+
+/**
+ * @var yii\base\View $this
+ * @var common\models\User $user;
+ */
+
+$resetLink = $this->context->createUrl('site/resetPassword', array('token' => $user->password_reset_token));
+?>
+
+Hello <?php echo Html::encode($user->username)?>,
+
+Follow the link below to reset your password:
+
+<?php Html::a(Html::encode($resetLink), $resetLink)?>
\ No newline at end of file
diff --git a/apps/advanced/frontend/views/site/resetPassword.php b/apps/advanced/frontend/views/site/resetPassword.php
new file mode 100644
index 0000000..3216bc1
--- /dev/null
+++ b/apps/advanced/frontend/views/site/resetPassword.php
@@ -0,0 +1,22 @@
+<?php
+use yii\helpers\Html;
+use yii\widgets\ActiveForm;
+
+/**
+ * @var yii\base\View $this
+ * @var yii\widgets\ActiveForm $form
+ * @var common\models\User $model
+ */
+$this->title = 'Reset password';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+<h1><?php echo Html::encode($this->title); ?></h1>
+
+<p>Please choose your new password:</p>
+
+<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
+	<?php echo $form->field($model, 'password')->passwordInput(); ?>
+	<div class="form-actions">
+		<?php echo Html::submitButton('Save', array('class' => 'btn btn-primary')); ?>
+	</div>
+<?php ActiveForm::end(); ?>
diff --git a/apps/advanced/frontend/views/site/sendPasswordResetTokenForm.php b/apps/advanced/frontend/views/site/sendPasswordResetTokenForm.php
new file mode 100644
index 0000000..4d8c429
--- /dev/null
+++ b/apps/advanced/frontend/views/site/sendPasswordResetTokenForm.php
@@ -0,0 +1,22 @@
+<?php
+use yii\helpers\Html;
+use yii\widgets\ActiveForm;
+
+/**
+ * @var yii\base\View $this
+ * @var yii\widgets\ActiveForm $form
+ * @var frontend\models\SendPasswordResetTokenForm $model
+ */
+$this->title = 'Request password reset';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+<h1><?php echo Html::encode($this->title); ?></h1>
+
+<p>Please fill out your email. A link to reset password will be sent there.</p>
+
+<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
+	<?php echo $form->field($model, 'email')->textInput(); ?>
+	<div class="form-actions">
+		<?php echo Html::submitButton('Send', array('class' => 'btn btn-primary')); ?>
+	</div>
+<?php ActiveForm::end(); ?>