PLIVO v3 validation not able to verify signature using PLIVO SDK - php

I am trying to validate the request received from the plivo to my application server.
For this I am using the sample code provided by the plivo in the documentation.
<?php
require 'vendor/autoload.php';
use Plivo\Exceptions\PlivoValidationException;
use Plivo\Util\v3SignatureValidation;
use Plivo\XML\Response;
if (preg_match('/speak/', $_SERVER["REQUEST_URI"])) {
$auth_token = "<auth_token>";
$signature = #$_SERVER["X-Plivo-Signature-V3"] ?: 'signature';
$nonce = #$_SERVER["X-Plivo-Signature-V3-Nonce"] ?: 'nonce';
$url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
$method = $_SERVER['REQUEST_METHOD'];
$SVUtil = new v3SignatureValidation();
if ($method == "GET") {
try {
$valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature);
} catch (PlivoValidationException $e) {
echo("error");
}
} else {
$body = file_get_contents("php://input");
$params = json_decode($body, true);
try {
$valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature, $params);
} catch (PlivoValidationException $e) {
echo("error");
}
}
echo $valid;
$body = 'Hi, Calling from Plivo';
$attributes = array(
'loop' => 3,
);
$r = new Response();
$r->addSpeak($body, $attributes);
echo($r->toXML());
} else {
echo "<p>Welcome to Plivo</p>";
}
But I am getting this error
Invalid argument supplied for foreach() in code/plivo/vendor/plivo/plivo-php/src/Plivo/Util/v3SignatureValidation.php on line 13
I am debugging, but not able to find the solution.
One thing I noticed that nothing is being received in json from the PLIVO server.
Can anyone help, as There is not enough documentation available for Plivo Request Validation.

Plivo's Developer Evangelist here. Please try the below code instead.
<?php
require 'vendor/autoload.php';
use Plivo\Exceptions\PlivoValidationException;
use Plivo\Util\v3SignatureValidation;
use Plivo\XML\Response;
if (preg_match('/speak/', $_SERVER["REQUEST_URI"]))
{
$auth_token = "<auth_token>";
$signature = #$_SERVER["HTTP_X_PLIVO_SIGNATURE_V3"] ? : 'signature';
$nonce = #$_SERVER["HTTP_X_PLIVO_SIGNATURE_V3_NONCE"] ? : 'nonce';
$url = $_SERVER['HTTP_REFERER'];
$method = $_SERVER['REQUEST_METHOD'];
$SVUtil = new v3SignatureValidation();
if ($method == "GET")
{
try
{
$valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature);
}
catch(PlivoValidationException $e)
{
echo ("error");
}
}
else
{
$body = file_get_contents("php://input", true);
parse_str($body, $get_array);
try
{
$valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature, $get_array);
}
catch(PlivoValidationException $e)
{
echo ("error");
}
}
error_log(print_r($valid, true));
$body = 'Hi, Calling from Plivo';
$attributes = array(
'loop' => 3,
);
$r = new Response();
$r->addSpeak($body, $attributes);
echo ($r->toXML());
}
else
{
echo "<p>Welcome to Plivo</p>";
}
And run the below command
php -S localhost:5000
In case if you still face any issues, please free to contact our support team
src: https://www.plivo.com/docs/voice/concepts/signature-validation#code

Related

Simple Telegram Bot but it doesn't respond to commands (PHP)

I'm fairly new to all of this, but I have created a simple telegram bot to test their functionality. I have set the webhook and I'm using ngrok for the "host". However when I type a command the bot just doesn't do anything.
Does anyone know how to fix this?
Here is the index.php file:
<?php
require('token.php');
require('config.php');
try{
$ngrokUrl = "ngrok url";
$bot = new TelegramBot($token);
$jH = new jsonHandler($token);
var_dump($bot->setWebhook($ngrokUrl));
$webhookJson = $jH->getWebhookJson();
$chatId = $jH->getChatId($webhookJson);
$msg = $jH->getText($webhookJson) !== "" ? $jH->getText($webhookJson) : "";
switch($msg){
default:{
if ($msg[0] == '/')
$bot->sendMessage($chatId, 'The command does not exist');
break;
}
case '/test':{
$msg = 'test test';
$bot->sendMessage($chatId, $msg);
break;
}
case '/help':{
$msg = 'Help!';
$bot->sendMessage($chatId, $msg);
break;
}
}
}catch(ErrorException $e){
echo $e->getMessage();
}
?>
And the config.php file:
<?php
function fetchApi($url){
$req = curl_init($url);
$resp = curl_exec($req);
if($resp == false){
$error = curl_error($req);
curl_close($req);
throw new ErrorException($error);
}
else{
curl_close($req);
//return $resp;
}
}
class TelegramBot{
protected $tUrl;
function __construct($token){
$this->tUrl = "https://api.telegram.org/bot".$token;
}
function setUrl($method){
return $this->tUrl."/".$method;
}
function sendMessage($chatId, $msg){
$data = [
'chat_id' => $chatId,
'&text' => $msg
];
$url = $this->setUrl("sendMessage?".http_build_query($data));
fetchApi($url);
file_get_contents($url);
}
class jsonHandler extends TelegramBot{
function getWebhookJson(){
$json = file_get_contents("php://input");
return json_decode($json, true);
}
function getChatId($jsonDecoded){
return $jsonDecoded["message"]["chat"]["id"];
}
function getText($jsonDecoded){
return $jsonDecoded["message"]["text"];
}
}
?>

how to use dreamscape api in nodejs for check domain name

I have already work this in php. Here is my working code:
$request = array(
'DomainNames' => $domain_names
);
$response = dreamScapeAPI('DomainCheck', $request);
$available = false;
$alt_domains = array(); // Alternative to user's expected domain names
if (!is_soap_fault($response)) {
// Successfully checked the availability of the domains
if (isset($response->APIResponse->AvailabilityList)) {
$availabilityList = $response->APIResponse->AvailabilityList;
foreach ($availabilityList as $list) {
if ($list->Available){
if ($domain == $list->Item) {
$available = true; // user prefered domain found
}
else {
$alt_domains[] = $list->Item;
}
}
}
}
else {
$error = $response->APIResponse->Errors;
foreach ($error as $e) {
$api_error = $e->Message;
//echo $e->Item . ' - ' . $e->Message . '<br />';
}
}
}
function dreamScapeAPI($method, $data = null) {
$reseller_api_soap_client = "";
$soap_location = 'http://soap.secureapi.com.au/API-2.1';
$wsdl_location = 'http://soap.secureapi.com.au/wsdl/API-2.1.wsdl';
$authenticate = array();
$authenticate['AuthenticateRequest'] = array();
$authenticate['AuthenticateRequest']['ResellerID'] = '**';
$authenticate['AuthenticateRequest']['APIKey'] = '**';
//convert $authenticate to a soap variable
$authenticate['AuthenticateRequest'] = new SoapVar($authenticate['AuthenticateRequest'], SOAP_ENC_OBJECT);
$authenticate = new SoapVar($authenticate, SOAP_ENC_OBJECT);
$header = new SoapHeader($soap_location, 'Authenticate', $authenticate, false);
$reseller_api_soap_client = new SoapClient($wsdl_location, array('soap_version' => SOAP_1_2, 'cache_wsdl' => WSDL_CACHE_NONE));
$reseller_api_soap_client->__setSoapHeaders(array($header));
$prepared_data = $data != null ? array($data) : array();
try {
$response = $reseller_api_soap_client->__soapCall($method, $prepared_data);
} catch (SoapFault $response) { }
return $response;
}
I tried with this : https://github.com/dan-power/node-dreamscape
But domain search can not work properly. Mainly, I want it on nodejs using nodejs dreamscape api but this method is not available on nodejs.
Here is my working demo: click here

List Azure files and folders from File share snapshots with php

To list the files and folders from Azure Files can be done with this code:
function ListFolder($shareName, $path)
{
global $fileRestProxy;
$vMaxResultados = 5000;
$vNextMarker = "";
$listResult = null;
try
{
do
{
$options = new ListDirectoriesAndFilesOptions();
$options->setMaxResults($vMaxResultados);
$options->setMarker($vNextMarker);
$listResult = $fileRestProxy->ListDirectoriesAndFiles($shareName,$path,$options);
$vNextMarker = $listResult->getNextMarker();
} while ($vNextMarker != "");
}
catch (Exception $e)
{
$code = $e->getCode();
$error_message = $e->getMessage();
return "ERROR:$code:$error_message";
}
return $listResult;
}
But how is the sintaxis or method to the same with a snapshot from these Share?
This doesn't work:
function ListSnapshotFolder($shareName, $path, $snapshot)
{
global $fileRestProxy;
$vMaxResultados = 5000;
$vNextMarker = "";
$listResult = null;
try
{
do
{
$options = new ListDirectoriesAndFilesOptions();
$options->setMaxResults($vMaxResultados);
$options->setMarker($vNextMarker);
$shareFull = $shareName . "?snapshot=" . $snapshot;
$listResult = $fileRestProxy->ListDirectoriesAndFiles($shareFull,$path,$options);
$vNextMarker = $listResult->getNextMarker();
} while ($vNextMarker != "");
}
catch (Exception $e)
{
$code = $e->getCode();
$error_message = $e->getMessage();
return "ERROR:$code:$error_message";
}
return $listResult;
}
Is there any parameter in the $option object to add?
Or maybe the $shareFull must be created in some format?
$shareFull = $shareName . "?snapshot=" . $snapshot;
Thanks in advance.
I believe you have found a bug in the SDK. I looked up the source code here and there's no provision to provide sharesnapshot query string parameter in the options as well as the code does not even handle it.
public function listDirectoriesAndFilesAsync(
$share,
$path = '',
ListDirectoriesAndFilesOptions $options = null
) {
Validate::notNull($share, 'share');
Validate::canCastAsString($share, 'share');
Validate::canCastAsString($path, 'path');
$method = Resources::HTTP_GET;
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->createPath($share, $path);
if (is_null($options)) {
$options = new ListDirectoriesAndFilesOptions();
}
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_REST_TYPE,
'directory'
);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_COMP,
'list'
);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_PREFIX_LOWERCASE,
$options->getPrefix()
);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_MARKER_LOWERCASE,
$options->getNextMarker()
);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_MAX_RESULTS_LOWERCASE,
$options->getMaxResults()
);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_TIMEOUT,
$options->getTimeout()
);
$dataSerializer = $this->dataSerializer;
return $this->sendAsync(
$method,
$headers,
$queryParams,
$postParams,
$path,
Resources::STATUS_OK,
Resources::EMPTY_STRING,
$options
)->then(function ($response) use ($dataSerializer) {
$parsed = $dataSerializer->unserialize($response->getBody());
return ListDirectoriesAndFilesResult::create(
$parsed,
Utilities::getLocationFromHeaders($response->getHeaders())
);
}, null);
}
You may want to open up an issue here: https://github.com/Azure/azure-storage-php/issues and bring this to SDK team's attention.

bluedart api pincode search not working in php for api integration

Any one please to help me i have one problem in blue dart api error. NO Error is came. how to solve this problem.
require_once('lib/nusoap.php');
function soaprequest($api_url, $api_username, $api_password, $service, $params)
{
if ($api_url != '' && $service != '' && count($params) > 0)
{
$wsdl = $api_url."?wsdl";
$client = new nusoap_client($wsdl, 'wsdl');
$client->setCredentials($api_username,$api_password);
$error = $client->getError();
if ($error)
{
echo "\nSOAP Error\n".$error."\n";
return false;
}
else
{
$result = $client->call($service, $params);
if ($client->fault)
{
print_r($result);
return false;
}
else
{
$result_arr = json_decode($result, true);
$return_array = $result_arr['result'];
return $return_array;
}
}
}
}
$api_url = "http://netconnect.bluedart.com/ver1.7/Demo/ShippingAPI/Finder/ServiceFinderQuery.svc?wsdl";
//$api_url = "http://netconnect.bluedart.com/ Demo/ShippingAPI/Finder/ServiceFinderQuery.svc?wsdl";
$api_username='XXXXXXXXXX';
$api_password = 'AAAAAAAAAAAAAAAAAAAAAAA';
$service ='GetServicesforPincode';
$params = array('pinCode'=>'620102');
soaprequest($api_url, $api_username, $api_password, $service, $params);
above code is download from codeigniter library and it have also not working
the url you are supplying terminates with ?wsdl but inside the soaprequest function ?wsdl gets appended to the url so I guess your url would look like
http://netconnect.bluedart.com/ver1.7/Demo/ShippingAPI/Finder/ServiceFinderQuery.svc?wsdl?wsdl
which doesn't seem right so try without the ?wsdl at the end of the url?

Twitter access token request returns "Invalid or expired token"

I am using custom code to connect to Twitter and request an access token. For some reason when trying to post to "access_token" on the API it returns "invalid or expired token". The code is as follows (apart from a few external function calls and properties this should be sufficient to replicate the error):
public function authenticate($get,$return = false) {
session_start();
if (!isset($get['oauth_verifier'])){
// Step 1 - get a request token
$step1 = $this->processRequest('oauth/request_token',0,$this->pObj->getRedirectUrl().'?process=true');
parse_str($step1,$parts);
if ($parts['oauth_callback_confirmed'] !== 'true'){ die('Error with process'); }
$_SESSION['tw_secret'] = $parts['oauth_token_secret'];
// Step 2
$url = str_replace('1.1/','',$this->api_url);
header("Location: {$url}oauth/authenticate?oauth_token={$parts['oauth_token']}");
} else {
// Step 3
$this->o_token = $get['oauth_token'];
$this->o_secret = $_SESSION['tw_secret'];
$content['oauth_verifier'] = $get['oauth_verifier'];
$step3 = $this->processRequest('oauth/access_token',1,null,$content,'array');
}
}
// https://dev.twitter.com/docs/auth/creating-signature
private function generateSignature($oauth,$fullurl,$http_method,$content){
// Take params from url
$main_url = explode('?',$fullurl);
// Split the content
$contents = explode('&',$content);
$urls = array_merge(explode('&',$main_url[1]),$contents);
foreach ($urls as $param){
$bits = explode('=',$param);
if (strlen($bits[0])){
$oauth[$bits[0]] = rawurlencode($bits[1]);
}
}
ksort($oauth);
$string = http_build_query($oauth);
$new_string = strtoupper($http_method).'&'.urlencode($main_url[0]).'&'.urlencode(urldecode($string));
// The request_token request doesn't need a o_secret because it doesn't have one!
$sign_key = strstr($fullurl,'request_token') ? $this->c_secret.'&' : $this->c_secret.'&'.$this->o_secret;
return urlencode(base64_encode(hash_hmac('sha1',$new_string,$sign_key,true)));
}
public function processRequest($in_url,$test = false,$callback = null,$content = null, $content_type = 'json',$form_content_type = 'application/x-www-form-urlencoded'){
$method = 'GET';
// Twitter still uses Oauth1 (which is a pain)
$oauth = array(
'oauth_consumer_key'=>$this->c_key,
'oauth_nonce'=>$this->random(32),
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>time(),
'oauth_token'=>$this->o_token,
'oauth_version'=>'1.0'
);
$url = $this->api_url.$in_url;
if (strlen($callback)){
$oauth['oauth_callback'] = urlencode(urldecode($callback));
unset($oauth['oauth_token']);
$method = 'POST';
$url = str_replace('1.1/','',$url);
}
if (is_array($content) || strlen($content)){ $method = 'POST'; }
$oauth['oauth_signature'] = $this->generateSignature($oauth,$url,$method,'');
ksort($oauth);
foreach ($oauth as $k=>$v){
$auths[] = $k.'="'.$v.'"';
}
$stream = array('http' =>
array(
'method' => $method,
'ignore_errors'=>true, // http://php.net/manual/en/context.http.php - otherwise browser returns error not error content
'follow_location'=>false,
'max_redirects'=>0,
'header'=> array(
'Content-type: '.$form_content_type,
'Authorization: OAuth '.implode(', ',$auths),
'Connection: close'
)
)
);
if (is_array($content)){
$content = $content_type == 'json' ? json_encode($content) : http_build_query($content);
/* foreach ($content as $k=>$v){
$strs[] = "$k=".urlencode(urldecode($v));
}
// Just for now to keep things simple
$content = 'status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21';*/
}
if (!is_null($content)){
$stream['http']['content'] = $content;
}
// Tell streams to make a request
// Invalid key or 401 error tends to suggest an incorrect signing key / signature
$response = file_get_contents($url, false, stream_context_create($stream));
if ($test){
print'<pre>';print_r($oauth);print'</pre>';
print'<pre>';print_r($stream);print'</pre>';
//echo $callback.'<br>';
echo $url.'<br>';
//print'<pre>';print_r($http_response_header);print'</pre>';
print'<pre>[';print_r($response);print']</pre>';
}
if (!is_object(json_decode($response))){
// Content supplied is not json - just return it
return $response;
} else {
$response = json_decode($response);
}
return $this->pObj->convertObjectToArray($response);
}
The reason for the problems are:
1) The version of the Twitter API should not be included
2) The post is missing the Oauth_verifier in the signature
Thanks to twitteroauth for providing some guiding light.

Categories