Adding forgot password functionality.

This commit is contained in:
Dan Cryer 2014-05-08 21:38:32 +01:00
parent 2cd4bade30
commit cf2d93f71a
6 changed files with 351 additions and 90 deletions

View file

@ -10,6 +10,7 @@
namespace PHPCI\Controller;
use b8;
use PHPCI\Helper\Email;
/**
* Session Controller - Handles user login / logout.
@ -88,4 +89,74 @@ class SessionController extends \PHPCI\Controller
header('Location: ' . PHPCI_URL);
die;
}
public function forgotPassword()
{
if ($this->request->getMethod() == 'POST') {
$email = $this->getParam('email', null);
$user = $this->userStore->getByEmail($email);
if (empty($user)) {
$this->view->error = 'No user exists with that email address, please try again.';
return $this->view->render();
}
$key = md5(date('Y-m-d') . $user->getHash());
$url = PHPCI_URL;
$name = $user->getName();
$id = $user->getId();
$message = <<<MSG
Hi {$name},
You have received this email because you, or someone else, has requested a password reset for PHPCI.
If this was you, please click the following link to reset your password: {$url}session/reset-password/{$id}/{$key}
Otherwise, please ignore this email and no action will be taken.
Thank you,
PHPCI
MSG;
$email = new Email();
$email->setTo($user->getEmail(), $user->getName());
$email->setSubject('Password reset');
$email->setBody($message);
$email->send();
$this->view->emailed = true;
}
return $this->view->render();
}
public function resetPassword($id, $key)
{
$user = $this->userStore->getById($id);
$userKey = md5(date('Y-m-d') . $user->getHash());
if (empty($user) || $key != $userKey) {
$this->view->error = 'Invalid password reset request.';
return $this->view->render();
}
if ($this->request->getMethod() == 'POST') {
$hash = password_hash($this->getParam('password'), PASSWORD_DEFAULT);
$user->setHash($hash);
$_SESSION['user'] = $this->userStore->save($user);
$_SESSION['user_id'] = $user->getId();
header('Location: ' . PHPCI_URL);
die;
}
$this->view->id = $id;
$this->view->key = $key;
return $this->view->render();
}
}

127
PHPCI/Helper/Email.php Normal file
View file

@ -0,0 +1,127 @@
<?php
namespace PHPCI\Helper;
use b8\Config;
use PHPCI\Helper\MailerFactory;
class Email
{
const DEFAULT_FROM = 'PHPCI <no-reply@phptesting.org>';
protected $to = array();
protected $cc = array();
protected $subject = 'Email from PHPCI';
protected $body = '';
protected $isHtml = false;
protected $config;
public function __construct()
{
$this->config = Config::getInstance();
}
public function setTo($email, $name = null)
{
$this->to[$email] = $name;
return $this;
}
public function addCc($email, $name = null)
{
$this->cc[$email] = $name;
return $this;
}
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
public function setBody($body)
{
$this->body = $body;
return $this;
}
public function setIsHtml($isHtml = false)
{
$this->isHtml = $isHtml;
return $this;
}
public function send()
{
$smtpServer = $this->config->get('phpci.email_settings.smtp_address');
if (empty($smtpServer)) {
return $this->sendViaMail();
} else {
return $this->sendViaSwiftMailer();
}
}
protected function sendViaMail()
{
$headers = '';
if ($this->isHtml) {
$headers = 'Content-Type: text/html' . PHP_EOL;
}
$headers .= 'From: ' . $this->getFrom() . PHP_EOL;
$to = array();
foreach ($this->to as $email => $name) {
$thisTo = $email;
if (!is_null($name)) {
$thisTo = '"' . $name . '" <' . $thisTo . '>';
}
$to[] = $thisTo;
}
$to = implode(', ', $to);
return mail($to, $this->subject, $this->body, $headers);
}
protected function sendViaSwiftMailer()
{
$factory = new MailerFactory($this->config->get('phpci'));
$mailer = $factory->getSwiftMailerFromConfig();
$message = \Swift_Message::newInstance($this->subject)
->setFrom($this->getFrom())
->setTo($this->to)
->setBody($this->body);
if ($this->isHtml) {
$message->setContentType('text/html');
}
if (is_array($this->cc) && count($this->cc)) {
$message->setCc($this->cc);
}
return $mailer->send($message);
}
protected function getFrom()
{
$email = $this->config->get('phpci.email_settings.from_address', self::DEFAULT_FROM);
if (empty($email)) {
$email = self::DEFAULT_FROM;
}
return $email;
}
}

88
PHPCI/View/Session.phtml Normal file
View file

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Log in to PHPCI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
<script src="//code.jquery.com/jquery-1.8.1.min.js"></script>
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
<style type="text/css">
html {
min-height: 100%;
}
body
{
background: #224466; /* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, #224466 0%, #112233 100%); /* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#224466), color-stop(100%,#112233)); /* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* IE10+ */
background: radial-gradient(ellipse at center, #224466 0%,#112233 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#224466', endColorstr='#112233',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
min-height: 100%;
font-family: Roboto, Arial, Sans-Serif;
font-style: normal;
font-weight: 300;
padding-top: 0px;
}
#login-box
{
background: #fcfcfc; /* Old browsers */
background: -moz-linear-gradient(top, #fcfcfc 50%, #e0e0e0 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#fcfcfc), color-stop(100%,#e0e0e0)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* IE10+ */
background: linear-gradient(to bottom, #fcfcfc 50%,#e0e0e0 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc', endColorstr='#e0e0e0',GradientType=0 ); /* IE6-9 */
border-radius: 5px;
box-shadow: 0 0 30px rgba(0,0,0, 0.3);
margin: 0 auto;
padding: 15px 30px;
text-align: left;
width: 350px;
}
#logo {
background: transparent url('http://www.block8.co.uk/badge-dark-muted.png') no-repeat top left;
display: inline-block;
height: 26px;
margin: 40px auto;
width: 90px;
}
#logo:hover {
background-image: url('http://www.block8.co.uk/badge-dark.png');
}
#phpci-logo img {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row" style="margin-top: 10%; text-align: center">
<a id="phpci-logo" href="http://www.phptesting.org">
<img src="<?php print PHPCI_URL; ?>/assets/img/logo-large.png">
</a>
<div class="" id="login-box">
<?php print $content; ?>
</div>
<a id="logo" href="http://www.block8.co.uk/"></a>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,33 @@
<?php if (isset($emailed)): ?>
<p class="alert alert-success" style="margin-bottom: 0">
We've emailed you a link to reset your password.
</p>
<?php else: ?>
<?php if (empty($error)): ?>
<div class="panel panel-success" style="margin-bottom: 0">
<div class="panel-heading">
<strong>Don't worry!</strong><br>Just enter your email address below and we'll email you a link to reset your password.
</div>
<?php else: ?>
<div class="panel panel-danger" style="margin-bottom: 0">
<div class="panel-heading">
<?php print $error; ?>
</div>
<?php endif; ?>
<div class="panel-body">
<form class="form" action="<?php print PHPCI_URL; ?>session/forgot-password" method="POST">
<div class="form-group">
<label for="email">Enter your email address:</label>
<input id="email" name="email" class="form-control" required>
</div>
<div class="form-group">
<input class="btn btn-success" type="submit" value="Email password reset">
</div>
</form>
</div>
</div>
<?php endif; ?>

View file

@ -1,91 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Log in to PHPCI</title>
<?php if($failed): ?>
<p class="alert alert-danger">Incorrect email address or password</p>
<?php endif; ?>
<?php print $form; ?>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
<script src="//code.jquery.com/jquery-1.8.1.min.js"></script>
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
<style type="text/css">
html {
min-height: 100%;
}
body
{
background: #224466; /* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, #224466 0%, #112233 100%); /* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#224466), color-stop(100%,#112233)); /* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* IE10+ */
background: radial-gradient(ellipse at center, #224466 0%,#112233 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#224466', endColorstr='#112233',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
min-height: 100%;
font-family: Roboto, Arial, Sans-Serif;
font-style: normal;
font-weight: 300;
padding-top: 0px;
}
#login-box
{
background: #fcfcfc; /* Old browsers */
background: -moz-linear-gradient(top, #fcfcfc 50%, #e0e0e0 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#fcfcfc), color-stop(100%,#e0e0e0)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* IE10+ */
background: linear-gradient(to bottom, #fcfcfc 50%,#e0e0e0 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc', endColorstr='#e0e0e0',GradientType=0 ); /* IE6-9 */
border-radius: 5px;
box-shadow: 0 0 30px rgba(0,0,0, 0.3);
margin: 0 auto;
padding: 15px 30px;
text-align: left;
width: 350px;
}
#logo {
background: transparent url('http://www.block8.co.uk/badge-dark-muted.png') no-repeat top left;
display: inline-block;
height: 26px;
margin: 40px auto;
width: 90px;
}
#logo:hover {
background-image: url('http://www.block8.co.uk/badge-dark.png');
}
#phpci-logo img {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row" style="margin-top: 10%; text-align: center">
<a id="phpci-logo" href="http://www.phptesting.org">
<img src="<?php print PHPCI_URL; ?>/assets/img/logo-large.png">
</a>
<div class="" id="login-box">
<?php if($failed): ?>
<p class="alert alert-danger">Incorrect email address or password</p>
<?php endif; ?>
<?php print $form; ?>
</div>
<a id="logo" href="http://www.block8.co.uk/"></a>
</div>
</div>
</body>
</html>
<a style="margin-top: -22px; font-size: 0.85em; color: #246" class="pull-right" href="<?php print PHPCI_URL; ?>session/forgot-password">Forgotten your password?</a>

View file

@ -0,0 +1,27 @@
<?php if (empty($error)): ?>
<div class="panel panel-success" style="margin-bottom: 0">
<div class="panel-heading">
Please enter a new password
</div>
<div class="panel-body">
<form class="form" action="<?php print PHPCI_URL; ?>session/reset-password/<?php print $id; ?>/<?php print $key; ?>" method="POST">
<div class="form-group">
<label for="password">New password:</label>
<input type="password" id="password" name="password" class="form-control" required>
</div>
<div class="form-group">
<input class="btn btn-success" type="submit" value="Change password">
</div>
</form>
</div>
</div>
<?php else: ?>
<div class="alert alert-danger" style="margin-bottom: 0">
<?php print $error; ?>
</div>
<?php endif; ?>