/** * Given a `$entry_id`, check to see whether this Entry has a valid * code, if it doesn't, generate one and return an array for insertion * into the entry table. * * @param integer $entry_id * @return array */ public function generateCode($entry_id = null) { $code = false; if (!is_null($entry_id)) { $code = $this->isCodeActive($entry_id); if ($code !== false) { return $code; } } // Generate a code do { $code = General::hash(uniqid(), 'sha1'); $row = Symphony::Database()->fetchRow(0, "\n\t\t\t\t\tSELECT 1 FROM `tbl_entries_data_{$this->get('id')}` WHERE `code` = '{$code}'\n\t\t\t\t"); } while (is_array($row) && !empty($row)); $data = array('code' => $code, 'timestamp' => DateTimeObj::get('Y-m-d H:i:s', time())); return $data; }
public function __actionEdit() { if (!($author_id = $this->_context[1])) { redirect(SYMPHONY_URL . '/system/authors/'); } $isOwner = $author_id == Administration::instance()->Author->get('id'); if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->_Author = AuthorManager::fetchByID($author_id); $authenticated = false; if ($fields['email'] != $this->_Author->get('email')) { $changing_email = true; } // Check the old password was correct if (isset($fields['old-password']) && strlen(trim($fields['old-password'])) > 0 && General::hash(trim($fields['old-password'])) == $this->_Author->get('password')) { $authenticated = true; } else { if (Administration::instance()->Author->isDeveloper()) { $authenticated = true; } } $this->_Author->set('id', $author_id); if ($this->_Author->isPrimaryAccount() || $isOwner && Administration::instance()->Author->isDeveloper()) { $this->_Author->set('user_type', 'developer'); // Primary accounts are always developer, Developers can't lower their level } elseif (Administration::instance()->Author->isDeveloper() && isset($fields['user_type'])) { $this->_Author->set('user_type', $fields['user_type']); // Only developer can change user type } $this->_Author->set('email', $fields['email']); $this->_Author->set('username', $fields['username']); $this->_Author->set('first_name', General::sanitize($fields['first_name'])); $this->_Author->set('last_name', General::sanitize($fields['last_name'])); $this->_Author->set('language', $fields['language']); if (trim($fields['password']) != '') { $this->_Author->set('password', General::hash($fields['password'])); $changing_password = true; } // Don't allow authors to set the Section Index as a default area // If they had it previously set, just save `null` which will redirect // the Author (when logging in) to their own Author record if ($this->_Author->get('user_type') == 'author' && $fields['default_area'] == '/blueprints/sections/') { $this->_Author->set('default_area', null); } else { $this->_Author->set('default_area', $fields['default_area']); } $this->_Author->set('auth_token_active', $fields['auth_token_active'] ? $fields['auth_token_active'] : 'no'); if ($this->_Author->validate($this->_errors)) { if (!$authenticated && ($changing_password || $changing_email)) { if ($changing_password) { $this->_errors['old-password'] = __('Wrong password. Enter old password to change it.'); } elseif ($changing_email) { $this->_errors['old-password'] = __('Wrong password. Enter old one to change email address.'); } } elseif (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) { $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match'); } elseif ($this->_Author->commit()) { Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' OR `author_id` = '" . $author_id . "' "); if ($isOwner) { Administration::instance()->login($this->_Author->get('username'), $this->_Author->get('password'), true); } /** * After editing an author, provided with the Author object * * @delegate AuthorPostEdit * @since Symphony 2.2 * @param string $context * '/system/authors/' * @param Author $author * An Author object */ Symphony::ExtensionManager()->notifyMembers('AuthorPostEdit', '/system/authors/', array('author' => $this->_Author)); redirect(SYMPHONY_URL . '/system/authors/edit/' . $author_id . '/saved/'); } else { $this->pageAlert(__('Unknown errors occurred while attempting to save.') . '<a href="' . SYMPHONY_URL . '/system/log/">' . __('Check your activity log') . '</a>.', Alert::ERROR); } } else { if (is_array($this->_errors) && !empty($this->_errors)) { $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR); } } } else { if (@array_key_exists('delete', $_POST['action'])) { /** * Prior to deleting an author, provided with the Author ID. * * @delegate AuthorPreDelete * @since Symphony 2.2 * @param string $context * '/system/authors/' * @param integer $author_id * The ID of Author ID that is about to be deleted */ Symphony::ExtensionManager()->notifyMembers('AuthorPreDelete', '/system/authors/', array('author_id' => $author_id)); if (!$isOwner) { AuthorManager::delete($author_id); redirect(SYMPHONY_URL . '/system/authors/'); } else { $this->pageAlert(__('You cannot remove yourself as you are the active Author.'), Alert::ERROR); } } } }
private function fake_password($length = 10) { $characters = '0123456789abcdefghijklmnopqrstuvwxyz'; $string = ''; for ($i = 0; $i < $length; $i++) { $string .= $characters[mt_rand(0, strlen($characters))]; } return General::hash($string); }
/** * Attempts to log an Author in given a username and password. * If the password is not hashed, it will be hashed using the sha1 * algorithm. The username and password will be sanitized before * being used to query the Database. If an Author is found, they * will be logged in and the sanitized username and password (also hashed) * will be saved as values in the `$Cookie`. * * @see toolkit.General#hash() * @param string $username * The Author's username. This will be sanitized before use. * @param string $password * The Author's password. This will be sanitized and then hashed before use * @param boolean $isHash * If the password provided is already hashed, setting this parameter to * true will stop it becoming rehashed. By default it is false. * @return boolean * True if the Author was logged in, false otherwise */ public function login($username, $password, $isHash = false) { $username = self::$Database->cleanValue($username); $password = self::$Database->cleanValue($password); if (strlen(trim($username)) > 0 && strlen(trim($password)) > 0) { if (!$isHash) { $password = General::hash($password); } $id = self::$Database->fetchVar('id', 0, "SELECT `id` FROM `tbl_authors` WHERE `username` = '{$username}' AND `password` = '{$password}' LIMIT 1"); if ($id) { $this->Author = AuthorManager::fetchByID($id); $this->Cookie->set('username', $username); $this->Cookie->set('pass', $password); self::$Database->update(array('last_seen' => DateTimeObj::get('Y-m-d H:i:s')), 'tbl_authors', " `id` = '{$id}'"); return true; } } return false; }
public function createAuthToken() { return General::substrmin(General::hash($this->get('username') . $this->get('password')), 8); }
function __actionEdit() { if (!($author_id = $this->_context[1])) { redirect(URL . '/symphony/system/authors/'); } $isOwner = $author_id == Administration::instance()->Author->get('id'); if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->_Author = AuthorManager::fetchByID($author_id); $authenticated = false; if ($fields['email'] != $this->_Author->get('email')) { $changing_email = true; } // Check the old password was correct if (isset($fields['old-password']) && strlen(trim($fields['old-password'])) > 0 && General::hash(trim($fields['old-password'])) == $this->_Author->get('password')) { $authenticated = true; } elseif (Administration::instance()->Author->isDeveloper() && $isOwner === false) { $authenticated = true; } $this->_Author->set('id', $author_id); if ($this->_Author->isPrimaryAccount() || $isOwner && Administration::instance()->Author->isDeveloper()) { $this->_Author->set('user_type', 'developer'); // Primary accounts are always developer, Developers can't lower their level } elseif (Administration::instance()->Author->isDeveloper() && isset($fields['user_type'])) { $this->_Author->set('user_type', $fields['user_type']); // Only developer can change user type } $this->_Author->set('email', $fields['email']); $this->_Author->set('username', $fields['username']); $this->_Author->set('first_name', General::sanitize($fields['first_name'])); $this->_Author->set('last_name', General::sanitize($fields['last_name'])); $this->_Author->set('language', $fields['language']); if (trim($fields['password']) != '') { $this->_Author->set('password', General::hash($fields['password'])); $changing_password = true; } $this->_Author->set('default_section', intval($fields['default_section'])); $this->_Author->set('auth_token_active', $fields['auth_token_active'] ? $fields['auth_token_active'] : 'no'); if ($this->_Author->validate($this->_errors)) { if (!$authenticated && ($changing_password || $changing_email)) { if ($changing_password) { $this->_errors['old-password'] = __('Wrong password. Enter old password to change it.'); } elseif ($changing_email) { $this->_errors['old-password'] = __('Wrong password. Enter old one to change email address.'); } } elseif (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) { $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match'); } elseif ($this->_Author->commit()) { Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' OR `author_id` = '" . $author_id . "' "); if ($isOwner) { $this->_Parent->login($this->_Author->get('username'), $this->_Author->get('password'), true); } ## TODO: Fix me ### # Delegate: Edit # Description: After editing an author. ID of the author is provided. //$ExtensionManager->notifyMembers('Edit', getCurrentPage(), array('author_id' => $_REQUEST['id'])); redirect(URL . '/symphony/system/authors/edit/' . $author_id . '/saved/'); } else { $this->pageAlert(__('Unknown errors occurred while attempting to save. Please check your <a href="%s">activity log</a>.', array(URL . '/symphony/system/log/')), Alert::ERROR); } } } elseif (@array_key_exists('delete', $_POST['action'])) { ## TODO: Fix Me ### # Delegate: Delete # Description: Prior to deleting an author. ID is provided. //$ExtensionManager->notifyMembers('Delete', getCurrentPage(), array('author_id' => $author_id)); if (!$isOwner) { AuthorManager::delete($author_id); redirect(URL . '/symphony/system/authors/'); } else { $this->pageAlert(__('You cannot remove yourself as you are the active Author.'), Alert::ERROR); } } }
/** * This function compares a given token to an Author's actual token. * * @deprecated This function will be removed in the next major release. It * is unused by Symphony. * @param string $token * A token to test against this Author's token * @return boolean */ public function verifyToken($token) { if (!$this->isTokenActive()) { return false; } $t = General::substrmin(General::hash($this->get('username') . $this->get('password')), 8); return $t == $token; }
/** * Given a string, this function will encode it using the * field's salt and the sha1 algorithm * * @param string $password * @return string */ public function encodePassword($password) { return General::hash($this->get('salt') . $password, 'sha1'); }
protected function __trigger() { $result = new XMLElement(self::ROOTELEMENT); $fields = $_POST['fields']; $driver = Symphony::ExtensionManager()->create('members'); // Add POST values to the Event XML $post_values = new XMLElement('post-values'); // Create the post data cookie element if (is_array($fields) && !empty($fields)) { General::array_to_xml($post_values, $fields, true); } // If a member is logged in, return early with an error if ($driver->getMemberDriver()->isLoggedIn()) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('You cannot generate a recovery code while being logged in.')))); $result->appendChild($post_values); return $result; } // Trigger the EventPreSaveFilter delegate. We are using this to make // use of the XSS Filter extension that will ensure our data is ok to use $this->notifyEventPreSaveFilter($result, $fields, $post_values); if ($result->getAttribute('result') == 'error') { return $result; } // Add any Email Templates for this event $this->addEmailTemplates('generate-recovery-code-template'); // Check that either a Member: Username or Member: Password field // has been detected $identity = SymphonyMember::setIdentityField($fields, false); if (!$identity instanceof Identity) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Identity field found.')))); $result->appendChild($post_values); return $result; } // Check that a member exists first before proceeding. if (!isset($fields[$identity->get('element_name')]) or empty($fields[$identity->get('element_name')])) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'missing', 'message' => __('%s is a required field.', array($identity->get('label'))), 'label' => $identity->get('label')))); $result->appendChild($post_values); return $result; } $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]); if (is_null($member_id)) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member not found.'), 'label' => $identity->get('label')))); $result->appendChild($post_values); return $result; } // Generate new password $newPassword = General::generatePassword(); // Set the Entry password to be reset and the current timestamp $auth = extension_Members::getField('authentication'); $status = Field::__OK__; $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id); $entry_data = $entry->getData(); // Generate a Recovery Code with the same logic as a normal password $data = $auth->processRawFieldData(array('password' => General::hash($newPassword . $member_id, 'sha1')), $status); $data['recovery-code'] = $data['password']; $data['reset'] = 'yes'; $data['expires'] = DateTimeObj::get('Y-m-d H:i:s', time()); // Overwrite the password with the old password data. This prevents // a users account from being locked out if it it just reset by a random // member of the public $data['password'] = $entry_data[$auth->get('id')]['password']; $data['length'] = $entry_data[$auth->get('id')]['length']; $data['strength'] = $entry_data[$auth->get('id')]['strength']; Symphony::Database()->update($data, 'tbl_entries_data_' . $auth->get('id'), ' `entry_id` = ' . $member_id); // Trigger the EventFinalSaveFilter delegate. The Email Template Filter // and Email Template Manager extensions use this delegate to send any // emails attached to this event $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry); // If a redirect is set, redirect, the page won't be able to receive // the Event XML anyway if (isset($_REQUEST['redirect'])) { redirect($_REQUEST['redirect']); } $result->setAttribute('result', 'success'); $result->appendChild(new XMLElement('recovery-code', $data['recovery-code'])); $result->appendChild($post_values); return $result; }
function action() { if (isset($_POST['action'])) { $actionParts = array_keys($_POST['action']); $action = end($actionParts); ##Login Attempted if ($action == 'login') { if (empty($_POST['username']) || empty($_POST['password']) || !$this->_Parent->login($_POST['username'], $_POST['password'])) { ## TODO: Fix Me ### # Delegate: LoginFailure # Description: Failed login attempt. Username is provided. //$ExtensionManager->notifyMembers('LoginFailure', getCurrentPage(), array('username' => $_POST['username'])); //$this->Body->appendChild(new XMLElement('p', 'Login invalid. <a href="'.URL.'/symphony/?forgot">Forgot your password?</a>')); //$this->_alert = 'Login invalid. <a href="'.URL.'/symphony/?forgot">Forgot your password?</a>'; $this->_invalidPassword = true; } else { ## TODO: Fix Me ### # Delegate: LoginSuccess # Description: Successful login attempt. Username is provided. //$ExtensionManager->notifyMembers('LoginSuccess', getCurrentPage(), array('username' => $_POST['username'])); if (isset($_POST['redirect'])) { redirect(URL . str_replace(parse_url(URL, PHP_URL_PATH), '', $_POST['redirect'])); } redirect(URL . '/symphony/'); } ##Reset of password requested } elseif ($action == 'reset') { $author = Symphony::Database()->fetchRow(0, "SELECT `id`, `email`, `first_name` FROM `tbl_authors` WHERE `email` = '" . $_POST['email'] . "'"); if (!empty($author)) { Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' "); if (!($token = Symphony::Database()->fetchVar('token', 0, "SELECT `token` FROM `tbl_forgotpass` WHERE `expiry` > '" . DateTimeObj::getGMT('c') . "' AND `author_id` = " . $author['id']))) { $token = substr(General::hash(time() . rand(0, 200)), 0, 6); Symphony::Database()->insert(array('author_id' => $author['id'], 'token' => $token, 'expiry' => DateTimeObj::getGMT('c', time() + 120 * 60)), 'tbl_forgotpass'); } $this->_email_sent = General::sendEmail($author['email'], Symphony::Database()->fetchVar('email', 0, "SELECT `email` FROM `tbl_authors` ORDER BY `id` ASC LIMIT 1"), __('Symphony Concierge'), __('New Symphony Account Password'), __('Hi %s,', array($author['first_name'])) . self::CRLF . __('A new password has been requested for your account. Login using the following link, and change your password via the Authors area:') . self::CRLF . self::CRLF . ' ' . URL . "/symphony/login/{$token}/" . self::CRLF . self::CRLF . __('It will expire in 2 hours. If you did not ask for a new password, please disregard this email.') . self::CRLF . self::CRLF . __('Best Regards,') . self::CRLF . __('The Symphony Team')); ## TODO: Fix Me ### # Delegate: PasswordResetSuccess # Description: A successful password reset has taken place. Author ID is provided //$ExtensionManager->notifyMembers('PasswordResetSuccess', getCurrentPage(), array('author_id' => $author['id'])); } else { ## TODO: Fix Me ### # Delegate: PasswordResetFailure # Description: A failed password reset has taken place. Author ID is provided //$ExtensionManager->notifyMembers('PasswordResetFailure', getCurrentPage(), array('author_id' => $author['id'])); $this->_email_sent = false; } ##Change of password requested } elseif ($action == 'change' && $this->_Parent->isLoggedIn()) { if (empty($_POST['password']) || empty($_POST['password-confirmation']) || $_POST['password'] != $_POST['password-confirmation']) { $this->_mismatchedPassword = true; } else { $author_id = $this->_Parent->Author->get('id'); $author = AuthorManager::fetchByID($author_id); $author->set('password', General::hash(Symphony::Database()->cleanValue($_POST['password']))); if (!$author->commit() || !$this->_Parent->login($author->get('username'), $_POST['password'])) { redirect(URL . "symphony/system/authors/edit/{$author_id}/error/"); } ## TODO: Fix me ### # Delegate: PasswordChanged # Description: After editing an author. ID of the author is provided. //$ExtensionManager->notifyMembers('PasswordChanged', getCurrentPage(), array('author_id' => $author_id)); redirect(URL . '/symphony/'); } } } elseif ($_REQUEST['action'] == 'resetpass' && isset($_REQUEST['token'])) { $sql = "SELECT t1.`id`, t1.`email`, t1.`first_name` \n\t\t\t\t\t FROM `tbl_authors` as t1, `tbl_forgotpass` as t2\n\t\t\t\t\t \tWHERE t2.`token` = '" . $_REQUEST['token'] . "' AND t1.`id` = t2.`author_id`\n\t\t\t\t\t \tLIMIT 1"; $author = Symphony::Database()->fetchRow(0, $sql); if (!empty($author)) { $newpass = General::generatePassword(); General::sendEmail($author['email'], '*****@*****.**', 'Symphony Concierge', 'RE: New Symphony Account Password', 'Hi ' . $author['first_name'] . ',' . self::CRLF . "As requested, here is your new Symphony Author Password for '" . URL . "'" . self::CRLF . "\t{$newpass}" . self::CRLF . self::CRLF . 'Best Regards,' . self::CRLF . 'The Symphony Team'); Symphony::Database()->update(array('password' => General::hash($newpass)), 'tbl_authors', " `id` = '" . $author['id'] . "' LIMIT 1"); Symphony::Database()->delete('tbl_forgotpass', " `author_id` = '" . $author['id'] . "'"); ## TODO: Fix Me ### # Delegate: PasswordResetRequest # Description: User has requested a password reset. Author ID is provided. //$ExtensionManager->notifyMembers('PasswordResetRequest', getCurrentPage(), array('author_id' => $author['id'])); $this->_alert = 'Password reset. Check your email'; } } }
public function action() { if (isset($_POST['action'])) { $actionParts = array_keys($_POST['action']); $action = end($actionParts); ##Login Attempted if ($action == 'login') { if (empty($_POST['username']) || empty($_POST['password']) || !Administration::instance()->login($_POST['username'], $_POST['password'])) { /** * A failed login attempt into the Symphony backend * * @delegate AuthorLoginFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who attempted to login. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginFailure', '/login/', array('username' => $_POST['username'])); $this->_invalidPassword = true; } else { /** * A successful login attempt into the Symphony backend * * @delegate AuthorLoginSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who logged in. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginSuccess', '/login/', array('username' => $_POST['username'])); if (isset($_POST['redirect'])) { redirect(URL . str_replace(parse_url(URL, PHP_URL_PATH), '', $_POST['redirect'])); } redirect(SYMPHONY_URL); } ##Reset of password requested } elseif ($action == 'reset') { $author = Symphony::Database()->fetchRow(0, "SELECT `id`, `email`, `first_name` FROM `tbl_authors` WHERE `email` = '" . Symphony::Database()->cleanValue($_POST['email']) . "'"); if (!empty($author)) { Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' "); if (!($token = Symphony::Database()->fetchVar('token', 0, "SELECT `token` FROM `tbl_forgotpass` WHERE `expiry` > '" . DateTimeObj::getGMT('c') . "' AND `author_id` = " . $author['id']))) { $token = substr(General::hash(time() . rand(0, 1000)), 0, 6); Symphony::Database()->insert(array('author_id' => $author['id'], 'token' => $token, 'expiry' => DateTimeObj::getGMT('c', time() + 120 * 60)), 'tbl_forgotpass'); } try { $email = Email::create(); $email->recipients = $author['email']; $email->subject = __('New Symphony Account Password'); $email->text_plain = __('Hi %s,', array($author['first_name'])) . self::CRLF . __('A new password has been requested for your account. Login using the following link, and change your password via the Authors area:') . self::CRLF . self::CRLF . ' ' . SYMPHONY_URL . "/login/{$token}/" . self::CRLF . self::CRLF . __('It will expire in 2 hours. If you did not ask for a new password, please disregard this email.') . self::CRLF . self::CRLF . __('Best Regards,') . self::CRLF . __('The Symphony Team'); $email->send(); $this->_email_sent = true; } catch (Exception $e) { } catch (EmailGatewayException $e) { throw new SymphonyErrorPage('Error sending email. ' . $e->getMessage()); } /** * When a password reset has occured and after the Password * Reset email has been sent. * * @delegate AuthorPostPasswordResetSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param integer $author_id * The ID of the Author who requested the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetSuccess', '/login/', array('author_id' => $author['id'])); } else { /** * When a password reset has been attempted, but Symphony doesn't * recognise the credentials the user has given. * * @delegate AuthorPostPasswordResetFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $email * The santizied Email of the Author who tried to request the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetFailure', '/login/', array('email' => Symphony::Database()->cleanValue($_POST['email']))); $this->_email_sent = false; } ##Change of password requested } elseif ($action == 'change' && Administration::instance()->isLoggedIn()) { if (empty($_POST['password']) || empty($_POST['password-confirmation']) || $_POST['password'] != $_POST['password-confirmation']) { $this->_mismatchedPassword = true; } else { $author_id = Administration::instance()->Author->get('id'); $author = AuthorManager::fetchByID($author_id); $author->set('password', General::hash(Symphony::Database()->cleanValue($_POST['password']))); if (!$author->commit() || !Administration::instance()->login($author->get('username'), $_POST['password'])) { redirect(SYMPHONY_URL . "/system/authors/edit/{$author_id}/error/"); } /** * When an Author changes their password as the result of a login * with an emergency token (ie. forgot password). Just after their * new password has been set successfully * * @delegate AuthorPostPasswordChange * @since Symphony 2.2 * @param string $context * '/login/' * @param integer $author_id * The ID of the Author who has just changed their password */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordChange', '/login/', array('author_id' => $author_id)); redirect(SYMPHONY_URL); } } } elseif ($_REQUEST['action'] == 'resetpass' && isset($_REQUEST['token'])) { $author = Symphony::Database()->fetchRow(0, "SELECT t1.`id`, t1.`email`, t1.`first_name`\n\t\t\t\t\t\tFROM `tbl_authors` as t1, `tbl_forgotpass` as t2\n\t\t\t\t\t \tWHERE t2.`token` = '" . Symphony::Database()->cleanValue($_REQUEST['token']) . "' AND t1.`id` = t2.`author_id`\n\t\t\t\t\t \tLIMIT 1"); if (!empty($author)) { $newpass = General::generatePassword(); General::sendEmail($author['email'], Symphony::Database()->fetchVar('email', 0, "SELECT `email` FROM `tbl_authors` ORDER BY `id` ASC LIMIT 1"), __('Symphony Concierge'), __('New Symphony Account Password'), __('Hi %s,', array($author['first_name'])) . self::CRLF . __("As requested, here is your new Symphony Author Password for ") . URL . " " . self::CRLF . " {$newpass}" . self::CRLF . self::CRLF . __('Best Regards,') . self::CRLF . __('The Symphony Team')); Symphony::Database()->update(array('password' => General::hash($newpass)), 'tbl_authors', " `id` = '" . $author['id'] . "' LIMIT 1"); Symphony::Database()->delete('tbl_forgotpass', " `author_id` = '" . $author['id'] . "'"); /** * Just after a Forgot Password email has been sent to the Author * who has requested a password reset. * * @delegate AuthorPostPasswordResetRequest * @since Symphony 2.2 * @param string $context * '/login/' * @param integer $author_id * The ID of the Author who has requested their password be reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetRequest', '/login/', array('author_id' => $author['id'])); $this->_alert = __('Password reset. Check your email'); } } }
public function action() { if (isset($_POST['action'])) { $actionParts = array_keys($_POST['action']); $action = end($actionParts); // Login Attempted if ($action == 'login') { if (empty($_POST['username']) || empty($_POST['password']) || !Administration::instance()->login($_POST['username'], $_POST['password'])) { /** * A failed login attempt into the Symphony backend * * @delegate AuthorLoginFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who attempted to login. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginFailure', '/login/', array('username' => $_POST['username'])); $this->_invalidPassword = true; } else { /** * A successful login attempt into the Symphony backend * * @delegate AuthorLoginSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who logged in. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginSuccess', '/login/', array('username' => $_POST['username'])); if (isset($_POST['redirect'])) { redirect(URL . str_replace(parse_url(URL, PHP_URL_PATH), '', $_POST['redirect'])); } redirect(SYMPHONY_URL); } // Reset of password requested } elseif ($action == 'reset') { $author = Symphony::Database()->fetchRow(0, "SELECT `id`, `email`, `first_name` FROM `tbl_authors` WHERE `email` = '" . Symphony::Database()->cleanValue($_POST['email']) . "'"); if (!empty($author)) { Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' "); if (!($token = Symphony::Database()->fetchVar('token', 0, "SELECT `token` FROM `tbl_forgotpass` WHERE `expiry` > '" . DateTimeObj::getGMT('c') . "' AND `author_id` = " . $author['id']))) { $token = substr(General::hash(time() . rand(0, 1000)), 0, 6); Symphony::Database()->insert(array('author_id' => $author['id'], 'token' => $token, 'expiry' => DateTimeObj::getGMT('c', time() + 120 * 60)), 'tbl_forgotpass'); } try { $email = Email::create(); $email->recipients = $author['email']; $email->subject = __('New Symphony Account Password'); $email->text_plain = __('Hi %s,', array($author['first_name'])) . PHP_EOL . __('A new password has been requested for your account. Login using the following link, and change your password via the Authors area:') . PHP_EOL . PHP_EOL . ' ' . SYMPHONY_URL . "/login/{$token}/" . PHP_EOL . PHP_EOL . __('It will expire in 2 hours. If you did not ask for a new password, please disregard this email.') . PHP_EOL . PHP_EOL . __('Best Regards,') . PHP_EOL . __('The Symphony Team'); $email->send(); $this->_email_sent = true; } catch (Exception $e) { } catch (EmailGatewayException $e) { throw new SymphonyErrorPage('Error sending email. ' . $e->getMessage()); } /** * When a password reset has occurred and after the Password * Reset email has been sent. * * @delegate AuthorPostPasswordResetSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param integer $author_id * The ID of the Author who requested the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetSuccess', '/login/', array('author_id' => $author['id'])); } else { /** * When a password reset has been attempted, but Symphony doesn't * recognise the credentials the user has given. * * @delegate AuthorPostPasswordResetFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $email * The sanitised Email of the Author who tried to request the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetFailure', '/login/', array('email' => Symphony::Database()->cleanValue($_POST['email']))); $this->_email_sent = false; } } } }