Create a controller for password recovery pages

This commit is contained in:
Dmitriy Simushev 2014-05-15 14:50:16 +00:00
parent d342a4ca9a
commit e3fe5b8022
7 changed files with 212 additions and 185 deletions

View File

@ -0,0 +1,196 @@
<?php
/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Mibew\Controller;
use Mibew\Database;
use Mibew\Http\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Contains actions realted with password recovery procedure.
*/
class PasswordRecoveryController extends AbstractController
{
/**
* Generate content for "password_recovery" route.
*
* @param Request $request
* @return string Rendered page content
*/
public function indexAction(Request $request)
{
if ($request->attributes->get('_operator')) {
// If the operator is logged in just redirect him to the home page.
return $this->redirect($request->getUriForPath('/operator'));
}
$page = array(
'version' => MIBEW_VERSION,
'title' => getlocal('restore.title'),
'headertitle' => getlocal('app.title'),
'show_small_login' => true,
'fixedwrap' => true,
'errors' => array(),
);
$login_or_email = '';
if ($request->request->has('loginoremail')) {
$login_or_email = $request->request->get('loginoremail');
$to_restore = is_valid_email($login_or_email)
? operator_by_email($login_or_email)
: operator_by_login($login_or_email);
if (!$to_restore) {
$page['errors'][] = getlocal('no_such_operator');
}
$email = $to_restore['vcemail'];
if (count($page['errors']) == 0 && !is_valid_email($email)) {
$page['errors'][] = "Operator hasn't set his e-mail";
}
if (count($page['errors']) == 0) {
$token = sha1($to_restore['vclogin'] . (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes(32)
: (time() + microtime()) . mt_rand(0, 99999999)));
$db = Database::getInstance();
$db->query(
("UPDATE {chatoperator} "
. "SET dtmrestore = :now, vcrestoretoken = :token "
. "WHERE operatorid = :operatorid"),
array(
':now' => time(),
':token' => $token,
':operatorid' => $to_restore['operatorid'],
)
);
$href = $this->getRouter()->generate(
'password_recovery_reset',
array(
'id' => $to_restore['operatorid'],
'token' => $token,
),
UrlGeneratorInterface::ABSOLUTE_URL
);
mibew_mail(
$email,
$email,
getstring('restore.mailsubj'),
getstring2(
'restore.mailtext',
array(get_operator_name($to_restore), $href)
)
);
$page['isdone'] = true;
return $this->render('password_recovery', $page);
}
}
$page['formloginoremail'] = $login_or_email;
$page['localeLinks'] = get_locale_links();
$page['isdone'] = false;
return $this->render('password_recovery', $page);
}
/**
* Generate content for "password_recovery_reset" route.
*
* @param Request $request
* @return string Rendered page content
*/
public function resetAction(Request $request)
{
$page = array(
'version' => MIBEW_VERSION,
'showform' => true,
'title' => getlocal('resetpwd.title'),
'headertitle' => getlocal('app.title'),
'show_small_login' => true,
'fixedwrap' => true,
'errors' => array(),
);
// Make sure user id is specified and its format is correct.
$op_id = $request->isMethod('GET')
? $request->query->get('id')
: $request->request->get('id');
if (!preg_match("/^\d{1,9}$/", $op_id)) {
throw new BadRequestException();
}
// Make sure token is specified and its format is correct.
$token = $request->isMethod('GET')
? $request->query->get('token')
: $request->request->get('token');
if (!preg_match("/^[\dabcdef]+$/", $token)) {
throw new BadRequestException();
}
$operator = operator_by_id($op_id);
if (!$operator) {
$page['errors'][] = 'No such operator';
$page['showform'] = false;
} elseif ($token != $operator['vcrestoretoken']) {
$page['errors'][] = 'Wrong token';
$page['showform'] = false;
}
if (count($page['errors']) == 0 && $request->request->has('password')) {
$password = $request->request->get('password');
$password_confirm = $request->request->get('passwordConfirm');
if (!$password) {
$page['errors'][] = no_field('form.field.password');
}
if ($password != $password_confirm) {
$page['errors'][] = getlocal('my_settings.error.password_match');
}
if (count($page['errors']) == 0) {
$page['isdone'] = true;
$db = Database::getInstance();
$db->query(
("UPDATE {chatoperator} "
. "SET vcpassword = ?, vcrestoretoken = '' "
. "WHERE operatorid = ?"),
array(
calculate_password_hash($operator['vclogin'], $password),
$op_id,
)
);
$page['loginname'] = $operator['vclogin'];
return $this->render('password_recovery_reset', $page);
}
}
$page['id'] = $op_id;
$page['token'] = $token;
$page['isdone'] = false;
return $this->render('password_recovery_reset', $page);
}
}

View File

@ -34,6 +34,16 @@ history_user:
requirements:
user_id: .{0,63}
password_recovery:
path: /operator/password-recovery
defaults:
_controller: Mibew\Controller\PasswordRecoveryController::indexAction
password_recovery_reset:
path: /operator/password-recovery/reset
defaults:
_controller: Mibew\Controller\PasswordRecoveryController::resetAction
updates:
path: /operator/updates
defaults:

View File

@ -1,86 +0,0 @@
<?php
/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Import namespaces and classes of the core
use Mibew\Database;
use Mibew\Style\PageStyle;
// Initialize libraries
require_once(dirname(dirname(__FILE__)) . '/libs/init.php');
$page = array(
'version' => MIBEW_VERSION,
'showform' => true,
'title' => getlocal("resetpwd.title"),
'headertitle' => getlocal("app.title"),
'show_small_login' => true,
'fixedwrap' => true,
'errors' => array(),
);
$page_style = new PageStyle(PageStyle::getCurrentStyle());
$op_id = verify_param("id", "/^\d{1,9}$/");
$token = verify_param("token", "/^[\dabcdef]+$/");
$operator = operator_by_id($op_id);
if (!$operator) {
$page['errors'][] = "No such operator";
$page['showform'] = false;
} elseif ($token != $operator['vcrestoretoken']) {
$page['errors'][] = "Wrong token";
$page['showform'] = false;
}
if (count($page['errors']) == 0 && isset($_POST['password'])) {
$password = get_param('password');
$password_confirm = get_param('passwordConfirm');
if (!$password) {
$page['errors'][] = no_field("form.field.password");
}
if ($password != $password_confirm) {
$page['errors'][] = getlocal("my_settings.error.password_match");
}
if (count($page['errors']) == 0) {
$page['isdone'] = true;
$db = Database::getInstance();
$db->query(
("UPDATE {chatoperator} "
. "SET vcpassword = ?, vcrestoretoken = '' "
. "WHERE operatorid = ?"),
array(
calculate_password_hash($operator['vclogin'], $password),
$op_id,
)
);
$page['loginname'] = $operator['vclogin'];
$page_style->render('resetpwd', $page);
exit;
}
}
$page['id'] = $op_id;
$page['token'] = $token;
$page['isdone'] = false;
$page_style->render('resetpwd', $page);

View File

@ -1,93 +0,0 @@
<?php
/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Import namespaces and classes of the core
use Mibew\Database;
use Mibew\Style\PageStyle;
// Initialize libraries
require_once(dirname(dirname(__FILE__)) . '/libs/init.php');
$page = array(
'version' => MIBEW_VERSION,
'title' => getlocal("restore.title"),
'headertitle' => getlocal("app.title"),
'show_small_login' => true,
'fixedwrap' => true,
'errors' => array(),
);
$login_or_email = "";
$page_style = new PageStyle(PageStyle::getCurrentStyle());
if (isset($_POST['loginoremail'])) {
$login_or_email = get_param("loginoremail");
$to_restore = is_valid_email($login_or_email)
? operator_by_email($login_or_email)
: operator_by_login($login_or_email);
if (!$to_restore) {
$page['errors'][] = getlocal("no_such_operator");
}
$email = $to_restore['vcemail'];
if (count($page['errors']) == 0 && !is_valid_email($email)) {
$page['errors'][] = "Operator hasn't set his e-mail";
}
if (count($page['errors']) == 0) {
$token = sha1($to_restore['vclogin'] . (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes(32)
: (time() + microtime()) . mt_rand(0, 99999999)));
$db = Database::getInstance();
$db->query(
("UPDATE {chatoperator} "
. "SET dtmrestore = :now, vcrestoretoken = :token "
. "WHERE operatorid = :operatorid"),
array(
':now' => time(),
':token' => $token,
':operatorid' => $to_restore['operatorid'],
)
);
$href = get_app_location(true, false) . "/operator/resetpwd.php?id="
. $to_restore['operatorid'] . "&token=$token";
mibew_mail(
$email,
$email,
getstring("restore.mailsubj"),
getstring2(
"restore.mailtext",
array(get_operator_name($to_restore), $href)
)
);
$page['isdone'] = true;
$page_style->render('restore', $page);
exit;
}
}
$page['formloginoremail'] = $login_or_email;
$page['localeLinks'] = get_locale_links();
$page['isdone'] = false;
$page_style->render('restore', $page);

View File

@ -54,7 +54,7 @@
<input type="image" name="login" src="{{mibewRoot}}{{l10n "image.button.login"}}" alt="{{l10n "button.enter"}}"/>
<div class="links">
<a href="restore.php">{{l10n "restore.pwd.message"}}</a><br/>
<a href="{{mibewRoot}}/operator/password-recovery">{{l10n "restore.pwd.message"}}</a><br/>
</div>
</div>

View File

@ -18,7 +18,7 @@
</div>
</div>
{{else}}
<form name="restoreForm" method="post" action="{{mibewRoot}}/operator/restore.php">
<form name="restoreForm" method="post" action="{{mibewRoot}}/operator/password-recovery">
<div id="loginpane">
<div class="header">

View File

@ -14,11 +14,11 @@
{{l10n "resetpwd.changed"}}
<br/>
<br/>
<a href="login.php?login={{loginname}}">{{l10n "resetpwd.login"}}</a>
<a href="{{mibewRoot}}/operator/login.php?login={{loginname}}">{{l10n "resetpwd.login"}}</a>
</div>
</div>
{{else}}
<form name="resetForm" method="post" action="{{mibewRoot}}/operator/resetpwd.php">
<form name="resetForm" method="post" action="{{mibewRoot}}/operator/password-recovery/reset">
<input type="hidden" name="id" value="{{id}}"/>
<input type="hidden" name="token" value="{{token}}"/>
@ -75,11 +75,11 @@
</table>
<div class="links">
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
<a href="{{mibewRoot}}/operator/login.php">{{l10n "restore.back_to_login"}}</a>
</div>
</div>
{{else}}
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
<a href="{{mibewRoot}}/operator/login.php">{{l10n "restore.back_to_login"}}</a>
{{/if}}
</div>