PluginProbe ʕ •ᴥ•ʔ
OttoKit: All-in-One Automation Platform / 1.0.74
OttoKit: All-in-One Automation Platform v1.0.74
1.1.31 1.1.30 1.1.29 1.1.28 1.1.27 1.1.9 trunk 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.47 1.0.48 1.0.49 1.0.50 1.0.51 1.0.52 1.0.53 1.0.54 1.0.55 1.0.56 1.0.57 1.0.58 1.0.59 1.0.60 1.0.61 1.0.62 1.0.63 1.0.64 1.0.65 1.0.66 1.0.67 1.0.68 1.0.69 1.0.7 1.0.70 1.0.71 1.0.72 1.0.73 1.0.74 1.0.75 1.0.76 1.0.77 1.0.78 1.0.79 1.0.8 1.0.80 1.0.81 1.0.82 1.0.83 1.0.84 1.0.85 1.0.86 1.0.87 1.0.88 1.0.89 1.0.9 1.0.90 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8
suretriggers / src / Controllers / RestController.php
suretriggers / src / Controllers Last commit date
AuthController.php 1 year ago AutomationController.php 3 years ago EventController.php 3 years ago GlobalSearchController.php 1 year ago IntegrationsController.php 2 years ago OptionController.php 3 years ago RestController.php 1 year ago RoutesController.php 3 years ago SettingsController.php 3 years ago WebhookRequestsController.php 1 year ago
RestController.php
468 lines
1 <?php
2 /**
3 * RestController.
4 * php version 5.6
5 *
6 * @category RestController
7 * @package SureTriggers
8 * @author BSF <username@example.com>
9 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
10 * @link https://www.brainstormforce.com/
11 * @since 1.0.0
12 */
13
14 namespace SureTriggers\Controllers;
15
16 use Exception;
17 use SureTriggers\Integrations\WordPress\WordPress;
18 use SureTriggers\Traits\SingletonLoader;
19 use SureTriggers\Models\SaasApiToken;
20 use WP_REST_Request;
21 use WP_REST_Response;
22 use WP_Error;
23
24 /**
25 * RestController
26 *
27 * @category RestController
28 * @package SureTriggers
29 * @author BSF <username@example.com>
30 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
31 * @link https://www.brainstormforce.com/
32 * @since 1.0.0
33 */
34 class RestController {
35
36 /**
37 * Access token for authentication.
38 *
39 * @var string $acccess_token
40 */
41 private $secret_key;
42
43 use SingletonLoader;
44
45 /**
46 * Initialise data.
47 */
48 public function __construct() {
49 $this->secret_key = SaasApiToken::get();
50 add_filter( 'determine_current_user', [ $this, 'basic_auth_handler' ], 20 );
51 add_filter( 'debug_information', [ $this, 'sure_triggers_connection_info' ] );
52 }
53
54 /**
55 * Permission callback for rest api after determination of current user.
56 *
57 * @param WP_REST_Request $request Request.
58 */
59 public function autheticate_user( $request ) {
60 $secret_key = $request->get_header( 'st_authorization' );
61 list($secret_key) = sscanf( $secret_key, 'Bearer %s' );
62
63 if ( $this->secret_key !== $secret_key ) {
64 return false;
65 }
66
67 return true;
68 }
69
70 /**
71 * Verify user token.
72 *
73 * @return array|WP_Error $response Response.
74 */
75 public static function verify_user_token() {
76 $args = [
77 'body' => [
78 'token' => SaasApiToken::get(),
79 'saas-token' => SaasApiToken::get(),
80 'base_url' => str_replace( '/wp-json/', '', get_rest_url() ),
81 ],
82 'sslverify' => false,
83 ];
84 $response = wp_remote_post( SURE_TRIGGERS_API_SERVER_URL . '/token/verify', $args );
85
86 return $response;
87 }
88
89 /**
90 * Verify connection.
91 *
92 * @return array|WP_Error $response Response.
93 */
94 public static function suretriggers_verify_wp_connection() {
95 $args = [
96 'body' => [
97 'saas-token' => SaasApiToken::get(),
98 'base_url' => str_replace( '/wp-json/', '', get_rest_url() ),
99 'plugin_version' => SURE_TRIGGERS_VER,
100 ],
101 'sslverify' => false,
102 ];
103 $response = wp_remote_post( SURE_TRIGGERS_API_SERVER_URL . '/connection/wordpress/ping', $args );
104 return $response;
105 }
106
107 /**
108 * Authenticate User for API calls.
109 *
110 * @param array|object $user USer.
111 *
112 * @return int|null
113 */
114 public function basic_auth_handler( $user ) {
115 // Don't authenticate twice.
116 if ( ! empty( $user ) ) {
117 return $user;
118 }
119
120 // Check that we're trying to authenticate.
121 if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) || ! isset( $_SERVER['PHP_AUTH_PW'] ) ) { //phpcs:ignore
122 return $user;
123 }
124
125 $username = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) ); //phpcs:ignore
126 $password = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_PW'] ) ); //phpcs:ignore
127
128 /**
129 * In multi-site, wp_authenticate_spam_check filter is run on authentication. This filter calls.
130 * get_currentuserinfo which in turn calls the determine_current_user filter. This leads to infinite.
131 * recursion and a stack overflow unless the current function is removed from the determine_current_user.
132 * filter during authentication.
133 */
134 remove_filter( 'determine_current_user', [ $this, 'basic_auth_handler' ], 20 );
135
136 $user = wp_authenticate( $username, $password );
137
138 add_filter( 'determine_current_user', [ $this, 'basic_auth_handler' ], 20 );
139
140 if ( is_wp_error( $user ) ) {
141 return null;
142 }
143
144 return $user->ID;
145 }
146
147 /**
148 * Authenticate user for new connection create api.
149 *
150 * @return bool
151 */
152 public function is_current_user() {
153 if ( current_user_can( 'manage_options' ) ) {
154 return true;
155 }
156 return false;
157 }
158
159 /**
160 * Execute action events.
161 *
162 * @param WP_REST_Request $request Request data.
163 * @return WP_REST_Response
164 */
165 public function run_action( $request ) {
166 $request->get_param( 'wp_user_id' );
167
168 $user_id = $request->get_param( 'wp_user_id' );
169 $automation_id = $request->get_param( 'automation_id' );
170 $integration = $request->get_param( 'integration' );
171 $action_type = $request->get_param( 'type_event' );
172 $selected_options = $request->get_param( 'selected_options' );
173 $context = $request->get_param( 'context' );
174 $fields = $request->get_param( 'fields' );
175
176 if ( empty( $user_id ) ) {
177 $user_id = isset( $context['pluggable_data']['wp_user_id'] ) ? sanitize_text_field( $context['pluggable_data']['wp_user_id'] ) : '';
178 }
179
180 if ( empty( $integration ) || empty( $action_type ) ) {
181 return self::error_message( 'Integration or action type is missing' );
182 }
183
184 if ( isset( $selected_options['wp_user_email'] ) && ! ( 'EDD' === $integration && 'find_user_purchased_download' === $action_type ) ) {
185 $is_valid = WordPress::validate_email( $selected_options['wp_user_email'] );
186
187 if ( ! $is_valid->valid ) {
188 if ( $is_valid->multiple ) {
189 return self::error_message( 'One or more email address is not valid.' );
190 } else {
191 return self::error_message( 'Email address is not valid.' );
192 }
193 }
194
195 if ( str_contains( $selected_options['wp_user_email'], ',' ) ) {
196 $email_list = explode( ',', $selected_options['wp_user_email'] );
197
198 foreach ( $email_list as $single_email ) {
199 if ( ! email_exists( trim( $single_email ) ) ) {
200 return self::error_message( 'User with email ' . $single_email . ' does not exists.' );
201 }
202 }
203 } else {
204 if ( ! email_exists( $selected_options['wp_user_email'] ) ) {
205 return self::error_message( 'User with email ' . $selected_options['wp_user_email'] . ' does not exists.' );
206 }
207 }
208 }
209 $registered_actions = EventController::get_instance()->actions;
210 $action_event = $registered_actions[ $integration ][ $action_type ];
211
212 $fun_params = [
213 $user_id,
214 $automation_id,
215 $fields,
216 $selected_options,
217 $context,
218 ];
219
220 try {
221 $result = call_user_func_array(
222 $action_event['function'],
223 $fun_params
224 );
225 return self::success_message( $result );
226 } catch ( Exception $e ) {
227 return self::error_message( $e->getMessage(), 400 );
228 }
229 }
230
231 /**
232 * Error message format.
233 *
234 * @param string $message Error message.
235 * @param string $status Error message.
236 *
237 * @return object
238 */
239 public static function error_message( $message, $status = 401 ) {
240 return new WP_REST_Response(
241 [
242 'success' => false,
243 'data' => [
244 'errors' => $message,
245 ],
246 ],
247 $status
248 );
249 }
250
251 /**
252 * Success message format.
253 *
254 * @param array $data response data to be sent.
255 *
256 * @return object
257 */
258 public static function success_message( $data = [] ) {
259 $result = [];
260
261 if ( ! empty( $data ) ) {
262 $result['result'] = $data;
263 }
264
265 return new WP_REST_Response(
266 [
267 'success' => true,
268 'data' => $result,
269 ],
270 200
271 );
272
273 }
274
275 /**
276 * Add/Remove/Update the triggers..
277 * When new/update/remove automation on Sass then execute this endpoint to update the automation.
278 *
279 * @param WP_REST_Request $request Request data.
280 * @return WP_REST_Response
281 */
282 public function manage_triggers( $request ) {
283 $events = $request->get_param( 'events' ) ? json_decode( stripslashes( $request->get_param( 'events' ) ), true ) : [];
284
285 // Selected field data from the trigger.
286 $data = $request->get_param( 'data' ) ? json_decode( stripslashes( $request->get_param( 'data' ) ), true ) : [];
287
288 // Get the trigger data from the option and append data in trigger data option.
289 $trigger_data = OptionController::get_option( 'trigger_data' );
290 if ( empty( $trigger_data ) ) {
291 $trigger_data = [];
292 }
293
294 if ( is_array( $data ) && is_array( $events ) ) {
295 $index = array_search( $data['trigger'], array_column( $events, 'trigger' ) );
296 if ( is_array( $trigger_data ) && false !== $index && $data['integration'] === $events[ $index ]['integration'] ) {
297 $trigger_data[ $data['integration'] ][ $data['trigger'] ]['selected_options'] = $data['selected_data'];
298 }
299 }
300
301 OptionController::set_option( 'triggers', $events );
302 // Set the new option for the trigger data.
303 OptionController::set_option( 'trigger_data', $trigger_data );
304 $events = array_column( $events, 'trigger' );
305 return self::success_message(
306 [
307 'events' => $events,
308 'data' => $trigger_data,
309 ]
310 );
311 }
312
313 /**
314 * Send response to Saas that trigger is executed.
315 *
316 * @param array $trigger_data Trigger data.
317 *
318 * @return bool
319 */
320 public function trigger_listener( $trigger_data ) {
321 // Pass unique WordPress webhook id.
322 $wordpress_webhook_uuid = str_replace( '-', '', wp_generate_uuid4() );
323 $site_url = esc_url_raw( str_replace( '/wp-json/', '', get_site_url() ) );
324 $site_url = preg_replace( '/^https?:\/\//', '', $site_url );
325 $encoded_site_url = urlencode( (string) $site_url );
326 $trigger_data['wordpress_webhook_uuid'] = $wordpress_webhook_uuid . '_' . $encoded_site_url;
327 $args = [
328 'headers' => [
329 'Authorization' => 'Bearer ' . $this->secret_key,
330 'Referer' => str_replace( '/wp-json/', '', get_site_url() ),
331 'RefererRestUrl' => str_replace( '/wp-json/', '', get_rest_url() ),
332 ],
333 'body' => json_decode( wp_json_encode( $trigger_data ), 1 ),
334 'sslverify' => false,
335 ];
336
337 /**
338 *
339 * Ignore line
340 *
341 * @phpstan-ignore-next-line
342 */
343 $response = wp_remote_post( SURE_TRIGGERS_WEBHOOK_SERVER_URL . '/wordpress/webhook', $args );
344 // Store every webhook requests.
345 $error_info = wp_remote_retrieve_body( $response );
346 if ( 405 === wp_remote_retrieve_response_code( $response ) ) {
347 $error_info = wp_remote_retrieve_response_message( $response );
348 }
349 if ( 0 === wp_remote_retrieve_response_code( $response ) ) {
350 $error_info = __( 'Service not available', 'suretriggers' );
351 }
352 unset( $args['headers']['Authorization'] );
353 WebhookRequestsController::suretriggers_log_request( (string) wp_json_encode( $args ), (int) wp_remote_retrieve_response_code( $response ), $error_info );
354
355 if ( wp_remote_retrieve_response_code( $response ) === 200 ) {
356 return true;
357 }
358
359 return false;
360 }
361
362 /**
363 * Update the connection from SAAS.
364 *
365 * @param WP_REST_Request $request Request data.
366 *
367 * @return void
368 */
369 public function connection_update( $request ) {
370 $secret = $request->get_param( 'secret_key' );
371 if ( $secret && is_string( $secret ) ) {
372 SaasApiToken::save( $secret );
373 }
374 }
375
376 /**
377 * Disconnect connection
378 *
379 * @param WP_REST_Request $request Request data.
380 * @return WP_REST_Response
381 */
382 public function connection_disconnect( $request ) {
383 SaasApiToken::save( null );
384 return self::success_message();
385 }
386
387 /**
388 * Test Trigger
389 * When test trigger is initiated on Sass then execute this endpoint to create a transient for identifying trigger event.
390 *
391 * @param WP_REST_Request $request Request data.
392 * @return WP_REST_Response
393 */
394 public function test_triggers( $request ) {
395 $test_triggers = (array) OptionController::get_option( 'test_triggers', [] );
396 $event = [
397 'trigger' => $request->get_param( 'trigger' ),
398 'integration' => $request->get_param( 'integration' ),
399 ];
400
401 // if request is to delete the transient, delete it and return.
402 if ( $request->get_param( 'clear_transient_data' ) === 'yes' ) {
403 $test_triggers = array_filter(
404 $test_triggers,
405 function ( $v ) use ( $event ) {
406 return $v !== $event;
407 }
408 );
409 OptionController::set_option( 'test_triggers', $test_triggers );
410
411 return;
412 }
413
414 $test_triggers[] = $event;
415 $test_triggers = array_unique( $test_triggers, SORT_REGULAR );
416 $tmp_test_triggers = [];
417
418 foreach ( $test_triggers as $test_trigger ) {
419 if ( ! empty( $test_trigger['trigger'] ) ) {
420 $tmp_test_triggers[] = $test_trigger;
421 }
422 }
423
424 OptionController::set_option( 'test_triggers', $tmp_test_triggers );
425 }
426
427 /**
428 * SureTriggers Connection Info
429 *
430 * @param array $debug_info Info data.
431 * @return array
432 */
433 public function sure_triggers_connection_info( $debug_info ) {
434 // Verify if SureTriggers is connected successfully.
435 $response = self::verify_user_token();
436 $connection = ( wp_remote_retrieve_response_code( $response ) === 200 );
437 if ( $connection ) {
438 $connection_status = 'Connection Successfully Set';
439 } else {
440 $connection_status = 'Error in Connection';
441 }
442 $debug_info['suretriggers'] = [
443 'label' => __( 'SureTriggers', 'suretriggers' ),
444 'fields' => [
445 'suretriggers_status' => [
446 'label' => __( 'SureTriggers Status', 'suretriggers' ),
447 'value' => $connection_status,
448 'private' => false,
449 ],
450 'rest_url' => [
451 'label' => __( 'Rest URL', 'suretriggers' ),
452 'value' => esc_url( get_rest_url() ),
453 'private' => false,
454 ],
455 'suretriggers_version' => [
456 'label' => __( 'SureTriggers Version', 'suretriggers' ),
457 'value' => SURE_TRIGGERS_VER,
458 'private' => false,
459 ],
460 ],
461 ];
462 return $debug_info;
463 }
464
465 }
466
467 RestController::get_instance();
468