protected function __trigger()
 {
     self::__init();
     $db = ASDCLoader::instance();
     $success = false;
     $Members = $this->_Parent->ExtensionManager->create('members');
     $Members->initialiseCookie();
     if ($Members->isLoggedIn() !== true) {
         redirect(URL . '/forbidden/');
     }
     $Members->initialiseMemberObject();
     // Make sure we dont accidently use an expired token
     extension_Members::purgeCodes();
     $activation_row = $db->query(sprintf("SELECT * FROM `tbl_members_codes` WHERE `token` = '%s' AND `member_id` = %d LIMIT 1", $db->escape($_POST['fields']['code']), (int) $Members->Member->get('id')))->current();
     // No code, you are a spy!
     if ($activation_row === false) {
         redirect(URL . '/members/activate/failed/');
     }
     // Got this far, all is well.
     $db->query(sprintf("UPDATE `tbl_entries_data_%d` SET `role_id` = %d WHERE `entry_id` = %d LIMIT 1", $Members->roleField(), 3, (int) $Members->Member->get('id')));
     extension_Members::purgeTokens((int) $Members->Member->get('id'));
     $em = new EntryManager($this->_Parent);
     $entry = end($em->fetch((int) $Members->Member->get('id')));
     $email = $entry->getData(self::findFieldID('email-address', 'members'));
     $name = $entry->getData(self::findFieldID('name', 'members'));
     $Members->emailNewMember(array('section' => $Members->memberSectionHandle(), 'entry' => $entry, 'fields' => array('username-and-password' => $entry->getData(self::findFieldID('username-and-password', 'members')), 'name' => $name['value'], 'email-address' => $email['value'])));
     redirect(URL . '/members/activate/success/');
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $success = false;
     self::__init();
     $db = ASDCLoader::instance();
     $Members = $this->_Parent->ExtensionManager->create('members');
     $Members->initialiseCookie();
     if ($Members->isLoggedIn() !== true) {
         $result->appendChild(new XMLElement('error', 'Must be logged in.'));
         $result->setAttribute('status', 'error');
         return $result;
     }
     $Members->initialiseMemberObject();
     // Make sure we dont accidently use an expired code
     extension_Members::purgeCodes();
     $em = new EntryManager($this->_Parent);
     $entry = end($em->fetch((int) $Members->Member->get('id')));
     $email = $entry->getData(self::findFieldID('email-address', 'members'));
     $name = $entry->getData(self::findFieldID('name', 'members'));
     $success = $Members->emailNewMember(array('entry' => $entry, 'fields' => array('username-and-password' => $entry->getData(self::findFieldID('username-and-password', 'members')), 'name' => $name['value'], 'email-address' => $email['value'])));
     if ($success == true && isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
     $result->setAttribute('result', $success === true ? 'success' : 'error');
     return $result;
 }
Exemplo n.º 3
0
 protected function addEmailTemplates($template)
 {
     // Read the template from the Configuration if it exists
     // This is required for the Email Template Filter/Email Template Manager
     if (!is_null(extension_Members::getSetting($template))) {
         $this->eParamFILTERS = array_merge($this->eParamFILTERS, explode(',', extension_Members::getSetting($template)));
     }
 }
Exemplo n.º 4
0
 protected function __trigger()
 {
     $role_field_handle = ASDCLoader::instance()->query(sprintf("SELECT `element_name` FROM `tbl_fields` WHERE `type` = 'memberrole' AND `parent_section` = %d LIMIT 1", extension_Members::memberSectionID()))->current()->element_name;
     $role_id = Symphony::Configuration()->get('new_member_default_role', 'members');
     if (Symphony::Configuration()->get('require_activation', 'members') == 'yes') {
         $role_id = extension_Members::INACTIVE_ROLE_ID;
     }
     $_POST['fields'][$role_field_handle] = $role_id;
     include TOOLKIT . '/events/event.section.php';
     return $result;
 }
Exemplo n.º 5
0
 /**
  * Where `$name` is one of the following values, `role`, `timezone`,
  * `email`, `activation`, `authentication` and `identity`, this function
  * will return the Field's `element_name`. `element_name` is a handle
  * of the Field's label, used most commonly by events in `$_POST` data.
  * If no `$name` is given, an array of all Member field handles will
  * be returned.
  *
  * @param string $type
  * @return string
  */
 public function getFieldHandle($type = null)
 {
     if (is_null($type)) {
         return null;
     }
     $type = extension_Members::getFieldType($type);
     // Check to see if this name has been stored in our 'static' cache
     // If it hasn't, lets go find it (for better or worse)
     if (!isset($this->handles[$type])) {
         $this->initialiseField($type, $this->section_id);
     }
     // No field, return null
     if (!isset($this->handles[$type])) {
         return null;
     }
     // Return the handle
     return $this->handles[$type];
 }
 protected function __trigger()
 {
     self::__init();
     $db = ASDCLoader::instance();
     $success = false;
     $Members = $this->_Parent->ExtensionManager->create('members');
     $Members->initialiseCookie();
     if ($Members->isLoggedIn() !== true) {
         redirect(URL . '/forbidden/');
     }
     $Members->initialiseMemberObject();
     // Make sure we dont accidently use an expired token
     extension_Members::purgeCodes();
     $em = new EntryManager($this->_Parent);
     $entry = end($em->fetch((int) $Members->Member->get('id')));
     $email = $entry->getData(self::findFieldID('email-address', 'members'));
     $name = $entry->getData(self::findFieldID('name', 'members'));
     $Members->emailNewMember(array('section' => $Members->memberSectionHandle(), 'entry' => $entry, 'fields' => array('username-and-password' => $entry->getData(self::findFieldID('username-and-password', 'members')), 'name' => $name['value'], 'email-address' => $email['value'])));
     redirect(URL . '/members/activate/sent/');
 }
    public static function documentation()
    {
        // Fetch all the Email Templates available and add to the end of the documentation
        $templates = extension_Members::fetchEmailTemplates();
        $div = new XMLElement('div');
        if (!empty($templates)) {
            $label = new XMLElement('label', __('Generate Recovery Code Email Template'));
            $generate_recovery_code_templates = extension_Members::setActiveTemplate($templates, 'generate-recovery-code-template');
            $label->appendChild(Widget::Select('members[generate-recovery-code-template][]', $generate_recovery_code_templates, array('multiple' => 'multiple')));
            $div->appendChild($label);
            $div->appendChild(Widget::Input('members[event]', 'generate-recovery-code', 'hidden'));
            $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's')));
        }
        return '
				<p>This event takes a member\'s email address or username to validate the existence of the Member before
				generating a recovery code for that member. A member\'s password is not completely reset until their 
				recovery code is used in the Members: Reset Password event. This recovery code can be seen
				by including the Member: Password field in a data source on the same page as this event, or by using
				the event\'s result.</p>
				<h3>Example Front-end Form Markup</h3>
				<p>This is an example of the markup you can use on your front end to create a form for this event. An input field
				accepts either the member\'s email address or username.</p>
				<pre class="XML"><code>
				&lt;form method="post"&gt;
					&lt;label&gt;Username: &lt;input name="fields[username]" type="text" value="{$username}"/&gt;&lt;/label&gt;
					or
					&lt;label&gt;Email: &lt;input name="fields[email]" type="text" value="{$email}"/&gt;&lt;/label&gt;
					&lt;input type="hidden" name="members-section-id" value="{$your-section-id}"/&gt;
					&lt;input type="submit" name="action[' . self::ROOTELEMENT . ']" value="Reset Password"/&gt;
					&lt;input type="hidden" name="redirect" value="{$root}/"/&gt;
				&lt;/form&gt;
				</code></pre>
				<h3>More Information</h3>
				<p>For further information about this event, including response and error XML, please refer to the
				<a href="https://github.com/symphonycms/members/wiki/Members%3A-Generate-Recovery-Code">wiki</a>.</p>
				' . $div->generate() . '
			';
    }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     self::__init();
     $db = ASDCLoader::instance();
     $success = false;
     $Members = Frontend::instance()->ExtensionManager->create('members');
     $Members->initialiseCookie();
     if ($Members->isLoggedIn() !== true) {
         $result->appendChild(new XMLElement('error', 'Must be logged in.'));
         $result->setAttribute('status', 'error');
         return $result;
     }
     $Members->initialiseMemberObject();
     // Make sure we dont accidently use an expired code
     extension_Members::purgeCodes();
     $activation_row = $db->query(sprintf("SELECT * FROM `tbl_members_codes` WHERE `code` = '%s' AND `member_id` = %d LIMIT 1", $db->escape($_POST['fields']['code']), (int) $Members->Member->get('id')))->current();
     // No code, you are a spy!
     if ($activation_row === false) {
         $success = false;
         $result->appendChild(new XMLElement('error', 'Activation failed. Code was invalid.'));
     } else {
         // Got this far, all is well.
         $db->query(sprintf("UPDATE `tbl_entries_data_%d` SET `role_id` = %d WHERE `entry_id` = %d LIMIT 1", $Members->roleField(), Symphony::Configuration()->get('new_member_default_role', 'members'), (int) $Members->Member->get('id')));
         extension_Members::purgeCodes((int) $Members->Member->get('id'));
         $em = new EntryManager($this->_Parent);
         $entry = end($em->fetch((int) $Members->Member->get('id')));
         $email = $entry->getData(self::findFieldID('email-address', 'members'));
         $name = $entry->getData(self::findFieldID('name', 'members'));
         $Members->emailNewMember(array('section' => $Members->memberSectionHandle(), 'entry' => $entry, 'fields' => array('username-and-password' => $entry->getData(self::findFieldID('username-and-password', 'members')), 'name' => $name['value'], 'email-address' => $email['value'])));
         $success = true;
     }
     if ($success == true && isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
     $result->setAttribute('status', $success === true ? 'success' : 'error');
     return $result;
 }
 public function __viewIndex()
 {
     // Add in custom assets
     Administration::instance()->Page->addStylesheetToHead(URL . '/extensions/sections_event/assets/sections_event.permissions_index.css', 'screen', 111);
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Symphony'), __('Section permissions'))));
     $this->appendSubheading(__('Section permissions'));
     // check if roles exist
     $roles = RoleManager::fetch();
     if (!is_array($roles) || empty($roles)) {
         return $this->Form->appendChild($this->buildErrorMessage(__('No roles found. <a href="%s">Add a new one?</a>', array(extension_Members::baseURL() . 'roles/new/'))));
     }
     // build table
     $aTableHead = array(array(__('Member role'), 'col'));
     $aTableBody = array();
     foreach ($roles as $role) {
         // Setup each cell
         $td1 = Widget::TableData(Widget::Anchor($role->get('name'), Administration::instance()->getCurrentPageURL() . 'edit/' . $role->get('id') . '/', null, 'content'));
         // Add cells to a row
         $aTableBody[] = Widget::TableRow(array($td1));
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), null, Widget::TableBody($aTableBody));
     $this->Form->appendChild($table);
 }
    public static function documentation()
    {
        // Fetch all the Email Templates available and add to the end of the documentation
        $templates = extension_Members::fetchEmailTemplates();
        $div = new XMLElement('div');
        if (!empty($templates)) {
            $label = new XMLElement('label', __('Regenerate Activation Code Email Template'));
            $regenerate_activation_code_templates = extension_Members::setActiveTemplate($templates, 'regenerate-activation-code-template');
            $label->appendChild(Widget::Select('members[regenerate-activation-code-template][]', $regenerate_activation_code_templates, array('multiple' => 'multiple')));
            $div->appendChild($label);
            $div->appendChild(Widget::Input('members[event]', 'reset-password', 'hidden'));
            $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's')));
        }
        return '
				<p>This event will regenerate an activation code for a user if their current
				activation code has expired. The activation code can be sent to a Member\'s email after
				this event has executed.</p>
				<h3>Example Front-end Form Markup</h3>
				<p>This is an example of the form markup you can use on your front end. An input field
				accepts either the member\'s email address or username.</p>
				<pre class="XML"><code>
				&lt;form method="post"&gt;
					&lt;label&gt;Username: &lt;input name="fields[username]" type="text" value="{$username}"/&gt;&lt;/label&gt;
					or
					&lt;label&gt;Email: &lt;input name="fields[email]" type="text" value="{$email}"/&gt;&lt;/label&gt;
					&lt;input type="hidden" name="members-section-id" value="{$your-section-id}"/&gt;
					&lt;input type="submit" name="action[' . self::ROOTELEMENT . ']" value="Regenerate Activation Code"/&gt;
					&lt;input type="hidden" name="redirect" value="{$root}/"/&gt;
				&lt;/form&gt;
				</code></pre>
				<h3>More Information</h3>
				<p>For further information about this event, including response and error XML, please refer to the
				<a href="https://github.com/symphonycms/members/wiki/Members%3A-Regenerate-Activation-Code">wiki</a>.</p>
				' . $div->generate() . '
			';
    }
 public function appendMemberRolePermissionFieldsets($context)
 {
     $fieldset = new XMLElement('fieldset');
     $fieldset->setAttribute('class', 'settings type-file');
     $fieldset->appendChild(new XMLElement('legend', 'Forum Permissions'));
     $aTableHead = array(array('Action', 'col'), array('Allowed', 'col'));
     $permissions = $context['permissions']['forum'];
     $group = new XMLElement('div', NULL, array('class' => 'group'));
     /** FIRST TABLE **/
     $aTableBody = extension_Members::buildRolePermissionTableBody(array(array('Start New Discussion', 'forum', 'start_discussion', isset($permissions['start_discussion'])), array('Edit Discussions', 'forum', 'edit_discussion', isset($permissions['edit_discussion'])), array('Edit Own Discussions*', 'forum', 'edit_own_discussion', isset($permissions['edit_own_discussion'])), array('Remove Discussions', 'forum', 'remove_discussion', isset($permissions['remove_discussion'])), array('Remove Own Discussions*', 'forum', 'remove_own_discussion', isset($permissions['remove_own_discussion']))));
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'role-permissions narrow');
     $group->appendChild($table);
     /** SECOND TABLE **/
     $aTableBody = extension_Members::buildRolePermissionTableBody(array(array('Add Comment', 'forum', 'add_comment', isset($permissions['add_comment'])), array('Edit Comment', 'forum', 'edit_comment', isset($permissions['edit_comment'])), array('Edit Own Comment*', 'forum', 'edit_own_comment', isset($permissions['edit_own_comment'])), array('Remove Comment', 'forum', 'remove_comment', isset($permissions['remove_comment'])), array('Remove Own Comment*', 'forum', 'remove_own_comment', isset($permissions['remove_own_comment']))));
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'role-permissions narrow');
     $group->appendChild($table);
     /** THIRD TABLE **/
     $aTableBody = extension_Members::buildRolePermissionTableBody(array(array('Pin/Unpin Discussion', 'forum', 'pin_discussion', isset($permissions['pin_discussion'])), array('Open/Close Discussion', 'forum', 'close_discussion', isset($permissions['close_discussion']))));
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'role-permissions narrow');
     $group->appendChild($table);
     $fieldset->appendChild($group);
     $fieldset->appendChild(new XMLElement('p', '* <em>Does not apply if global edit/remove is allowed</em>', array('class' => 'help')));
     $context['form']->appendChild($fieldset);
 }
 private function __triggerCode()
 {
     $result = new XMLElement(self::ROOTELEMENT, NULL, array('step' => '2'));
     $success = false;
     $Members = $this->_Parent->ExtensionManager->create('members');
     $code = $_POST['fields']['code'];
     self::__init();
     $db = ASDCLoader::instance();
     // Make sure we dont accidently use an expired code
     extension_Members::purgeCodes();
     $code_row = $db->query(sprintf("SELECT * FROM `tbl_members_codes` WHERE `code` = '%s' LIMIT 1", $db->escape($code)))->current();
     // No code, you are a spy!
     if ($code_row !== false) {
         extension_Members::purgeCodes($code_row->member_id);
         $success = $Members->sendNewPasswordEmail($code_row->member_id);
     }
     $result->setAttribute('result', $success === true ? 'success' : 'error');
     if ($success == false) {
         $result->appendChild(new XMLElement('error', 'Sending email containing new password failed.'));
     } elseif ($success == true && isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
     return $result;
 }
Exemplo n.º 13
0
 public function addMemberDetailsToPageParams(array $context = null)
 {
     if (!$this->isLoggedIn()) {
         return;
     }
     $this->initialiseMemberObject();
     $context['params']['member-id'] = $this->getMemberID();
     if (!is_null(extension_Members::getFieldHandle('role'))) {
         $role_data = $this->getMember()->getData(extension_Members::getField('role')->get('id'));
         $role = RoleManager::fetch($role_data['role_id']);
         if ($role instanceof Role) {
             $context['params']['member-role'] = $role->get('name');
         }
     }
     if (!is_null(extension_Members::getFieldHandle('activation'))) {
         if ($this->getMember()->getData(extension_Members::getField('activation')->get('id'), true)->activated != "yes") {
             $context['params']['member-activated'] = 'no';
         }
     }
 }
Exemplo n.º 14
0
 /**
  * This function will ensure that the user who has submitted the form (and
  * hence is requesting that an event be triggered) is actually allowed to
  * do this request.
  * There are 2 action types, creation and editing. Creation is a simple yes/no
  * affair, whereas editing has three levels of permission, None, Own Entries
  * or All Entries:
  * - None: This user can't do process this event
  * - Own Entries: If the entry the user is trying to update is their own
  *   determined by if the `entry_id` or, in the case of a SBL or
  *   similar field, the `entry_id` of the linked entry matches the logged in
  *   user's id, process the event.
  * - All Entries: The user can update any entry in Symphony.
  * If there are no Roles in this system, or the event is set to ignore permissions
  * (by including a function, `ignoreRolePermissions` that returns `true`, it will
  * immediately proceed to processing any of the Filters attached to the event
  * before returning.
  *
  * @uses EventPreSaveFilter
  *
  * @param array $context
  * @return null
  */
 public function checkEventPermissions(array &$context)
 {
     // If this system has no Roles, or the event is set to ignore role permissions
     // continue straight to processing the Filters
     if (!FieldManager::isFieldUsed(extension_Members::getFieldType('role')) || method_exists($context['event'], 'ignoreRolePermissions') && $context['event']->ignoreRolePermissions() == true) {
         $this->__processEventFilters($context);
         return null;
     }
     // Prior to Symphony 2.2.2, the EventPreSaveFilter delegate doesn't
     // pass the `$entry_id`. This can cause an issue when an Event has the
     // `allow_multiple` filter set as we can't determine the correct `$entry_id`
     // This will check to see if the `$entry_id` is set, otherwise fallback
     // to the previous logic. This will mean that using `allow_multiple` will
     // not be compatible without Symphony 2.2.2 and Members 1.1
     // @see https://github.com/symphonycms/members/issues/167
     if (isset($context['entry_id']) && is_numeric($context['entry_id'])) {
         $entry_id = (int) $context['entry_id'];
         $action = 'edit';
     } else {
         if (isset($_POST['id']) && !empty($_POST['id'])) {
             $entry_id = (int) $_POST['id'];
             $action = 'edit';
         } else {
             $action = 'create';
             $entry_id = 0;
         }
     }
     $required_level = $action == 'create' ? EventPermissions::CREATE : EventPermissions::ALL_ENTRIES;
     $role_id = Role::PUBLIC_ROLE;
     $isLoggedIn = $this->getMemberDriver()->isLoggedIn();
     if ($isLoggedIn && $this->getMemberDriver()->initialiseMemberObject()) {
         if ($this->getMemberDriver()->getMember() instanceof Entry) {
             $required_level = EventPermissions::OWN_ENTRIES;
             $role_data = $this->getMemberDriver()->getMember()->getData(extension_Members::getField('role')->get('id'));
             $role_id = $role_data['role_id'];
             if ($action == 'edit' && method_exists($context['event'], 'getSource')) {
                 $section_id = $context['event']->getSource();
                 $isOwner = false;
                 // If the event is the same section as the Members section, then for `$isOwner`
                 // to be true, the `$entry_id` must match the currently logged in user.
                 if ($section_id == $this->getMemberDriver()->getMember()->get('section_id')) {
                     // Check the logged in member is the same as the `entry_id` that is about to
                     // be updated. If so the user is the Owner and can modify EventPermissions::OWN_ENTRIES
                     $isOwner = $this->getMemberDriver()->getMemberID() == $entry_id;
                 } else {
                     $field_ids = array();
                     // Get the ID's of the fields that may be used for Linking (Username/Email)
                     if (!is_null(extension_Members::getFieldHandle('identity'))) {
                         $field_ids[] = extension_Members::getField('identity')->get('id');
                     }
                     if (!is_null(extension_Members::getFieldHandle('email'))) {
                         $field_ids[] = extension_Members::getField('email')->get('id');
                     }
                     // Query for the `field_id` of any linking fields that link to the members
                     // section AND to one of the linking fields (Username/Email)
                     $fields = Symphony::Database()->fetchCol('child_section_field_id', sprintf("\n\t\t\t\t\t\t\t\t\tSELECT `child_section_field_id`\n\t\t\t\t\t\t\t\t\tFROM `tbl_sections_association`\n\t\t\t\t\t\t\t\t\tWHERE `parent_section_id` = %d\n\t\t\t\t\t\t\t\t\tAND `child_section_id` = %d\n\t\t\t\t\t\t\t\t\tAND `parent_section_field_id` IN ('%s')\n\t\t\t\t\t\t\t\t", $this->getMemberDriver()->getMember()->get('section_id'), $section_id, implode("','", $field_ids)));
                     // If there was a link found, get the `relation_id`, which is the `member_id` of
                     // an entry in the active Members section.
                     if (!empty($fields)) {
                         foreach ($fields as $field_id) {
                             if ($isOwner === true) {
                                 break;
                             }
                             $field = FieldManager::fetch($field_id);
                             if ($field instanceof Field) {
                                 // So we are trying to find all entries that have selected the Member entry
                                 // to determine ownership. This check will use the `fetchAssociatedEntryIDs`
                                 // function, which typically works backwards, by accepting the `entry_id` (in
                                 // this case, our logged in Member ID). This will return an array of all the
                                 // linked entries, so we then just check that the current entry that is going to
                                 // be updated is in that array
                                 $member_id = $field->fetchAssociatedEntryIDs($this->getMemberDriver()->getMemberID());
                                 $isOwner = in_array($entry_id, $member_id);
                             }
                         }
                     }
                 }
                 // User is not the owner, so they can edit EventPermissions::ALL_ENTRIES
                 if ($isOwner === false) {
                     $required_level = EventPermissions::ALL_ENTRIES;
                 }
             }
         }
     }
     $role = RoleManager::fetch($role_id);
     $event_handle = strtolower(preg_replace('/^event/i', NULL, get_class($context['event'])));
     $success = false;
     if ($role) {
         $success = $role->canProcessEvent($event_handle, $action, $required_level) ? true : false;
     }
     $context['messages'][] = array('permission', $success, $success === false ? __('You are not authorised to perform this action.') : null);
     // Process the Filters for this event.
     $this->__processEventFilters($context);
 }
Exemplo n.º 15
0
 /**
  * Will delete the Role given a `$role_id`. Should `$purge_members`
  * be passed, this function will remove all Members associated with
  * this role as well
  *
  * @param integer $role_id
  * @param boolean $purge_members
  * @return boolean
  */
 public static function delete($role_id, $purge_members = false)
 {
     Symphony::Database()->delete("`tbl_members_roles_forbidden_pages`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles_event_permissions`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles`", " `id` = " . $role_id);
     $role_fields = FieldManager::fetch(null, null, 'ASC', 'sortorder', extension_Members::getFieldType('role'));
     if ($purge_members) {
         $members = array();
         foreach ($role_fields as $role_field) {
             $members_of_role = Symphony::Database()->fetchCol('entry_id', sprintf("SELECT `entry_id` FROM `tbl_entries_data_%d` WHERE `role_id` = %d", $role_field->get('id'), $role_id));
             $members = array_merge($members, $members_of_role);
         }
         /**
          * Prior to deletion of entries. An array of Entry ID's is provided which
          * can be manipulated. This delegate was renamed from `Delete` to `EntryPreDelete`
          * in Symphony 2.3.
          *
          * @delegate EntryPreDelete
          * @param string $context
          * '/publish/'
          * @param array $entry_id
          *  An array of Entry ID's passed by reference
          */
         Symphony::ExtensionManager()->notifyMembers('EntryPreDelete', '/publish/', array('entry_id' => &$members));
         EntryManager::delete($members);
         /**
          * After the deletion of entries, this delegate provides an array of Entry ID's
          * that were deleted.
          *
          * @since Symphony 2.3
          * @delegate EntryPostDelete
          * @param string $context
          * '/publish/'
          * @param array $entry_id
          *  An array of Entry ID's that were deleted.
          */
         Symphony::ExtensionManager()->notifyMembers('EntryPostDelete', '/publish/', array('entry_id' => $members));
     }
     return true;
 }
    protected function __trigger()
    {
        $success = true;
        $result = new XMLElement('forgot-password');
        $Members = $this->_Parent->ExtensionManager->create('members');
        $username = $email = $code = NULL;
        if (isset($_POST['fields']['code']) && strlen(trim($_POST['fields']['code'])) > 0) {
            $code = $_POST['fields']['code'];
            $new_password = General::generatePassword();
            self::__init();
            $db = ASDCLoader::instance();
            // Make sure we dont accidently use an expired token
            extension_Members::purgeTokens();
            $token_row = $db->query(sprintf("SELECT * FROM `tbl_members_login_tokens` WHERE `token` = '%s' LIMIT 1", $db->escape($code)))->current();
            // No code, you are a spy!
            if ($token_row === false) {
                redirect(URL . '/members/reset-pass/failed/');
            }
            // Attempt to update the password
            $db->query(sprintf("UPDATE `tbl_entries_data_%d` SET `password` = '%s' WHERE `entry_id` = %d LIMIT 1", $Members->usernameAndPasswordField(), md5($new_password), $token_row->member_id));
            extension_Members::purgeTokens($token_row->member_id);
            // SEND THE EMAIL!!
            $entry = $Members->initialiseMemberObject($token_row->member_id);
            $email_address = $entry->getData(self::findFieldID('email-address', 'members'));
            $name = $entry->getData(self::findFieldID('name', 'members'));
            $subject = 'Your new password';
            $body = 'Dear {$name},

Just now, you have asked the Symphony brain trust to bestow you with a new password.

Well, here it is: {$new-password}

There\'s a good chance that you won\'t like this new password and want to change it - don\'t worry, we\'re not offended.

You can do that once you\'ve logged in by going here: {$root}/members/change-pass/

If you have any trouble, please email us at support@symphony-cms.com and we\'ll do our best to help.

Regards,

Symphony Team';
            $body = str_replace(array('{$name}', '{$root}', '{$new-password}'), array($name['value'], URL, $new_password), $body);
            $sender_email = 'noreply@' . parse_url(URL, PHP_URL_HOST);
            $sender_name = Symphony::Configuration()->get('sitename', 'general');
            General::sendEmail($email_address['value'], $sender_email, $sender_name, $subject, $body);
            redirect(URL . '/members/reset-pass/success/');
        }
        // Username take precedence
        if (isset($_POST['fields']['member-username']) && strlen(trim($_POST['fields']['member-username'])) > 0) {
            $username = $_POST['fields']['member-username'];
        }
        if (isset($_POST['fields']['member-email-address']) && strlen(trim($_POST['fields']['member-email-address'])) > 0) {
            $email = $_POST['fields']['member-email-address'];
        }
        if (is_null($username) && is_null($email)) {
            $success = false;
            $result->appendChild(new XMLElement('member-username', NULL, array('type' => 'missing')));
            $result->appendChild(new XMLElement('member-email-address', NULL, array('type' => 'missing')));
        } else {
            $members = array();
            if (!is_null($email)) {
                $members = $Members->findMemberIDFromEmail($email);
            }
            if (!is_null($username)) {
                $members[] = $Members->findMemberIDFromUsername($username);
            }
            // remove duplicates
            $members = array_unique($members);
            try {
                if (is_array($members) && !empty($members)) {
                    foreach ($members as $member_id) {
                        $Members->sendForgotPasswordEmail($member_id);
                    }
                    redirect(URL . '/members/reset-pass/code/');
                }
            } catch (Exception $e) {
                // Shouldn't get here, but will catch an invalid member ID if it does
            }
            $success = false;
        }
        $result->setAttribute('status', $success === true ? 'success' : 'error');
        return $result;
    }
Exemplo n.º 17
0
 /**
  * Will delete the Role given a `$role_id`. Should `$purge_members`
  * be passed, this function will remove all Members associated with
  * this role as well
  *
  * @param integer $role_id
  * @param boolean $purge_members
  * @return boolean
  */
 public function delete($role_id, $purge_members = false)
 {
     Symphony::Database()->delete("`tbl_members_roles_forbidden_pages`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles_event_permissions`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles`", " `id` = " . $role_id);
     if ($purge_members) {
         $members = Symphony::Database()->fetchCol('entry_id', sprintf("SELECT `entry_id` FROM `tbl_entries_data_%d` WHERE `role_id` = %d", extension_Members::getField('role')->get('id'), $role_id));
         /**
          * Prior to deletion of entries. Array of Entry ID's is provided.
          * The array can be manipulated
          *
          * @delegate Delete
          * @param string $context
          * '/publish/'
          * @param array $checked
          *  An array of Entry ID's passed by reference
          */
         Symphony::ExtensionManager()->notifyMembers('Delete', '/publish/', array('entry_id' => &$checked));
         $entryManager = new EntryManager(Symphony::Engine());
         $entryManager->delete($members);
     }
     return true;
 }
 /**
  * This will determine required action level for given a give section ID.
  *
  * @param $section_id
  * @param $entry_id
  *
  * @return integer
  */
 private function determineActionLevel($section_id, $entry_id = null)
 {
     // if member role is Public, require ALL
     if ($this->memberGetRoleId() == Role::PUBLIC_ROLE) {
         return SE_Permissions::LEVEL_ALL;
     }
     if (!is_numeric($entry_id)) {
         $entry_id = null;
     }
     // if the section is same as Members section
     if ($section_id == extension_Members::getMembersSection() && $entry_id !== null) {
         // check the `entry_id` is the same as the logged in member
         if ($entry_id == $this->memberGetDriver()->getMemberID()) {
             return SE_Permissions::LEVEL_OWN;
         }
     } elseif ($this->relatedFieldExists($section_id)) {
         if ($entry_id === null) {
             return SE_Permissions::LEVEL_OWN;
         }
         $entry_member_id = $this->relatedFieldGetMemberId($section_id, $entry_id);
         $logged_in_member_id = $this->memberGetDriver()->getMemberID();
         if ($entry_member_id == $logged_in_member_id) {
             return SE_Permissions::LEVEL_OWN;
         }
     }
     // default to ALL
     return SE_Permissions::LEVEL_ALL;
 }
 /**
  * Determine current member role ID.
  *
  * @return int
  */
 private final function memberDetermineRoleId()
 {
     $driver = $this->memberGetDriver();
     // not logged in?
     if (!$driver->isLoggedIn()) {
         return $this->memberGetDefaultRoleId();
     }
     /** @var $member Entry */
     $member = $driver->getMember();
     $role_data = $member->getData(extension_Members::getField('role')->get('id'));
     $role = RoleManager::fetch($role_data['role_id']);
     // role doesn't exist?
     if (!$role instanceof Role) {
         return $this->memberGetDefaultRoleId();
     }
     return (int) $role_data['role_id'];
 }
 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;
 }
Exemplo n.º 21
0
 /**
  * Login function takes an associative array of fields that contain
  * an Identity field (Email/Username) and a Password field. They keys
  * should be the Field's `element_name`.
  * An optional parameter, `$isHashed` refers to if the password provided
  * is hashed already, or requires hashing prior to logging in.
  *
  * @throws Exception
  * @param array $credentials
  * @param boolean $isHashed
  *  Defaults to false
  * @return boolean
  */
 public function login(array $credentials, $isHashed = false)
 {
     $username = $email = $password = null;
     $data = extension_Members::$_errors = array();
     // Map POST data to simple terms
     if (isset($credentials[$this->section->getFieldHandle('identity')])) {
         $username = $credentials[$this->section->getFieldHandle('identity')];
     }
     if (isset($credentials[$this->section->getFieldHandle('email')])) {
         $email = $credentials[$this->section->getFieldHandle('email')];
     }
     // Allow login via username OR email. This normalises the $data array from the custom
     // field names to simple names for ease of use.
     if (isset($username)) {
         $data['username'] = Symphony::Database()->cleanValue($username);
     } else {
         if (isset($email) && !is_null($this->section->getFieldHandle('email'))) {
             $data['email'] = Symphony::Database()->cleanValue($email);
         }
     }
     // Map POST data for password to `$password`
     if (isset($credentials[$this->section->getFieldHandle('authentication')])) {
         $password = $credentials[$this->section->getFieldHandle('authentication')];
         $data['password'] = !empty($password) ? $password : '';
     }
     // Check to ensure that we actually have some data to try and log a user in with.
     if (empty($data['password']) && isset($credentials[$this->section->getFieldHandle('authentication')])) {
         extension_Members::$_errors[$this->section->getFieldHandle('authentication')] = array('label' => $this->section->getField('authentication')->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($this->section->getField('authentication')->get('label'))));
     }
     if (isset($data['username']) && empty($data['username'])) {
         extension_Members::$_errors[$this->section->getFieldHandle('identity')] = array('label' => $this->section->getField('identity')->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($this->section->getField('identity')->get('label'))));
     }
     if (isset($data['email']) && empty($data['email'])) {
         extension_Members::$_errors[$this->section->getFieldHandle('email')] = array('label' => $this->section->getField('email')->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($this->section->getField('email')->get('label'))));
     } else {
         if (!fieldMemberEmail::applyValidationRule($email)) {
             extension_Members::$_errors[$this->section->getFieldHandle('email')] = array('message' => __('\'%s\' contains invalid characters.', array($this->section->getField('email')->get('label'))), 'message-id' => EventMessages::FIELD_INVALID, 'type' => 'invalid', 'label' => $this->section->getField('email')->get('label'));
             return null;
         }
     }
     // If there is errors already, no point continuing, return false
     if (!empty(extension_Members::$_errors)) {
         return false;
     }
     if ($id = $this->findMemberIDFromCredentials($data, $isHashed)) {
         try {
             self::$member_id = $id;
             $this->initialiseCookie();
             $this->initialiseMemberObject();
             $this->cookie->set('id', $id);
             $this->cookie->set('members-section-id', $this->getMember()->get('section_id'));
             if (isset($username)) {
                 $this->cookie->set('username', $data['username']);
             } else {
                 $this->cookie->set('email', $data['email']);
             }
             $this->cookie->set('password', $this->getMember()->getData($this->section->getField('authentication')->get('id'), true)->password);
             self::$isLoggedIn = true;
         } catch (Exception $ex) {
             // Or do something else?
             throw new Exception($ex);
         }
         return true;
     }
     $this->logout();
     return false;
 }
 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;
 }
 public function checkFrontendPagePermissions($context)
 {
     $this->initialiseCookie();
     ## Cookies only show up on page refresh. This flag helps in making sure the correct XML is being set
     $loggedin = false;
     $action = $_REQUEST['member-action'];
     if (trim($action) == 'logout') {
         $this->logout();
         redirect(URL);
     } elseif (isset($action['login'])) {
         $username = Symphony::Database()->cleanValue($_REQUEST['username']);
         $password = Symphony::Database()->cleanValue($_REQUEST['password']);
         if ($this->login($username, $password)) {
             if (isset($_REQUEST['redirect'])) {
                 redirect($_REQUEST['redirect']);
             }
             redirect(URL . $_SERVER['REQUEST_URI']);
         }
         self::$_failed_login_attempt = true;
     } elseif (isset($context['env']['url']['member-token']) && preg_match('/^[a-f0-9]{8}$/', $context['env']['url']['member-token'])) {
         $token = Symphony::Database()->fetchRow(0, "SELECT * FROM `tbl_members_login_tokens` WHERE `token` = '" . $context['env']['url']['member-token'] . "' LIMIT 1");
         if (is_array($token) && !empty($token)) {
             $entry = $this->fetchMemberFromID($token['member_id']);
             $username_field_data = $entry->getData($this->usernameAndPasswordField());
             $loggedin = $this->login($username_field_data['username'], $username_field_data['password'], true);
             self::purgeTokens($token['member_id']);
         }
     } else {
         $loggedin = $this->isLoggedIn();
     }
     $this->initialiseMemberObject();
     if ($loggedin && is_object($this->Member)) {
         $role_data = $this->Member->getData($this->roleField());
     }
     $role = $this->fetchRole($loggedin ? $role_data['role_id'] : 1, true);
     if (!$role->canAccessPage((int) $context['page_data']['id'])) {
         /*
         	Array
         	(
         	    [id] => 115
         	    [parent] => 91
         	    [title] => New
         	    [handle] => new
         	    [path] => downloads
         	    [params] => type
         	    [data_sources] => menu
         	    [events] => save_download
         	    [sortorder] => 13
         	    [type] => Array
         	        (
         	        )
         
         	    [filelocation] => /Users/pointybeard/Sites/projects/overture/public/workspace/pages/downloads_new.xsl
         	)
         
         	Array
         	(
         	    [id] => 136
         	    [parent] =>
         	    [title] => Forbidden
         	    [handle] => forbidden
         	    [path] =>
         	    [params] =>
         	    [data_sources] => menu
         	    [events] =>
         	    [sortorder] => 37
         	)
         */
         if ($row = Symphony::Database()->fetchRow(0, "SELECT `tbl_pages`.* FROM `tbl_pages`, `tbl_pages_types`\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  WHERE `tbl_pages_types`.page_id = `tbl_pages`.id AND tbl_pages_types.`type` = '403'\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  LIMIT 1")) {
             //redirect(URL . '/' . $row['path'] . '/' . $row['handle']);
             //$page['filelocation'] = $this->resolvePageFileLocation($page['path'], $page['handle']);
             //$page['type'] = $this->__fetchPageTypes($page['id']);
             $row['type'] = Symphony::Database()->fetchCol('type', "SELECT `type` FROM `tbl_pages_types` WHERE `page_id` = '" . $row['id'] . "' ");
             $row['filelocation'] = PAGES . '/' . trim(str_replace('/', '_', $row['path'] . '_' . $row['handle']), '_') . '.xsl';
             $context['page_data'] = $row;
             return;
         }
         $this->_Parent->customError(E_USER_ERROR, 'Forbidden', 'Please <a href="' . URL . '/symphony/login/">login</a> to view this page.', false, true, 'error', array('header' => 'HTTP/1.0 403 Forbidden'));
     }
     //$context['wrapper']->appendChild($this->buildXML());
 }
Exemplo n.º 24
0
 public function cbCheckFrontendPagePermissions($context)
 {
     $this->initialiseCookie();
     ## Cookies only show up on page refresh. This flag helps in making sure the correct XML is being set
     $loggedin = false;
     $action = $_REQUEST['member-action'];
     if (trim($action) == 'logout') {
         $this->logout();
         if (isset($_REQUEST['redirect'])) {
             redirect($_REQUEST['redirect']);
         }
         redirect(URL);
     } elseif (trim($action) == 'login') {
         $username = Symphony::Database()->cleanValue($_REQUEST['username']);
         $password = Symphony::Database()->cleanValue($_REQUEST['password']);
         if ($this->login($username, $password)) {
             if (isset($_REQUEST['redirect'])) {
                 redirect($_REQUEST['redirect']);
             }
             redirect(URL);
         }
         self::$_failed_login_attempt = true;
     } else {
         $loggedin = $this->isLoggedIn();
     }
     $this->initialiseMemberObject();
     if ($loggedin && is_object($this->Member)) {
         $role_data = $this->Member->getData($this->roleField());
         $this->__updateSystemTimezoneOffset();
     }
     $role = $this->fetchRole($loggedin ? $role_data['role_id'] : 1, true);
     if (!$role->canAccessPage((int) $context['page_data']['id'])) {
         if ($row = Symphony::Database()->fetchRow(0, "SELECT `tbl_pages`.* FROM `tbl_pages`, `tbl_pages_types` \r\n\t\t\t\t\tWHERE `tbl_pages_types`.page_id = `tbl_pages`.id AND tbl_pages_types.`type` = '403' \r\n\t\t\t\t\tLIMIT 1")) {
             $row['type'] = Symphony::Database()->fetchCol('type', "SELECT `type` FROM `tbl_pages_types` WHERE `page_id` = '" . $row['id'] . "' ");
             $row['filelocation'] = PAGES . '/' . trim(str_replace('/', '_', $row['path'] . '_' . $row['handle']), '_') . '.xsl';
             $context['page_data'] = $row;
             return;
         }
         throw new SymphonyErrorPage('Please <a href="' . URL . '/symphony/login/">login</a> to view this page.', 'Forbidden', 'error', array('header' => 'HTTP/1.0 403 Forbidden'));
     }
 }
Exemplo n.º 25
0
 public static function findCodeExpiry()
 {
     return extension_Members::findCodeExpiry('tbl_fields_memberpassword');
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_REQUEST['fields'];
     $this->driver = Symphony::ExtensionManager()->create('members');
     $requested_identity = $fields[extension_Members::getFieldHandle('identity')];
     // 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);
     }
     // Set the section ID
     $result = $this->setMembersSection($result, $_REQUEST['members-section-id']);
     if ($result->getAttribute('result') === 'error') {
         // We are not calling notifyMembersPasswordResetFailure here,
         // because this is not an authentication error
         $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') {
         // We are not calling notifyMembersPasswordResetFailure here,
         // because this is not an authentication 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 = $this->driver->getMemberDriver()->section->getField('authentication');
     if (!$auth instanceof fieldMemberPassword) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Authentication field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email field
     // has been detected
     $identity = $this->driver->getMemberDriver()->setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Identity field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $result->appendChild($post_values);
         return $result;
     }
     if (!isset($fields[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code']) or empty($fields[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code'])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('Recovery code is a required field.'))));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $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[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code'])));
     if (empty($row)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Member encountered errors.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'invalid', 'message-id' => EventMessages::FIELD_INVALID, 'message' => __('No recovery code found.'))));
         $this->notifyMembersPasswordResetFailure($requested_identity);
     } else {
         // Retrieve Member Entry record
         $entry = $this->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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($identity->get('element_name'), null, extension_Members::$_errors[$identity->get('element_name')]));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'invalid', 'message-id' => MemberEventMessages::RECOVERY_CODE_INVALID, 'message' => __('Recovery code has expired.'))));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $result->appendChild($post_values);
             return $result;
         }
         // Create new password using the auth field so simulate the checkPostFieldData
         // and processRawFieldData functions.
         $message = '';
         // For the purposes of this event, the auth field should ALWAYS be required
         // as we have to set a password (ie. handle the case where this field is
         // actually optional) RE: #193
         $auth->set('required', 'yes');
         $status = $auth->checkPostFieldData($fields[$auth->get('element_name')], $message, $member_id);
         if (Field::__OK__ != $status) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => $status == Field::__MISSING_FIELDS__ ? 'missing' : 'invalid', 'message' => $message, 'message-id' => $status == Field::__MISSING_FIELDS__ ? EventMessages::FIELD_MISSING : EventMessages::FIELD_INVALID, 'label' => $auth->get('label'))));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $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);
         /**
          * Fired just after a Member has reset their password.
          *
          * @delegate MembersPostResetPassword
          * @param string $context
          *  '/frontend/'
          * @param integer $member_id
          *  The Member ID of the member who just reset their password
          */
         Symphony::ExtensionManager()->notifyMembers('MembersPostResetPassword', '/frontend/', array('member_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.
             $this->driver->getMemberDriver()->filter_UpdatePasswordLogin(array('entry' => $entry, 'fields' => array($this->driver->getMemberDriver()->section->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;
 }
Exemplo n.º 27
0
 public function __actionDelete($role_id = null, $redirect = null, $purge_members = false)
 {
     if (array_key_exists('delete', $_POST['action'])) {
         if (!$role_id) {
             redirect(extension_Members::baseURL() . 'roles/');
         }
         if ($role_id == Role::PUBLIC_ROLE) {
             return $this->pageAlert(__('The Public role cannot be removed'), Alert::ERROR);
         }
         if (!($existing = RoleManager::fetch($role_id))) {
             throw new SymphonyErrorPage(__('The role you requested to delete does not exist.'), __('Role not found'));
         }
         // @todo What should happen to any Members that had this Role?
         RoleManager::delete($role_id, $purge_members);
         if (!is_null($redirect)) {
             redirect($redirect);
         }
     }
 }
Exemplo n.º 28
0
 /**
  * If the Members installation has a Activation field used, we need to make sure
  * that this field represents accurately what Role this Member actually has.
  * The Activation field allows developers to set a Activation Role, which is the role
  * assigned to Members who have registered, but not yet activated their account.
  * This Activation role masks the Role field's value, so the Member assumes the
  * Role of the Activation role.
  *
  * @param integer $entry_id
  *  The Entry ID of the Member
  * @param integer $role_id
  *  A given Role ID
  * @return integer
  *  The resulting Role ID, whether that is the Activation ID or the
  *  given `$role_id`.
  */
 public function getActivationRole($entry_id = null, $role_id = null)
 {
     if (is_null($entry_id)) {
         return null;
     }
     $activation_role_id = null;
     $activation = extension_Members::getField('activation', $this->get('parent_section'));
     if (!is_null($activation) && !is_null($entry_id)) {
         $entry = EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if ($entry instanceof Entry && $entry->getData($activation->get('id'), true)->activated != 'yes') {
             $activation_role_id = $activation->get('activation_role_id');
         }
     }
     if (!is_null($role_id) && is_null($activation_role_id)) {
         return $role_id;
     } else {
         return $activation_role_id;
     }
 }
Exemplo n.º 29
0
 /**
  * Part 2 - Update Password, logs the user in
  * If the user changed their password, we need to login them back into the
  * system with their new password.
  */
 public function filter_UpdatePasswordLogin(array $context)
 {
     // If the user didn't update their password, or no Identity field exists return
     if (empty($context['fields'][extension_Members::getFieldHandle('authentication')]['password'])) {
         return;
     }
     // Handle which is the Identity field, either the Member: Username or Member: Email field
     $identity = is_null(extension_Members::getFieldHandle('identity')) ? 'email' : 'identity';
     $this->login(array(extension_Members::getFieldHandle($identity) => $context['entry']->getData(extension_Members::getField($identity)->get('id'), true)->value, extension_Members::getFieldHandle('authentication') => $context['fields'][extension_Members::getFieldHandle('authentication')]['password']), false);
     if (isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
 }
 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;
 }