| @@ -7,13 +7,21 @@ | ||
| 7 | 7 | |
| 8 | 8 | namespace WP_Defender\Model\Setting; |
| 9 | 9 | |
| 10 | 10 | use Calotes\Model\Setting; |
| 11 | +use WP_Defender\Component\User_Agent as User_Agent_Service; | |
| 11 | 12 | |
| 12 | 13 | /** |
| 13 | 14 | * Model for user agent lockout settings. |
| 15 | + * | |
| 16 | + * Since with v5.4.0 blocklisted UA has groups: | |
| 17 | + * 'Blocklist Presets' is associated with the properties $blocklist_presets & $blocklist_preset_values, | |
| 18 | + * 'Scripts Presets' is associated with the properties $script_presets & $script_preset_values, | |
| 19 | + * 'Custom User Agents' is associated with the property $blacklist. | |
| 14 | 20 | */ |
| 15 | 21 | class User_Agent_Lockout extends Setting { |
| 22 | + const BOT_LOCKOUT_TYPE_ALLOWED = array( 'temporary', 'permanent' ); | |
| 23 | + const BOT_LOCKOUT_DURATION_UNIT_ALLOWED = array( 'seconds', 'minutes', 'hours' ); | |
| 16 | 24 | |
| 17 | 25 | /** |
| 18 | 26 | * Option name. |
| 19 | 27 | * |
| @@ -21,14 +29,14 @@ | ||
| 21 | 29 | */ |
| 22 | 30 | protected $table = 'wd_user_agent_settings'; |
| 23 | 31 | |
| 24 | 32 | /** |
| 25 | - * Is module enabled. | |
| 33 | + * Is module enabled? | |
| 26 | 34 | * |
| 27 | 35 | * @var bool |
| 28 | 36 | * @defender_property |
| 29 | 37 | */ |
| 30 | - public $enabled = false; | |
| 38 | + public bool $enabled = false; | |
| 31 | 39 | |
| 32 | 40 | /** |
| 33 | 41 | * Blacklist User Agents. |
| 34 | 42 | * |
| @@ -62,14 +70,185 @@ | ||
| 62 | 70 | */ |
| 63 | 71 | public $empty_headers = false; |
| 64 | 72 | |
| 65 | 73 | /** |
| 74 | + * Is blocklist presets enabled? | |
| 75 | + * | |
| 76 | + * @var bool | |
| 77 | + * @defender_property | |
| 78 | + */ | |
| 79 | + public $blocklist_presets = true; | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * The list of Blocklist presets. | |
| 83 | + * | |
| 84 | + * @var array | |
| 85 | + * @defender_property | |
| 86 | + */ | |
| 87 | + public $blocklist_preset_values = array(); | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * Is script presets enabled? | |
| 91 | + * | |
| 92 | + * @var bool | |
| 93 | + * @defender_property | |
| 94 | + */ | |
| 95 | + public $script_presets = false; | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * The list of Script presets. | |
| 99 | + * | |
| 100 | + * @var array | |
| 101 | + * @defender_property | |
| 102 | + */ | |
| 103 | + public $script_preset_values = array(); | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Is malicious bot enabled? | |
| 107 | + * | |
| 108 | + * @var bool | |
| 109 | + * @defender_property | |
| 110 | + */ | |
| 111 | + public bool $malicious_bot_enabled = false; | |
| 112 | + | |
| 113 | + /** | |
| 114 | + * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. | |
| 115 | + * | |
| 116 | + * @var string | |
| 117 | + * @defender_property | |
| 118 | + * @rule in[temporary,permanent] | |
| 119 | + */ | |
| 120 | + public $malicious_bot_lockout_type = 'temporary'; | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * Duration for the lockout. | |
| 124 | + * | |
| 125 | + * @var int | |
| 126 | + * @defender_property | |
| 127 | + * @rule required|integer | |
| 128 | + */ | |
| 129 | + public $malicious_bot_lockout_duration = 300; | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * Duration unit. | |
| 133 | + * | |
| 134 | + * @var string | |
| 135 | + * @defender_property | |
| 136 | + * @rule in[seconds,minutes,hours] | |
| 137 | + */ | |
| 138 | + public $malicious_bot_lockout_duration_unit = 'seconds'; | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * The message to show on frontend when a malicious bot is triggered. | |
| 142 | + * | |
| 143 | + * @var string | |
| 144 | + * @defender_property | |
| 145 | + * @sanitize sanitize_textarea_field | |
| 146 | + */ | |
| 147 | + public $malicious_bot_message = ''; | |
| 148 | + | |
| 149 | + /** | |
| 150 | + * Is fake bots enabled? | |
| 151 | + * | |
| 152 | + * @var bool | |
| 153 | + * @defender_property | |
| 154 | + */ | |
| 155 | + public bool $fake_bots_enabled = false; | |
| 156 | + | |
| 157 | + /** | |
| 158 | + * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. | |
| 159 | + * | |
| 160 | + * @var string | |
| 161 | + * @defender_property | |
| 162 | + * @rule in[temporary,permanent] | |
| 163 | + */ | |
| 164 | + public $fake_bots_lockout_type = 'temporary'; | |
| 165 | + | |
| 166 | + /** | |
| 167 | + * Duration for the lockout. | |
| 168 | + * | |
| 169 | + * @var int | |
| 170 | + * @defender_property | |
| 171 | + * @rule required|integer | |
| 172 | + */ | |
| 173 | + public $fake_bots_lockout_duration = 300; | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Duration unit. | |
| 177 | + * | |
| 178 | + * @var string | |
| 179 | + * @defender_property | |
| 180 | + * @rule in[seconds,minutes,hours] | |
| 181 | + */ | |
| 182 | + public $fake_bots_lockout_duration_unit = 'seconds'; | |
| 183 | + | |
| 184 | + /** | |
| 185 | + * The message to show on frontend when a fake bot is triggered. | |
| 186 | + * | |
| 187 | + * @var string | |
| 188 | + * @defender_property | |
| 189 | + * @sanitize sanitize_textarea_field | |
| 190 | + */ | |
| 191 | + public $fake_bots_message = ''; | |
| 192 | + | |
| 193 | + /** | |
| 194 | + * Old properties of the Bot Trap option for backward compatibility. We can remove them in future versions. | |
| 195 | + * Is bot trap enabled? | |
| 196 | + * | |
| 197 | + * @var bool | |
| 198 | + * @defender_property | |
| 199 | + */ | |
| 200 | + public bool $bot_trap_enabled = false; | |
| 201 | + | |
| 202 | + /** | |
| 203 | + * How the lock is going to be, if we choose permanent, then their IP will be blacklisted. | |
| 204 | + * | |
| 205 | + * @var string | |
| 206 | + * @defender_property | |
| 207 | + * @rule in[temporary,permanent] | |
| 208 | + */ | |
| 209 | + public $bot_trap_lockout_type = 'temporary'; | |
| 210 | + | |
| 211 | + /** | |
| 212 | + * Duration for the lockout. | |
| 213 | + * | |
| 214 | + * @var int | |
| 215 | + * @defender_property | |
| 216 | + * @rule required|integer | |
| 217 | + */ | |
| 218 | + public $bot_trap_lockout_duration = 300; | |
| 219 | + | |
| 220 | + /** | |
| 221 | + * Duration unit. | |
| 222 | + * | |
| 223 | + * @var string | |
| 224 | + * @defender_property | |
| 225 | + * @rule in[seconds,minutes,hours] | |
| 226 | + */ | |
| 227 | + public $bot_trap_lockout_duration_unit = 'seconds'; | |
| 228 | + | |
| 229 | + /** | |
| 66 | 230 | * Rules for validation. |
| 67 | 231 | * |
| 68 | 232 | * @var array |
| 69 | 233 | */ |
| 70 | 234 | protected $rules = array( |
| 71 | - array( array( 'enabled', 'empty_headers' ), '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 | + ), | |
| 247 | + array( array( 'malicious_bot_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ), | |
| 248 | + array( array( 'malicious_bot_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ), | |
| 249 | + array( array( 'fake_bots_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ), | |
| 250 | + array( array( 'fake_bots_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ), | |
| 72 | 251 | ); |
| 73 | 252 | |
| 74 | 253 | /** |
| 75 | 254 | * Get default values. |
| @@ -82,14 +261,21 @@ | ||
| 82 | 261 | $whitelist .= "\nbutterfly\ncloudflare\nchrome\nduckduckbot\nembedly\nfacebookexternalhit\nfacebot\ngoogle page speed"; |
| 83 | 262 | $whitelist .= "\ngooglebot\nia_archiver\nlinkedinbot\nmediapartners-google\nmsnbot\nnetcraftsurvey"; |
| 84 | 263 | $whitelist .= "\noutbrain\npinterest\nquora\nslackbot\nslurp\ntweetmemebot\ntwitterbot\nuptimerobot"; |
| 85 | 264 | $whitelist .= "\nurlresolver\nvkshare\nw3c_validator\nwordpress\nwp rocket\nyandex"; |
| 265 | + $message = esc_html__( 'You have been blocked from accessing this website.', 'defender-security' ); | |
| 86 | 266 | |
| 87 | 267 | return array( |
| 88 | - 'message' => esc_html__( 'You have been blocked from accessing this website.', 'defender-security' ), | |
| 89 | - 'whitelist' => $whitelist, | |
| 268 | + 'message' => $message, | |
| 269 | + 'malicious_bot_message' => $message, | |
| 270 | + 'fake_bots_message' => $message, | |
| 271 | + 'whitelist' => $whitelist, | |
| 90 | 272 | // Blocked User Agents. |
| 91 | - 'blacklist' => "MJ12Bot\nDotBot", | |
| 273 | + 'blacklist' => '', | |
| 274 | + 'blocklist_presets' => true, | |
| 275 | + 'blocklist_preset_values' => array( 'mj12bot', 'dotbot' ), | |
| 276 | + 'script_presets' => false, | |
| 277 | + 'script_preset_values' => array(), | |
| 92 | 278 | ); |
| 93 | 279 | } |
| 94 | 280 | |
| 95 | 281 | /** |
| @@ -99,12 +285,18 @@ | ||
| 99 | 285 | * |
| 100 | 286 | * @return void |
| 101 | 287 | */ |
| 102 | 288 | protected function before_load(): void { |
| 103 | - $default_values = $this->get_default_values(); | |
| 104 | - $this->message = $default_values['message']; | |
| 105 | - $this->whitelist = $default_values['whitelist']; | |
| 106 | - $this->blacklist = $default_values['blacklist']; | |
| 289 | + $default_values = $this->get_default_values(); | |
| 290 | + $this->message = $default_values['message']; | |
| 291 | + $this->whitelist = $default_values['whitelist']; | |
| 292 | + $this->blacklist = $default_values['blacklist']; | |
| 293 | + $this->blocklist_presets = $default_values['blocklist_presets']; | |
| 294 | + $this->blocklist_preset_values = $default_values['blocklist_preset_values']; | |
| 295 | + $this->script_presets = $default_values['script_presets']; | |
| 296 | + $this->script_preset_values = $default_values['script_preset_values']; | |
| 297 | + $this->malicious_bot_message = $default_values['malicious_bot_message']; | |
| 298 | + $this->fake_bots_message = $default_values['fake_bots_message']; | |
| 107 | 299 | } |
| 108 | 300 | |
| 109 | 301 | /** |
| 110 | 302 | * Checks if the User Agent Lockout feature is active. |
| @@ -111,31 +303,49 @@ | ||
| 111 | 303 | * |
| 112 | 304 | * @return bool Returns true if the User Agent Lockout feature is active, false otherwise. |
| 113 | 305 | */ |
| 114 | 306 | public function is_active(): bool { |
| 115 | - return (bool) apply_filters( | |
| 307 | + $enable = apply_filters( | |
| 116 | 308 | 'wd_user_agents_enable', |
| 117 | 309 | $this->enabled |
| 118 | 310 | ); |
| 311 | + | |
| 312 | + return is_bool( $enable ) ? $enable : (bool) $enable; | |
| 119 | 313 | } |
| 120 | 314 | |
| 121 | 315 | /** |
| 122 | - * Get list of blocklisted or allowlisted data. | |
| 316 | + * Get a list of blocklisted or allowlisted data. | |
| 123 | 317 | * |
| 124 | - * @param string $type blocklist|allowlist. | |
| 318 | + * @param string $type blocklist|allowlist. | |
| 125 | 319 | * @param bool $lower Whether to convert the list to lowercase. |
| 126 | 320 | * |
| 127 | 321 | * @return array |
| 128 | 322 | */ |
| 129 | 323 | public function get_lockout_list( $type = 'blocklist', $lower = true ): array { |
| 130 | - $data = ( 'blocklist' === $type ) ? $this->blacklist : $this->whitelist; | |
| 131 | - $arr = is_array( $data ) ? $data : array_filter( preg_split( "/\r\n|\n|\r/", $data ) ); | |
| 132 | - $arr = array_map( 'trim', $arr ); | |
| 324 | + $data = 'blocklist' === $type ? $this->blacklist : $this->whitelist; | |
| 325 | + $data = trim( $data ); | |
| 326 | + | |
| 327 | + if ( '' === $data ) { | |
| 328 | + return array(); | |
| 329 | + } | |
| 330 | + | |
| 331 | + $arr = preg_split( "/\r\n|\n|\r/", $data ); | |
| 332 | + if ( ! is_array( $arr ) ) { | |
| 333 | + return array(); | |
| 334 | + } | |
| 335 | + | |
| 133 | 336 | if ( $lower ) { |
| 134 | - $arr = array_map( 'strtolower', $arr ); | |
| 337 | + $arr = array_map( | |
| 338 | + function ( $value ) { | |
| 339 | + return strtolower( trim( $value ) ); | |
| 340 | + }, | |
| 341 | + $arr | |
| 342 | + ); | |
| 343 | + } else { | |
| 344 | + $arr = array_map( 'trim', $arr ); | |
| 135 | 345 | } |
| 136 | 346 | |
| 137 | - return $arr; | |
| 347 | + return array_unique( $arr ); | |
| 138 | 348 | } |
| 139 | 349 | |
| 140 | 350 | /** |
| 141 | 351 | * Define settings labels. |
| @@ -159,28 +369,34 @@ | ||
| 159 | 369 | * |
| 160 | 370 | * @return array |
| 161 | 371 | */ |
| 162 | 372 | public function get_access_status( $ua ): array { |
| 163 | - $blocklist = str_replace( '#', '\#', $this->get_lockout_list( 'blocklist' ) ); | |
| 164 | - $allowlist = str_replace( '#', '\#', $this->get_lockout_list( 'allowlist' ) ); | |
| 373 | + $blocklist = $this->get_all_selected_blocklist_ua(); | |
| 374 | + $allowlist = $this->get_lockout_list( 'allowlist' ); | |
| 165 | 375 | |
| 166 | - $blocklist_regex_pattern = '#' . implode( '|', $blocklist ) . '#i'; | |
| 167 | - $allowlist_regex_pattern = '#' . implode( '|', $allowlist ) . '#i'; | |
| 376 | + // Escape regex special characters in each item before building the pattern. | |
| 377 | + $blocklist_escaped = array_map( 'preg_quote', $blocklist, array_fill( 0, count( $blocklist ), '#' ) ); | |
| 378 | + $allowlist_escaped = array_map( 'preg_quote', $allowlist, array_fill( 0, count( $allowlist ), '#' ) ); | |
| 168 | 379 | |
| 169 | - $blocklist_match = preg_match( $blocklist_regex_pattern, $ua ); | |
| 170 | - $allowlist_match = preg_match( $allowlist_regex_pattern, $ua ); | |
| 380 | + $blocklist_regex_pattern = '#' . implode( '|', $blocklist_escaped ) . '#i'; | |
| 381 | + $allowlist_regex_pattern = '#' . implode( '|', $allowlist_escaped ) . '#i'; | |
| 171 | 382 | |
| 172 | - if ( empty( $blocklist_match ) && empty( $allowlist_match ) ) { | |
| 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 ); | |
| 173 | 385 | |
| 386 | + if ( ! $blocklist_match && ! $allowlist_match ) { | |
| 174 | 387 | return array( 'na' ); |
| 175 | 388 | } |
| 176 | 389 | |
| 177 | 390 | $result = array(); |
| 178 | 391 | |
| 179 | - if ( ! empty( $blocklist_match ) && empty( $allowlist_match ) ) { | |
| 392 | + // Check blocklist first - if it matches, add 'banned'. | |
| 393 | + if ( $blocklist_match ) { | |
| 180 | 394 | $result[] = 'banned'; |
| 181 | 395 | } |
| 182 | - if ( ! empty( $allowlist_match ) ) { | |
| 396 | + | |
| 397 | + // Check allowlist - if it matches, add 'allowlist'. | |
| 398 | + if ( $allowlist_match ) { | |
| 183 | 399 | $result[] = 'allowlist'; |
| 184 | 400 | } |
| 185 | 401 | |
| 186 | 402 | return $result; |
| @@ -186,74 +402,8 @@ | ||
| 186 | 402 | return $result; |
| 187 | 403 | } |
| 188 | 404 | |
| 189 | 405 | /** |
| 190 | - * Checks if a user agent is present in a given list. | |
| 191 | - * | |
| 192 | - * @param string $ua The user agent to check. | |
| 193 | - * @param string $collection The type of list to check against ('blocklist' or 'allowlist'). | |
| 194 | - * | |
| 195 | - * @return bool Returns true if the user agent is in the list, false otherwise. | |
| 196 | - */ | |
| 197 | - public function is_ua_in_list( $ua, $collection ): bool { | |
| 198 | - $arr = str_replace( '#', '\#', $this->get_lockout_list( $collection ) ); | |
| 199 | - | |
| 200 | - $list_regex_pattern = '#' . implode( '|', $arr ) . '#i'; | |
| 201 | - | |
| 202 | - $list_match = preg_match( $list_regex_pattern, $ua ); | |
| 203 | - | |
| 204 | - return ! empty( $list_match ); | |
| 205 | - } | |
| 206 | - | |
| 207 | - /** | |
| 208 | - * Remove User Agent from a list. | |
| 209 | - * | |
| 210 | - * @param string $ua The user agent to remove. | |
| 211 | - * @param string $collection blocklist|allowlist. | |
| 212 | - * | |
| 213 | - * @return void | |
| 214 | - */ | |
| 215 | - public function remove_from_list( $ua, $collection ) { | |
| 216 | - $arr = $this->get_lockout_list( $collection ); | |
| 217 | - // Array can contain uppercase. | |
| 218 | - $orig_arr = str_replace( '#', '\#', $this->get_lockout_list( $collection, false ) ); | |
| 219 | - | |
| 220 | - $list_regex_pattern = '#' . implode( '|', $arr ) . '#i'; | |
| 221 | - | |
| 222 | - $list_match = preg_match( $list_regex_pattern, $ua ); | |
| 223 | - | |
| 224 | - if ( false !== $list_match ) { | |
| 225 | - | |
| 226 | - // Plain string match. For e.g. r.n regex matches ran & run but we can add/block UA string name if user send the useragent name as run then we include that in allowlist so run won't be blocked but ran will be blocked. | |
| 227 | - $key = array_search( $ua, $arr, true ); | |
| 228 | - | |
| 229 | - if ( false !== $key && isset( $orig_arr[ $key ] ) ) { | |
| 230 | - unset( $orig_arr[ $key ] ); | |
| 231 | - $is_string_match = true; | |
| 232 | - } else { | |
| 233 | - // If plain string not matched then add the user agent in opposite list if unban is clicked then add that string to allow list, else if ban user agent clicked then add that string to blocklist though allow list take higher priority i.e. in allow list r.n present then adding r.n or run or ran in blocklist won't block the user agent because of priority. | |
| 234 | - $is_string_match = false; | |
| 235 | - } | |
| 236 | - | |
| 237 | - if ( 'blocklist' === $collection ) { | |
| 238 | - $this->blacklist = implode( PHP_EOL, $orig_arr ); | |
| 239 | - | |
| 240 | - if ( false === $is_string_match ) { | |
| 241 | - $this->whitelist = $this->push_ua_to_list( $ua, 'allowlist' ); | |
| 242 | - } | |
| 243 | - } elseif ( 'allowlist' === $collection ) { | |
| 244 | - $this->whitelist = implode( PHP_EOL, $orig_arr ); | |
| 245 | - | |
| 246 | - if ( false === $is_string_match ) { | |
| 247 | - $this->blacklist = $this->push_ua_to_list( $ua, 'blocklist' ); | |
| 248 | - } | |
| 249 | - } | |
| 250 | - | |
| 251 | - $this->save(); | |
| 252 | - } | |
| 253 | - } | |
| 254 | - | |
| 255 | - /** | |
| 256 | 406 | * Add an UA to the list. |
| 257 | 407 | * |
| 258 | 408 | * @param string $ua User agent name. |
| 259 | 409 | * @param string $collection blocklist|allowlist. |
| @@ -261,9 +411,17 @@ | ||
| 261 | 411 | * @return void |
| 262 | 412 | */ |
| 263 | 413 | public function add_to_list( $ua, $collection ) { |
| 264 | 414 | if ( 'blocklist' === $collection ) { |
| 265 | - $this->blacklist = $this->push_ua_to_list( $ua, $collection ); | |
| 415 | + if ( User_Agent_Service::is_blocklist_presets( $ua ) ) { | |
| 416 | + $this->blocklist_presets = true; | |
| 417 | + $this->blocklist_preset_values[] = $ua; | |
| 418 | + } elseif ( User_Agent_Service::is_script_presets( $ua ) ) { | |
| 419 | + $this->script_presets = true; | |
| 420 | + $this->script_preset_values[] = $ua; | |
| 421 | + } else { | |
| 422 | + $this->blacklist = $this->push_ua_to_list( $ua, $collection ); | |
| 423 | + } | |
| 266 | 424 | } elseif ( 'allowlist' === $collection ) { |
| 267 | 425 | $this->whitelist = $this->push_ua_to_list( $ua, $collection ); |
| 268 | 426 | } |
| 269 | 427 | |
| @@ -270,9 +428,9 @@ | ||
| 270 | 428 | $this->save(); |
| 271 | 429 | } |
| 272 | 430 | |
| 273 | 431 | /** |
| 274 | - * Push the UA to either blocklist or allowlist | |
| 432 | + * Push the UA to either blocklist (only in 'Custom User Agents') or allowlist | |
| 275 | 433 | * |
| 276 | 434 | * @param string $ua User agent name. |
| 277 | 435 | * @param string $collection List type i.e. blocklist or allowlist. |
| 278 | 436 | * |
| @@ -286,8 +444,23 @@ | ||
| 286 | 444 | return implode( PHP_EOL, $arr ); |
| 287 | 445 | } |
| 288 | 446 | |
| 289 | 447 | /** |
| 448 | + * Filter the UAs, as we use a textarea to submit, so it can contain some un-valid UAs. | |
| 449 | + */ | |
| 450 | + protected function after_validate(): void { | |
| 451 | + $this->blacklist = implode( | |
| 452 | + PHP_EOL, | |
| 453 | + array_filter( $this->get_lockout_list( 'blocklist' ), 'strlen' ) | |
| 454 | + ); | |
| 455 | + | |
| 456 | + $this->whitelist = implode( | |
| 457 | + PHP_EOL, | |
| 458 | + array_filter( $this->get_lockout_list( 'allowlist' ), 'strlen' ) | |
| 459 | + ); | |
| 460 | + } | |
| 461 | + | |
| 462 | + /** | |
| 290 | 463 | * Get the module name. |
| 291 | 464 | * |
| 292 | 465 | * @return string |
| 293 | 466 | */ |
| @@ -303,6 +476,30 @@ | ||
| 303 | 476 | * @return string |
| 304 | 477 | */ |
| 305 | 478 | public static function get_module_state( $flag ): string { |
| 306 | 479 | return $flag ? esc_html__( 'active', 'defender-security' ) : esc_html__( 'inactive', 'defender-security' ); |
| 480 | + } | |
| 481 | + | |
| 482 | + /** | |
| 483 | + * Get the list of all selected blocklisted UA values. | |
| 484 | + * | |
| 485 | + * @param bool $lower Whether to convert the list to lowercase. | |
| 486 | + * | |
| 487 | + * @return array | |
| 488 | + */ | |
| 489 | + public function get_all_selected_blocklist_ua( $lower = true ): array { | |
| 490 | + $blocklist_custom = $this->get_lockout_list( 'blocklist', $lower ); | |
| 491 | + $blocklist_presets = $this->blocklist_presets ? $this->blocklist_preset_values : array(); | |
| 492 | + $script_presets = $this->script_presets ? $this->script_preset_values : array(); | |
| 493 | + | |
| 494 | + return array_merge( $blocklist_custom, $blocklist_presets, $script_presets ); | |
| 495 | + } | |
| 496 | + | |
| 497 | + /** | |
| 498 | + * Return the module slug. | |
| 499 | + * | |
| 500 | + * @return string | |
| 501 | + */ | |
| 502 | + public static function get_module_slug(): string { | |
| 503 | + return 'ua-lockout'; | |
| 307 | 504 | } |
| 308 | 505 | } |