I am trying to use the Sinch Rest API with PHP to mute and unmute specific participants from Conference calls but have not been able to find an example of how to send an application signed request with PHP. I have been trying to work off of this documentation from Sinch here https://www.sinch.com/docs/voice/rest/index.html#muteunmuteconfparticipant
My initial guesses are that this would require the use of CURL and that I would also need to use similar pieces of this example to sign my application but I"m not sure how to combine the two. https://github.com/sinch/php-auth-ticket
Any help appreciated. Thanks!
edit: #cjensen I added this code snippet I've been working on to try and use as the signed request maker. It's very similar to that github link above
<?php
class SinchTicketGenerator
{
private $applicationKey;
private $applicationSecret;
public function __construct($applicationKey, $applicationSecret)
{
$this->applicationKey = $applicationKey;
$this->applicationSecret = $applicationSecret;
}
public function generateTicket()
{
$request = [
'command' => 'mute',
];
$requestJson = preg_replace('/\s+/', '', json_encode($request));
$requestBase64 = $this->base64Encode($requestJson);
$digest = $this->createDigest($requestJson);
$signature = $this->base64Encode($digest);
$requestSigned = $requestBase64.':'.$signature;
return $requestSigned;
}
private function base64Encode($data)
{
return trim(base64_encode($data));
}
private function createDigest($data)
{
return trim(hash_hmac('sha256', $data, base64_decode($this->applicationSecret), true));
}
}
$generator = new SinchTicketGenerator('app-key', 'app-secret');
$signedrequest = $generator->generateTicket();
echo $signedrequest;
?>
Related
I have a function in my Laravel application that generates TwiML for a holding queue. It seems that when I try to dynamically generate the value for the waitUrl attribute, I end up getting a 500 server error during runtime. Routes are properly established and I'm able to view the correct XML at the waitURL in the browser. However, the error persists.
If I create a static XML file with the same exact content, or use a TwiML Bin, it works like a charm.
Here are the relevant functions:
public function wait() {
return $this->generateWaitTwiml();
}
public function onHold($agentId) {
return $this->generateHoldQueueTwiml($agentId, '/phone/wait');
}
private function generateHoldQueueTwiml($agentId, $waitUrl = null) {
$queue = $agentId . '_hold';
if ($waitUrl === null){
$waitUrl = 'path_to_static.xml';
}
$queue = $agentId . '_hold';
$response = new Twiml();
$response->enqueue(
$queue,
['waitUrl' => $waitUrl]
);
return response($response)->header('Content-Type', 'application/xml');
}
private function generateWaitTwiml() {
$response = new Twiml();
$response
->play('http://path_to_my.mp3');
return response($response)->header('Content-Type', 'application/xml');
}
This was resolved by excluding the URIs from the CSRF verification (in VerifyCsrfToken.php):
class VerifyCsrfToken extends Middleware {
protected $except = [
'uri/',
'uri2/*',
];
}
searching for a good authentication method for my rest api i came a cross this :
"What is stateless authentication?
Again, stateless means without state. But, how can we identify a user from a token without having any state on the server? Surprisingly, it’s very easy! just send all the data to the client.
So what would you store/send (send to client/network)? The most trivial example is an access token. Access tokens usually have a unique ID, an expiration date and the ID of the client that created it. To store this, you would just put this data into a JSON object, and encode it using base64."
Now, having a self-contained token, you will need to make sure that nobody can manipulate the data. For this you should sign it using MAC algorithm or any other digital signature method available.
This is a little confusing for me , how can i validate the access token when the request comes(nothing stored to match it), but i find it a good idea and i want to implement it, any advice will be very helpful.
My rest api is very simple I receive every request to index.php , then i create new object with the request class to analyze every element of the request.
request class looks like this :
<?php
class Request {
public $url_elements;
public $verb;
public $parameters;
public function __construct() {
$this->verb = $_SERVER['REQUEST_METHOD'];
$this->url_elements = explode('/', $_SERVER['PATH_INFO']);
$this->parseIncomingParams();
$this->format = 'json';
if(isset($this->parameters['format'])) {
$this->format = $this->parameters['format'];
}
return true;
}
public function parseIncomingParams() {
$parameters = array();
if (isset($_SERVER['QUERY_STRING'])) {
parse_str($_SERVER['QUERY_STRING'], $parameters);
}
$body = file_get_contents("php://input");
$content_type = false;
if(isset($_SERVER['CONTENT_TYPE'])) {
$content_type = $_SERVER['CONTENT_TYPE'];
}
switch($content_type) {
case "application/json":
$body_params = json_decode($body);
if($body_params) {
foreach($body_params as $param_name => $param_value) {
$parameters[$param_name] = $param_value;
}
}
$this->format = "json";
break;
case "application/x-www-form-urlencoded":
parse_str($body, $postvars);
foreach($postvars as $field => $value) {
$parameters[$field] = $value;
}
$this->format = "html";
break;
default:
break;
}
$this->parameters = $parameters;
}
}
?>
After this i proceed with the proper controller that is the first element after index.php/
Thank you very much for your time and sorry if the question is not very clear as i am new to rest :/
I have to fetch task using Asana API under project,
I tried so far but gives error
$tasksall = $asana->getProjectTasks($projectId);
$tasksJson = json_decode($tasksall);
print_r($taskJson);
Call a function
public function getProjectTasks($projectId){
return $this->askAsana($this->taskUrl."?project={$projectId}");
}
Try this..
Use this as your main part
$projectId='Your project id';
$taskbyproject = $asana->getProjectTasks($projectId);
//print_r($taskbyproject);
Use this as Function
public function getProjectTasks($projectId, array $opts = array())
{
$options = http_build_query($opts);
return $this->askAsana($this->taskUrl . '?project=' . $projectId . '&' . $options);
}
I am trying to connect to this WSDL server using PHP:
https://services.PWSDemo.com/CreditCardTransactionService.svc?wsdl
I have tried:
$client = new SoapClient('https://services.PWSDemo.com/CreditCardTransactionService.svc?wsdl');
$result = $client->AuthorizeAndCapture( array( 'credentials' => $credentials, 'authorizeAndCaptureParams' => $acparam));
Where $credentials is an array like this:
$credentials = array();
$credentials['ClientCode'] = "XYZOffice";
$credentials['UserName'] = "Linxtrans";
$credentials['Password'] = "C0de5ample!";
And
$acParem is a similar but much more complicated array I am not posting in full for brevity (see below for more)
I also tried with classes such as:
class ClientCredentials {
public $ClientCode;
public $Password;
public $UserName;
}
Without success, I always get the error: The authorizeAndCaptureParams parameter is required.
In the class example, the acparam is defined this way:
class AuthorizeAndCaptureParams {
public $AddOrUpdateCard;
public $CreditCardTransaction;
public $TerminalIdentifier;
public function __construct(){
$this->TerminalIdentifier = new TerminalIdentifier();
$this->CreditCardTransaction= new CreditCardTransaction();
}
}
In the PHP array attempt, I start this way:
$acParams['CreditCardTransaction'] = array();
$acParams['CreditCardTransaction']['CreditCard'] = array();
$acParams['CreditCardTransaction']['CreditCard']['Cardholder'] = array();
$acParams['CreditCardTransaction']['CreditCard']['Cardholder']['FirstName'] = "John";
$acParams['CreditCardTransaction']['CreditCard']['Cardholder']['LastName'] = "Smith";
$acParams['CreditCardTransaction']['CreditCard']['BillingAddress'] = array();
The company only supplies examples in C# and when asked for PHP support, they reply that PHP is not supported, but "many of their customers implemented their API with PHP".
And so, I am at a loss as to how to proceed....
I have implemented WSDL clients in the past, but with simple data structures, but never with such elaborate data structures!
I am trying to setup an Oauth server using the pecl-php oauth library http://php.net/manual/en/book.oauth.php
This code assumes that the client has already received a user verified access token, for simplicity sake I've not included any database calls and have hardcoded matching values into my client and provider.
Class OauthVerify
{
private static $consumer_secret = 'f63ed7f7a8899e59d3848085c9668a0d';
private static $token_secret = '72814e6059441037152eecef2e8559a748b84259';
private $provider;
public function __construct()
{
$this->provider = new OAuthProvider();
$this->provider->consumerHandler(array($this,'consumerHandler'));
$this->provider->timestampNonceHandler(array($this,'timestampNonceHandler'));
$this->provider->tokenHandler(array($this,'checkAccessToken'));
}
//Check the client request
public function checkRequest()
{
try {
$this->provider->checkOAuthRequest();
} catch (Exception $Exception) {
return OAuthProvider::reportProblem($Exception);
}
return true;
}
public static function timestampNonceHandler($Provider)
{
//I'm leaving out this logic now, to keep it simple and for testing purposes
return OAUTH_OK;
}
public static function consumerHandler($Provider)
{
//I'm leaving out this logic now, to keep it simple and for testing purposes
$Provider->consumer_secret = self::$consumer_secret;
return OAUTH_OK;
}
public static function checkAccessToken($Provider)
{
$Provider->token_secret = self::$token_secret;
return OAUTH_OK;
}
}
The above code should give me the barebones I need to authenticate an Oauth request.
Before any particular route is executed I call the $OauthVerify->checkRequest() method which checks if the client request is valid, however the server keeps throwing a 'signatures do not match' error. I don't think that the problem is with the clients as I've tried both postman (for chrome) and a PHP implementation and they both generate the same signature. I have however for interest sake included my client call.
$consumer_key = '87d6d61e87f0e30d8747810ae40041d1';
$consumer_secret = 'f63ed7f7a8899e59d3848085c9668a0d';
$token= 'b9d55b3ec4b755d3fe25d7a781da1dfd044b5155';
$token_secret = '72814e6059441037152eecef2e8559a748b84259';
$timestamp = '1417515075';
$nonce = '9QV4rn';
$version = '1.0';
$method = 'GET';
$url = 'https://localhost/micro/v1/nappi';
try {
$oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$oauth->enableDebug();
$oauth->disableSSLChecks();
$oauth->setNonce($nonce);
$oauth->setTimestamp($timestamp);
$oauth->setToken($token, $token_secret);
$oauth->setVersion($version);
$oauth->fetch("$url");
$json = json_decode($oauth->getLastResponse());
print_r($json);
}
catch(OAuthException $E) {
print_r($E);
}
I've burned a good couple of hours trying to figure this out, someone please help!
I finally managed to solve it, my .htaccess file had a rewrite rule that was processing a _url parameter for my framework. This parameter was ofcourse being included in the signature that the server generated. I simply instructed OAuth Provider to ignore the the _url parameter in my constructor:
$this->provider->setParam('_url',NULL);,
that was all it took, everything runs perfectly now.