PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/controller/class-ua-lockout.php +69 -43 5.6.0 → 6.3.0 View file →
@@ -7,13 +7,16 @@
7 7
8 8 namespace WP_Defender\Controller;
9 9
10 10 use Exception;
11 +use Generator;
11 12 use WP_Defender\Event;
12 13 use Calotes\Component\Request;
13 14 use Calotes\Component\Response;
14 15 use WP_Defender\Traits\Setting;
16 +use WP_Defender\Model\Lockout_Log;
15 17 use WP_Defender\Model\Setting\User_Agent_Lockout;
18 +use WP_Defender\Component\Export\Csv;
16 19 use WP_Defender\Component\Config\Config_Hub_Helper;
17 20 use WP_Defender\Component\User_Agent as User_Agent_Service;
18 21
19 22 /**
@@ -76,9 +79,8 @@
76 79 public function enqueue_assets() {
77 80 if ( ! $this->is_page_active() ) {
78 81 return;
79 82 }
80 - wp_localize_script( 'def-iplockout', 'ua_lockout', $this->data_frontend() );
81 83 }
82 84
83 85 /**
84 86 * Save settings.
@@ -90,11 +92,11 @@
90 92 * @throws Exception If the table is not defined.
91 93 */
92 94 public function save_settings( Request $request ) {
93 95 $data = $request->get_data_by_model( $this->model );
94 - $old_enabled = (bool) $this->model->enabled;
95 - $old_malicious_bot_enabled = (bool) $this->model->malicious_bot_enabled;
96 - $old_fake_bots_enabled = (bool) $this->model->fake_bots_enabled;
96 + $old_enabled = $this->model->enabled;
97 + $old_malicious_bot_enabled = $this->model->malicious_bot_enabled;
98 + $old_fake_bots_enabled = $this->model->fake_bots_enabled;
97 99 $prev_data = $this->model->export();
98 100
99 101 $this->model->import( $data );
100 102 if ( $this->model->validate() ) {
@@ -135,9 +137,9 @@
135 137 }
136 138
137 139 $this->model->save();
138 140 Config_Hub_Helper::set_clear_active_flag();
139 -
141 + // Attention: next actions after saving model changes.
140 142 if (
141 143 ( ! $this->model->enabled && $old_enabled ) ||
142 144 ( ! $this->model->malicious_bot_enabled && $old_malicious_bot_enabled )
143 145 ) {
@@ -157,9 +159,13 @@
157 159 }
158 160
159 161 // Maybe track.
160 162 if ( ! defender_is_wp_cli() ) {
161 - if ( $this->is_feature_state_changed( $prev_data, $data ) ) {
163 + // Track if UA Module is activated/deactivated OR there is a change in State on Add/Remove Custom User Agents (Allowlist/Blocklist).
164 + if ( ( $old_enabled !== $data['enabled'] )
165 + || ( $this->is_feature_state_changed( $prev_data['blacklist'], $data['blacklist'] ) )
166 + || ( $this->is_feature_state_changed( $prev_data['whitelist'], $data['whitelist'] ) )
167 + ) {
162 168 $track_data = array(
163 169 'Action' => $data['enabled'] ? 'Enabled' : 'Disabled',
164 170 'No of Bots in the Whitelist' => count( $this->model->get_lockout_list( 'allowlist', false ) ),
165 171 'No of Bots in the Blocklist' => count( $this->model->get_lockout_list( 'blocklist', false ) ),
@@ -253,15 +259,23 @@
253 259 * @return array An array of data for the frontend.
254 260 */
255 261 public function data_frontend(): array {
256 262 $arr_model = $this->model->export();
257 - $misc = array(
258 - 'no_ua' => '' === $arr_model['blacklist'] && '' === $arr_model['whitelist'],
259 - 'module_name' => User_Agent_Lockout::get_module_name(),
260 - 'blocklist_presets' => User_Agent_Service::get_blocklist_presets(),
261 - 'script_presets' => User_Agent_Service::get_script_presets(),
262 - 'show_feature_dot' => wd_di()->get( \WP_Defender\Behavior\WPMUDEV::class )->is_pro()
263 - && ! (bool) wd_di()->get( \WP_Defender\Component\Breadcrumbs::class )->get_meta_key(),
263 +
264 + // Check for empty Disallow line only if Bot Trap is enabled.
265 + $has_empty_disallow = false;
266 + if ( $this->model->enabled && $this->model->malicious_bot_enabled ) {
267 + $malicious_bot_service = wd_di()->get( \WP_Defender\Component\Malicious_Bot::class );
268 + $has_empty_disallow = $malicious_bot_service->has_empty_disallow_line();
269 + }
270 +
271 + $misc = array(
272 + 'no_ua' => '' === $arr_model['blacklist'] && '' === $arr_model['whitelist'],
273 + 'module_name' => User_Agent_Lockout::get_module_name(),
274 + 'blocklist_presets' => User_Agent_Service::get_blocklist_presets(),
275 + 'script_presets' => User_Agent_Service::get_script_presets(),
276 + 'has_empty_disallow_line' => $has_empty_disallow,
277 + 'lockouts_last_24_hours' => Lockout_Log::count_ua_lockouts_in_24_hours(),
264 278 );
265 279
266 280 return array_merge(
267 281 array(
@@ -333,34 +347,34 @@
333 347 * @defender_route
334 348 * @since 2.6.0
335 349 */
336 350 public function export_ua(): void {
337 - $data = array();
351 + try {
352 + Csv::to_browser( 'ua', $this->get_export_rows() );
353 + } catch ( \RuntimeException $e ) {
354 + $this->log( $e->getMessage(), 'ua-lockout' );
355 + }
356 + }
338 357
339 - foreach ( $this->model->get_lockout_list( 'blocklist', false ) as $ua ) {
340 - $data[] = array(
358 + /**
359 + * Generates User Agent export rows.
360 + *
361 + * @return Generator
362 + */
363 + private function get_export_rows(): Generator {
364 + foreach ( $this->model->get_lockout_list( 'allowlist', false ) as $ua ) {
365 + yield array(
341 366 'ua' => $ua,
342 - 'type' => 'blocklist',
367 + 'type' => 'allowlist',
343 368 );
344 369 }
345 - foreach ( $this->model->get_lockout_list( 'allowlist', false ) as $ua ) {
346 - $data[] = array(
370 +
371 + foreach ( $this->model->get_all_selected_blocklist_ua( false ) as $ua ) {
372 + yield array(
347 373 'ua' => $ua,
348 - 'type' => 'allowlist',
374 + 'type' => 'blocklist',
349 375 );
350 376 }
351 - // WP_Filesystem class doesn’t directly provide a function for opening a stream to php://memory with the 'w' mode.
352 - $fp = fopen( 'php://memory', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
353 - foreach ( $data as $fields ) {
354 - fputcsv( $fp, $fields, ',', '"', '\\' );
355 - }
356 - $filename = 'wdf-ua-export-' . wp_date( 'ymdHis' ) . '.csv';
357 - fseek( $fp, 0 );
358 - header( 'Content-Type: text/csv' );
359 - header( 'Content-Disposition: attachment; filename="' . $filename . '";' );
360 - // Make php send the generated csv lines to the browser.
361 - fpassthru( $fp );
362 - exit();
363 377 }
364 378
365 379 /**
366 380 * Importing UAs from exporter.
@@ -378,18 +392,27 @@
378 392 ),
379 393 )
380 394 );
381 395
382 - $attached_id = $data['id'];
383 - if ( ! is_object( get_post( $attached_id ) ) ) {
384 - return new Response(
385 - false,
386 - array( 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ) )
387 - );
396 + $file = '';
397 + $attached_id = $data['id'] ?? 0;
398 + if ( 0 < $attached_id ) {
399 + if ( ! is_object( get_post( $attached_id ) ) ) {
400 + return new Response(
401 + false,
402 + array( 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ) )
403 + );
404 + }
405 +
406 + $file = get_attached_file( $attached_id );
407 + } else {
408 + $file_data = defender_get_data_from_request( 'file', 'f' );
409 + if ( is_array( $file_data ) && isset( $file_data['tmp_name'] ) && is_uploaded_file( $file_data['tmp_name'] ) ) {
410 + $file = $file_data['tmp_name'];
411 + }
388 412 }
389 413
390 - $file = get_attached_file( $attached_id );
391 - if ( ! is_file( $file ) ) {
414 + if ( ! is_string( $file ) || '' === $file || ! is_file( $file ) ) {
392 415 return new Response(
393 416 false,
394 417 array( 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ) )
395 418 );
@@ -411,11 +434,14 @@
411 434 }
412 435
413 436 return new Response(
414 437 true,
415 - array(
416 - 'message' => esc_html__( 'Your blocklist and allowlist have been successfully imported.', 'defender-security' ),
417 - 'interval' => 1,
438 + array_merge(
439 + array(
440 + 'message' => esc_html__( 'Your blocklist and allowlist have been successfully imported.', 'defender-security' ),
441 + 'auto_close' => true,
442 + ),
443 + $this->data_frontend()
418 444 )
419 445 );
420 446 }
421 447