PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.1.0
Defender Security – Malware Scanner, Login Security & Firewall v3.1.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 / central.php

central.php in Defender Security – Malware Scanner, Login Security & Firewall 3.1.0, at src/central.php

228 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender;
4
5 use Calotes\Component\Request;
6 use Calotes\Component\Response;
7 use Calotes\Helper\HTTP;
8 use WP_Defender\Traits\IO;
9 use WP_Defender\Traits\Permission;
10
11 /**
12 * This class will act as a central manager, every request must go through this.
13 * Also, it should manage the data state of every model too.
14 *
15 * Class Central
16 * @package WP_Defender
17 */
18 class Central extends Component {
19 use IO, Permission;
20
21 public const ACTION = 'wp_defender/v1/hub/';
22 /**
23 * This will hold the db data of each module, all data must be getting through this.
24 * @var array
25 */
26 protected $states = [];
27
28 /**
29 * This should be constructed only once.
30 */
31 public function __construct() {
32 add_action( 'wp_ajax_' . self::ACTION, [ &$this, 'routing' ] );
33 add_action( 'wp_ajax_nopriv_' . self::ACTION, [ &$this, 'routing' ] );
34 }
35
36 /**
37 * This is a global ajax call, receive all the requests and dispatch to the right controller.
38 */
39 public function routing() {
40 // This is the intention, we will use it to find the data stored in DI.
41 $route = HTTP::get( 'route', false );
42 $nonce = HTTP::get( '_def_nonce', false );
43 if ( empty( $route ) || empty( $nonce ) ) {
44 exit;
45 }
46
47 $this->check_opcache();
48
49 $route = wp_unslash( $route );
50
51 if (
52 is_admin() &&
53 ! is_user_logged_in() &&
54 $this->is_private_access( $route )
55 ) {
56 wp_send_json_error(
57 array(
58 'message' => __( 'Your session expired. Please login to continue.', 'wpdef' ),
59 'type_notice' => 'session_out',
60 )
61 );
62 }
63
64 // Nonce is not valid.
65 if ( ! wp_verify_nonce( $nonce, $route ) ) {
66 wp_send_json_error(
67 array(
68 'message' => __( 'Invalid API request.', 'wpdef' ),
69 )
70 );
71 }
72
73 $key = sprintf( 'controller.%s', $route );
74
75 try {
76 $package = wd_di()->get( $key );
77 [$class, $method, $is_private] = $package;
78 if ( $is_private && ! $this->check_permission() ) {
79 wp_send_json_error( [
80 'message' => __( 'You shall not pass.', 'wpdef' )
81 ] );
82 }
83 if ( $is_private ) {
84 if ( ! wp_next_scheduled( 'defender_hub_sync' ) ) {
85 // Sync with HUB on every request it made, but not on public call.
86 wp_schedule_single_event( time(), 'defender_hub_sync' );
87 }
88 }
89 $this->execute_intention( $class, $method );
90 } catch ( \Exception $e ) {
91 $this->log( $e->getMessage(), 'internal.log' );
92 }
93 }
94
95 /**
96 * Execute the method, return should be various base on the method.
97 *
98 * @param string $class
99 * @param string $method
100 *
101 * @return Response
102 */
103 private function execute_intention( $class, $method ) {
104 $object = wd_di()->get( $class );
105 if ( is_object( $object ) ) {
106 $request = new Request();
107 // Because the method is getting params from $_REQUEST directly, we don't need to pass any args, just call.
108 // No use reflection method for performance, also this just a simple call.
109 // Manipulate the POST as raw data.
110 $_POST = $request->get_data();
111
112 return $object->$method( $request );
113 } else {
114 $this->log( sprintf( 'class not found when executing: %s %s', $class, $method ), 'internal.log' );
115 }
116 }
117
118 /**
119 * @param string $method The function to call.
120 * @param string $class Class name.
121 * @param bool $is_private Should this expose for non-auth user.
122 *
123 * @return void
124 */
125 public function add_route( $method, $class, $is_private = true ) {
126 // This will be passed into frontend for the query later.
127 $user_id = get_current_user_id();
128 $intention = hash( 'md5', sprintf( '%s.%s.%d', $class, $method, $user_id ) );
129 if ( defined( 'DEFENDER_DEBUG' ) && constant( 'DEFENDER_DEBUG' ) === true ) {
130 $intention = sprintf( '%s.%s.%d', $class, $method, $user_id );
131 }
132 wd_di()->set( sprintf( 'controller.%s', $intention ), [ $class, $method, $is_private ] );
133 wd_di()->set( sprintf( 'route.%s', $intention ), $intention );
134 wd_di()->set( sprintf( 'nonce.%s', $intention ), wp_create_nonce( $intention ) );
135 }
136
137 /**
138 * @param string $method
139 * @param string $class
140 *
141 * @return mixed
142 */
143 public function get_route( $method, $class ) {
144 $user_id = get_current_user_id();
145 $intention = hash( 'md5', sprintf( '%s.%s.%d', $class, $method, $user_id ) );
146 if ( defined( 'DEFENDER_DEBUG' ) && constant( 'DEFENDER_DEBUG' ) === true ) {
147 $intention = sprintf( '%s.%s.%d', $class, $method, $user_id );
148 }
149 try {
150 return wd_di()->get( sprintf( 'route.%s', $intention ) );
151 } catch ( \Exception $e ) {
152 $this->log( $e->getMessage(), 'internal.log' );
153 }
154 }
155
156 /**
157 * @param string $method
158 * @param string $class
159 *
160 * @return mixed
161 */
162 public function get_nonce( $method, $class ) {
163 $intention = hash( 'md5', sprintf( '%s.%s.%d', $class, $method, get_current_user_id() ) );
164 if ( defined( 'DEFENDER_DEBUG' ) && constant( 'DEFENDER_DEBUG' ) === true ) {
165 $intention = sprintf( '%s.%s.%d', $class, $method, get_current_user_id() );
166 }
167 try {
168 return wd_di()->get( sprintf( 'nonce.%s', $intention ) );
169 } catch ( \Exception $e ) {
170 $this->log( $e->getMessage(), 'internal.log' );
171 }
172 }
173
174 /**
175 * Check OPcache is enabled or not.
176 */
177 private function check_opcache() {
178 if ( $this->is_opcache_save_comments_disabled() ) {
179 wp_send_json_error(
180 array(
181 'message' => sprintf( __( '%s is disabled. Please contact your hosting provider to enable it.', 'wpdef' ), '<strong>OPcache Save Comments</strong>' ),
182 )
183 );
184 }
185 }
186
187 /**
188 * Check OPcache is enabled or not.
189 *
190 * @return bool
191 */
192 public function is_opcache_save_comments_disabled() {
193 // If OPcache is disabled.
194 if ( ini_get( 'opcache.enable' ) !== '1' ) {
195 return false;
196 }
197
198 // If OPcache is enabled and save comments disabled.
199 if ( ini_get( 'opcache.save_comments' ) !== '1' ) {
200 return true;
201 }
202
203 // Any other case.
204 return false;
205 }
206
207 /**
208 * Verify is ajax call is private.
209 * Here private stands for only authenticated user can do ajax call.
210 *
211 * @param string $route Route md5 hash.
212 *
213 * @return bool Return true if the request is private else false.
214 */
215 private function is_private_access( $route ) {
216 $key = sprintf( 'controller.%s', $route );
217
218 try {
219 $package = wd_di()->get( $key );
220 return isset( $package[2] ) && $package[2];
221 } catch ( \Exception $e ) {
222 $this->log( $e->getMessage(), 'internal.log' );
223 }
224
225 return false;
226 }
227 }
228