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

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

285 lines 6.9 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\Model\Lockout_Log;
16 use WP_Defender\Component\Blacklist_Lockout;
17 use WP_Defender\Model\Setting\Notfound_Lockout;
18 use WP_Defender\Component\Config\Config_Hub_Helper;
19
20 /**
21 * Handles not found lockout.
22 */
23 class Nf_Lockout extends Event {
24
25 use IP;
26 use Setting;
27
28 /**
29 * The slug identifier for this controller.
30 *
31 * @var string
32 */
33 public $slug = 'wdf-ip-lockout';
34
35 /**
36 * Service for handling logic.
37 *
38 * @var \WP_Defender\Component\Notfound_Lockout
39 */
40 protected $service;
41
42 /**
43 * The model for handling the data.
44 *
45 * @var Notfound_Lockout
46 */
47 protected $model;
48
49 /**
50 * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
51 */
52 public function __construct() {
53 $this->register_routes();
54 add_action( 'defender_enqueue_assets', array( $this, 'enqueue_assets' ) );
55 $this->model = wd_di()->get( Notfound_Lockout::class );
56 $this->service = wd_di()->get( \WP_Defender\Component\Notfound_Lockout::class );
57 $service = wd_di()->get( Blacklist_Lockout::class );
58 $ip = $this->get_user_ip();
59 if ( $this->model->enabled && ! $service->are_ips_whitelisted( $ip ) ) {
60 $this->service->add_hooks();
61 }
62 }
63
64 /**
65 * Enqueues scripts and styles for this page.
66 * Only enqueues assets if the page is active.
67 */
68 public function enqueue_assets() {
69 if ( ! $this->is_page_active() ) {
70 return;
71 }
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 = $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 $summary = Lockout_Log::get_summary();
131
132 return array_merge(
133 array(
134 'model' => $this->model->export(),
135 'misc' => array(
136 'module_name' => Notfound_Lockout::get_module_name(),
137 'hits_today' => (int) ( $summary['lockout_404_today'] ?? 0 ),
138 'lockouts_today' => (int) ( $summary['lockout_404_today'] ?? 0 ),
139 ),
140 ),
141 $this->dump_routes_and_nonces()
142 );
143 }
144
145 /**
146 * Converts the current object state to an array.
147 *
148 * @return array The array representation of the object.
149 */
150 public function to_array(): array {
151 return array();
152 }
153
154 /**
155 * Adapt the given data array by adding additional fields if necessary.
156 *
157 * @param array $data The data array to adapt.
158 *
159 * @return array The adapted data array.
160 */
161 private function adapt_data( array $data ): array {
162 $adapted_data = array();
163 if ( isset( $data['detect_404'] ) ) {
164 $adapted_data['enabled'] = $data['detect_404'];
165 }
166 if ( isset( $data['detect_404_threshold'] ) ) {
167 $adapted_data['attempt'] = $data['detect_404_threshold'];
168 }
169 if ( isset( $data['detect_404_timeframe'] ) ) {
170 $adapted_data['timeframe'] = $data['detect_404_timeframe'];
171 }
172 if ( isset( $data['detect_404_lockout_duration'] ) ) {
173 $adapted_data['duration'] = $data['detect_404_lockout_duration'];
174 }
175 if ( isset( $data['detect_404_lockout_duration_unit'] ) ) {
176 $adapted_data['duration_unit'] = $data['detect_404_lockout_duration_unit'];
177 }
178 if ( isset( $data['detect_404_lockout_ban'] ) ) {
179 $adapted_data['lockout_type'] = 'permanent' === $data['detect_404_lockout_ban'] ? 'permanent' : 'timeframe';
180 }
181 if ( isset( $data['detect_404_blacklist'] ) ) {
182 $adapted_data['blacklist'] = $data['detect_404_blacklist'];
183 }
184 if ( isset( $data['detect_404_whitelist'] ) ) {
185 $adapted_data['whitelist'] = $data['detect_404_whitelist'];
186 }
187 if ( isset( $data['detect_404_lockout_message'] ) ) {
188 $adapted_data['lockout_message'] = $data['detect_404_lockout_message'];
189 }
190 if ( isset( $data['detect_404_logged'] ) ) {
191 $adapted_data['detect_logged'] = $data['detect_404_logged'];
192 }
193
194 return array_merge( $data, $adapted_data );
195 }
196
197 /**
198 * Imports data into the model.
199 *
200 * @param array $data Data to be imported into the model.
201 */
202 public function import_data( array $data ) {
203 if ( array() !== $data ) {
204 $data = $this->adapt_data( $data );
205 $model = $this->model;
206 $model->import( $data );
207 if ( $model->validate() ) {
208 $model->save();
209 }
210 }
211 }
212
213 /**
214 * Removes settings for all submodules.
215 */
216 public function remove_settings() {
217 }
218
219 /**
220 * Delete all the data & the cache.
221 */
222 public function remove_data() {
223 }
224
225 /**
226 * Exports strings.
227 *
228 * @return array An array of strings.
229 */
230 public function export_strings(): array {
231 return array();
232 }
233
234 /**
235 * Rules for request data.
236 *
237 * @return array
238 */
239 private function request_filter_rules(): array {
240 return array(
241 'enabled' => array(
242 'type' => 'boolean',
243 ),
244 'attempt' => array(
245 'type' => 'int',
246 'sanitize' => 'sanitize_text_field',
247 ),
248 'duration' => array(
249 'type' => 'int',
250 'sanitize' => 'sanitize_text_field',
251 ),
252 'duration_unit' => array(
253 'type' => 'string',
254 'sanitize' => 'sanitize_text_field',
255 ),
256 'lockout_message' => array(
257 'type' => 'string',
258 'sanitize' => 'sanitize_text_field',
259 ),
260 'lockout_type' => array(
261 'type' => 'string',
262 'sanitize' => 'sanitize_text_field',
263 ),
264 'timeframe' => array(
265 'type' => 'int',
266 'sanitize' => 'sanitize_text_field',
267 ),
268 'blacklist' => array(
269 'type' => 'string',
270 'sanitize' => 'sanitize_textarea_field',
271 ),
272 'whitelist' => array(
273 'type' => 'string',
274 'sanitize' => array(
275 'rawurldecode',
276 'sanitize_textarea_field',
277 ),
278 ),
279 'detect_logged' => array(
280 'type' => 'boolean',
281 ),
282 );
283 }
284 }
285