function test_sends_failed_login_message()
 {
     Jetpack_Protect_Module::instance()->log_failed_attempt();
     $this->sender->do_sync();
     $action = $this->server_event_storage->get_most_recent_event('jpp_log_failed_attempt');
     $this->assertEquals('127.0.0.1', $action->args[0]);
 }
Esempio n. 2
0
 /**
  * Request an api key from wordpress.com
  *
  * @return bool | string
  */
 public function get_protect_key()
 {
     $protect_blog_id = Jetpack_Protect_Module::get_main_blog_jetpack_id();
     // If we can't find the the blog id, that means we are on multisite, and the main site never connected
     // the protect api key is linked to the main blog id - instruct the user to connect their main blog
     if (!$protect_blog_id) {
         $this->api_key_error = __('Your main blog is not connected to WordPress.com. Please connect to get an API key.', 'jetpack');
         return false;
     }
     $request = array('jetpack_blog_id' => $protect_blog_id, 'bruteprotect_api_key' => get_site_option('bruteprotect_api_key'), 'multisite' => '0');
     // Send the number of blogs on the network if we are on multisite
     if (is_multisite()) {
         $request['multisite'] = get_blog_count();
         if (!$request['multisite']) {
             global $wpdb;
             $request['multisite'] = $wpdb->get_var("SELECT COUNT(blog_id) as c FROM {$wpdb->blogs} WHERE spam = '0' AND deleted = '0' and archived = '0'");
         }
     }
     // Request the key
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.protect.requestKey', $request);
     // Hmm, can't talk to wordpress.com
     if ($xml->isError()) {
         $code = $xml->getErrorCode();
         $message = $xml->getErrorMessage();
         $this->api_key_error = sprintf(__('Error connecting to WordPress.com. Code: %1$s, %2$s', 'jetpack'), $code, $message);
         return false;
     }
     $response = $xml->getResponse();
     // Hmm. Can't talk to the protect servers ( api.bruteprotect.com )
     if (!isset($response['data'])) {
         $this->api_key_error = __('No reply from Jetpack servers', 'jetpack');
         return false;
     }
     // There was an issue generating the key
     if (empty($response['success'])) {
         $this->api_key_error = $response['data'];
         return false;
     }
     // Key generation successful!
     $active_plugins = Jetpack::get_active_plugins();
     // We only want to deactivate BruteProtect if we successfully get a key
     if (in_array('bruteprotect/bruteprotect.php', $active_plugins)) {
         Jetpack_Client_Server::deactivate_plugin('bruteprotect/bruteprotect.php', 'BruteProtect');
     }
     $key = $response['data'];
     update_site_option('jetpack_protect_key', $key);
     return $key;
 }
Esempio n. 3
0
 public function process_generate_math_page()
 {
     $salt = get_site_option('jetpack_protect_key') . get_site_option('admin_email');
     $ans = (int) $_POST['jetpack_protect_num'];
     $salted_ans = sha1($salt . $ans);
     $correct_ans = $_POST['jetpack_protect_answer'];
     if ($salted_ans != $correct_ans) {
         Jetpack_Protect_Math_Authenticate::generate_math_page(true);
     } else {
         $temp_pass = substr(sha1(rand(1, 100000000) . get_site_option('jetpack_protect_key')), 5, 25);
         Jetpack_Protect_Module::set_transient('jpp_math_pass_' . $temp_pass, 3, DAY_IN_SECONDS);
         setcookie('jpp_math_pass', $temp_pass, time() + DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, false);
         return true;
     }
 }
 /**
  * If it's a valid Jetpack module and configuration parameters have been sent, update it.
  *
  * @since 4.3.0
  *
  * @param WP_REST_Request $data {
  *     Array of parameters received by request.
  *
  *     @type string $slug Module slug.
  * }
  *
  * @return bool|WP_Error True if module was updated. Otherwise, a WP_Error instance with the corresponding error.
  */
 public function update_data($data)
 {
     // If it's null, we're trying to update many module options from different modules.
     if (is_null($data['slug'])) {
         // Value admitted by Jetpack_Core_Json_Api_Endpoints::get_updateable_data_list that will make it return all module options.
         // It will not be passed. It's just checked in this method to pass that method a string or array.
         $data['slug'] = 'any';
     } else {
         if (!Jetpack::is_module($data['slug'])) {
             return new WP_Error('not_found', esc_html__('The requested Jetpack module was not found.', 'jetpack'), array('status' => 404));
         }
         if (!Jetpack::is_module_active($data['slug'])) {
             return new WP_Error('inactive', esc_html__('The requested Jetpack module is inactive.', 'jetpack'), array('status' => 409));
         }
     }
     // Get parameters to update the module.
     $params = $data->get_json_params();
     // Exit if no parameters were passed.
     if (!is_array($params)) {
         return new WP_Error('missing_options', esc_html__('Missing options.', 'jetpack'), array('status' => 404));
     }
     // Get available module options.
     $options = Jetpack_Core_Json_Api_Endpoints::get_updateable_data_list('any' === $data['slug'] ? $params : $data['slug']);
     // Prepare to toggle module if needed
     $toggle_module = new Jetpack_Core_API_Module_Toggle_Endpoint(new Jetpack_IXR_Client());
     // Options that are invalid or failed to update.
     $invalid = array_keys(array_diff_key($params, $options));
     $not_updated = array();
     // Remove invalid options
     $params = array_intersect_key($params, $options);
     // Used if response is successful. The message can be overwritten and additional data can be added here.
     $response = array('code' => 'success', 'message' => esc_html__('The requested Jetpack data updates were successful.', 'jetpack'));
     // If there are modules to activate, activate them first so they're ready when their options are set.
     foreach ($params as $option => $value) {
         if ('modules' === $options[$option]['jp_group']) {
             // Used if there was an error. Can be overwritten with specific error messages.
             $error = '';
             // Set to true if the module toggling was successful.
             $updated = false;
             // Check if user can toggle the module.
             if ($toggle_module->can_request()) {
                 // Activate or deactivate the module according to the value passed.
                 $toggle_result = $value ? $toggle_module->activate_module($option) : $toggle_module->deactivate_module($option);
                 if (is_wp_error($toggle_result)) {
                     $error = $toggle_result->get_error_message();
                 } else {
                     $updated = true;
                 }
             } else {
                 $error = Jetpack_Core_Json_Api_Endpoints::$user_permissions_error_msg;
             }
             // The module was not toggled.
             if (!$updated) {
                 $not_updated[$option] = $error;
             }
             // Remove module from list so we don't go through it again.
             unset($params[$option]);
         }
     }
     foreach ($params as $option => $value) {
         // Used if there was an error. Can be overwritten with specific error messages.
         $error = '';
         // Set to true if the option update was successful.
         $updated = false;
         // Get option attributes, including the group it belongs to.
         $option_attrs = $options[$option];
         // If this is a module option and the related module isn't active for any reason, continue with the next one.
         if ('settings' !== $option_attrs['jp_group']) {
             if (!Jetpack::is_module($option_attrs['jp_group'])) {
                 $not_updated[$option] = esc_html__('The requested Jetpack module was not found.', 'jetpack');
                 continue;
             }
             if (!Jetpack::is_module_active($option_attrs['jp_group'])) {
                 $not_updated[$option] = esc_html__('The requested Jetpack module is inactive.', 'jetpack');
                 continue;
             }
         }
         // Properly cast value based on its type defined in endpoint accepted args.
         $value = Jetpack_Core_Json_Api_Endpoints::cast_value($value, $option_attrs);
         switch ($option) {
             case 'monitor_receive_notifications':
                 $monitor = new Jetpack_Monitor();
                 // If we got true as response, consider it done.
                 $updated = true === $monitor->update_option_receive_jetpack_monitor_notification($value);
                 break;
             case 'post_by_email_address':
                 if ('create' == $value) {
                     $result = $this->_process_post_by_email('jetpack.createPostByEmailAddress', esc_html__('Unable to create the Post by Email address. Please try again later.', 'jetpack'));
                 } elseif ('regenerate' == $value) {
                     $result = $this->_process_post_by_email('jetpack.regeneratePostByEmailAddress', esc_html__('Unable to regenerate the Post by Email address. Please try again later.', 'jetpack'));
                 } elseif ('delete' == $value) {
                     $result = $this->_process_post_by_email('jetpack.deletePostByEmailAddress', esc_html__('Unable to delete the Post by Email address. Please try again later.', 'jetpack'));
                 } else {
                     $result = false;
                 }
                 // If we got an email address (create or regenerate) or 1 (delete), consider it done.
                 if (preg_match('/[a-z0-9]+@post.wordpress.com/', $result)) {
                     $response[$option] = $result;
                     $updated = true;
                 } elseif (1 == $result) {
                     $updated = true;
                 } elseif (is_array($result) && isset($result['message'])) {
                     $error = $result['message'];
                 }
                 break;
             case 'jetpack_protect_key':
                 $protect = Jetpack_Protect_Module::instance();
                 if ('create' == $value) {
                     $result = $protect->get_protect_key();
                 } else {
                     $result = false;
                 }
                 // If we got one of Protect keys, consider it done.
                 if (preg_match('/[a-z0-9]{40,}/i', $result)) {
                     $response[$option] = $result;
                     $updated = true;
                 }
                 break;
             case 'jetpack_protect_global_whitelist':
                 $updated = jetpack_protect_save_whitelist(explode(PHP_EOL, str_replace(array(' ', ','), array('', "\n"), $value)));
                 if (is_wp_error($updated)) {
                     $error = $updated->get_error_message();
                 }
                 break;
             case 'show_headline':
             case 'show_thumbnails':
                 $grouped_options = $grouped_options_current = (array) Jetpack_Options::get_option('relatedposts');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? Jetpack_Options::update_option('relatedposts', $grouped_options) : true;
                 break;
             case 'google':
             case 'bing':
             case 'pinterest':
             case 'yandex':
                 $grouped_options = $grouped_options_current = (array) get_option('verification_services_codes');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? update_option('verification_services_codes', $grouped_options) : true;
                 break;
             case 'sharing_services':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 // If option value was the same, consider it done.
                 $updated = $value != $sharer->get_blog_services() ? $sharer->set_blog_services($value['visible'], $value['hidden']) : true;
                 break;
             case 'button_style':
             case 'sharing_label':
             case 'show':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $grouped_options = $sharer->get_global_options();
                 $grouped_options[$option] = $value;
                 $updated = $sharer->set_global_options($grouped_options);
                 break;
             case 'custom':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $updated = $sharer->new_service(stripslashes($value['sharing_name']), stripslashes($value['sharing_url']), stripslashes($value['sharing_icon']));
                 // Return new custom service
                 $response[$option] = $updated;
                 break;
             case 'sharing_delete_service':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $updated = $sharer->delete_service($value);
                 break;
             case 'jetpack-twitter-cards-site-tag':
                 $value = trim(ltrim(strip_tags($value), '@'));
                 $updated = get_option($option) !== $value ? update_option($option, $value) : true;
                 break;
             case 'onpublish':
             case 'onupdate':
             case 'Bias Language':
             case 'Cliches':
             case 'Complex Expression':
             case 'Diacritical Marks':
             case 'Double Negative':
             case 'Hidden Verbs':
             case 'Jargon Language':
             case 'Passive voice':
             case 'Phrases to Avoid':
             case 'Redundant Expression':
             case 'guess_lang':
                 if (in_array($option, array('onpublish', 'onupdate'))) {
                     $atd_option = 'AtD_check_when';
                 } elseif ('guess_lang' == $option) {
                     $atd_option = 'AtD_guess_lang';
                     $option = 'true';
                 } else {
                     $atd_option = 'AtD_options';
                 }
                 $user_id = get_current_user_id();
                 $grouped_options_current = AtD_get_options($user_id, $atd_option);
                 unset($grouped_options_current['name']);
                 $grouped_options = $grouped_options_current;
                 if ($value && !isset($grouped_options[$option])) {
                     $grouped_options[$option] = $value;
                 } elseif (!$value && isset($grouped_options[$option])) {
                     unset($grouped_options[$option]);
                 }
                 // If option value was the same, consider it done, otherwise try to update it.
                 $options_to_save = implode(',', array_keys($grouped_options));
                 $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $options_to_save) : true;
                 break;
             case 'ignored_phrases':
             case 'unignore_phrase':
                 $user_id = get_current_user_id();
                 $atd_option = 'AtD_ignored_phrases';
                 $grouped_options = $grouped_options_current = explode(',', AtD_get_setting($user_id, $atd_option));
                 if ('ignored_phrases' == $option) {
                     $grouped_options = explode(',', $value);
                 } else {
                     $index = array_search($value, $grouped_options);
                     if (false !== $index) {
                         unset($grouped_options[$index]);
                         $grouped_options = array_values($grouped_options);
                     }
                 }
                 $ignored_phrases = implode(',', array_filter(array_map('strip_tags', $grouped_options)));
                 $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $ignored_phrases) : true;
                 break;
             case 'admin_bar':
             case 'roles':
             case 'count_roles':
             case 'blog_id':
             case 'do_not_track':
             case 'hide_smile':
             case 'version':
                 $grouped_options = $grouped_options_current = (array) get_option('stats_options');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? update_option('stats_options', $grouped_options) : true;
                 break;
             case Jetpack_Core_Json_Api_Endpoints::holiday_snow_option_name():
                 $updated = get_option($option) != $value ? update_option($option, (bool) $value ? 'letitsnow' : '') : true;
                 break;
             case 'wp_mobile_featured_images':
             case 'wp_mobile_excerpt':
                 $value = 'enabled' === $value ? '1' : '0';
                 // break intentionally omitted
             // break intentionally omitted
             default:
                 // If option value was the same, consider it done.
                 $updated = get_option($option) != $value ? update_option($option, $value) : true;
                 break;
         }
         // The option was not updated.
         if (!$updated) {
             $not_updated[$option] = $error;
         }
     }
     if (empty($invalid) && empty($not_updated)) {
         // The option was updated.
         return rest_ensure_response($response);
     } else {
         $invalid_count = count($invalid);
         $not_updated_count = count($not_updated);
         $error = '';
         if ($invalid_count > 0) {
             $error = sprintf(_n('Invalid option: %s.', 'Invalid options: %s.', $invalid_count, 'jetpack'), join(', ', $invalid));
         }
         if ($not_updated_count > 0) {
             $not_updated_messages = array();
             foreach ($not_updated as $not_updated_option => $not_updated_message) {
                 if (!empty($not_updated_message)) {
                     $not_updated_messages[] = sprintf(__('Extra info for %1$s: %2$s', 'jetpack'), $not_updated_option, $not_updated_message);
                 }
             }
             if (!empty($error)) {
                 $error .= ' ';
             }
             $error .= sprintf(_n('Option not updated: %s.', 'Options not updated: %s.', $not_updated_count, 'jetpack'), join(', ', array_keys($not_updated)));
             if (!empty($not_updated_messages)) {
                 $error .= ' ' . join('. ', $not_updated_messages);
             }
         }
         // There was an error because some options were updated but others were invalid or failed to update.
         return new WP_Error('some_updated', esc_html($error), array('status' => 400));
     }
 }
 /**
  * If it's a valid Jetpack module and configuration parameters have been sent, update it.
  *
  * @since 4.1.0
  *
  * @param WP_REST_Request $data {
  *     Array of parameters received by request.
  *
  *     @type string $slug Module slug.
  * }
  *
  * @return bool|WP_Error True if module was updated. Otherwise, a WP_Error instance with the corresponding error.
  */
 public static function update_module($data)
 {
     if (!Jetpack::is_module($data['slug'])) {
         return new WP_Error('not_found', esc_html__('The requested Jetpack module was not found.', 'jetpack'), array('status' => 404));
     }
     if (!Jetpack::is_module_active($data['slug'])) {
         return new WP_Error('inactive', esc_html__('The requested Jetpack module is inactive.', 'jetpack'), array('status' => 409));
     }
     // Get parameters to update the module.
     $param = $data->get_json_params();
     // Exit if no parameters were passed.
     if (!is_array($param)) {
         return new WP_Error('missing_option', esc_html__('Missing option.', 'jetpack'), array('status' => 404));
     }
     // Get option name and value.
     $option = key($param);
     $value = current($param);
     // Get available module options.
     $options = self::get_module_available_options();
     // If option is invalid, don't go any further.
     if (!in_array($option, array_keys($options))) {
         return new WP_Error('invalid_param', esc_html(sprintf(__('The option %s is invalid for this module.', 'jetpack'), $option)), array('status' => 404));
     }
     // Used if response is successful. The message can be overwritten and additional data can be added here.
     $response = array('code' => 'success', 'message' => esc_html__('The requested Jetpack module was updated.', 'jetpack'));
     // Used if there was an error. Can be overwritten with specific error messages.
     /* Translators: the variable is a module option name. */
     $error = sprintf(__('The option %s was not updated.', 'jetpack'), $option);
     // Set to true if the option update was successful.
     $updated = false;
     // Properly cast value based on its type defined in endpoint accepted args.
     $value = self::cast_value($value, $options[$option]);
     switch ($option) {
         case 'monitor_receive_notifications':
             $monitor = new Jetpack_Monitor();
             // If we got true as response, consider it done.
             $updated = true === $monitor->update_option_receive_jetpack_monitor_notification($value);
             break;
         case 'post_by_email_address':
             if ('create' == $value) {
                 $result = self::_process_post_by_email('jetpack.createPostByEmailAddress', esc_html__('Unable to create the Post by Email address. Please try again later.', 'jetpack'));
             } elseif ('regenerate' == $value) {
                 $result = self::_process_post_by_email('jetpack.regeneratePostByEmailAddress', esc_html__('Unable to regenerate the Post by Email address. Please try again later.', 'jetpack'));
             } elseif ('delete' == $value) {
                 $result = self::_process_post_by_email('jetpack.deletePostByEmailAddress', esc_html__('Unable to delete the Post by Email address. Please try again later.', 'jetpack'));
             } else {
                 $result = false;
             }
             // If we got an email address (create or regenerate) or 1 (delete), consider it done.
             if (preg_match('/[a-z0-9]+@post.wordpress.com/', $result)) {
                 $response[$option] = $result;
                 $updated = true;
             } elseif (1 == $result) {
                 $updated = true;
             } elseif (is_array($result) && isset($result['message'])) {
                 $error = $result['message'];
             }
             break;
         case 'jetpack_protect_key':
             $protect = Jetpack_Protect_Module::instance();
             if ('create' == $value) {
                 $result = $protect->get_protect_key();
             } else {
                 $result = false;
             }
             // If we got one of Protect keys, consider it done.
             if (preg_match('/[a-z0-9]{40,}/i', $result)) {
                 $response[$option] = $result;
                 $updated = true;
             }
             break;
         case 'jetpack_protect_global_whitelist':
             $updated = jetpack_protect_save_whitelist(explode(PHP_EOL, str_replace(' ', '', $value)));
             if (is_wp_error($updated)) {
                 $error = $updated->get_error_message();
             }
             break;
         case 'show_headline':
         case 'show_thumbnails':
             $grouped_options = $grouped_options_current = Jetpack_Options::get_option('relatedposts');
             $grouped_options[$option] = $value;
             // If option value was the same, consider it done.
             $updated = $grouped_options_current != $grouped_options ? Jetpack_Options::update_option('relatedposts', $grouped_options) : true;
             break;
         case 'google':
         case 'bing':
         case 'pinterest':
             $grouped_options = $grouped_options_current = get_option('verification_services_codes');
             $grouped_options[$option] = $value;
             // If option value was the same, consider it done.
             $updated = $grouped_options_current != $grouped_options ? update_option('verification_services_codes', $grouped_options) : true;
             break;
         case 'sharing_services':
             $sharer = new Sharing_Service();
             // If option value was the same, consider it done.
             $updated = $value != $sharer->get_blog_services() ? $sharer->set_blog_services($value['visible'], $value['hidden']) : true;
             break;
         case 'button_style':
         case 'sharing_label':
         case 'show':
             $sharer = new Sharing_Service();
             $grouped_options = $sharer->get_global_options();
             $grouped_options[$option] = $value;
             $updated = $sharer->set_global_options($grouped_options);
             break;
         case 'custom':
             $sharer = new Sharing_Service();
             $updated = $sharer->new_service(stripslashes($value['sharing_name']), stripslashes($value['sharing_url']), stripslashes($value['sharing_icon']));
             // Return new custom service
             $response[$option] = $updated;
             break;
         case 'sharing_delete_service':
             $sharer = new Sharing_Service();
             $updated = $sharer->delete_service($value);
             break;
         case 'jetpack-twitter-cards-site-tag':
             $value = trim(ltrim(strip_tags($value), '@'));
             $updated = get_option($option) !== $value ? update_option($option, $value) : true;
             break;
         case 'onpublish':
         case 'onupdate':
         case 'Bias Language':
         case 'Cliches':
         case 'Complex Expression':
         case 'Diacritical Marks':
         case 'Double Negative':
         case 'Hidden Verbs':
         case 'Jargon Language':
         case 'Passive voice':
         case 'Phrases to Avoid':
         case 'Redundant Expression':
         case 'guess_lang':
             if (in_array($option, array('onpublish', 'onupdate'))) {
                 $atd_option = 'AtD_check_when';
             } elseif ('guess_lang' == $option) {
                 $atd_option = 'AtD_guess_lang';
                 $option = 'true';
             } else {
                 $atd_option = 'AtD_options';
             }
             $user_id = get_current_user_id();
             $grouped_options_current = AtD_get_options($user_id, $atd_option);
             unset($grouped_options_current['name']);
             $grouped_options = $grouped_options_current;
             if ($value && !isset($grouped_options[$option])) {
                 $grouped_options[$option] = $value;
             } elseif (!$value && isset($grouped_options[$option])) {
                 unset($grouped_options[$option]);
             }
             // If option value was the same, consider it done, otherwise try to update it.
             $options_to_save = implode(',', array_keys($grouped_options));
             $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $options_to_save) : true;
             break;
         case 'ignored_phrases':
         case 'unignore_phrase':
             $user_id = get_current_user_id();
             $atd_option = 'AtD_ignored_phrases';
             $grouped_options = $grouped_options_current = explode(',', AtD_get_setting($user_id, $atd_option));
             if ('ignored_phrases' == $option) {
                 $grouped_options[] = $value;
             } else {
                 $index = array_search($value, $grouped_options);
                 if (false !== $index) {
                     unset($grouped_options[$index]);
                     $grouped_options = array_values($grouped_options);
                 }
             }
             $ignored_phrases = implode(',', array_filter(array_map('strip_tags', $grouped_options)));
             $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $ignored_phrases) : true;
             break;
         default:
             // If option value was the same, consider it done.
             $updated = get_option($option) != $value ? update_option($option, $value) : true;
             break;
     }
     // The option was not updated.
     if (!$updated) {
         return new WP_Error('module_option_not_updated', esc_html($error), array('status' => 400));
     }
     // The option was updated.
     return rest_ensure_response($response);
 }