Example #1
0
 public function isLoggedIn()
 {
     if (self::$isLoggedIn) {
         return true;
     }
     $this->initialiseCookie();
     $data = array('password' => $this->cookie->get('password'));
     if (!is_null($this->cookie->get('username'))) {
         $data['username'] = $this->cookie->get('username');
     } else {
         $data['email'] = $this->cookie->get('email');
     }
     if ($id = $this->findMemberIDFromCredentials($data)) {
         self::$member_id = $id;
         self::$isLoggedIn = true;
         return true;
     }
     $this->logout();
     return false;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_REQUEST['fields'];
     // 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);
     }
     // 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('reset-password-template');
     // Check that there is a row with this recovery code and that they
     // request a password reset
     $auth = extension_Members::getField('authentication');
     if (!$auth instanceof fieldMemberPassword) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Authentication field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email 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;
     }
     if (!isset($fields[extension_Members::getFieldHandle('authentication')]['recovery-code']) or empty($fields[extension_Members::getFieldHandle('authentication')]['recovery-code'])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'missing', 'message' => __('Recovery code is a required field.'), 'label' => $auth->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     $row = Symphony::Database()->fetchRow(0, sprintf("\n\t\t\t\t\tSELECT `entry_id`, `recovery-code`\n\t\t\t\t\tFROM tbl_entries_data_%d\n\t\t\t\t\tWHERE reset = 'yes'\n\t\t\t\t\tAND `recovery-code` = '%s'\n\t\t\t\t", $auth->get('id'), Symphony::Database()->cleanValue($fields[extension_Members::getFieldHandle('authentication')]['recovery-code'])));
     if (empty($row)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'invalid', 'message' => __('No recovery code found.'), 'label' => $auth->get('label'))));
     } else {
         // Retrieve Member Entry record
         $driver = Symphony::ExtensionManager()->create('members');
         $entry = $driver->getMemberDriver()->fetchMemberFromID($row['entry_id']);
         // Check that the given Identity data matches the Member that the
         // recovery code is for
         $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]);
         if (!$entry instanceof Entry || $member_id != $row['entry_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;
         }
         // Check that the recovery code is still valid and has not expired
         if (is_null(Symphony::Database()->fetchVar('entry_id', 0, sprintf("\n\t\t\t\t\t\tSELECT `entry_id`\n\t\t\t\t\t\tFROM `tbl_entries_data_%d`\n\t\t\t\t\t\tWHERE `entry_id` = %d\n\t\t\t\t\t\tAND DATE_FORMAT(expires, '%%Y-%%m-%%d %%H:%%i:%%s') > '%s'\n\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t", $auth->get('id'), $member_id, DateTimeObj::get('Y-m-d H:i:s', strtotime('now - ' . $auth->get('code_expiry'))))))) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'invalid', 'message' => __('Recovery code has expired.'), 'label' => $auth->get('label'))));
             $result->appendChild($post_values);
             return $result;
         }
         // Create new password using the auth field so simulate the checkPostFieldData
         // and processRawFieldData functions.
         $message = '';
         $status = $auth->checkPostFieldData($fields[$auth->get('element_name')], $message, $member_id);
         if (Field::__OK__ != $status) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => $status == Field::__MISSING_FIELDS__ ? 'missing' : 'invalid', 'message' => $message, 'label' => $auth->get('label'))));
             $result->appendChild($post_values);
             return $result;
         }
         // processRawFieldData will encode the user's new password with the current one
         $status = Field::__OK__;
         $data = $auth->processRawFieldData(array('password' => Symphony::Database()->cleanValue($fields[$auth->get('element_name')]['password'])), $status);
         $data['recovery-code'] = null;
         $data['reset'] = 'no';
         $data['expires'] = null;
         // Update the database with the new password, removing the recovery code and setting
         // reset to no.
         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 (extension_Members::getSetting('reset-password-auto-login') == "yes") {
             // Instead of replicating the same logic, call the UpdatePasswordLogin which will
             // handle relogging in the user.
             $driver->getMemberDriver()->filter_UpdatePasswordLogin(array('entry' => $entry, 'fields' => array(extension_Members::getFieldHandle('authentication') => array('password' => Symphony::Database()->cleanValue($fields[$auth->get('element_name')]['password'])))));
         }
         if (isset($_REQUEST['redirect'])) {
             redirect($_REQUEST['redirect']);
         }
         $result->setAttribute('result', 'success');
     }
     $result->appendChild($post_values);
     return $result;
 }
 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;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     // 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);
     }
     // 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('activate-account-template');
     // Do sanity checks on the incoming data
     $activation = extension_Members::getField('activation');
     if (!$activation instanceof fieldMemberActivation) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Activation field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email 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;
     }
     // Ensure that the Member: Activation field has been provided
     if (!isset($fields[$activation->get('element_name')]) or empty($fields[$activation->get('element_name')])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'missing', 'message' => __('%s is a required field.', array($activation->get('label'))), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     } else {
         $fields[$activation->get('element_name')] = trim($fields[$activation->get('element_name')]);
     }
     // Check that a member exists first before proceeding.
     $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;
     }
     // Retrieve Member's entry
     $driver = Symphony::ExtensionManager()->create('members');
     $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id);
     if ($entry->getData($activation->get('id'), true)->activated == 'yes') {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member is already activated.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Make sure we dont accidently use an expired code
     $activation->purgeCodes();
     $code = $activation->isCodeActive($member_id);
     if ($code['code'] != $fields[$activation->get('element_name')]) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Activation error. Code was invalid or has expired.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Got to here, then everything is awesome.
     $status = Field::__OK__;
     $data = $activation->processRawFieldData(array('activated' => 'yes', 'timestamp' => DateTimeObj::get('Y-m-d H:i:s', time()), 'code' => null), $status);
     // Update the database setting activation to yes.
     Symphony::Database()->update($data, 'tbl_entries_data_' . $activation->get('id'), ' `entry_id` = ' . $member_id);
     // Update our `$entry` object with the new activation data
     $entry->setData($activation->get('id'), $data);
     // Simulate an array to login with.
     $data_fields = array_merge($fields, array(extension_Members::getFieldHandle('authentication') => $entry->getData(extension_Members::getField('authentication')->get('id'), true)->password));
     // Only login if the Activation field allows auto login.
     if (extension_Members::getSetting('activate-account-auto-login') == 'no' || $driver->getMemberDriver()->login($data_fields, true)) {
         // 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');
     } else {
         if (extension_Members::getSetting('activate-account-auto-login') == 'yes') {
             if (isset($_REQUEST['redirect'])) {
                 redirect($_REQUEST['redirect']);
             }
             $result->setAttribute('result', 'error');
         }
     }
     $result->appendChild($post_values);
     return $result;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     // 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);
     }
     // 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('regenerate-activation-code-template');
     $activation = extension_Members::getField('activation');
     if (!$activation instanceof fieldMemberActivation) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Activation field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // 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;
     }
     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;
     }
     // Make sure we dont accidently use an expired code
     $activation->purgeCodes();
     // Check that a member exists first before proceeding.
     $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;
     }
     // Check that the current member isn't already activated. If they
     // are, no point in regenerating the code.
     $driver = Symphony::ExtensionManager()->create('members');
     $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id);
     if ($entry->getData($activation->get('id'), true)->activated == 'yes') {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member is already activated.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Regenerate the code
     $status = Field::__OK__;
     $data = $activation->processRawFieldData(array('activated' => 'no'), $status);
     // Update the database setting activation to yes.
     Symphony::Database()->update($data, 'tbl_entries_data_' . $activation->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('activation-code', $data['code']));
     $result->appendChild($post_values);
     return $result;
 }