From ec3b95aabc98d1045c66746415690d04bc191d99 Mon Sep 17 00:00:00 2001 From: Michael McAndrew Date: Mon, 12 Mar 2018 08:56:51 +0000 Subject: [PATCH 1/5] first draft callback functionality --- proxy/callback.functions.php | 66 ++++++++++++++++++++++++++++++++++ proxy/callback.php | 69 ++++++++++++++++++++++++++++++++++++ proxy/config.php | 9 +++++ 3 files changed, 144 insertions(+) create mode 100644 proxy/callback.functions.php create mode 100644 proxy/callback.php diff --git a/proxy/callback.functions.php b/proxy/callback.functions.php new file mode 100644 index 0000000..f25a604 --- /dev/null +++ b/proxy/callback.functions.php @@ -0,0 +1,66 @@ + [ + // 'secret' => '', + 'request_method' => 'POST', + 'target_path' => 'civicrm/sparkpost/callback' + ] +]; From 5dedecb2f34172c6be3a508d6a4360845579a293 Mon Sep 17 00:00:00 2001 From: Michael McAndrew Date: Mon, 12 Mar 2018 09:50:03 +0000 Subject: [PATCH 2/5] Add checks for supported content types --- proxy/callback.functions.php | 3 +++ proxy/callback.php | 9 ++++++--- proxy/config.php | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/proxy/callback.functions.php b/proxy/callback.functions.php index f25a604..47790b3 100644 --- a/proxy/callback.functions.php +++ b/proxy/callback.functions.php @@ -33,6 +33,9 @@ function civiproxy_callback_validate_body_xwwwformurlencoded($expected, $actual) //TODO } +// For now, I have written this 'placeholder' method to pass on post requests. +// Sparkpost says that it works OK. Might be a good idea to refactor/improve +// civiproxy_redirect() instead/as well. function civiproxy_callback_redirect($target_path, $method) { switch ($method) { case 'POST': diff --git a/proxy/callback.php b/proxy/callback.php index c3d48ed..a8b2fd9 100644 --- a/proxy/callback.php +++ b/proxy/callback.php @@ -43,6 +43,7 @@ if(!isset($query_params['secret']) || $definition['secret'] !== $query_params['s civiproxy_http_error("Invalid secret", 403); } +// Check this is a supported request method if(!in_array($_SERVER['REQUEST_METHOD'], ['POST'])){ civiproxy_http_error("Unsupported request method", 501); } @@ -52,6 +53,11 @@ if(isset($definition['request_method'])){ civiproxy_callback_validate_request_method($definition['request_method'], $_SERVER['REQUEST_METHOD']); } +// Check this is a supported content type +if(!in_array($_SERVER['CONTENT_TYPE'], ['application/json', 'application/x-www-form-urlencoded'])){ + civiproxy_http_error("Unsupported content type", 501); +} + // If a content type has been defined, validate it if(isset($definition['content_type'])){ civiproxy_callback_validate_content_type($definition['content_type'], $_SERVER['CONTENT_TYPE']); @@ -63,7 +69,4 @@ if(isset($validator['body'])){ } // We have passed all the validators, forward the request - -// TODO for now, I have written my own method to pass on post requests. Would be -// better to refactor / improve civiproxy_redirect() civiproxy_callback_redirect($definition['target_path'], $_SERVER['REQUEST_METHOD']); diff --git a/proxy/config.php b/proxy/config.php index ea0e4f8..35413b0 100644 --- a/proxy/config.php +++ b/proxy/config.php @@ -124,6 +124,7 @@ $callbacks = [ 'sparkpost' => [ // 'secret' => '', 'request_method' => 'POST', + 'content_type' => 'application/json', 'target_path' => 'civicrm/sparkpost/callback' ] ]; From abd31ca0ef4e2103fca788d3ebad751d5e244dfc Mon Sep 17 00:00:00 2001 From: Michael McAndrew Date: Mon, 12 Mar 2018 10:25:31 +0000 Subject: [PATCH 3/5] Allow multiple request methods per callback. --- proxy/callback.functions.php | 8 ++++++-- proxy/config.php | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/proxy/callback.functions.php b/proxy/callback.functions.php index 47790b3..729880d 100644 --- a/proxy/callback.functions.php +++ b/proxy/callback.functions.php @@ -1,9 +1,13 @@ [ - // 'secret' => '', - 'request_method' => 'POST', + 'secret' => '85c573b980c3c248f083f9ca6a175659', + 'request_method' => 'POST', // single value or array 'content_type' => 'application/json', 'target_path' => 'civicrm/sparkpost/callback' ] From 324b8c2e96f84c250332cb56841055a6fcaf70c7 Mon Sep 17 00:00:00 2001 From: Michael McAndrew Date: Mon, 12 Mar 2018 10:30:01 +0000 Subject: [PATCH 4/5] Support GET request method --- proxy/callback.functions.php | 24 ++++++++++++++++++++++++ proxy/callback.php | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/proxy/callback.functions.php b/proxy/callback.functions.php index 729880d..7ebb5b4 100644 --- a/proxy/callback.functions.php +++ b/proxy/callback.functions.php @@ -45,6 +45,9 @@ function civiproxy_callback_redirect($target_path, $method) { case 'POST': civiproxy_callback_redirect_post($target_path); break; + case 'GET': + civiproxy_callback_redirect_get($target_path); + break; } exit; } @@ -71,3 +74,24 @@ function civiproxy_callback_redirect_post($target_path) { // But some might be interested in the response. echo $response; } + +// Change the URL, forward the body. Respond with the response +function civiproxy_callback_redirect_get($target_path) { + global $target_civicrm; + $target_url = "$target_civicrm/{$target_path}"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $target_url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); + curl_setopt($ch, CURLOPT_HEADER, 0); + $response = curl_exec($ch); + if (curl_error($ch)){ + civiproxy_http_error("CURL error (" . curl_errno($ch) . ") ".curl_error($ch) , 501); + } + + // I think that most callbacks just want a response code + http_response_code(curl_getinfo($ch, CURLINFO_HTTP_CODE)); + + // But some might be interested in the response. + echo $response; +} diff --git a/proxy/callback.php b/proxy/callback.php index a8b2fd9..c9425ae 100644 --- a/proxy/callback.php +++ b/proxy/callback.php @@ -44,7 +44,7 @@ if(!isset($query_params['secret']) || $definition['secret'] !== $query_params['s } // Check this is a supported request method -if(!in_array($_SERVER['REQUEST_METHOD'], ['POST'])){ +if(!in_array($_SERVER['REQUEST_METHOD'], ['GET', 'POST'])){ civiproxy_http_error("Unsupported request method", 501); } From f5d0dc8311af041bea720996f3c0a20d17798642 Mon Sep 17 00:00:00 2001 From: systopia Date: Wed, 21 Mar 2018 11:31:51 +0100 Subject: [PATCH 5/5] minor adjustments to #26 --- proxy/callback.functions.php | 5 +++++ proxy/callback.php | 6 ++++++ proxy/config.php | 26 ++++++++++++++++++-------- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/proxy/callback.functions.php b/proxy/callback.functions.php index 7ebb5b4..7f43fba 100644 --- a/proxy/callback.functions.php +++ b/proxy/callback.functions.php @@ -1,4 +1,9 @@ "; @@ -118,13 +123,18 @@ $rest_allowed_actions = array( ), ); -$callbacks_enabled = false; -$callbacks = [ - 'sparkpost' => [ - 'secret' => '85c573b980c3c248f083f9ca6a175659', +/**************************************************************** + ** ALLOWED CALLBACKS ** + ****************************************************************/ + +// defines the callbacks that are to be forwarded to the target system +// make sure $callbacks_enabled is TRUE for this to work +$callbacks = array( + 'sparkpost_example' => array( + 'secret' => '85c573b980c3c248f083f9ca6a175659', 'request_method' => 'POST', // single value or array - 'content_type' => 'application/json', - 'target_path' => 'civicrm/sparkpost/callback' - ] -]; + 'content_type' => 'application/json', + 'target_path' => 'civicrm/sparkpost/callback' + ) +);