| @@ -34,9 +34,9 @@ | ||
| 34 | 34 | * |
| 35 | 35 | * @var bool |
| 36 | 36 | * @defender_property |
| 37 | 37 | */ |
| 38 | - public $enabled = false; | |
| 38 | + public bool $enabled = false; | |
| 39 | 39 | |
| 40 | 40 | /** |
| 41 | 41 | * Blacklist User Agents. |
| 42 | 42 | * |
| @@ -107,9 +107,9 @@ | ||
| 107 | 107 | * |
| 108 | 108 | * @var bool |
| 109 | 109 | * @defender_property |
| 110 | 110 | */ |
| 111 | - public $malicious_bot_enabled = false; | |
| 111 | + public bool $malicious_bot_enabled = false; | |
| 112 | 112 | |
| 113 | 113 | /** |
| 114 | 114 | * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. |
| 115 | 115 | * |
| @@ -151,9 +151,9 @@ | ||
| 151 | 151 | * |
| 152 | 152 | * @var bool |
| 153 | 153 | * @defender_property |
| 154 | 154 | */ |
| 155 | - public $fake_bots_enabled = false; | |
| 155 | + public bool $fake_bots_enabled = false; | |
| 156 | 156 | |
| 157 | 157 | /** |
| 158 | 158 | * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. |
| 159 | 159 | * |
| @@ -196,9 +196,9 @@ | ||
| 196 | 196 | * |
| 197 | 197 | * @var bool |
| 198 | 198 | * @defender_property |
| 199 | 199 | */ |
| 200 | - public $bot_trap_enabled = false; | |
| 200 | + public bool $bot_trap_enabled = false; | |
| 201 | 201 | |
| 202 | 202 | /** |
| 203 | 203 | * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. |
| 204 | 204 | * |
| @@ -231,9 +231,20 @@ | ||
| 231 | 231 | * |
| 232 | 232 | * @var array |
| 233 | 233 | */ |
| 234 | 234 | protected $rules = array( |
| 235 | - array( array( 'enabled', 'empty_headers', 'blocklist_presets', 'script_presets' ), 'boolean' ), | |
| 235 | + array( | |
| 236 | + array( | |
| 237 | + 'enabled', | |
| 238 | + 'empty_headers', | |
| 239 | + 'blocklist_presets', | |
| 240 | + 'script_presets', | |
| 241 | + 'malicious_bot_enabled', | |
| 242 | + 'bot_trap_enabled', | |
| 243 | + 'fake_bots_enabled', | |
| 244 | + ), | |
| 245 | + 'boolean', | |
| 246 | + ), | |
| 236 | 247 | array( array( 'malicious_bot_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ), |
| 237 | 248 | array( array( 'malicious_bot_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ), |
| 238 | 249 | array( array( 'fake_bots_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ), |
| 239 | 250 | array( array( 'fake_bots_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ), |
| @@ -292,12 +303,14 @@ | ||
| 292 | 303 | * |
| 293 | 304 | * @return bool Returns true if the User Agent Lockout feature is active, false otherwise. |
| 294 | 305 | */ |
| 295 | 306 | public function is_active(): bool { |
| 296 | - return (bool) apply_filters( | |
| 307 | + $enable = apply_filters( | |
| 297 | 308 | 'wd_user_agents_enable', |
| 298 | 309 | $this->enabled |
| 299 | 310 | ); |
| 311 | + | |
| 312 | + return is_bool( $enable ) ? $enable : (bool) $enable; | |
| 300 | 313 | } |
| 301 | 314 | |
| 302 | 315 | /** |
| 303 | 316 | * Get a list of blocklisted or allowlisted data. |
| @@ -356,10 +369,10 @@ | ||
| 356 | 369 | * |
| 357 | 370 | * @return array |
| 358 | 371 | */ |
| 359 | 372 | public function get_access_status( $ua ): array { |
| 360 | - $blocklist = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua() ); | |
| 361 | - $allowlist = str_replace( '#', '\#', $this->get_lockout_list( 'allowlist' ) ); | |
| 373 | + $blocklist = $this->get_all_selected_blocklist_ua(); | |
| 374 | + $allowlist = $this->get_lockout_list( 'allowlist' ); | |
| 362 | 375 | |
| 363 | 376 | // Escape regex special characters in each item before building the pattern. |
| 364 | 377 | $blocklist_escaped = array_map( 'preg_quote', $blocklist, array_fill( 0, count( $blocklist ), '#' ) ); |
| 365 | 378 | $allowlist_escaped = array_map( 'preg_quote', $allowlist, array_fill( 0, count( $allowlist ), '#' ) ); |
| @@ -366,12 +379,12 @@ | ||
| 366 | 379 | |
| 367 | 380 | $blocklist_regex_pattern = '#' . implode( '|', $blocklist_escaped ) . '#i'; |
| 368 | 381 | $allowlist_regex_pattern = '#' . implode( '|', $allowlist_escaped ) . '#i'; |
| 369 | 382 | |
| 370 | - $blocklist_match = preg_match( $blocklist_regex_pattern, $ua ); | |
| 371 | - $allowlist_match = preg_match( $allowlist_regex_pattern, $ua ); | |
| 383 | + $blocklist_match = count( $blocklist ) > 0 && 1 === preg_match( $blocklist_regex_pattern, $ua ); | |
| 384 | + $allowlist_match = count( $allowlist ) > 0 && 1 === preg_match( $allowlist_regex_pattern, $ua ); | |
| 372 | 385 | |
| 373 | - if ( 1 !== $blocklist_match && 1 !== $allowlist_match ) { | |
| 386 | + if ( ! $blocklist_match && ! $allowlist_match ) { | |
| 374 | 387 | return array( 'na' ); |
| 375 | 388 | } |
| 376 | 389 | |
| 377 | 390 | $result = array(); |
| @@ -376,14 +389,14 @@ | ||
| 376 | 389 | |
| 377 | 390 | $result = array(); |
| 378 | 391 | |
| 379 | 392 | // Check blocklist first - if it matches, add 'banned'. |
| 380 | - if ( 1 === $blocklist_match ) { | |
| 393 | + if ( $blocklist_match ) { | |
| 381 | 394 | $result[] = 'banned'; |
| 382 | 395 | } |
| 383 | 396 | |
| 384 | 397 | // Check allowlist - if it matches, add 'allowlist'. |
| 385 | - if ( 1 === $allowlist_match ) { | |
| 398 | + if ( $allowlist_match ) { | |
| 386 | 399 | $result[] = 'allowlist'; |
| 387 | 400 | } |
| 388 | 401 | |
| 389 | 402 | return $result; |
| @@ -389,100 +402,8 @@ | ||
| 389 | 402 | return $result; |
| 390 | 403 | } |
| 391 | 404 | |
| 392 | 405 | /** |
| 393 | - * Checks if a user agent is present in a given list. | |
| 394 | - * | |
| 395 | - * @param string $ua The user agent to check. | |
| 396 | - * @param string $collection The type of list to check against ('blocklist' or 'allowlist'). | |
| 397 | - * | |
| 398 | - * @return bool Returns true if the user agent is in the list, false otherwise. | |
| 399 | - */ | |
| 400 | - public function is_ua_in_list( $ua, $collection ): bool { | |
| 401 | - if ( 'allowlist' === $collection ) { | |
| 402 | - $arr = str_replace( '#', '\#', $this->get_lockout_list( $collection ) ); | |
| 403 | - } else { | |
| 404 | - $arr = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua() ); | |
| 405 | - } | |
| 406 | - | |
| 407 | - // Escape regex special characters in each item before building the pattern. | |
| 408 | - $arr_escaped = array_map( 'preg_quote', $arr, array_fill( 0, count( $arr ), '#' ) ); | |
| 409 | - $list_regex_pattern = '#' . implode( '|', $arr_escaped ) . '#i'; | |
| 410 | - | |
| 411 | - return 1 === preg_match( $list_regex_pattern, $ua ); | |
| 412 | - } | |
| 413 | - | |
| 414 | - /** | |
| 415 | - * Remove User Agent from a list. | |
| 416 | - * | |
| 417 | - * @param string $ua The user agent to remove. | |
| 418 | - * @param string $collection blocklist|allowlist. | |
| 419 | - * | |
| 420 | - * @return void | |
| 421 | - */ | |
| 422 | - public function remove_from_list( $ua, $collection ) { | |
| 423 | - if ( 'allowlist' === $collection ) { | |
| 424 | - $arr = $this->get_lockout_list( $collection ); | |
| 425 | - // Array can contain uppercase. | |
| 426 | - $orig_arr = str_replace( '#', '\#', $this->get_lockout_list( $collection, false ) ); | |
| 427 | - } else { | |
| 428 | - $arr = $this->get_all_selected_blocklist_ua(); | |
| 429 | - // Array can contain uppercase. | |
| 430 | - $orig_arr = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua( false ) ); | |
| 431 | - } | |
| 432 | - | |
| 433 | - $list_regex_pattern = '#' . implode( '|', $arr ) . '#i'; | |
| 434 | - $list_match = preg_match( $list_regex_pattern, $ua ); | |
| 435 | - if ( false !== $list_match ) { | |
| 436 | - if ( 'blocklist' === $collection ) { | |
| 437 | - // Check in 'Blocklist Presets'. | |
| 438 | - if ( $this->blocklist_presets ) { | |
| 439 | - $key = array_search( $ua, $this->blocklist_preset_values, true ); | |
| 440 | - if ( false !== $key ) { | |
| 441 | - unset( $this->blocklist_preset_values[ $key ] ); | |
| 442 | - $this->blocklist_preset_values = array_values( $this->blocklist_preset_values ); | |
| 443 | - } | |
| 444 | - } | |
| 445 | - // Check in 'Script Presets' using Regex. | |
| 446 | - if ( $this->script_presets ) { | |
| 447 | - if ( false !== strpos( $ua, User_Agent_Service::GO_HTTP_CLIENT_KEY . '/' ) ) { | |
| 448 | - $key_script_preset = User_Agent_Service::GO_HTTP_CLIENT_KEY; | |
| 449 | - } elseif ( false !== strpos( $ua, User_Agent_Service::PYTHON_REQUESTS_KEY . '/' ) ) { | |
| 450 | - $key_script_preset = User_Agent_Service::PYTHON_REQUESTS_KEY; | |
| 451 | - } else { | |
| 452 | - $key_script_preset = ''; | |
| 453 | - } | |
| 454 | - | |
| 455 | - $key = array_search( $key_script_preset, $this->script_preset_values, true ); | |
| 456 | - if ( false !== $key ) { | |
| 457 | - unset( $this->script_preset_values[ $key ] ); | |
| 458 | - $this->script_preset_values = array_values( $this->script_preset_values ); | |
| 459 | - } | |
| 460 | - } | |
| 461 | - // Check 'Custom User Agents' case. | |
| 462 | - $arr_blocklist = $this->get_lockout_list( 'blocklist', false ); | |
| 463 | - if ( array() !== $arr_blocklist ) { | |
| 464 | - $key = array_search( $ua, $arr_blocklist, true ); | |
| 465 | - if ( false !== $key && isset( $arr_blocklist[ $key ] ) ) { | |
| 466 | - unset( $arr_blocklist[ $key ] ); | |
| 467 | - // Convert back to string. | |
| 468 | - $this->blacklist = implode( PHP_EOL, $arr_blocklist ); | |
| 469 | - } | |
| 470 | - } | |
| 471 | - } elseif ( 'allowlist' === $collection ) { | |
| 472 | - $key = array_search( $ua, $arr, true ); | |
| 473 | - if ( false !== $key && isset( $arr[ $key ] ) ) { | |
| 474 | - unset( $arr[ $key ] ); | |
| 475 | - // Convert back to string. | |
| 476 | - $this->whitelist = implode( PHP_EOL, $arr ); | |
| 477 | - } | |
| 478 | - } | |
| 479 | - | |
| 480 | - $this->save(); | |
| 481 | - } | |
| 482 | - } | |
| 483 | - | |
| 484 | - /** | |
| 485 | 406 | * Add an UA to the list. |
| 486 | 407 | * |
| 487 | 408 | * @param string $ua User agent name. |
| 488 | 409 | * @param string $collection blocklist|allowlist. |
| @@ -526,17 +447,17 @@ | ||
| 526 | 447 | /** |
| 527 | 448 | * Filter the UAs, as we use a textarea to submit, so it can contain some un-valid UAs. |
| 528 | 449 | */ |
| 529 | 450 | protected function after_validate(): void { |
| 530 | - $lists = array( | |
| 531 | - 'blacklist' => $this->get_lockout_list( 'blocklist' ), | |
| 532 | - 'whitelist' => $this->get_lockout_list( 'allowlist' ), | |
| 451 | + $this->blacklist = implode( | |
| 452 | + PHP_EOL, | |
| 453 | + array_filter( $this->get_lockout_list( 'blocklist' ), 'strlen' ) | |
| 533 | 454 | ); |
| 534 | 455 | |
| 535 | - foreach ( $lists as $key => &$collection ) { | |
| 536 | - // If UA collection is not valid, we should display an error message. We'll improve it by UA standard/pattern. | |
| 537 | - $this->$key = implode( PHP_EOL, array_filter( $collection, 'strlen' ) ); | |
| 538 | - } | |
| 456 | + $this->whitelist = implode( | |
| 457 | + PHP_EOL, | |
| 458 | + array_filter( $this->get_lockout_list( 'allowlist' ), 'strlen' ) | |
| 459 | + ); | |
| 539 | 460 | } |
| 540 | 461 | |
| 541 | 462 | /** |
| 542 | 463 | * Get the module name. |