PluginProbe ʕ •ᴥ•ʔ
OttoKit: All-in-One Automation Platform / 1.0.72
OttoKit: All-in-One Automation Platform v1.0.72
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
450 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_WEBHOOK_SERVER_URL . '/token/verify', $args );
85
86 return $response;
87 }
88
89 /**
90 * Authenticate User for API calls.
91 *
92 * @param array|object $user USer.
93 *
94 * @return int|null
95 */
96 public function basic_auth_handler( $user ) {
97 // Don't authenticate twice.
98 if ( ! empty( $user ) ) {
99 return $user;
100 }
101
102 // Check that we're trying to authenticate.
103 if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) || ! isset( $_SERVER['PHP_AUTH_PW'] ) ) { //phpcs:ignore
104 return $user;
105 }
106
107 $username = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) ); //phpcs:ignore
108 $password = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_PW'] ) ); //phpcs:ignore
109
110 /**
111 * In multi-site, wp_authenticate_spam_check filter is run on authentication. This filter calls.
112 * get_currentuserinfo which in turn calls the determine_current_user filter. This leads to infinite.
113 * recursion and a stack overflow unless the current function is removed from the determine_current_user.
114 * filter during authentication.
115 */
116 remove_filter( 'determine_current_user', [ $this, 'basic_auth_handler' ], 20 );
117
118 $user = wp_authenticate( $username, $password );
119
120 add_filter( 'determine_current_user', [ $this, 'basic_auth_handler' ], 20 );
121
122 if ( is_wp_error( $user ) ) {
123 return null;
124 }
125
126 return $user->ID;
127 }
128
129 /**
130 * Authenticate user for new connection create api.
131 *
132 * @return bool
133 */
134 public function is_current_user() {
135 if ( current_user_can( 'manage_options' ) ) {
136 return true;
137 }
138 return false;
139 }
140
141 /**
142 * Execute action events.
143 *
144 * @param WP_REST_Request $request Request data.
145 * @return WP_REST_Response
146 */
147 public function run_action( $request ) {
148 $request->get_param( 'wp_user_id' );
149
150 $user_id = $request->get_param( 'wp_user_id' );
151 $automation_id = $request->get_param( 'automation_id' );
152 $integration = $request->get_param( 'integration' );
153 $action_type = $request->get_param( 'type_event' );
154 $selected_options = $request->get_param( 'selected_options' );
155 $context = $request->get_param( 'context' );
156 $fields = $request->get_param( 'fields' );
157
158 if ( empty( $user_id ) ) {
159 $user_id = isset( $context['pluggable_data']['wp_user_id'] ) ? sanitize_text_field( $context['pluggable_data']['wp_user_id'] ) : '';
160 }
161
162 if ( empty( $integration ) || empty( $action_type ) ) {
163 return self::error_message( 'Integration or action type is missing' );
164 }
165
166 if ( isset( $selected_options['wp_user_email'] ) ) {
167 $is_valid = WordPress::validate_email( $selected_options['wp_user_email'] );
168
169 if ( ! $is_valid->valid ) {
170 if ( $is_valid->multiple ) {
171 return self::error_message( 'One or more email address is not valid.' );
172 } else {
173 return self::error_message( 'Email address is not valid.' );
174 }
175 }
176
177 if ( str_contains( $selected_options['wp_user_email'], ',' ) ) {
178 $email_list = explode( ',', $selected_options['wp_user_email'] );
179
180 foreach ( $email_list as $single_email ) {
181 if ( ! email_exists( trim( $single_email ) ) ) {
182 return self::error_message( 'User with email ' . $single_email . ' does not exists.' );
183 }
184 }
185 } else {
186 if ( ! email_exists( $selected_options['wp_user_email'] ) ) {
187 return self::error_message( 'User with email ' . $selected_options['wp_user_email'] . ' does not exists.' );
188 }
189 }
190 }
191 $registered_actions = EventController::get_instance()->actions;
192 $action_event = $registered_actions[ $integration ][ $action_type ];
193
194 $fun_params = [
195 $user_id,
196 $automation_id,
197 $fields,
198 $selected_options,
199 $context,
200 ];
201
202 try {
203 $result = call_user_func_array(
204 $action_event['function'],
205 $fun_params
206 );
207 return self::success_message( $result );
208 } catch ( Exception $e ) {
209 return self::error_message( $e->getMessage(), 400 );
210 }
211 }
212
213 /**
214 * Error message format.
215 *
216 * @param string $message Error message.
217 * @param string $status Error message.
218 *
219 * @return object
220 */
221 public static function error_message( $message, $status = 401 ) {
222 return new WP_REST_Response(
223 [
224 'success' => false,
225 'data' => [
226 'errors' => $message,
227 ],
228 ],
229 $status
230 );
231 }
232
233 /**
234 * Success message format.
235 *
236 * @param array $data response data to be sent.
237 *
238 * @return object
239 */
240 public static function success_message( $data = [] ) {
241 $result = [];
242
243 if ( ! empty( $data ) ) {
244 $result['result'] = $data;
245 }
246
247 return new WP_REST_Response(
248 [
249 'success' => true,
250 'data' => $result,
251 ],
252 200
253 );
254
255 }
256
257 /**
258 * Add/Remove/Update the triggers..
259 * When new/update/remove automation on Sass then execute this endpoint to update the automation.
260 *
261 * @param WP_REST_Request $request Request data.
262 * @return WP_REST_Response
263 */
264 public function manage_triggers( $request ) {
265 $events = $request->get_param( 'events' ) ? json_decode( stripslashes( $request->get_param( 'events' ) ), true ) : [];
266
267 // Selected field data from the trigger.
268 $data = $request->get_param( 'data' ) ? json_decode( stripslashes( $request->get_param( 'data' ) ), true ) : [];
269
270 // Get the trigger data from the option and append data in trigger data option.
271 $trigger_data = OptionController::get_option( 'trigger_data' );
272 if ( empty( $trigger_data ) ) {
273 $trigger_data = [];
274 }
275
276 if ( is_array( $data ) && is_array( $events ) ) {
277 $index = array_search( $data['trigger'], array_column( $events, 'trigger' ) );
278 if ( is_array( $trigger_data ) && false !== $index && $data['integration'] === $events[ $index ]['integration'] ) {
279 $trigger_data[ $data['integration'] ][ $data['trigger'] ]['selected_options'] = $data['selected_data'];
280 }
281 }
282
283 OptionController::set_option( 'triggers', $events );
284 // Set the new option for the trigger data.
285 OptionController::set_option( 'trigger_data', $trigger_data );
286 $events = array_column( $events, 'trigger' );
287 return self::success_message(
288 [
289 'events' => $events,
290 'data' => $trigger_data,
291 ]
292 );
293 }
294
295 /**
296 * Send response to Saas that trigger is executed.
297 *
298 * @param array $trigger_data Trigger data.
299 *
300 * @return bool
301 */
302 public function trigger_listener( $trigger_data ) {
303 // Pass unique WordPress webhook id.
304 $wordpress_webhook_uuid = str_replace( '-', '', wp_generate_uuid4() );
305 $site_url = esc_url_raw( str_replace( '/wp-json/', '', get_site_url() ) );
306 $site_url = preg_replace( '/^https?:\/\//', '', $site_url );
307 $encoded_site_url = urlencode( (string) $site_url );
308 $trigger_data['wordpress_webhook_uuid'] = $wordpress_webhook_uuid . '_' . $encoded_site_url;
309 $args = [
310 'headers' => [
311 'Authorization' => 'Bearer ' . $this->secret_key,
312 'Referer' => str_replace( '/wp-json/', '', get_site_url() ),
313 'RefererRestUrl' => str_replace( '/wp-json/', '', get_rest_url() ),
314 ],
315 'body' => json_decode( wp_json_encode( $trigger_data ), 1 ),
316 'sslverify' => false,
317 ];
318
319 /**
320 *
321 * Ignore line
322 *
323 * @phpstan-ignore-next-line
324 */
325 $response = wp_remote_post( SURE_TRIGGERS_WEBHOOK_SERVER_URL . '/wordpress/webhook', $args );
326 // Store every webhook requests.
327 $error_info = wp_remote_retrieve_body( $response );
328 if ( 405 === wp_remote_retrieve_response_code( $response ) ) {
329 $error_info = wp_remote_retrieve_response_message( $response );
330 }
331 if ( 0 === wp_remote_retrieve_response_code( $response ) ) {
332 $error_info = __( 'Service not available', 'suretriggers' );
333 }
334 unset( $args['headers']['Authorization'] );
335 WebhookRequestsController::suretriggers_log_request( (string) wp_json_encode( $args ), (int) wp_remote_retrieve_response_code( $response ), $error_info );
336
337 if ( wp_remote_retrieve_response_code( $response ) === 200 ) {
338 return true;
339 }
340
341 return false;
342 }
343
344 /**
345 * Update the connection from SAAS.
346 *
347 * @param WP_REST_Request $request Request data.
348 *
349 * @return void
350 */
351 public function connection_update( $request ) {
352 $secret = $request->get_param( 'secret_key' );
353 if ( $secret && is_string( $secret ) ) {
354 SaasApiToken::save( $secret );
355 }
356 }
357
358 /**
359 * Disconnect connection
360 *
361 * @param WP_REST_Request $request Request data.
362 * @return WP_REST_Response
363 */
364 public function connection_disconnect( $request ) {
365 SaasApiToken::save( null );
366 return self::success_message();
367 }
368
369 /**
370 * Test Trigger
371 * When test trigger is initiated on Sass then execute this endpoint to create a transient for identifying trigger event.
372 *
373 * @param WP_REST_Request $request Request data.
374 * @return WP_REST_Response
375 */
376 public function test_triggers( $request ) {
377 $test_triggers = (array) OptionController::get_option( 'test_triggers', [] );
378 $event = [
379 'trigger' => $request->get_param( 'trigger' ),
380 'integration' => $request->get_param( 'integration' ),
381 ];
382
383 // if request is to delete the transient, delete it and return.
384 if ( $request->get_param( 'clear_transient_data' ) === 'yes' ) {
385 $test_triggers = array_filter(
386 $test_triggers,
387 function ( $v ) use ( $event ) {
388 return $v !== $event;
389 }
390 );
391 OptionController::set_option( 'test_triggers', $test_triggers );
392
393 return;
394 }
395
396 $test_triggers[] = $event;
397 $test_triggers = array_unique( $test_triggers, SORT_REGULAR );
398 $tmp_test_triggers = [];
399
400 foreach ( $test_triggers as $test_trigger ) {
401 if ( ! empty( $test_trigger['trigger'] ) ) {
402 $tmp_test_triggers[] = $test_trigger;
403 }
404 }
405
406 OptionController::set_option( 'test_triggers', $tmp_test_triggers );
407 }
408
409 /**
410 * SureTriggers Connection Info
411 *
412 * @param array $debug_info Info data.
413 * @return array
414 */
415 public function sure_triggers_connection_info( $debug_info ) {
416 // Verify if SureTriggers is connected successfully.
417 $response = self::verify_user_token();
418 $connection = ( wp_remote_retrieve_response_code( $response ) === 200 );
419 if ( $connection ) {
420 $connection_status = 'Connection Successfully Set';
421 } else {
422 $connection_status = 'Error in Connection';
423 }
424 $debug_info['suretriggers'] = [
425 'label' => __( 'SureTriggers', 'suretriggers' ),
426 'fields' => [
427 'suretriggers_status' => [
428 'label' => __( 'SureTriggers Status', 'suretriggers' ),
429 'value' => $connection_status,
430 'private' => false,
431 ],
432 'rest_url' => [
433 'label' => __( 'Rest URL', 'suretriggers' ),
434 'value' => esc_url( get_rest_url() ),
435 'private' => false,
436 ],
437 'suretriggers_version' => [
438 'label' => __( 'SureTriggers Version', 'suretriggers' ),
439 'value' => SURE_TRIGGERS_VER,
440 'private' => false,
441 ],
442 ],
443 ];
444 return $debug_info;
445 }
446
447 }
448
449 RestController::get_instance();
450