| @@ -15,8 +15,9 @@ | ||
| 15 | 15 | use WP_Defender\Behavior\WPMUDEV; |
| 16 | 16 | use WP_Defender\Component\Network_Cron_Manager; |
| 17 | 17 | use WP_Defender\Model\Setting\Global_Ip_Lockout; |
| 18 | 18 | use WP_Defender\Component\Config\Config_Hub_Helper; |
| 19 | +use WP_Defender\Component\IP\Antibot_Global_Firewall; | |
| 19 | 20 | use WP_Defender\Component\IP\Global_IP as Global_IP_Component; |
| 20 | 21 | |
| 21 | 22 | /** |
| 22 | 23 | * Handles global IP lockout settings. |
| @@ -26,8 +27,15 @@ | ||
| 26 | 27 | use Setting; |
| 27 | 28 | use Formats; |
| 28 | 29 | |
| 29 | 30 | /** |
| 31 | + * Module slug for identifying Custom IP sync auto-enable after Hub connection. | |
| 32 | + * | |
| 33 | + * @const string | |
| 34 | + */ | |
| 35 | + public const MODULE_SLUG = 'custom-ip-sync'; | |
| 36 | + | |
| 37 | + /** | |
| 30 | 38 | * The slug identifier for this controller. |
| 31 | 39 | * |
| 32 | 40 | * @var string |
| 33 | 41 | */ |
| @@ -75,16 +83,39 @@ | ||
| 75 | 83 | array( $this, 'fetch_global_ip_list' ), |
| 76 | 84 | HOUR_IN_SECONDS |
| 77 | 85 | ); |
| 78 | 86 | |
| 79 | - if ( $this->service->can_blocklist_autosync() ) { | |
| 80 | - // No need to run Rate mechanism for IP lockouts because we do it in Blacklist class. | |
| 81 | - add_action( 'wd_blacklist_this_ip', array( $this, 'blacklist_an_ip' ) ); | |
| 87 | + add_action( 'init', array( $this->service, 'handle_expired_membership' ) ); | |
| 88 | + if ( $this->wpmudev->is_wpmu_hosting() ) { | |
| 89 | + // sync_state must run before can_blocklist_autosync is evaluated, so both hooks use priority 10. | |
| 90 | + add_action( 'init', array( $this, 'sync_state' ) ); | |
| 82 | 91 | } |
| 83 | - add_action( 'init', array( $this->service, 'handle_expired_membership' ) ); | |
| 92 | + // Register after sync_state so the model reflects the current Hosting state. | |
| 93 | + add_action( 'init', array( $this, 'maybe_register_blocklist_autosync_hook' ) ); | |
| 94 | + // admin_init priority 20 runs after Hub_Connector sets the transient (priority 10); | |
| 95 | + // the other two hooks cover async-sync cases. | |
| 96 | + add_action( 'admin_init', array( $this, 'maybe_hcm_connection_attempt' ), 20 ); | |
| 97 | + add_action( 'wpdef_hub_connector_synced', array( $this, 'maybe_hcm_connection_attempt' ) ); | |
| 98 | + add_action( 'wpmudev_hub_connector_first_sync_completed', array( $this, 'maybe_hcm_connection_attempt' ) ); | |
| 84 | 99 | } |
| 85 | 100 | |
| 86 | 101 | /** |
| 102 | + * Auto-enable Custom IP list sync after Hub connection if user triggered from Custom Rules page. | |
| 103 | + * | |
| 104 | + * @return void | |
| 105 | + */ | |
| 106 | + public function maybe_hcm_connection_attempt(): void { | |
| 107 | + $data = get_site_transient( Hub_Connector::TRANSIENT_KEY ); | |
| 108 | + $module_slug = $data['module_slug'] ?? ''; | |
| 109 | + | |
| 110 | + if ( self::MODULE_SLUG !== $module_slug || ! self::get_hcm_status() ) { | |
| 111 | + return; | |
| 112 | + } | |
| 113 | + | |
| 114 | + delete_site_transient( Hub_Connector::TRANSIENT_KEY ); | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 87 | 118 | * Save settings. |
| 88 | 119 | * |
| 89 | 120 | * @param Request $request The request object containing new settings data. |
| 90 | 121 | * |
| @@ -112,9 +143,9 @@ | ||
| 112 | 143 | $message_type = 'antibot'; |
| 113 | 144 | unset( $data['module_title'] ); |
| 114 | 145 | } |
| 115 | 146 | |
| 116 | - $old_enabled = (bool) $this->model->enabled; | |
| 147 | + $old_enabled = $this->model->enabled; | |
| 117 | 148 | $old_self_unlock = $this->model->allow_self_unlock; |
| 118 | 149 | |
| 119 | 150 | $this->model->import( $data ); |
| 120 | 151 | if ( $this->model->validate() ) { |
| @@ -120,14 +151,17 @@ | ||
| 120 | 151 | if ( $this->model->validate() ) { |
| 121 | 152 | $this->model->save(); |
| 122 | 153 | Config_Hub_Helper::set_clear_active_flag(); |
| 123 | 154 | if ( 'central_ip' === $message_type ) { |
| 155 | + if ( isset( $data['enabled'] ) && $old_enabled !== $this->model->enabled ) { | |
| 156 | + $this->service->toggle_on_hosting( $this->model->enabled ); | |
| 157 | + } | |
| 124 | 158 | $message = $this->get_update_message( $data, $old_enabled, Global_Ip_Lockout::get_module_name() ); |
| 125 | 159 | } else { |
| 126 | 160 | $message = ''; |
| 127 | - if ( ! empty( $data['allow_self_unlock'] ) ) { | |
| 161 | + if ( $data['allow_self_unlock'] ?? false ) { | |
| 128 | 162 | $message = esc_html__( 'Temporary self unlock CAPTCHA challenge is enabled successfully.', 'defender-security' ); |
| 129 | - } elseif ( ! empty( $old_self_unlock ) && empty( $data['allow_self_unlock'] ) ) { | |
| 163 | + } elseif ( true === $old_self_unlock && ! ( $data['allow_self_unlock'] ?? false ) ) { | |
| 130 | 164 | $message = esc_html__( 'Temporary self unlock CAPTCHA challenge is disabled successfully.', 'defender-security' ); |
| 131 | 165 | } |
| 132 | 166 | } |
| 133 | 167 | |
| @@ -153,10 +187,10 @@ | ||
| 153 | 187 | * Enqueues scripts and styles for this page. |
| 154 | 188 | * Only enqueues assets if the page is active. |
| 155 | 189 | */ |
| 156 | 190 | public function enqueue_assets() { |
| 157 | - if ( $this->is_page_active() ) { | |
| 158 | - wp_localize_script( 'def-iplockout', 'global_ip', $this->data_frontend() ); | |
| 191 | + if ( ! $this->is_page_active() ) { | |
| 192 | + return; | |
| 159 | 193 | } |
| 160 | 194 | } |
| 161 | 195 | |
| 162 | 196 | /** |
| @@ -177,14 +211,15 @@ | ||
| 177 | 211 | esc_html__( 'Connect to a WPMU DEV account to activate %s.', 'defender-security' ), |
| 178 | 212 | Global_Ip_Lockout::get_module_name() |
| 179 | 213 | ), |
| 180 | 214 | 'is_show_dashboard_notice' => $this->service->is_show_dashboard_notice(), |
| 181 | - 'current_plan' => $this->service->get_membership_type(), | |
| 182 | 215 | 'is_expired_membership' => $this->service->is_expired_membership_type(), |
| 183 | 216 | ), |
| 184 | 217 | 'hub' => array( |
| 185 | 218 | 'global_ip_list' => $this->service->get_formated_global_ip_list(), |
| 186 | - 'global_ip_setting_url' => $this->wpmudev->get_api_base_url() . 'hub2/ip-banning', | |
| 219 | + 'global_ip_setting_url' => defender_is_unlimited_hosting() | |
| 220 | + ? wd_di()->get( Antibot_Global_Firewall::class )->get_uh_site_tools_link() | |
| 221 | + : $this->wpmudev->get_api_base_url() . 'hub2/security-center/custom-ip-list', | |
| 187 | 222 | ), |
| 188 | 223 | ), |
| 189 | 224 | $this->dump_routes_and_nonces() |
| 190 | 225 | ); |
| @@ -299,6 +334,36 @@ | ||
| 299 | 334 | * @return array An array of strings. |
| 300 | 335 | */ |
| 301 | 336 | public function export_strings() { |
| 302 | 337 | return array(); |
| 338 | + } | |
| 339 | + | |
| 340 | + /** | |
| 341 | + * Register the blocklist autosync hook after sync_state has updated the model. | |
| 342 | + * | |
| 343 | + * @return void | |
| 344 | + */ | |
| 345 | + public function maybe_register_blocklist_autosync_hook(): void { | |
| 346 | + if ( $this->service->can_blocklist_autosync() ) { | |
| 347 | + // No need to run Rate mechanism for IP lockouts because we do it in Blacklist class. | |
| 348 | + add_action( 'wd_blacklist_this_ip', array( $this, 'blacklist_an_ip' ) ); | |
| 349 | + } | |
| 350 | + } | |
| 351 | + | |
| 352 | + /** | |
| 353 | + * Sync custom ip list status with Hosting. | |
| 354 | + * | |
| 355 | + * @return void | |
| 356 | + */ | |
| 357 | + public function sync_state(): void { | |
| 358 | + $hosting_enabled = defender_get_hosting_feature_state( 'globaliplist' ); | |
| 359 | + if ( '' === $hosting_enabled ) { | |
| 360 | + return; | |
| 361 | + } | |
| 362 | + $hosting_enabled = (bool) $hosting_enabled; | |
| 363 | + if ( $hosting_enabled !== $this->model->enabled ) { | |
| 364 | + $this->model->enabled = $hosting_enabled; | |
| 365 | + $this->model->blocklist_autosync = $hosting_enabled; | |
| 366 | + $this->model->save(); | |
| 367 | + } | |
| 303 | 368 | } |
| 304 | 369 | } |