PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.3.1
Defender Security – Malware Scanner, Login Security & Firewall v5.3.1
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
defender-security / src / controller / class-nf-lockout.php

class-nf-lockout.php in Defender Security – Malware Scanner, Login Security & Firewall 5.3.1, at src/controller/class-nf-lockout.php

279 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles not found lockout.
4 *
5 * @package WP_Defender\Controller
6 */
7
8 namespace WP_Defender\Controller;
9
10 use WP_Defender\Event;
11 use WP_Defender\Traits\IP;
12 use Calotes\Component\Request;
13 use Calotes\Component\Response;
14 use WP_Defender\Traits\Setting;
15 use WP_Defender\Component\Blacklist_Lockout;
16 use WP_Defender\Model\Setting\Notfound_Lockout;
17 use WP_Defender\Component\Config\Config_Hub_Helper;
18
19 /**
20 * Handles not found lockout.
21 */
22 class Nf_Lockout extends Event {
23
24 use IP;
25 use Setting;
26
27 /**
28 * The slug identifier for this controller.
29 *
30 * @var string
31 */
32 public $slug = 'wdf-ip-lockout';
33
34 /**
35 * Service for handling logic.
36 *
37 * @var \WP_Defender\Component\Notfound_Lockout
38 */
39 protected $service;
40
41 /**
42 * The model for handling the data.
43 *
44 * @var Notfound_Lockout
45 */
46 protected $model;
47
48 /**
49 * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
50 */
51 public function __construct() {
52 $this->register_routes();
53 add_action( 'defender_enqueue_assets', array( $this, 'enqueue_assets' ) );
54 $this->model = wd_di()->get( Notfound_Lockout::class );
55 $this->service = wd_di()->get( \WP_Defender\Component\Notfound_Lockout::class );
56 $service = wd_di()->get( Blacklist_Lockout::class );
57 $ip = $this->get_user_ip();
58 if ( $this->model->enabled && ! $service->are_ips_whitelisted( $ip ) ) {
59 $this->service->add_hooks();
60 }
61 }
62
63 /**
64 * Enqueues scripts and styles for this page.
65 * Only enqueues assets if the page is active.
66 */
67 public function enqueue_assets() {
68 if ( ! $this->is_page_active() ) {
69 return;
70 }
71 wp_localize_script( 'def-iplockout', 'nf_lockout', $this->data_frontend() );
72 }
73
74 /**
75 * Save settings.
76 *
77 * @param Request $request The request object containing new settings data.
78 *
79 * @return Response
80 * @defender_route
81 */
82 public function save_settings( Request $request ) {
83 $data = $request->get_data( $this->request_filter_rules() );
84 $old_enabled = (bool) $this->model->enabled;
85 $prev_data = $this->model->export();
86
87 $this->model->import( $data );
88 if ( $this->model->validate() ) {
89 $this->model->save();
90 Config_Hub_Helper::set_clear_active_flag();
91 // Maybe track.
92 if ( ! defender_is_wp_cli() && $this->is_feature_state_changed( $prev_data, $data ) ) {
93 $track_data = array(
94 'Action' => $data['enabled'] ? 'Enabled' : 'Disabled',
95 'Duration' => 'timeframe' === $data['lockout_type'] ? 'Temporary' : 'Permanent',
96 );
97 $this->track_feature( 'def_404_detection', $track_data );
98 }
99
100 return new Response(
101 true,
102 array_merge(
103 array(
104 'message' => $this->get_update_message(
105 $data,
106 $old_enabled,
107 Notfound_Lockout::get_module_name()
108 ),
109 'auto_close' => true,
110 ),
111 $this->data_frontend()
112 )
113 );
114 }
115
116 return new Response(
117 false,
118 array(
119 'message' => $this->model->get_formatted_errors(),
120 )
121 );
122 }
123
124 /**
125 * Provides data for the frontend.
126 *
127 * @return array An array of data for the frontend.
128 */
129 public function data_frontend(): array {
130 return array_merge(
131 array(
132 'model' => $this->model->export(),
133 'misc' => array( 'module_name' => Notfound_Lockout::get_module_name() ),
134 ),
135 $this->dump_routes_and_nonces()
136 );
137 }
138
139 /**
140 * Converts the current object state to an array.
141 *
142 * @return array The array representation of the object.
143 */
144 public function to_array(): array {
145 return array();
146 }
147
148 /**
149 * Adapt the given data array by adding additional fields if necessary.
150 *
151 * @param array $data The data array to adapt.
152 *
153 * @return array The adapted data array.
154 */
155 private function adapt_data( array $data ): array {
156 $adapted_data = array();
157 if ( isset( $data['detect_404'] ) ) {
158 $adapted_data['enabled'] = $data['detect_404'];
159 }
160 if ( isset( $data['detect_404_threshold'] ) ) {
161 $adapted_data['attempt'] = $data['detect_404_threshold'];
162 }
163 if ( isset( $data['detect_404_timeframe'] ) ) {
164 $adapted_data['timeframe'] = $data['detect_404_timeframe'];
165 }
166 if ( isset( $data['detect_404_lockout_duration'] ) ) {
167 $adapted_data['duration'] = $data['detect_404_lockout_duration'];
168 }
169 if ( isset( $data['detect_404_lockout_duration_unit'] ) ) {
170 $adapted_data['duration_unit'] = $data['detect_404_lockout_duration_unit'];
171 }
172 if ( isset( $data['detect_404_lockout_ban'] ) ) {
173 $adapted_data['lockout_type'] = 'permanent' === $data['detect_404_lockout_ban'] ? 'permanent' : 'timeframe';
174 }
175 if ( isset( $data['detect_404_blacklist'] ) ) {
176 $adapted_data['blacklist'] = $data['detect_404_blacklist'];
177 }
178 if ( isset( $data['detect_404_whitelist'] ) ) {
179 $adapted_data['whitelist'] = $data['detect_404_whitelist'];
180 }
181 if ( isset( $data['detect_404_lockout_message'] ) ) {
182 $adapted_data['lockout_message'] = $data['detect_404_lockout_message'];
183 }
184 if ( isset( $data['detect_404_logged'] ) ) {
185 $adapted_data['detect_logged'] = $data['detect_404_logged'];
186 }
187
188 return array_merge( $data, $adapted_data );
189 }
190
191 /**
192 * Imports data into the model.
193 *
194 * @param array $data Data to be imported into the model.
195 */
196 public function import_data( array $data ) {
197 if ( ! empty( $data ) ) {
198 $data = $this->adapt_data( $data );
199 $model = $this->model;
200 $model->import( $data );
201 if ( $model->validate() ) {
202 $model->save();
203 }
204 }
205 }
206
207 /**
208 * Removes settings for all submodules.
209 */
210 public function remove_settings() {
211 }
212
213 /**
214 * Delete all the data & the cache.
215 */
216 public function remove_data() {
217 }
218
219 /**
220 * Exports strings.
221 *
222 * @return array An array of strings.
223 */
224 public function export_strings(): array {
225 return array();
226 }
227
228 /**
229 * Rules for request data.
230 *
231 * @return array
232 */
233 private function request_filter_rules(): array {
234 return array(
235 'enabled' => array(
236 'type' => 'boolean',
237 ),
238 'attempt' => array(
239 'type' => 'int',
240 'sanitize' => 'sanitize_text_field',
241 ),
242 'duration' => array(
243 'type' => 'int',
244 'sanitize' => 'sanitize_text_field',
245 ),
246 'duration_unit' => array(
247 'type' => 'string',
248 'sanitize' => 'sanitize_text_field',
249 ),
250 'lockout_message' => array(
251 'type' => 'string',
252 'sanitize' => 'sanitize_text_field',
253 ),
254 'lockout_type' => array(
255 'type' => 'string',
256 'sanitize' => 'sanitize_text_field',
257 ),
258 'timeframe' => array(
259 'type' => 'int',
260 'sanitize' => 'sanitize_text_field',
261 ),
262 'blacklist' => array(
263 'type' => 'string',
264 'sanitize' => 'sanitize_textarea_field',
265 ),
266 'whitelist' => array(
267 'type' => 'string',
268 'sanitize' => array(
269 'rawurldecode',
270 'sanitize_textarea_field',
271 ),
272 ),
273 'detect_logged' => array(
274 'type' => 'boolean',
275 ),
276 );
277 }
278 }
279