| @@ -18,9 +18,9 @@ | ||
| 18 | 18 | use WP_Defender\Behavior\WPMUDEV; |
| 19 | 19 | use WP_Defender\Model\Lockout_Ip; |
| 20 | 20 | use WP_Defender\Traits\Continent; |
| 21 | 21 | use WP_Defender\Component\Blacklist_Lockout; |
| 22 | -use MaxMind\Db\Reader\InvalidDatabaseException; | |
| 22 | +use WP_DEFENDER_VENDOR\MaxMind\Db\Reader\InvalidDatabaseException; | |
| 23 | 23 | use WP_Defender\Component\Network_Cron_Manager; |
| 24 | 24 | use WP_Defender\Integrations\MaxMind_Geolocation; |
| 25 | 25 | use WP_Defender\Component\Config\Config_Hub_Helper; |
| 26 | 26 | use WP_Defender\Model\Setting\Blacklist_Lockout as Model_Blacklist_Lockout; |
| @@ -64,11 +64,12 @@ | ||
| 64 | 64 | $this->model = wd_di()->get( Model_Blacklist_Lockout::class ); |
| 65 | 65 | $this->service = wd_di()->get( Blacklist_Lockout::class ); |
| 66 | 66 | add_action( 'wd_blacklist_this_ip', array( $this, 'blacklist_an_ip' ) ); |
| 67 | 67 | // Update MaxMind's DB. |
| 68 | - if ( ! empty( $this->model->maxmind_license_key ) ) { | |
| 68 | + if ( '' !== $this->model->maxmind_license_key ) { | |
| 69 | 69 | // @since 2.8.0 Allows update or remove the database of MaxMind automatic and periodically (MaxMind's TOS). |
| 70 | - $bind_updater = (bool) apply_filters( 'wd_update_maxmind_database', true ); | |
| 70 | + $bind_updater = apply_filters( 'wd_update_maxmind_database', true ); | |
| 71 | + $bind_updater = is_bool( $bind_updater ) ? $bind_updater : (bool) $bind_updater; | |
| 71 | 72 | |
| 72 | 73 | if ( $bind_updater ) { |
| 73 | 74 | /** |
| 74 | 75 | * Network Cron Manager |
| @@ -109,9 +110,8 @@ | ||
| 109 | 110 | public function enqueue_assets() { |
| 110 | 111 | if ( ! $this->is_page_active() ) { |
| 111 | 112 | return; |
| 112 | 113 | } |
| 113 | - wp_localize_script( 'def-iplockout', 'blacklist', $this->data_frontend() ); | |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | /** |
| 117 | 117 | * Provides data for the frontend. |
| @@ -146,9 +146,9 @@ | ||
| 146 | 146 | $current_country[] = $this->get_current_country( $ip ); |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | $misc = array( |
| 150 | - 'user_ip' => implode( ',', $user_ip ), | |
| 150 | + 'user_ip' => implode( ', ', $user_ip ), | |
| 151 | 151 | 'is_geodb_downloaded' => $exist_geodb, |
| 152 | 152 | 'blacklist_countries' => $blacklist_countries, |
| 153 | 153 | 'whitelist_countries' => $whitelist_countries, |
| 154 | 154 | 'current_country' => $current_country, |
| @@ -174,9 +174,9 @@ | ||
| 174 | 174 | * |
| 175 | 175 | * @return string The masked license key. |
| 176 | 176 | */ |
| 177 | 177 | private function mask_license_key( $maxmind_license_key ): string { |
| 178 | - if ( ! is_string( $maxmind_license_key ) || empty( $maxmind_license_key ) ) { | |
| 178 | + if ( ! is_string( $maxmind_license_key ) || '' === $maxmind_license_key ) { | |
| 179 | 179 | return $maxmind_license_key; |
| 180 | 180 | } |
| 181 | 181 | // Get the length of the license key. |
| 182 | 182 | $key_length = strlen( $maxmind_license_key ); |
| @@ -228,8 +228,10 @@ | ||
| 228 | 228 | 'sanitize' => 'sanitize_textarea_field', |
| 229 | 229 | ), |
| 230 | 230 | ) |
| 231 | 231 | ); |
| 232 | + $data = $this->remove_country_list_conflicts( $data ); | |
| 233 | + | |
| 232 | 234 | $this->model->import( $data ); |
| 233 | 235 | if ( $this->model->validate() ) { |
| 234 | 236 | $this->model->save(); |
| 235 | 237 | Config_Hub_Helper::set_clear_active_flag(); |
| @@ -255,10 +257,8 @@ | ||
| 255 | 257 | $this->model->save(); |
| 256 | 258 | Config_Hub_Helper::set_clear_active_flag(); |
| 257 | 259 | } |
| 258 | 260 | |
| 259 | - $this->model->import( $data ); | |
| 260 | - | |
| 261 | 261 | return new Response( |
| 262 | 262 | false, |
| 263 | 263 | array_merge( |
| 264 | 264 | array( 'message' => $this->model->get_formatted_errors() ), |
| @@ -267,8 +267,44 @@ | ||
| 267 | 267 | ); |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | /** |
| 271 | + * Prevent the same country from being saved in both blocked and allowed lists. | |
| 272 | + * | |
| 273 | + * @param array $data Settings data. | |
| 274 | + * | |
| 275 | + * @return array | |
| 276 | + */ | |
| 277 | + private function remove_country_list_conflicts( array $data ): array { | |
| 278 | + if ( ! isset( $data['country_blacklist'], $data['country_whitelist'] ) ) { | |
| 279 | + return $data; | |
| 280 | + } | |
| 281 | + | |
| 282 | + $country_blacklist = array_values( array_unique( $data['country_blacklist'] ) ); | |
| 283 | + $country_whitelist = array_values( array_unique( $data['country_whitelist'] ) ); | |
| 284 | + $added_blacklist = array_diff( $country_blacklist, $this->model->country_blacklist ); | |
| 285 | + $added_whitelist = array_diff( $country_whitelist, $this->model->country_whitelist ); | |
| 286 | + | |
| 287 | + if ( array() !== $added_blacklist ) { | |
| 288 | + $country_whitelist = array_values( array_diff( $country_whitelist, $added_blacklist ) ); | |
| 289 | + } | |
| 290 | + | |
| 291 | + if ( array() !== $added_whitelist ) { | |
| 292 | + $country_blacklist = array_values( array_diff( $country_blacklist, $added_whitelist ) ); | |
| 293 | + } | |
| 294 | + | |
| 295 | + $remaining_conflicts = array_intersect( $country_blacklist, $country_whitelist ); | |
| 296 | + if ( array() !== $remaining_conflicts ) { | |
| 297 | + $country_whitelist = array_values( array_diff( $country_whitelist, $remaining_conflicts ) ); | |
| 298 | + } | |
| 299 | + | |
| 300 | + $data['country_blacklist'] = $country_blacklist; | |
| 301 | + $data['country_whitelist'] = $country_whitelist; | |
| 302 | + | |
| 303 | + return $data; | |
| 304 | + } | |
| 305 | + | |
| 306 | + /** | |
| 271 | 307 | * Download the GEODB IP from Maxmind. |
| 272 | 308 | * |
| 273 | 309 | * @param Request $request The request object containing the license key. |
| 274 | 310 | * |
| @@ -305,9 +341,9 @@ | ||
| 305 | 341 | } |
| 306 | 342 | |
| 307 | 343 | foreach ( $this->get_user_ip() as $ip ) { |
| 308 | 344 | $country = $this->get_current_country( $ip ); |
| 309 | - if ( ! empty( $country ) && ! empty( $country['iso'] ) ) { | |
| 345 | + if ( isset( $country['iso'] ) && '' !== (string) $country['iso'] ) { | |
| 310 | 346 | $this->model = $this->service->add_default_whitelisted_country( $this->model, $country['iso'] ); |
| 311 | 347 | } |
| 312 | 348 | } |
| 313 | 349 | $this->model->maxmind_license_key = $license_key; |
| @@ -324,19 +360,23 @@ | ||
| 324 | 360 | ) |
| 325 | 361 | ); |
| 326 | 362 | } else { |
| 327 | 363 | $this->log( 'Error from MaxMind: ' . $tmp->get_error_message(), Firewall::FIREWALL_LOG ); |
| 328 | - $string = sprintf( | |
| 329 | - /* translators: 1. License key with link. */ | |
| 330 | - esc_html__( | |
| 331 | - 'You have entered an invalid %1$s. If you just created the key, please wait 5 minutes before trying to activate it.', | |
| 332 | - 'defender-security' | |
| 333 | - ), | |
| 334 | - '<a target="_blank" href="https://www.maxmind.com/en/accounts/current/license-key">' . esc_html__( 'license key', 'defender-security' ) . '</a>' | |
| 364 | + $string = esc_html__( | |
| 365 | + 'The license key you entered isn\'t valid. If you recently created it, allow up to 5 minutes for activation before trying again.', | |
| 366 | + 'defender-security' | |
| 335 | 367 | ); |
| 336 | 368 | |
| 337 | 369 | if ( ( new WPMUDEV() )->show_support_links() ) { |
| 338 | - $string .= defender_support_ticket_text(); | |
| 370 | + $string = sprintf( | |
| 371 | + /* translators: 1. Opening support link, 2. Closing support link. */ | |
| 372 | + esc_html__( | |
| 373 | + 'The license key you entered isn\'t valid. If you recently created it, allow up to 5 minutes for activation before trying again. Need help? %1$sContact support%2$s.', | |
| 374 | + 'defender-security' | |
| 375 | + ), | |
| 376 | + '<a target="_blank" href="' . WP_DEFENDER_SUPPORT_LINK . '">', | |
| 377 | + '</a>' | |
| 378 | + ); | |
| 339 | 379 | } |
| 340 | 380 | |
| 341 | 381 | return new Response( false, array( 'invalid_text' => $string ) ); |
| 342 | 382 | } |
| @@ -469,9 +509,9 @@ | ||
| 469 | 509 | $ips = null; |
| 470 | 510 | $bulk_ips = null; |
| 471 | 511 | $limit = 50; |
| 472 | 512 | |
| 473 | - if ( ! empty( $data['ips'] ) ) { | |
| 513 | + if ( isset( $data['ips'] ) && is_string( $data['ips'] ) && '' !== $data['ips'] ) { | |
| 474 | 514 | $ips = json_decode( $data['ips'] ); |
| 475 | 515 | $first_nth_ips = array_slice( $ips, 0, $limit ); |
| 476 | 516 | $bulk_ips = wp_list_pluck( $first_nth_ips, 'ip' ); |
| 477 | 517 | } |
| @@ -521,9 +561,9 @@ | ||
| 521 | 561 | */ |
| 522 | 562 | public function query_locked_ips() { |
| 523 | 563 | $results = Lockout_Ip::query_locked_ip(); |
| 524 | 564 | $locked_ips = array(); |
| 525 | - if ( ! empty( $results ) ) { | |
| 565 | + if ( array() !== $results ) { | |
| 526 | 566 | foreach ( $results as $key => $locked_ip ) { |
| 527 | 567 | $locked_ips[] = array( |
| 528 | 568 | 'id' => $locked_ip['id'], |
| 529 | 569 | 'ip' => $locked_ip['ip'], |
| @@ -572,9 +612,9 @@ | ||
| 572 | 612 | 'ip_blacklist' => $data['ip_blacklist'], |
| 573 | 613 | 'ip_whitelist' => $data['ip_whitelist'], |
| 574 | 614 | 'ip_lockout_message' => $data['ip_lockout_message'], |
| 575 | 615 | ); |
| 576 | - if ( isset( $data['geoIP_db'] ) && file_exists( $data['geoIP_db'] ) ) { | |
| 616 | + if ( isset( $data['geoIP_db'] ) && is_string( $data['geoIP_db'] ) && file_exists( $data['geoIP_db'] ) ) { | |
| 577 | 617 | $adapted_data['geodb_path'] = $data['geoIP_db']; |
| 578 | 618 | if ( isset( $data['country_blacklist'] ) ) { |
| 579 | 619 | $adapted_data['country_blacklist'] = $data['country_blacklist']; |
| 580 | 620 | } |
| @@ -593,9 +633,9 @@ | ||
| 593 | 633 | * |
| 594 | 634 | * @throws Exception If table is not defined. |
| 595 | 635 | */ |
| 596 | 636 | public function import_data( array $data ) { |
| 597 | - if ( ! empty( $data ) ) { | |
| 637 | + if ( array() !== $data ) { | |
| 598 | 638 | // Upgrade for old versions. |
| 599 | 639 | $data = $this->adapt_data( $data ); |
| 600 | 640 | $model = $this->model; |
| 601 | 641 | $model->import( $data ); |
| @@ -641,20 +681,29 @@ | ||
| 641 | 681 | 'type' => 'int', |
| 642 | 682 | ), |
| 643 | 683 | ) |
| 644 | 684 | ); |
| 645 | - $attached_id = $data['id']; | |
| 646 | - if ( ! is_object( get_post( $attached_id ) ) ) { | |
| 647 | - return new Response( | |
| 648 | - false, | |
| 649 | - array( | |
| 650 | - 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ), | |
| 651 | - ) | |
| 652 | - ); | |
| 685 | + $file = ''; | |
| 686 | + $attached_id = $data['id'] ?? 0; | |
| 687 | + if ( 0 < $attached_id ) { | |
| 688 | + if ( ! is_object( get_post( $attached_id ) ) ) { | |
| 689 | + return new Response( | |
| 690 | + false, | |
| 691 | + array( | |
| 692 | + 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ), | |
| 693 | + ) | |
| 694 | + ); | |
| 695 | + } | |
| 696 | + | |
| 697 | + $file = get_attached_file( $attached_id ); | |
| 698 | + } else { | |
| 699 | + $file_data = defender_get_data_from_request( 'file', 'f' ); | |
| 700 | + if ( is_array( $file_data ) && isset( $file_data['tmp_name'] ) && is_uploaded_file( $file_data['tmp_name'] ) ) { | |
| 701 | + $file = $file_data['tmp_name']; | |
| 702 | + } | |
| 653 | 703 | } |
| 654 | 704 | |
| 655 | - $file = get_attached_file( $attached_id ); | |
| 656 | - if ( ! is_file( $file ) ) { | |
| 705 | + if ( ! is_string( $file ) || '' === $file || ! is_file( $file ) ) { | |
| 657 | 706 | return new Response( |
| 658 | 707 | false, |
| 659 | 708 | array( |
| 660 | 709 | 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ), |
| @@ -678,11 +727,14 @@ | ||
| 678 | 727 | } |
| 679 | 728 | |
| 680 | 729 | return new Response( |
| 681 | 730 | true, |
| 682 | - array( | |
| 683 | - 'message' => esc_html__( 'Your allowlist/blocklist has been successfully imported.', 'defender-security' ), | |
| 684 | - 'interval' => 1, | |
| 731 | + array_merge( | |
| 732 | + array( | |
| 733 | + 'message' => esc_html__( 'Your allowlist/blocklist has been successfully imported.', 'defender-security' ), | |
| 734 | + 'auto_close' => true, | |
| 735 | + ), | |
| 736 | + $this->data_frontend() | |
| 685 | 737 | ) |
| 686 | 738 | ); |
| 687 | 739 | } |
| 688 | 740 | |
| @@ -693,9 +745,9 @@ | ||
| 693 | 745 | * @throws Exception If table is not defined. |
| 694 | 746 | * @since 2.8.0 |
| 695 | 747 | */ |
| 696 | 748 | public function update_database() { |
| 697 | - if ( empty( $this->model->maxmind_license_key ) ) { | |
| 749 | + if ( '' === $this->model->maxmind_license_key ) { | |
| 698 | 750 | return; |
| 699 | 751 | } |
| 700 | 752 | |
| 701 | 753 | $service_geo = wd_di()->get( MaxMind_Geolocation::class ); |