/**
* Validate the forms
*/
private function validateForm()
{
if ($this->frm->isSubmitted()) {
$txtEmail = $this->frm->getField('backend_email');
$txtPassword = $this->frm->getField('backend_password');
// required fields
if (!$txtEmail->isFilled() || !$txtPassword->isFilled()) {
// add error
$this->frm->addError('fields required');
// show error
$this->tpl->assign('hasError', true);
}
$this->getContainer()->get('logger')->info("Trying to authenticate user '{$txtEmail->getValue()}'.");
// invalid form-token?
if ($this->frm->getToken() != $this->frm->getField('form_token')->getValue()) {
// set a correct header, so bots understand they can't mess with us.
if (!headers_sent()) {
header('400 Bad Request', true, 400);
}
}
// get the user's id
$userId = BackendUsersModel::getIdByEmail($txtEmail->getValue());
// all fields are ok?
if ($txtEmail->isFilled() && $txtPassword->isFilled() && $this->frm->getToken() == $this->frm->getField('form_token')->getValue()) {
// try to login the user
if (!BackendAuthentication::loginUser($txtEmail->getValue(), $txtPassword->getValue())) {
$this->getContainer()->get('logger')->info("Failed authenticating user '{$txtEmail->getValue()}'.");
// add error
$this->frm->addError('invalid login');
// store attempt in session
$current = \SpoonSession::exists('backend_login_attempts') ? (int) \SpoonSession::get('backend_login_attempts') : 0;
// increment and store
\SpoonSession::set('backend_login_attempts', ++$current);
// save the failed login attempt in the user's settings
if ($userId !== false) {
BackendUsersModel::setSetting($userId, 'last_failed_login_attempt', time());
}
// show error
$this->tpl->assign('hasError', true);
}
}
// check sessions
if (\SpoonSession::exists('backend_login_attempts') && (int) \SpoonSession::get('backend_login_attempts') >= 5) {
// get previous attempt
$previousAttempt = \SpoonSession::exists('backend_last_attempt') ? \SpoonSession::get('backend_last_attempt') : time();
// calculate timeout
$timeout = 5 * (\SpoonSession::get('backend_login_attempts') - 4);
// too soon!
if (time() < $previousAttempt + $timeout) {
// sleep until the user can login again
sleep($timeout);
// set a correct header, so bots understand they can't mess with us.
if (!headers_sent()) {
header('503 Service Unavailable', true, 503);
}
} else {
// increment and store
\SpoonSession::set('backend_last_attempt', time());
}
// too many attempts
$this->frm->addEditor('too many attempts');
$this->getContainer()->get('logger')->info("Too many login attempts for user '{$txtEmail->getValue()}'.");
// show error
$this->tpl->assign('hasTooManyAttemps', true);
$this->tpl->assign('hasError', false);
}
// no errors in the form?
if ($this->frm->isCorrect()) {
// cleanup sessions
\SpoonSession::delete('backend_login_attempts');
\SpoonSession::delete('backend_last_attempt');
// save the login timestamp in the user's settings
$lastLogin = BackendUsersModel::getSetting($userId, 'current_login');
BackendUsersModel::setSetting($userId, 'current_login', time());
if ($lastLogin) {
BackendUsersModel::setSetting($userId, 'last_login', $lastLogin);
}
$this->getContainer()->get('logger')->info("Successfully authenticated user '{$txtEmail->getValue()}'.");
// redirect to the correct URL (URL the user was looking for or fallback)
$this->redirectToAllowedModuleAndAction();
}
}
// is the form submitted
if ($this->frmForgotPassword->isSubmitted()) {
// backend email
$email = $this->frmForgotPassword->getField('backend_email_forgot')->getValue();
// required fields
if ($this->frmForgotPassword->getField('backend_email_forgot')->isEmail(BL::err('EmailIsInvalid'))) {
// check if there is a user with the given emailaddress
if (!BackendUsersModel::existsEmail($email)) {
$this->frmForgotPassword->getField('backend_email_forgot')->addError(BL::err('EmailIsUnknown'));
}
}
// no errors in the form?
if ($this->frmForgotPassword->isCorrect()) {
// generate the key for the reset link and fetch the user ID for this email
$key = BackendAuthentication::getEncryptedString($email, uniqid());
// insert the key and the timestamp into the user settings
$userId = BackendUsersModel::getIdByEmail($email);
$user = new User($userId);
$user->setSetting('reset_password_key', $key);
$user->setSetting('reset_password_timestamp', time());
// variables to parse in the e-mail
$variables['resetLink'] = SITE_URL . BackendModel::createURLForAction('ResetPassword') . '&email=' . $email . '&key=' . $key;
// send e-mail to user
$from = $this->get('fork.settings')->get('Core', 'mailer_from');
$replyTo = $this->get('fork.settings')->get('Core', 'mailer_reply_to');
$message = \Common\Mailer\Message::newInstance(\SpoonFilter::ucfirst(BL::msg('ResetYourPasswordMailSubject')))->setFrom(array($from['email'] => $from['name']))->setTo(array($email))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml(BACKEND_MODULES_PATH . '/Authentication/Layout/Templates/Mails/ResetPassword.tpl', $variables);
$this->get('mailer')->send($message);
// clear post-values
$_POST['backend_email_forgot'] = '';
// show success message
$this->tpl->assign('isForgotPasswordSuccess', true);
// show form
$this->tpl->assign('showForm', true);
} else {
// errors?
$this->tpl->assign('showForm', true);
}
}
}