diff --git a/inc/cleantalk-public-integrations.php b/inc/cleantalk-public-integrations.php index d30821f3d..815f36c5d 100644 --- a/inc/cleantalk-public-integrations.php +++ b/inc/cleantalk-public-integrations.php @@ -1,5 +1,6 @@ ' . __FUNCTION__ . '():' . __LINE__, $_POST); - - return $errors; - } - - if ( $apbct->settings['forms__registrations_test'] == 0 ) { - do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST); - - return $errors; - } - - // The function already executed - // It happens when used ct_register_post(); - if ( $ct_signup_done && is_object($errors) && count($errors->errors) > 0 ) { - do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST); - - if ($errors instanceof WP_Error) { - return $errors; - } else { - return new WP_Error('registration_error', 'An unexpected error occurred.'); - } - } - - /** - * Exclusions - */ - if ( Post::get('wpmem_reg_page') && apbct_is_plugin_active('wp-members/wp-members.php') ) { - return $errors; - } - // BuddyBoss login form - if ( Post::getString('wp-submit') && Post::getString('log') && Post::getString('pwd') ) { - return $errors; - } - - $facebook = false; - // Facebook registration - $fb_userdata = Post::get('FB_userdata'); - if ( is_array($fb_userdata) ) { - if ( $sanitized_user_login === null && isset($fb_userdata['name']) ) { - $sanitized_user_login = Sanitize::cleanUser($fb_userdata['name']); - $facebook = true; - } - if ($user_email === null && isset($fb_userdata['email'])) { - $user_email = Sanitize::cleanEmail($fb_userdata['email']); - $facebook = true; - } - } - - // BuddyPress actions - $buddypress = false; - if ( $sanitized_user_login === null && Post::get('signup_username') ) { - $sanitized_user_login = Sanitize::cleanUser(Post::get('signup_username')); - $buddypress = true; - } - if ( $user_email === null && Post::get('signup_email') ) { - $user_email = Sanitize::cleanEmail(Post::get('signup_email')); - $buddypress = true; - } - - // Get BuddyPress core instance if available - $bp = function_exists('buddypress') ? buddypress() : null; - - // Skip BuddyPress request already contained validation errors - if ( ! empty($bp->signup->errors) ) { - do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST); - return $errors; - } - - // Break tests because we already have servers response - if ( $buddypress && $ct_signup_done ) { - if ( $ct_negative_comment ) { - $bp->signup->errors['signup_username'] = $ct_negative_comment; - } - do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST); - - return $errors; - } - - if ( current_filter() === 'woocommerce_registration_errors' ) { - $checkjs = apbct_js_test(Sanitize::cleanTextField(Cookie::get('ct_checkjs')), true); - $checkjs_post = null; - $checkjs_cookie = $checkjs; - } else { - // This hack can be helpful when plugin uses with untested themes&signups plugins. - $checkjs_post = apbct_js_test(Sanitize::cleanTextField(Post::get($ct_checkjs_register_form))); - $checkjs_cookie = apbct_js_test(Sanitize::cleanTextField(Cookie::get('ct_checkjs')), true); - $checkjs = $checkjs_cookie ?: $checkjs_post; - } - - // BuddyBoss Platform use rest api for registration from phone app - if ( apbct_is_plugin_active('buddyboss-app/buddyboss-app.php') && apbct_is_in_uri('/wp-json/buddyboss-app/v1/signup') ) { - $checkjs = Post::getString('checkjs') === 'true' ? 1 : 0; - } - - $sender_info = array( - 'post_checkjs_passed' => $checkjs_post, - 'cookie_checkjs_passed' => $checkjs_cookie, - 'form_validation' => ! empty($errors) && $errors instanceof \WP_Error - ? json_encode( - array( - 'validation_notice' => $errors->get_error_message(), - 'page_url' => TT::toString(Server::get('HTTP_HOST')) . TT::toString(Server::get('REQUEST_URI')), - ) - ) - : null, - ); - - /** - * Changing the type of check for BuddyPress - */ - if ( Post::get('signup_username') && Post::get('signup_email') ) { - // if buddy press set up custom fields - $reg_flag = ! empty(Post::get('signup_profile_field_ids')); - } - - /** - * Changing the type of check for Avada Fusion - */ - if ( Post::get('fusion_login_box') ) { - $reg_flag = true; - } - - if (current_filter() === 'woocommerce_registration_errors') { - if (!is_null($sanitized_user_login) && strpos($sanitized_user_login, '.') !== false) { - $username_parts = explode('.', $sanitized_user_login); - $sanitized_user_login = implode(' ', $username_parts); - } - } - - if (Post::getString('tutor_action') === 'tutor_register_student') { - $user_email = Post::getString('email'); - $sanitized_user_login = Post::getString('user_login'); - $reg_flag = true; - } - - $base_call_array = array( - 'sender_email' => $user_email, - 'sender_nickname' => $sanitized_user_login, - 'sender_info' => $sender_info, - 'js_on' => $checkjs, - ); - - if ( !$reg_flag ) { - $field_values = ''; - $fields_numbers_to_check = explode(',', TT::toString(Post::get('signup_profile_field_ids'))); - foreach ( $fields_numbers_to_check as $field_number ) { - $field_name = 'field_' . $field_number; - $field_value = Post::get($field_name) ? Sanitize::cleanTextareaField(Post::get($field_name)) : ''; - $field_values .= $field_value . "\n"; - } - $base_call_array['message'] = $field_values; - } - - $base_call_result = apbct_base_call( - $base_call_array, - $reg_flag - ); - - if ( ! isset($base_call_result['ct_result']) ) { - return $errors; - } - - $ct_result = $base_call_result['ct_result']; - ct_hash($ct_result->id); - - // Change mail notification if license is out of date - if ( $apbct->data['moderate'] == 0 && - ($ct_result->fast_submit == 1 || $ct_result->blacklisted == 1 || $ct_result->js_disabled == 1) - ) { - $apbct->sender_email = $user_email; - $apbct->sender_ip = Helper::ipGet('real'); - add_filter( - 'wp_new_user_notification_email_admin', - 'apbct_registration__Wordpress__changeMailNotification', - 100, - 3 - ); - } - - $ct_signup_done = true; - $cleantalk_executed = true; - - if ( $ct_result->inactive != 0 ) { - ct_send_error_notice($ct_result->comment); - return $errors; - } - - if ( $ct_result->allow != 0 ) { - if (current_filter() === 'woocommerce_registration_errors' && $apbct->settings['forms__wc_register_from_order']) { - $cleantalk_executed = false; - } - } - - if ( $ct_result->allow == 0 ) { - $ct_negative_comment = $ct_result->comment; - $ct_registration_error_comment = $ct_result->comment; - - if (current_filter() === 'woocommerce_registration_errors') { - add_action('woocommerce_store_api_checkout_order_processed', ['Cleantalk\Antispam\IntegrationsByClass\Woocommerce', 'storeApiCheckoutOrderProcessed'], 10, 2); - } - - if ( $buddypress === true ) { - $bp->signup->errors['signup_username'] = $ct_result->comment; - } - - if (apbct_is_plugin_active('buddyboss-app/buddyboss-app.php') && apbct_is_in_uri('/wp-json/buddyboss-app/v1/signup')) { - wp_send_json_error(['success' => false, 'message' => $ct_result->comment]); - } - - if ( $facebook ) { - /** @psalm-suppress InvalidArrayOffset */ - $_POST['FB_userdata']['email'] = ''; - /** @psalm-suppress InvalidArrayOffset */ - $_POST['FB_userdata']['name'] = ''; - return; - } - - if ((defined('MGM_PLUGIN_NAME') || apbct_is_plugin_active('bbpress/bbpress.php')) && - current_filter() !== 'woocommerce_registration_errors' - ) { - ct_die_extended($ct_result->comment); - } - - if ( is_wp_error($errors) ) { - $errors->add('ct_error', $ct_result->comment); - } - - return $errors; - } - - if ( $ct_result->id !== null ) { - $apbct_cookie_request_id = $ct_result->id; - Cookie::set($apbct_cookie_register_ok_label, $ct_result->id, time() + 10, '/'); - Cookie::set($apbct_cookie_request_id_label, $ct_result->id, time() + 10, '/'); - } - - return $errors; + $handler = new WPRegistrationErrors(); + return $handler->handle($errors, $sanitized_user_login, $user_email); } /** diff --git a/lib/Cleantalk/Antispam/IntegrationsByClass/WPRegistrationErrors.php b/lib/Cleantalk/Antispam/IntegrationsByClass/WPRegistrationErrors.php new file mode 100644 index 000000000..e899c0247 --- /dev/null +++ b/lib/Cleantalk/Antispam/IntegrationsByClass/WPRegistrationErrors.php @@ -0,0 +1,549 @@ +apbct = $apbct; + } + + /** + * Test users registration + * + * @param mixed|WP_Error $errors + * @param null|mixed $sanitized_user_login + * @param null|mixed $user_email + * + * @return void|WP_Error + * @psalm-suppress UnusedVariable + */ + public function handle($errors, $sanitized_user_login = null, $user_email = null) + { + $this->bp_object = $this->defineBuddyPressObject(); + //BUDDYPRESS + $this->is_buddypress = $this->probablyBuddyPressCredentials($sanitized_user_login, $user_email); + //FACEBOOK + $this->is_facebook = $this->probablyFacebookCredentials($sanitized_user_login, $user_email); + //WOOCOMMERCE + $this->probablyWooCommerceCredentials($sanitized_user_login); + //TUTOR LMS PLUGIN + $this->probablyTutorLMSCredentials($sanitized_user_login, $user_email); + + //Skipping rules + $on_skip_errors = $this->doSkipRequest($errors); + if (false !== $on_skip_errors) { + return $on_skip_errors; + } + + //Gathering CheckJS + $check_js_data = $this->getCheckJSData(); + $checkjs_post = $check_js_data['checkjs_post'] ?? null; + $checkjs_cookie = $check_js_data['checkjs_cookie'] ?? null; + $checkjs = $check_js_data['checkjs'] ?? null; + $sender_info = array( + 'post_checkjs_passed' => $checkjs_post, + 'cookie_checkjs_passed' => $checkjs_cookie, + 'form_validation' => $errors instanceof WP_Error + ? json_encode( + array( + 'validation_notice' => $errors->get_error_message(), + 'page_url' => Server::getString('HTTP_HOST') . Server::getString('REQUEST_URI'), + ) + ) + : null, + ); + + //Gathering basecall data + $base_call_array = array( + 'sender_email' => $user_email, + 'sender_nickname' => $sanitized_user_login, + 'sender_info' => $sender_info, + 'js_on' => $checkjs, + ); + + //force reg flag states + $this->reg_flag = $this->forceRegFlagCases($this->reg_flag); + if ( !$this->reg_flag ) { + $base_call_array['message'] = $this->defineMessageForNonRegistrationMethod(); + } + + //do base call + $base_call_result = $this->doBaseCall( + $base_call_array, + $this->reg_flag + ); + + $ct_result_object = $base_call_result['ct_result'] ?? null; + + if (!$ct_result_object) { + return $errors; + } + + $this->doServiceActions($ct_result_object, $user_email); + + if ( $ct_result_object->inactive != 0 ) { + ct_send_error_notice(TT::toString($ct_result_object->comment)); + return $errors; + } + + if ( $ct_result_object->allow != 0 ) { + $this->onAllowActions($ct_result_object); + } else { + $errors = $this->onDenyActions($ct_result_object, $errors); + } + + return $errors; + } + + /** + * @param $errors + * @return false|WP_Error + */ + public function doSkipRequest($errors) + { + global $ct_signup_done, $ct_negative_comment; + + if ($this->isUserEnabled()) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): USER_IS_LOGGED_IN on line ' . __LINE__, $_POST); + return $errors; + } + + if ($this->isRegistrationCheckDisabled()) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): REGISTRATION_CHECK_DISABLED on line ' . __LINE__, $_POST); + return $errors; + } + + if ($this->isSignupHandled($errors, $ct_signup_done)) { + if (!($errors instanceof WP_Error)) { + $errors = new WP_Error('registration_error', 'An unexpected error occurred.'); + } + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): SIGNUP_ALREADY_HANDLED on line ' . __LINE__, $_POST); + return $errors; + } + + if ($this->isWPMembersExclusion()) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): WP_MEMBER_EXCLUSION_FOUND on line ' . __LINE__, $_POST); + return $errors; + } + + if ($this->isBuddyBossLoginForm()) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): BUDDY_BOSS_EXCLUSION_FOUND on line ' . __LINE__, $_POST); + return $errors; + } + + if ($this->isBuddyPressAlreadyHasValidationErrors($ct_signup_done, $ct_negative_comment)) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '(): BUDDY_PRESS_VALIDATION_ERRORS_FOUND on line ' . __LINE__, $_POST); + return $errors; + } + + return false; + } + + /** + * @return bool + */ + public function isUserEnabled() + { + return apbct_is_user_enable() === false; + } + + /** + * @return bool + */ + public function isRegistrationCheckDisabled() + { + return $this->apbct->settings['forms__registrations_test'] == 0; + } + + /** + * @return bool + */ + public function isSignupHandled($errors, $ct_signup_done) + { + return $ct_signup_done && is_object($errors) && count($errors->errors) > 0; + } + + /** + * @return bool + */ + public function isWPMembersExclusion() + { + return Post::get('wpmem_reg_page') && apbct_is_plugin_active('wp-members/wp-members.php'); + } + + /** + * @return bool + */ + public function isBuddyBossLoginForm() + { + return Post::getString('wp-submit') && Post::getString('log') && Post::getString('pwd'); + } + + /** + * @return object|null + */ + public function defineBuddyPressObject() + { + // Get BuddyPress core instance if available + $bp = function_exists('buddypress') ? buddypress() : null; + if ( ! is_object($bp) || ! isset($bp->signup) || ! is_object($bp->signup) ) { + return null; + } + if ( ! isset($bp->signup->errors) ) { + $bp->signup->errors = array(); + } + + return $bp; + } + + /** + * @param bool $ct_signup_done + * @param string $ct_negative_comment + * @return bool + */ + public function isBuddyPressAlreadyHasValidationErrors($ct_signup_done, $ct_negative_comment) + { + if (!$this->bp_object) { + return false; + } + + if (! empty($this->bp_object->signup->errors)) { + return true; + } + + // Break tests because we already have server response + if ( $this->is_buddypress && $ct_signup_done ) { + if ( $ct_negative_comment ) { + $this->bp_object->signup->errors['signup_username'] = $ct_negative_comment; + } + return true; + } + // Skip BuddyPress request already contained validation errors + return false; + } + + /** + * @return array|false + */ + public function getFacebookFlow() + { + // Facebook registration + $facebook_flow = Post::getArray('FB_userdata'); + if ( !empty($facebook_flow) ) { + return $facebook_flow; + } + return false; + } + + /** + * @param string|null $sanitized_user_login + * @param string|null $user_email + * @return bool + */ + public function probablyFacebookCredentials(&$sanitized_user_login, &$user_email) + { + $facebook_flow = $this->getFacebookFlow(); + $is_facebook = false; + if ($facebook_flow) { + if ( $sanitized_user_login === null && isset($facebook_flow['name']) ) { + $sanitized_user_login = Sanitize::cleanUser($facebook_flow['name']); + $is_facebook = true; + } + if ($user_email === null && isset($facebook_flow['email'])) { + $user_email = Sanitize::cleanEmail($facebook_flow['email']); + $is_facebook = true; + } + } + return $is_facebook; + } + + /** + * @param string|null $sanitized_user_login + * @param string|null $user_email + * @return bool + */ + public function probablyBuddyPressCredentials(&$sanitized_user_login = null, &$user_email = null) + { + $is_buddypress = false; + //BuddyPress + if ( $sanitized_user_login === null && Post::get('signup_username') ) { + $sanitized_user_login = Sanitize::cleanUser(Post::get('signup_username')); + $is_buddypress = true; + } + if ( $user_email === null && Post::get('signup_email') ) { + $user_email = Sanitize::cleanEmail(Post::get('signup_email')); + $is_buddypress = true; + } + return $is_buddypress; + } + + /** + * @param string|null $sanitized_user_login + * @return void + */ + public function probablyWooCommerceCredentials(&$sanitized_user_login) + { + if (current_filter() === 'woocommerce_registration_errors') { + if (!is_null($sanitized_user_login) && strpos($sanitized_user_login, '.') !== false) { + $username_parts = explode('.', $sanitized_user_login); + $sanitized_user_login = implode(' ', $username_parts); + $sanitized_user_login = Sanitize::cleanUser($sanitized_user_login); + } + } + } + + /** + * @param string|null $sanitized_user_login + * @param string|null $user_email + * @return void + */ + public function probablyTutorLMSCredentials(&$sanitized_user_login, &$user_email) + { + if ( + Post::getString('tutor_action') === 'tutor_register_student' || + Post::getString('tutor_action') === 'tutor_register_instructor' + ) { + $user_email = Sanitize::cleanEmail(Post::getString('email')); + $sanitized_user_login = Sanitize::cleanUser(Post::getString('user_login')); + $this->reg_flag = true; + } + } + + /** + * @return array + */ + public function getCheckJSData() + { + global $ct_checkjs_register_form; + $stub = array( + 'checkjs' => null, + 'checkjs_post' => null, + 'checkjs_cookie' => null + ); + if ( current_filter() === 'woocommerce_registration_errors' ) { + $stub['checkjs'] = apbct_js_test(Sanitize::cleanTextField(Cookie::get('ct_checkjs')), true); + $stub['checkjs_post'] = null; + $stub['checkjs_cookie'] = $stub['checkjs']; + } else { + // This hack can be helpful when plugin uses with untested themes&signups plugins. + $stub['checkjs_post'] = apbct_js_test(Sanitize::cleanTextField(Post::getString($ct_checkjs_register_form))); + $stub['checkjs_cookie'] = apbct_js_test(Sanitize::cleanTextField(Cookie::getString('ct_checkjs')), true); + $stub['checkjs'] = $stub['checkjs_cookie'] ?: $stub['checkjs_post']; + } + + // BuddyBoss Platform use rest api for registration from phone app + if ( apbct_is_plugin_active('buddyboss-app/buddyboss-app.php') && apbct_is_in_uri('/wp-json/buddyboss-app/v1/signup') ) { + $stub['checkjs'] = Post::getString('checkjs') === 'true' ? 1 : 0; + } + + return $stub; + } + + /** + * @return bool + */ + public function forceRegFlagCases($reg_flag) + { + $reg_flag_inner = $reg_flag; + /** + * Changing the type of check for BuddyPress + */ + if ( Post::getString('signup_username') && Post::getString('signup_email') ) { + // if buddy press set up custom fields + $reg_flag_inner = ! empty(Post::getString('signup_profile_field_ids')); + } + + /** + * Changing the type of check for Avada Fusion + */ + if ( Post::get('fusion_login_box') ) { + $reg_flag_inner = true; + } + + return $reg_flag_inner; + } + + public function defineMessageForNonRegistrationMethod() + { + $field_values = ''; + $fields_numbers_to_check = explode(',', TT::toString(Post::get('signup_profile_field_ids'))); + foreach ( $fields_numbers_to_check as $field_number ) { + $field_name = 'field_' . $field_number; + $field_value = Post::getString($field_name) ? Sanitize::cleanTextareaField(Post::getString($field_name)) : ''; + $field_values .= $field_value . "\n"; + } + return $field_values; + } + + /** + * @param $base_call_array + * @param $reg_flag + * @return array|CleantalkResponse[] + */ + public function doBaseCall($base_call_array, $reg_flag) + { + return apbct_base_call( + $base_call_array, + $reg_flag + ); + } + + /** + * @param CleantalkResponse $ct_result_object + * @return void + */ + public function saveCTHash($ct_result_object) + { + ct_hash($ct_result_object->id); + } + + /** + * @param CleantalkResponse $ct_result_object + * @return void + */ + public function onAllowActions($ct_result_object) + { + global $cleantalk_executed, $apbct_cookie_register_ok_label, $apbct_cookie_request_id_label, $apbct_cookie_request_id; + if (current_filter() === 'woocommerce_registration_errors' && $this->apbct->settings['forms__wc_register_from_order']) { + $cleantalk_executed = false; + } + + if ( $ct_result_object->id !== null ) { + $apbct_cookie_request_id = $ct_result_object->id; + Cookie::set($apbct_cookie_register_ok_label, TT::toString($ct_result_object->id), time() + 10, '/'); + Cookie::set($apbct_cookie_request_id_label, TT::toString($ct_result_object->id), time() + 10, '/'); + } + } + + /** + * @param CleantalkResponse $ct_result_object + * @param $errors + * @return mixed|void|null + */ + public function onDenyActions($ct_result_object, $errors) + { + global $ct_negative_comment, $ct_registration_error_comment; + $ct_negative_comment = TT::toString($ct_result_object->comment); + $ct_registration_error_comment = TT::toString($ct_result_object->comment); + + $this->runMaybeDieActions($ct_result_object); + + if ( $this->is_facebook ) { + /** @psalm-suppress InvalidArrayOffset */ + $_POST['FB_userdata']['email'] = ''; + /** @psalm-suppress InvalidArrayOffset */ + $_POST['FB_userdata']['name'] = ''; + } + + if (current_filter() === 'woocommerce_registration_errors') { + add_action('woocommerce_store_api_checkout_order_processed', ['Cleantalk\Antispam\IntegrationsByClass\Woocommerce', 'storeApiCheckoutOrderProcessed'], 10, 2); + } + + if ( $this->is_buddypress === true && $this->bp_object ) { + $this->bp_object->signup->errors['signup_username'] = TT::toString($ct_result_object->comment); + } + + if ( is_wp_error($errors) ) { + $errors->add('ct_error', TT::toString($ct_result_object->comment)); + } + + return $errors; + } + + /** + * @param CleantalkResponse $ct_result_object + * @return void + */ + public function runMaybeDieActions($ct_result_object) + { + if (apbct_is_plugin_active('buddyboss-app/buddyboss-app.php') && apbct_is_in_uri('/wp-json/buddyboss-app/v1/signup')) { + wp_send_json_error(['success' => false, 'message' => TT::toString($ct_result_object->comment)]); + } + if ((defined('MGM_PLUGIN_NAME') || apbct_is_plugin_active('bbpress/bbpress.php')) && + current_filter() !== 'woocommerce_registration_errors' + ) { + ct_die_extended(TT::toString($ct_result_object->comment)); + } + } + + public function reforgeGlobals() + { + global $ct_signup_done, $cleantalk_executed; + $ct_signup_done = true; + $cleantalk_executed = true; + } + + /** + * @param CleantalkResponse $ct_result_object + * @param string $user_email + * @return void + */ + public function prepareEmailForNonModeratedLicense($ct_result_object, $user_email) + { + if ( + $ct_result_object->fast_submit == 1 || + $ct_result_object->blacklisted == 1 || + $ct_result_object->js_disabled == 1 + ) { + $this->apbct->sender_email = $user_email; + $this->apbct->sender_ip = Helper::ipGet('real'); + add_filter( + 'wp_new_user_notification_email_admin', + 'apbct_registration__Wordpress__changeMailNotification', + 100, + 3 + ); + } + } + + /** + * @param $ct_result_object + * @param $user_email + * @return void + */ + public function doServiceActions($ct_result_object, $user_email) + { + $this->reforgeGlobals(); + + $this->saveCTHash($ct_result_object); + + // Change mail notification if license is out of date + if ( $this->apbct->data['moderate'] == 0) { + $this->prepareEmailForNonModeratedLicense($ct_result_object, $user_email); + } + } +} diff --git a/tests/Antispam/WPRegistrationErrorsAllowTest.php b/tests/Antispam/WPRegistrationErrorsAllowTest.php new file mode 100644 index 000000000..4e8eddd35 --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsAllowTest.php @@ -0,0 +1,16 @@ +makeCtResult(array('id' => 555)); + + $handler->onAllowActions($ctResult); + + $this->assertSame(555, $GLOBALS['apbct_cookie_request_id']); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsCredentialsTest.php b/tests/Antispam/WPRegistrationErrorsCredentialsTest.php new file mode 100644 index 000000000..77ac87d1d --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsCredentialsTest.php @@ -0,0 +1,47 @@ +getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array('getFacebookFlow')) + ->disableOriginalConstructor() + ->getMock(); + + $this->setHandlerState($handler); + + $handler->method('getFacebookFlow')->willReturn(array( + 'name' => 'John Doe', + 'email' => 'john@example.com', + )); + + $login = null; + $email = null; + + $isFacebook = $handler->probablyFacebookCredentials($login, $email); + + $this->assertTrue($isFacebook); + $this->assertSame('John Doe', $login); + $this->assertSame('john@example.com', $email); + } + + public function test_probably_buddypress_credentials_reads_from_post() + { + $_POST['signup_username'] = 'buddy_user'; + $_POST['signup_email'] = 'buddy@example.com'; + + $handler = new WPRegistrationErrors(); + + $login = null; + $email = null; + + $isBuddyPress = $handler->probablyBuddyPressCredentials($login, $email); + + $this->assertTrue($isBuddyPress); + $this->assertSame('buddy_user', $login); + $this->assertSame('buddy@example.com', $email); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsDenyTest.php b/tests/Antispam/WPRegistrationErrorsDenyTest.php new file mode 100644 index 000000000..43de4a29c --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsDenyTest.php @@ -0,0 +1,57 @@ +getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array('runMaybeDieActions')) + ->getMock(); + + $ctResult = $this->makeCtResult(array( + 'allow' => 0, + 'comment' => 'Spam detected', + )); + + $errors = new WP_Error(); + + $handler->expects($this->once()) + ->method('runMaybeDieActions'); + + $result = $handler->onDenyActions($ctResult, $errors); + + $this->assertSame($errors, $result); + $this->assertArrayHasKey('ct_error', $errors->errors); + $this->assertSame('Spam detected', $errors->errors['ct_error'][0]); + $this->assertSame('Spam detected', $GLOBALS['ct_negative_comment']); + $this->assertSame('Spam detected', $GLOBALS['ct_registration_error_comment']); + } + + public function test_on_deny_actions_cleans_facebook_payload() + { + $_POST['FB_userdata'] = array( + 'email' => 'john@example.com', + 'name' => 'John Doe', + ); + + $handler = $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array('runMaybeDieActions')) + ->getMock(); + + $handler->is_facebook = true; + + $ctResult = $this->makeCtResult(array( + 'allow' => 0, + 'comment' => 'Spam detected', + )); + + $handler->method('runMaybeDieActions')->willReturn(null); + + $handler->onDenyActions($ctResult, new WP_Error()); + + $this->assertSame('', $_POST['FB_userdata']['email']); + $this->assertSame('', $_POST['FB_userdata']['name']); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsHandleTest.php b/tests/Antispam/WPRegistrationErrorsHandleTest.php new file mode 100644 index 000000000..29f84decc --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsHandleTest.php @@ -0,0 +1,122 @@ +getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'defineBuddyPressObject', + 'probablyBuddyPressCredentials', + 'probablyFacebookCredentials', + 'probablyWooCommerceCredentials', + 'probablyTutorLMSCredentials', + 'doSkipRequest', + )) + ->getMock(); + + $errors = new WP_Error(); + + $handler->method('defineBuddyPressObject')->willReturn(null); + $handler->method('probablyBuddyPressCredentials')->willReturn(false); + $handler->method('probablyFacebookCredentials')->willReturn(false); + $handler->method('probablyWooCommerceCredentials')->willReturn(null); + $handler->method('probablyTutorLMSCredentials')->willReturn(null); + $handler->method('doSkipRequest')->willReturn($errors); + + $result = $handler->handle($errors, 'john', 'john@example.com'); + + $this->assertSame($errors, $result); + } + + public function test_handle_returns_errors_if_base_call_has_no_ct_result() + { + $handler = $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'defineBuddyPressObject', + 'probablyBuddyPressCredentials', + 'probablyFacebookCredentials', + 'probablyWooCommerceCredentials', + 'probablyTutorLMSCredentials', + 'doSkipRequest', + 'getCheckJSData', + 'forceRegFlagCases', + 'doBaseCall', + )) + ->getMock(); + + $errors = new WP_Error(); + + $handler->method('defineBuddyPressObject')->willReturn(null); + $handler->method('probablyBuddyPressCredentials')->willReturn(false); + $handler->method('probablyFacebookCredentials')->willReturn(false); + $handler->method('probablyWooCommerceCredentials')->willReturn(null); + $handler->method('probablyTutorLMSCredentials')->willReturn(null); + $handler->method('doSkipRequest')->willReturn(false); + $handler->method('getCheckJSData')->willReturn(array( + 'checkjs' => 1, + 'checkjs_post' => 1, + 'checkjs_cookie' => 1, + )); + $handler->method('forceRegFlagCases')->willReturn(true); + $handler->method('doBaseCall')->willReturn(array()); + + $result = $handler->handle($errors, 'john', 'john@example.com'); + + $this->assertSame($errors, $result); + } + + public function test_handle_calls_on_deny_actions_when_ct_result_disallows_registration() + { + $handler = $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'defineBuddyPressObject', + 'probablyBuddyPressCredentials', + 'probablyFacebookCredentials', + 'probablyWooCommerceCredentials', + 'probablyTutorLMSCredentials', + 'doSkipRequest', + 'getCheckJSData', + 'forceRegFlagCases', + 'doBaseCall', + 'doServiceActions', + 'onDenyActions', + )) + ->getMock(); + + $errors = new WP_Error(); + $ctResult = $this->makeCtResult(array( + 'allow' => 0, + 'comment' => 'Spam detected', + )); + + $handler->method('defineBuddyPressObject')->willReturn(null); + $handler->method('probablyBuddyPressCredentials')->willReturn(false); + $handler->method('probablyFacebookCredentials')->willReturn(false); + $handler->method('probablyWooCommerceCredentials')->willReturn(null); + $handler->method('probablyTutorLMSCredentials')->willReturn(null); + $handler->method('doSkipRequest')->willReturn(false); + $handler->method('getCheckJSData')->willReturn(array( + 'checkjs' => 1, + 'checkjs_post' => 1, + 'checkjs_cookie' => 1, + )); + $handler->method('forceRegFlagCases')->willReturn(true); + $handler->method('doBaseCall')->willReturn(array( + 'ct_result' => $ctResult, + )); + $handler->expects($this->once())->method('doServiceActions'); + $handler->expects($this->once()) + ->method('onDenyActions') + ->with($ctResult, $errors) + ->willReturn($errors); + + $result = $handler->handle($errors, 'john', 'john@example.com'); + + $this->assertSame($errors, $result); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsRegFlagTest.php b/tests/Antispam/WPRegistrationErrorsRegFlagTest.php new file mode 100644 index 000000000..b0981f4bd --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsRegFlagTest.php @@ -0,0 +1,43 @@ +forceRegFlagCases(true); + + $this->assertFalse($result); + } + + public function test_force_reg_flag_cases_keeps_flag_true_for_avada() + { + $_POST['fusion_login_box'] = '1'; + + $handler = new WPRegistrationErrors(); + + $result = $handler->forceRegFlagCases(false); + + $this->assertTrue($result); + } + + public function test_define_message_for_non_registration_method_collects_profile_fields() + { + $_POST['signup_profile_field_ids'] = '2,3'; + $_POST['field_2'] = 'First field'; + $_POST['field_3'] = 'Second field'; + + $handler = new WPRegistrationErrors(); + + $result = $handler->defineMessageForNonRegistrationMethod(); + + $this->assertSame("First field\nSecond field\n", $result); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsSkipTest.php b/tests/Antispam/WPRegistrationErrorsSkipTest.php new file mode 100644 index 000000000..39e5d494b --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsSkipTest.php @@ -0,0 +1,93 @@ +getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'isUserEnabled', + 'isRegistrationCheckDisabled', + 'isSignupHandled', + 'isWPMembersExclusion', + 'isBuddyBossLoginForm', + 'isBuddyPressAlreadyHasValidationErrors', + )) + ->disableOriginalConstructor() + ->getMock(); + + $this->setHandlerState($handler); + + $handler->method('isUserEnabled')->willReturn(true); + $handler->method('isRegistrationCheckDisabled')->willReturn(false); + $handler->method('isSignupHandled')->willReturn(false); + $handler->method('isWPMembersExclusion')->willReturn(false); + $handler->method('isBuddyBossLoginForm')->willReturn(false); + $handler->method('isBuddyPressAlreadyHasValidationErrors')->willReturn(false); + + $errors = new WP_Error(); + $result = $handler->doSkipRequest($errors); + + $this->assertSame($errors, $result); + } + + public function test_do_skip_request_returns_wp_error_when_signup_already_handled_and_input_is_not_wp_error() + { + $handler = $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'isUserEnabled', + 'isRegistrationCheckDisabled', + 'isSignupHandled', + 'isWPMembersExclusion', + 'isBuddyBossLoginForm', + 'isBuddyPressAlreadyHasValidationErrors', + )) + ->disableOriginalConstructor() + ->getMock(); + + $this->setHandlerState($handler); + + $handler->method('isUserEnabled')->willReturn(false); + $handler->method('isRegistrationCheckDisabled')->willReturn(false); + $handler->method('isSignupHandled')->willReturn(true); + $handler->method('isWPMembersExclusion')->willReturn(false); + $handler->method('isBuddyBossLoginForm')->willReturn(false); + $handler->method('isBuddyPressAlreadyHasValidationErrors')->willReturn(false); + + $errors = (object) array('errors' => array('x' => array('msg'))); + $result = $handler->doSkipRequest($errors); + + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertSame('An unexpected error occurred.', $result->get_error_message()); + } + + public function test_do_skip_request_returns_false_when_no_skip_conditions_match() + { + $handler = $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods(array( + 'isUserEnabled', + 'isRegistrationCheckDisabled', + 'isSignupHandled', + 'isWPMembersExclusion', + 'isBuddyBossLoginForm', + 'isBuddyPressAlreadyHasValidationErrors', + )) + ->disableOriginalConstructor() + ->getMock(); + + $this->setHandlerState($handler); + + $handler->method('isUserEnabled')->willReturn(false); + $handler->method('isRegistrationCheckDisabled')->willReturn(false); + $handler->method('isSignupHandled')->willReturn(false); + $handler->method('isWPMembersExclusion')->willReturn(false); + $handler->method('isBuddyBossLoginForm')->willReturn(false); + $handler->method('isBuddyPressAlreadyHasValidationErrors')->willReturn(false); + + $result = $handler->doSkipRequest(new WP_Error()); + + $this->assertFalse($result); + } +} diff --git a/tests/Antispam/WPRegistrationErrorsTestBase.php b/tests/Antispam/WPRegistrationErrorsTestBase.php new file mode 100644 index 000000000..1fd4b3459 --- /dev/null +++ b/tests/Antispam/WPRegistrationErrorsTestBase.php @@ -0,0 +1,77 @@ +settings['forms__registrations_test'] = 1; + $apbct->settings['forms__wc_register_from_order'] = 0; + $apbct->data['moderate'] = 1; + + Post::getInstance()->variables = []; + Cookie::getInstance()->variables = []; + Server::getInstance()->variables = []; + $_SERVER['HTTP_HOST'] = 'example.com'; + $_SERVER['REQUEST_URI'] = '/register'; + $_COOKIE = array(); + $_POST = array(); + + + $GLOBALS['ct_signup_done'] = false; + $GLOBALS['ct_negative_comment'] = ''; + $GLOBALS['ct_registration_error_comment'] = ''; + $GLOBALS['cleantalk_executed'] = false; + $GLOBALS['apbct_cookie_request_id'] = null; + $GLOBALS['apbct_cookie_register_ok_label'] = 'apbct_register_ok'; + $GLOBALS['apbct_cookie_request_id_label'] = 'apbct_request_id'; + $GLOBALS['ct_checkjs_register_form'] = 'ct_checkjs_register'; + } + + protected function makeHandler(array $onlyMethods = array()) + { + if (empty($onlyMethods)) { + return new WPRegistrationErrors(); + } + + return $this->getMockBuilder(WPRegistrationErrors::class) + ->onlyMethods($onlyMethods) + ->disableOriginalConstructor() + ->getMock(); + } + + protected function setHandlerState(WPRegistrationErrors $handler) + { + $ref = new ReflectionClass($handler); + + $apbctProp = $ref->getProperty('apbct'); + $apbctProp->setAccessible(true); + $apbctProp->setValue($handler, $GLOBALS['apbct']); + + $regFlagProp = $ref->getProperty('reg_flag'); + $regFlagProp->setAccessible(true); + $regFlagProp->setValue($handler, true); + } + + protected function makeCtResult(array $data = array()) + { + $default = array( + 'id' => 123, + 'allow' => 1, + 'inactive' => 0, + 'comment' => '', + 'fast_submit' => 0, + 'blacklisted' => 0, + 'js_disabled' => 0, + ); + + return (object) array_merge($default, $data); + } +}