Пример #1
0
 /**
  * Given an array or string as `$needle` and an existing `$member_id`
  * this function will return the `$member_id` if the given
  * password matches this `$member_id`, otherwise null.
  *
  * @param array|string $needle
  * @param integer $member_id
  * @param boolean $isHashed
  * @return Entry|null
  */
 public function fetchMemberIDBy($needle, $member_id = null, $isHashed = false)
 {
     $valid = true;
     if (is_array($needle)) {
         extract($needle);
     } else {
         $password = $needle;
     }
     if (empty($password)) {
         extension_Members::$_errors[$this->get('element_name')] = array('message' => __('\'%s\' is a required field.', array($this->get('label'))), 'message-id' => EventMessages::FIELD_MISSING, 'type' => 'missing', 'label' => $this->get('label'));
         return null;
     }
     $data = Symphony::Database()->fetchRow(0, sprintf("\n\t\t\t\t\tSELECT `entry_id`, `password`, `reset`\n\t\t\t\t\tFROM `tbl_entries_data_%d`\n\t\t\t\t\tWHERE %s\n\t\t\t\t\tLIMIT 1\n\t\t\t\t", $this->get('id'), is_null($member_id) ? '1 = 1' : sprintf('`entry_id` = %d', Symphony::Database()->cleanValue($member_id))));
     if (!empty($data)) {
         // The old passwords had salts, so add that the password
         // for accurate comparsion to determine if migrating needs to happen
         if ($isHashed === false && strlen($data['password']) === 40 && !is_null($this->get('salt'))) {
             $compare_password = $this->get('salt') . $password;
         } else {
             $compare_password = $password;
         }
         // Check if the password's match
         if (Cryptography::compare($compare_password, $data['password'], $isHashed)) {
             // Great! They match, but do we need to update the original password
             // to a more secure algorithm now?
             if (Cryptography::requiresMigration($data['password'])) {
                 Symphony::Database()->update(array('password' => $this->encodePassword($password)), 'tbl_entries_data_' . $this->get('id'), sprintf('`entry_id` = %d', Symphony::Database()->cleanValue($member_id)));
             }
         } else {
             $valid = false;
         }
     }
     // Check that if the password has been reset that it is still valid
     if ($valid && $data['reset'] == 'yes') {
         $valid_id = 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", $this->get('id'), $data['entry_id'], DateTimeObj::get('Y-m-d H:i:s', strtotime('now - ' . $this->get('code_expiry')))));
         // If we didn't get an entry_id back, then it's because it was expired
         if (is_null($valid_id)) {
             extension_Members::$_errors[$this->get('element_name')] = array('message' => __('Recovery code has expired.'), 'type' => 'invalid', 'label' => $this->get('label'));
         } else {
             $fields = array('reset' => 'no', 'expires' => null);
             Symphony::Database()->update($fields, 'tbl_entries_data_' . $this->get('id'), ' `entry_id` = ' . $valid_id);
         }
     }
     if ($valid) {
         return $member_id;
     }
     extension_Members::$_errors[$this->get('element_name')] = array('message' => __('Invalid %s.', array($this->get('label'))), 'message-id' => MemberEventMessages::MEMBER_INVALID, 'type' => 'invalid', 'label' => $this->get('label'));
     return null;
 }
Пример #2
0
 /**
  * Overload the Symphony::login function to bypass some code that
  * forces use of the Administration class (which of course is not
  * available in Shell). Hopefully this is fixed in the core Symphony code
  *
  */
 public static function login($username, $password, $isHash = false)
 {
     $username = self::Database()->cleanValue($username);
     $password = self::Database()->cleanValue($password);
     if (strlen(trim($username)) > 0 && strlen(trim($password)) > 0) {
         $author = \AuthorManager::fetch('id', 'ASC', 1, null, sprintf("\n                `username` = '%s'\n                ", $username));
         if (!empty($author) && \Cryptography::compare($password, current($author)->get('password'), $isHash)) {
             self::$Author = current($author);
             // Only migrate hashes if there is no update available as the update might change the tbl_authors table.
             if (\Cryptography::requiresMigration(self::$Author->get('password'))) {
                 throw new ShellException('User details require updating. Please login to the admin interface.');
             }
             self::$Cookie->set('username', $username);
             self::$Cookie->set('pass', self::$Author->get('password'));
             self::Database()->update(array('last_seen' => \DateTimeObj::get('Y-m-d H:i:s')), 'tbl_authors', sprintf(" `id` = %d", self::$Author->get('id')));
             return true;
         }
     }
     return false;
 }
Пример #3
0
 /**
  * This function determines whether an there is a currently logged in
  * Author for Symphony by using the `$Cookie`'s username
  * and password. If an Author is found, they will be logged in, otherwise
  * the `$Cookie` will be destroyed.
  *
  * @see core.Cookie#expire()
  */
 public function isLoggedIn()
 {
     // Ensures that we're in the real world.. Also reduces three queries from database
     // We must return true otherwise exceptions are not shown
     if (is_null(self::$_instance)) {
         return true;
     }
     if ($this->Author) {
         return true;
     } else {
         $username = self::Database()->cleanValue($this->Cookie->get('username'));
         $password = self::Database()->cleanValue($this->Cookie->get('pass'));
         if (strlen(trim($username)) > 0 && strlen(trim($password)) > 0) {
             $author = AuthorManager::fetch('id', 'ASC', 1, null, sprintf("\n\t\t\t\t\t\t\t`username` = '%s'\n\t\t\t\t\t\t", $username));
             if (!empty($author) && Cryptography::compare($password, current($author)->get('password'), true)) {
                 $this->Author = current($author);
                 self::Database()->update(array('last_seen' => DateTimeObj::get('Y-m-d H:i:s')), 'tbl_authors', sprintf(" `id` = %d", $this->Author->get('id')));
                 // Only set custom author language in the backend
                 if (class_exists('Administration')) {
                     Lang::set($this->Author->get('language'));
                 }
                 return true;
             }
         }
         $this->Cookie->expire();
         return false;
     }
 }
Пример #4
0
 /**
  * Attempts to log an Author in given a username and password.
  * If the password is not hashed, it will be hashed using the sha1
  * algorithm. The username and password will be sanitized before
  * being used to query the Database. If an Author is found, they
  * will be logged in and the sanitized username and password (also hashed)
  * will be saved as values in the `$Cookie`.
  *
  * @see toolkit.Cryptography#hash()
  * @throws DatabaseException
  * @param string $username
  *  The Author's username. This will be sanitized before use.
  * @param string $password
  *  The Author's password. This will be sanitized and then hashed before use
  * @param boolean $isHash
  *  If the password provided is already hashed, setting this parameter to
  *  true will stop it becoming rehashed. By default it is false.
  * @return boolean
  *  True if the Author was logged in, false otherwise
  */
 public static function login($username, $password, $isHash = false)
 {
     $username = trim(self::Database()->cleanValue($username));
     $password = trim(self::Database()->cleanValue($password));
     if (strlen($username) > 0 && strlen($password) > 0) {
         $author = AuthorManager::fetch('id', 'ASC', 1, null, sprintf("`username` = '%s'", $username));
         if (!empty($author) && Cryptography::compare($password, current($author)->get('password'), $isHash)) {
             self::$Author = current($author);
             // Only migrate hashes if there is no update available as the update might change the tbl_authors table.
             if (self::isUpgradeAvailable() === false && Cryptography::requiresMigration(self::$Author->get('password'))) {
                 self::$Author->set('password', Cryptography::hash($password));
                 self::Database()->update(array('password' => self::$Author->get('password')), 'tbl_authors', sprintf(" `id` = %d", self::$Author->get('id')));
             }
             self::$Cookie->set('username', $username);
             self::$Cookie->set('pass', self::$Author->get('password'));
             self::Database()->update(array('last_seen' => DateTimeObj::get('Y-m-d H:i:s')), 'tbl_authors', sprintf(" `id` = %d", self::$Author->get('id')));
             // Only set custom author language in the backend
             if (class_exists('Administration', false)) {
                 Lang::set(self::$Author->get('language'));
             }
             return true;
         }
     }
     return false;
 }
Пример #5
0
 public function __actionEdit()
 {
     if (!($author_id = (int) $this->_context[1])) {
         redirect(SYMPHONY_URL . '/system/authors/');
     }
     $isOwner = $author_id == Administration::instance()->Author->get('id');
     if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) {
         $fields = $_POST['fields'];
         $this->_Author = AuthorManager::fetchByID($author_id);
         $authenticated = false;
         if ($fields['email'] != $this->_Author->get('email')) {
             $changing_email = true;
         }
         // Check the old password was correct
         if (isset($fields['old-password']) && strlen(trim($fields['old-password'])) > 0 && Cryptography::compare(trim($fields['old-password']), $this->_Author->get('password'))) {
             $authenticated = true;
         } else {
             if (Administration::instance()->Author->isDeveloper()) {
                 $authenticated = true;
             }
         }
         $this->_Author->set('id', $author_id);
         if ($this->_Author->isPrimaryAccount() || $isOwner && Administration::instance()->Author->isDeveloper()) {
             $this->_Author->set('user_type', 'developer');
             // Primary accounts are always developer, Developers can't lower their level
         } elseif (Administration::instance()->Author->isDeveloper() && isset($fields['user_type'])) {
             $this->_Author->set('user_type', $fields['user_type']);
             // Only developer can change user type
         }
         $this->_Author->set('email', $fields['email']);
         $this->_Author->set('username', $fields['username']);
         $this->_Author->set('first_name', General::sanitize($fields['first_name']));
         $this->_Author->set('last_name', General::sanitize($fields['last_name']));
         $this->_Author->set('language', $fields['language']);
         if (trim($fields['password']) != '') {
             $this->_Author->set('password', Cryptography::hash($fields['password']));
             $changing_password = true;
         }
         // Don't allow authors to set the Section Index as a default area
         // If they had it previously set, just save `null` which will redirect
         // the Author (when logging in) to their own Author record
         if ($this->_Author->get('user_type') == 'author' && $fields['default_area'] == '/blueprints/sections/') {
             $this->_Author->set('default_area', null);
         } else {
             $this->_Author->set('default_area', $fields['default_area']);
         }
         $this->_Author->set('auth_token_active', $fields['auth_token_active'] ? $fields['auth_token_active'] : 'no');
         if ($this->_Author->validate($this->_errors)) {
             if (!$authenticated && ($changing_password || $changing_email)) {
                 if ($changing_password) {
                     $this->_errors['old-password'] = __('Wrong password. Enter old password to change it.');
                 } elseif ($changing_email) {
                     $this->_errors['old-password'] = __('Wrong password. Enter old one to change email address.');
                 }
             } elseif (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) {
                 $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match');
             } elseif ($this->_Author->commit()) {
                 Symphony::Database()->delete('tbl_forgotpass', " `expiry` < '" . DateTimeObj::getGMT('c') . "' OR `author_id` = '" . $author_id . "' ");
                 if ($isOwner) {
                     Administration::instance()->login($this->_Author->get('username'), $this->_Author->get('password'), true);
                 }
                 /**
                  * After editing an author, provided with the Author object
                  *
                  * @delegate AuthorPostEdit
                  * @since Symphony 2.2
                  * @param string $context
                  * '/system/authors/'
                  * @param Author $author
                  * An Author object
                  */
                 Symphony::ExtensionManager()->notifyMembers('AuthorPostEdit', '/system/authors/', array('author' => $this->_Author));
                 redirect(SYMPHONY_URL . '/system/authors/edit/' . $author_id . '/saved/');
             } else {
                 $this->pageAlert(__('Unknown errors occurred while attempting to save.') . '<a href="' . SYMPHONY_URL . '/system/log/">' . __('Check your activity log') . '</a>.', Alert::ERROR);
             }
         } else {
             if (is_array($this->_errors) && !empty($this->_errors)) {
                 $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR);
             }
         }
     } else {
         if (@array_key_exists('delete', $_POST['action'])) {
             /**
              * Prior to deleting an author, provided with the Author ID.
              *
              * @delegate AuthorPreDelete
              * @since Symphony 2.2
              * @param string $context
              * '/system/authors/'
              * @param integer $author_id
              *  The ID of Author ID that is about to be deleted
              */
             Symphony::ExtensionManager()->notifyMembers('AuthorPreDelete', '/system/authors/', array('author_id' => $author_id));
             if (!$isOwner) {
                 AuthorManager::delete($author_id);
                 redirect(SYMPHONY_URL . '/system/authors/');
             } else {
                 $this->pageAlert(__('You cannot remove yourself as you are the active Author.'), Alert::ERROR);
             }
         }
     }
 }