示例#1
0
/**
 * Authenticate the user using the username and password.
 *
 * @since 0.0.1
 *
 * @param HQ_User|HQ_Error|null $user     HQ_User or HQ_Error object from a previous callback. Default null.
 * @param string                $username Username for authentication.
 * @param string                $password Password for authentication.
 * @return HQ_User|HQ_Error HQ_User on success, HQ_Error on failure.
 */
function hq_authenticate_username_password($user, $username, $password)
{
    if ($user instanceof HQ_User) {
        return $user;
    }
    if (empty($username) || empty($password)) {
        if (is_hq_error($user)) {
            return $user;
        }
        $error = new HQ_Error();
        if (empty($username)) {
            $error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));
        }
        if (empty($password)) {
            $error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
        }
        return $error;
    }
    $user = get_user_by('login', $username);
    if (!$user) {
        return new HQ_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s">Lost your password?</a>'), hq_lostpassword_url()));
    }
    /**
     * Filter whether the given user can be authenticated with the provided $password.
     *
     * @since 0.0.1
     *
     * @param HQ_User|HQ_Error $user     HQ_User or HQ_Error object if a previous
     *                                   callback failed authentication.
     * @param string           $password Password to check against the user.
     */
    $user = apply_filters('hq_authenticate_user', $user, $password);
    if (is_hq_error($user)) {
        return $user;
    }
    if (!hq_check_password($password, $user->user_pass, $user->ID)) {
        return new HQ_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. <a href="%2$s">Lost your password?</a>'), $username, hq_lostpassword_url()));
    }
    return $user;
}
示例#2
0
/**
 * Edit user settings based on contents of $_POST
 *
 * Used on user-edit.php and profile.php to manage and process user options, passwords etc.
 *
 * @since 0.0.1
 *
 * @param int $user_id Optional. User ID.
 * @return int|HQ_Error user id of the updated user
 */
function edit_user($user_id = 0)
{
    $hq_roles = hq_roles();
    $user = new stdClass();
    if ($user_id) {
        $update = true;
        $user->ID = (int) $user_id;
        $userdata = get_userdata($user_id);
        $user->user_login = hq_slash($userdata->user_login);
    } else {
        $update = false;
    }
    if (!$update && isset($_POST['user_login'])) {
        $user->user_login = sanitize_user($_POST['user_login'], true);
    }
    $pass1 = $pass2 = '';
    if (isset($_POST['pass1'])) {
        $pass1 = $_POST['pass1'];
    }
    if (isset($_POST['pass2'])) {
        $pass2 = $_POST['pass2'];
    }
    if (isset($_POST['role']) && current_user_can('edit_users')) {
        $new_role = sanitize_text_field($_POST['role']);
        $potential_role = isset($hq_roles->role_objects[$new_role]) ? $hq_roles->role_objects[$new_role] : false;
        // Don't let anyone with 'edit_users' (admins) edit their own role to something without it.
        // Multisite super admins can freely edit their blog roles -- they possess all caps.
        if (is_multisite() && current_user_can('manage_sites') || $user_id != get_current_user_id() || $potential_role && $potential_role->has_cap('edit_users')) {
            $user->role = $new_role;
        }
        // If the new role isn't editable by the logged-in user die with error
        $editable_roles = get_editable_roles();
        if (!empty($new_role) && empty($editable_roles[$new_role])) {
            hq_die(__('You can&#8217;t give users that role.'));
        }
    }
    if (isset($_POST['email'])) {
        $user->user_email = sanitize_text_field(hq_unslash($_POST['email']));
    }
    if (isset($_POST['url'])) {
        if (empty($_POST['url']) || $_POST['url'] == 'http://') {
            $user->user_url = '';
        } else {
            $user->user_url = esc_url_raw($_POST['url']);
            $protocols = implode('|', array_map('preg_quote', hq_allowed_protocols()));
            $user->user_url = preg_match('/^(' . $protocols . '):/is', $user->user_url) ? $user->user_url : 'http://' . $user->user_url;
        }
    }
    if (isset($_POST['first_name'])) {
        $user->first_name = sanitize_text_field($_POST['first_name']);
    }
    if (isset($_POST['last_name'])) {
        $user->last_name = sanitize_text_field($_POST['last_name']);
    }
    if (isset($_POST['nickname'])) {
        $user->nickname = sanitize_text_field($_POST['nickname']);
    }
    if (isset($_POST['display_name'])) {
        $user->display_name = sanitize_text_field($_POST['display_name']);
    }
    if (isset($_POST['description'])) {
        $user->description = trim($_POST['description']);
    }
    foreach (hq_get_user_contact_methods($user) as $method => $name) {
        if (isset($_POST[$method])) {
            $user->{$method} = sanitize_text_field($_POST[$method]);
        }
    }
    if ($update) {
        $user->rich_editing = isset($_POST['rich_editing']) && 'false' == $_POST['rich_editing'] ? 'false' : 'true';
        $user->admin_color = isset($_POST['admin_color']) ? sanitize_text_field($_POST['admin_color']) : 'fresh';
        $user->show_admin_bar_front = isset($_POST['admin_bar_front']) ? 'true' : 'false';
    }
    $user->comment_shortcuts = isset($_POST['comment_shortcuts']) && 'true' == $_POST['comment_shortcuts'] ? 'true' : '';
    $user->use_ssl = 0;
    if (!empty($_POST['use_ssl'])) {
        $user->use_ssl = 1;
    }
    $errors = new HQ_Error();
    /* checking that username has been typed */
    if ($user->user_login == '') {
        $errors->add('user_login', __('<strong>ERROR</strong>: Please enter a username.'));
    }
    /* checking the password has been typed twice */
    /**
     * Fires before the password and confirm password fields are checked for congruity.
     *
     * @since 0.0.1
     *
     * @param string $user_login The username.
     * @param string &$pass1     The password, passed by reference.
     * @param string &$pass2     The confirmed password, passed by reference.
     */
    do_action_ref_array('check_passwords', array($user->user_login, &$pass1, &$pass2));
    if ($update) {
        if (empty($pass1) && !empty($pass2)) {
            $errors->add('pass', __('<strong>ERROR</strong>: You entered your new password only once.'), array('form-field' => 'pass1'));
        } elseif (!empty($pass1) && empty($pass2)) {
            $errors->add('pass', __('<strong>ERROR</strong>: You entered your new password only once.'), array('form-field' => 'pass2'));
        }
    } else {
        if (empty($pass1)) {
            $errors->add('pass', __('<strong>ERROR</strong>: Please enter your password.'), array('form-field' => 'pass1'));
        } elseif (empty($pass2)) {
            $errors->add('pass', __('<strong>ERROR</strong>: Please enter your password twice.'), array('form-field' => 'pass2'));
        }
    }
    /* Check for "\" in password */
    if (false !== strpos(hq_unslash($pass1), "\\")) {
        $errors->add('pass', __('<strong>ERROR</strong>: Passwords may not contain the character "\\".'), array('form-field' => 'pass1'));
    }
    /* checking the password has been typed twice the same */
    if ($pass1 != $pass2) {
        $errors->add('pass', __('<strong>ERROR</strong>: Please enter the same password in the two password fields.'), array('form-field' => 'pass1'));
    }
    if (!empty($pass1)) {
        $user->user_pass = $pass1;
    }
    if (!$update && isset($_POST['user_login']) && !validate_username($_POST['user_login'])) {
        $errors->add('user_login', __('<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.'));
    }
    if (!$update && username_exists($user->user_login)) {
        $errors->add('user_login', __('<strong>ERROR</strong>: This username is already registered. Please choose another one.'));
    }
    /* checking e-mail address */
    if (empty($user->user_email)) {
        $errors->add('empty_email', __('<strong>ERROR</strong>: Please enter an e-mail address.'), array('form-field' => 'email'));
    } elseif (!is_email($user->user_email)) {
        $errors->add('invalid_email', __('<strong>ERROR</strong>: The email address isn&#8217;t correct.'), array('form-field' => 'email'));
    } elseif (($owner_id = email_exists($user->user_email)) && (!$update || $owner_id != $user->ID)) {
        $errors->add('email_exists', __('<strong>ERROR</strong>: This email is already registered, please choose another one.'), array('form-field' => 'email'));
    }
    /**
     * Fires before user profile update errors are returned.
     *
     * @since 0.0.1
     *
     * @param array   &$errors An array of user profile update errors, passed by reference.
     * @param bool    $update  Whether this is a user update.
     * @param HQ_User &$user   HQ_User object, passed by reference.
     */
    do_action_ref_array('user_profile_update_errors', array(&$errors, $update, &$user));
    if ($errors->get_error_codes()) {
        return $errors;
    }
    if ($update) {
        $user_id = hq_update_user($user);
    } else {
        $user_id = hq_insert_user($user);
        hq_new_user_notification($user_id, null, 'both');
    }
    return $user_id;
}
示例#3
0
/**
 * Populate network settings.
 *
 * @since 0.0.1
 *
 * @global hqdb       $hqdb
 * @global object     $current_site
 * @global int        $hq_db_version
 * @global HQ_Rewrite $hq_rewrite
 *
 * @param int $network_id ID of network to populate.
 * @return bool|HQ_Error True on success, or HQ_Error on warning (with the install otherwise successful,
 *                       so the error code must be checked) or failure.
 */
function populate_network($network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false)
{
    global $hqdb, $current_site, $hq_db_version, $hq_rewrite;
    $errors = new HQ_Error();
    if ('' == $domain) {
        $errors->add('empty_domain', __('You must provide a domain name.'));
    }
    if ('' == $site_name) {
        $errors->add('empty_sitename', __('You must provide a name for your network of sites.'));
    }
    // Check for network collision.
    if ($network_id == $hqdb->get_var($hqdb->prepare("SELECT id FROM {$hqdb->site} WHERE id = %d", $network_id))) {
        $errors->add('siteid_exists', __('The network already exists.'));
    }
    $site_user = get_user_by('email', $email);
    if (!is_email($email)) {
        $errors->add('invalid_email', __('You must provide a valid e-mail address.'));
    }
    if ($errors->get_error_code()) {
        return $errors;
    }
    // Set up site tables.
    $template = get_option('template');
    $stylesheet = get_option('stylesheet');
    $allowed_themes = array($stylesheet => true);
    if ($template != $stylesheet) {
        $allowed_themes[$template] = true;
    }
    if (HQ_DEFAULT_THEME != $stylesheet && HQ_DEFAULT_THEME != $template) {
        $allowed_themes[HQ_DEFAULT_THEME] = true;
    }
    if (1 == $network_id) {
        $hqdb->insert($hqdb->site, array('domain' => $domain, 'path' => $path));
        $network_id = $hqdb->insert_id;
    } else {
        $hqdb->insert($hqdb->site, array('domain' => $domain, 'path' => $path, 'id' => $network_id));
    }
    hq_cache_delete('networks_have_paths', 'site-options');
    //TODO: no multisite
    //if ( !is_multisite() ) {
    $site_admins = array($site_user->user_login);
    $users = get_users(array('fields' => array('ID', 'user_login')));
    if ($users) {
        foreach ($users as $user) {
            if (is_super_admin($user->ID) && !in_array($user->user_login, $site_admins)) {
                $site_admins[] = $user->user_login;
            }
        }
    }
    //} else {
    //	$site_admins = get_site_option( 'site_admins' );
    //}
    /* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
    $welcome_email = __('Howdy USERNAME,

Your new SITE_NAME site has been successfully set up at:
BLOG_URL

You can log in to the administrator account with the following information:

Username: USERNAME
Password: PASSWORD
Log in here: BLOG_URLhq-login.php

We hope you enjoy your new site. Thanks!

--The Team @ SITE_NAME');
    $misc_exts = array('jpg', 'jpeg', 'png', 'gif', 'mov', 'avi', 'mpg', '3gp', '3g2', 'midi', 'mid', 'pdf', 'doc', 'ppt', 'odt', 'pptx', 'docx', 'pps', 'ppsx', 'xls', 'xlsx', 'key');
    $audio_exts = hq_get_audio_extensions();
    $video_exts = hq_get_video_extensions();
    $upload_filetypes = array_unique(array_merge($misc_exts, $audio_exts, $video_exts));
    $sitemeta = array('site_name' => $site_name, 'admin_email' => $site_user->user_email, 'admin_user_id' => $site_user->ID, 'registration' => 'none', 'upload_filetypes' => implode(' ', $upload_filetypes), 'blog_upload_space' => 100, 'fileupload_maxk' => 1500, 'site_admins' => $site_admins, 'allowedthemes' => $allowed_themes, 'illegal_names' => array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files'), 'hqmu_upgrade_site' => $hq_db_version, 'welcome_email' => $welcome_email, 'first_post' => __('Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start blogging!'), 'siteurl' => get_option('siteurl') . '/', 'add_new_users' => '0', 'upload_space_check_disabled' => '1', 'subdomain_install' => intval($subdomain_install), 'global_terms_enabled' => global_terms_enabled() ? '1' : '0', 'ms_files_rewriting' => '0', 'initial_db_version' => get_option('initial_db_version'), 'active_sitewide_plugins' => array(), 'HQLANG' => get_locale());
    if (!$subdomain_install) {
        $sitemeta['illegal_names'][] = 'blog';
    }
    /**
     * Filter meta for a network on creation.
     *
     * @since 0.0.1
     *
     * @param array $sitemeta   Associative array of network meta keys and values to be inserted.
     * @param int   $network_id ID of network to populate.
     */
    $sitemeta = apply_filters('populate_network_meta', $sitemeta, $network_id);
    $insert = '';
    foreach ($sitemeta as $meta_key => $meta_value) {
        if (is_array($meta_value)) {
            $meta_value = serialize($meta_value);
        }
        if (!empty($insert)) {
            $insert .= ', ';
        }
        $insert .= $hqdb->prepare("( %d, %s, %s)", $network_id, $meta_key, $meta_value);
    }
    $hqdb->query("INSERT INTO {$hqdb->sitemeta} ( site_id, meta_key, meta_value ) VALUES " . $insert);
    /*
     * When upgrading from single to multisite, assume the current site will
     * become the main site of the network. When using populate_network()
     * to create another network in an existing multisite environment, skip
     * these steps since the main site of the new network has not yet been
     * created.
     */
    //TODO: no multisite
    //if ( ! is_multisite() ) {
    $current_site = new stdClass();
    $current_site->domain = $domain;
    $current_site->path = $path;
    $current_site->site_name = ucfirst($domain);
    $hqdb->insert($hqdb->blogs, array('site_id' => $network_id, 'blog_id' => 1, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')));
    $current_site->blog_id = $blog_id = $hqdb->insert_id;
    update_user_meta($site_user->ID, 'source_domain', $domain);
    update_user_meta($site_user->ID, 'primary_blog', $blog_id);
    if ($subdomain_install) {
        $hq_rewrite->set_permalink_structure('/%year%/%monthnum%/%day%/%postname%/');
    } else {
        $hq_rewrite->set_permalink_structure('/blog/%year%/%monthnum%/%day%/%postname%/');
    }
    flush_rewrite_rules();
    if (!$subdomain_install) {
        return true;
    }
    $vhost_ok = false;
    $errstr = '';
    $hostname = substr(md5(time()), 0, 6) . '.' . $domain;
    // Very random hostname!
    $page = hq_remote_get('http://' . $hostname, array('timeout' => 5, 'httpversion' => '1.1'));
    if (is_hq_error($page)) {
        $errstr = $page->get_error_message();
    } elseif (200 == hq_remote_retrieve_response_code($page)) {
        $vhost_ok = true;
    }
    if (!$vhost_ok) {
        $msg = '<p><strong>' . __('Warning! Wildcard DNS may not be configured correctly!') . '</strong></p>';
        $msg .= '<p>' . sprintf(__('The installer attempted to contact a random hostname (<code>%1$s</code>) on your domain.'), $hostname);
        if (!empty($errstr)) {
            $msg .= ' ' . sprintf(__('This resulted in an error message: %s'), '<code>' . $errstr . '</code>');
        }
        $msg .= '</p>';
        $msg .= '<p>' . __('To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a <code>*</code> hostname record pointing at your web server in your DNS configuration tool.') . '</p>';
        $msg .= '<p>' . __('You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.') . '</p>';
        return new HQ_Error('no_wildcard_dns', $msg);
    }
    //}
    return true;
}
示例#4
0
/**
 * Handles sending password retrieval email to user.
 *
 * @global hqdb         $hqdb      HiveQueen database abstraction object.
 * @global PasswordHash $hq_hasher Portable PHP password hashing framework.
 *
 * @return bool|HQ_Error True: when finish. HQ_Error on error
 */
function retrieve_password()
{
    global $hqdb, $hq_hasher;
    $errors = new HQ_Error();
    if (empty($_POST['user_login'])) {
        $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or e-mail address.'));
    } elseif (strpos($_POST['user_login'], '@')) {
        $user_data = get_user_by('email', trim($_POST['user_login']));
        if (empty($user_data)) {
            $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.'));
        }
    } else {
        $login = trim($_POST['user_login']);
        $user_data = get_user_by('login', $login);
    }
    /**
     * Fires before errors are returned from a password reset request.
     *
     * @since 0.0.1
     */
    do_action('lostpassword_post');
    if ($errors->get_error_code()) {
        return $errors;
    }
    if (!$user_data) {
        $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.'));
        return $errors;
    }
    // Redefining user_login ensures we return the right case in the email.
    $user_login = $user_data->user_login;
    $user_email = $user_data->user_email;
    /**
     * Fires before a new password is retrieved.
     *
     * @since 0.0.1
     *
     * @param string $user_login The user login name.
     */
    do_action('retreive_password', $user_login);
    /**
     * Fires before a new password is retrieved.
     *
     * @since 0.0.1
     *
     * @param string $user_login The user login name.
     */
    do_action('retrieve_password', $user_login);
    /**
     * Filter whether to allow a password to be reset.
     *
     * @since 0.0.1
     *
     * @param bool true           Whether to allow the password to be reset. Default true.
     * @param int  $user_data->ID The ID of the user attempting to reset a password.
     */
    $allow = apply_filters('allow_password_reset', true, $user_data->ID);
    if (!$allow) {
        return new HQ_Error('no_password_reset', __('Password reset is not allowed for this user'));
    } elseif (is_hq_error($allow)) {
        return $allow;
    }
    // Generate something random for a password reset key.
    $key = hq_generate_password(20, false);
    /**
     * Fires when a password reset key is generated.
     *
     * @since 0.0.1
     *
     * @param string $user_login The username for the user.
     * @param string $key        The generated password reset key.
     */
    do_action('retrieve_password_key', $user_login, $key);
    // Now insert the key, hashed, into the DB.
    if (empty($hq_hasher)) {
        require_once ABSPATH . HQINC . '/class-phpass.php';
        $hq_hasher = new PasswordHash(8, true);
    }
    $hashed = time() . ':' . $hq_hasher->HashPassword($key);
    $hqdb->update($hqdb->users, array('user_activation_key' => $hashed), array('user_login' => $user_login));
    $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    $message .= network_home_url('/') . "\r\n\r\n";
    $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $message .= '<' . network_site_url("hq-login.php?action=rp&key={$key}&login="******">\r\n";
    //TODO: Goyo no multisite
    //if ( is_multisite() )
    if (false) {
        $blogname = $GLOBALS['current_site']->site_name;
    } else {
        /*
         * The blogname option is escaped with esc_html on the way into the database
         * in sanitize_option we want to reverse this for the plain text arena of emails.
         */
        $blogname = hq_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    }
    $title = sprintf(__('[%s] Password Reset'), $blogname);
    /**
     * Filter the subject of the password reset email.
     *
     * @since 0.0.1
     *
     * @param string $title Default email title.
     */
    $title = apply_filters('retrieve_password_title', $title);
    /**
     * Filter the message body of the password reset mail.
     *
     * @since 0.0.1
     *
     * @param string  $message    Default mail message.
     * @param string  $key        The activation key.
     * @param string  $user_login The username for the user.
     * @param HQ_User $user_data  HQ_User object.
     */
    $message = apply_filters('retrieve_password_message', $message, $key, $user_login, $user_data);
    if ($message && !hq_mail($user_email, hq_specialchars_decode($title), $message)) {
        hq_die(__('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function.'));
    }
    return true;
}