Tableau Trusted Authentication Ticket with PHP - php

I am trying to understand how the Trusted Authentication ticket is meant to work with PHP. I've been looking up different questions and came up with this code
$url = 'https://tableau.godigitally.io/trusted/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=" . $userid . ""); // define what you want to post
$response = curl_exec($ch);
curl_close($ch);
//echo 'Test: ' . $response;
echo '<iframe src=', $url, $ticket, 'views/Dashboard2_0/Dashboard1?', $urlparams, '"
width="700" height="400">
</iframe>';
But I get the following error when I run this code
I have no idea where I'm going wrong. I have confirmed that my server configuration is correct by using the testing techniques described in https://help.tableau.com/current/server/en-us/trusted_auth_testing.htm

To Work with Tableau and web UI , the best way, you should add a Tableau js library to your web application and follow the steps
Generate the Ticket from tableau server call ,
To generate the ticket from tableau server ,first you should add your user to tableau server and follow the below steps
this is the code sample which you can use to generate the ticket
function getTabTicket(tableauServer, username, site){
return new Promise((resolve,reject)=>{
let url = new URL(tableauServer + '/trusted');
let body = {
username: username,
};
if (site) {
body['target_site'] = site;
}
let postData = querystring.stringify(body);
let proto = http;
if (url.protocol === 'https:') {
proto = https;
}
let req = proto.request({
method: 'POST',
hostname: url.hostname,
port:url.port,
path: '/trusted',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}, function (response) {
let ticketData = '';
response.on('data', function (chunk) {
ticketData += chunk;
});
response.on('end', function () {
let contents = {ticket: ticketData};
resolve(contents);
});
});
req.on('error', function (error) {
reject(error);
console.log('ERROR: ' + error);
});
req.write(postData);
req.end();
})
}
You can check this library which is open source you can use to generate the Ticket.
https://github.com/aalteirac/jwt-tableau-broker
https://anthony-alteirac.medium.com/tableau-trusted-authentication-the-ticket-broker-cloud-friendly-709789942aa3
After generating Ticket , you have to call the tableau server to get the report .
I am using js library for that .
Now 2 step is include js using NPM or by reference
and then you can call the function
var tableuReport = new tableau.Viz(this.reportContainerDiv, fullTableauDashboardUrl, Constants.tableauReportUISettings);
reportContainerDiv // the div element in which you have to render the component
fullTableauDashboardURL = {tableau_server_url}+"trusted"/{ticektId}/reportsuburl // the tableau URL it is in the format
for example your ,
tableau_server_url = "https://tableau-dev-abc.com"
tableauDashboardUrl = "#/site/CovidApp/views/IndiaReport/IndiaReport_v2?:iid=1/"
ticketId = "fjdjadheuihrieywfiwnfih"
So your final URL will be like
fullTableauDashboardUrl = "https://tableau-dev-abc.com/trusted/fjdjadheuihrieywfiwnfih/t/CovidApp/views/IndiaReport/IndiaReport_v2?:iid=1
fullTableauDashboardUrl.replace("#/site", "t");
PS: we have to replace the #/site to t

Related

Returning data from Google's Geocoding API with PHP curl

This question is similar to another one answered, however the solution in that case was to use a country code, which is not feasible for this particular use, as the address is being provided by the user through an input field (so a country may not be provided).
Here is the content of my current request
Request coming from AngularJS:
function getCoordinatesFromApi(address) {
addressApiResponse = $http({
url: 'php/coordinates.php',
method: 'get',
params: {
address: address
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
return addressApiResponse;
}
Request handled in PHP:
$api_maps = 'https://maps.googleapis.com/maps/';
$address = urencode($_GET['address']);
$api_key = 'API_key_here';
$url = $api_maps . 'api/geocode/json?address=' . $address . '&key=' . $api_key;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$curl_response = curl_exec($curl);
curl_close($curl);
echo ($curl_response);
When this is called, I consistently get back a valid response with status: 200, but data is an empty string.
I've checked the validity of the $url being build in PHP and it is ok, accessing that url directly in the browser displays a valid API response with data.
I've also tried using Angular's $http method and that too returns a valid response from the API:
function getCoordinatesFromApi(address) {
addressApiResponse = $http.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&key=API_key_here');
return addressApiResponse;
}
For some reason, it's ony the curl method that does not behave as expected. Has any one dealt with this problem?
If you are saying that echo ($curl_response); return nothing even if status is 200, it's because it's encoded JSON!
Please try this :
$decodedresponse = json_decode($curl_response);
//send me what var_dump return so I can hellp you accessing the array!
echo var_dump($decodedresponse);
//You would use as an array DEPENDING ON HOW THE ARRAY IS BUILD OF COURSE
echo $decodedresponse['response']['lat'];
echo $decodedresponse['response']['long'];
try again
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false

Geoserver Rest API update workspace name

I am trying to update workspace name through geoserver rest api using put method.
I am getting "Can't change the name of a workspace." error.
This is my code.
$service = geoserver_url;
$data = "<workspace><name>testnew</name></workspace>";
$url = $service . "rest/workspaces/workspacename";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$passwordStr = username:password
curl_setopt($ch, CURLOPT_USERPWD, $passwordStr);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/xml"););
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
Any kind of help appreciated.
That is not an allowable operation (as mentioned in the manual). Any PUT that changes the name of a workspace returns a 403 Error.
All you can do is create a new workspace, copy the contents of the old one and then delete it.
According to geoserver REST API documentations (link), you can simply edit workspace name (ws_name) by putting a request which has an xml string data in its body.
Here I've given you an example. Because of using Express as my application sever I've implemented a request using javascript but it can be changed to your favorite syntax.
const options = {
url: 'http://localhost:8080/geoserver/rest/workspaces/{current_ws_sname}',
method: 'PUT',
headers: { 'Content-type': 'text/xml' },
body: '<workspace><name>{new_ws_name}</name></workspace>',
auth: {
user: {geoserver_username},
pass: {geoserver_password}
}
and for executing the request based on above option variable I've used request function in Express:
request(options, (error, response, body) => {
console.log('response status code:' , response.statusCode)
console.log('response status message: ', response.statusMessage)
const result = {}
if (!error) {
const statusCode = response.statusCode;
const statusMessage = response.statusMessage;
if (statusCode == 200) {
result.err = false
result.msg = `Modified`
} else if (statusCode == 404) {
result.err = true
result.msg = 'Workspace not found!'
} else if (statusCode == 405) {
result.err = true
result.msg = 'Forbidden to change the name of the workspace!'
//because of your username and/or password
} else if (statusCode == 500) {
result.err = true
result.msg = 'Server internal error or duplicate names'
}
} else {
result.err = true,
result.msg = error;
}
res.send(result);
})
Don't forget to replace {current_ws_sname}, {new_ws_sname}, {geoserver_username}, {geoserver_password} by your own values.
All the possible situations have been mentioned as above (i.e. 200, 404, 405, 500) and there is no error message like "Can't change the name of a workspace." in geoserver documentations!
What statusCode and statusMessage do you get in response? Can you confirm that your {new_ws_sname} isn't duplicate?

How PHP get the content from web service?

I have a problem in getting the content/array from web service to my php code. When I type in the url in browser like http://server1-xeon.asuscomm.com/currency/?amount=1.20,from=MYR,to=SGD, then the result in the browser is displayed like this: [ 1.20MYR , 0.39SGD ]. My PHP code looks like this:
$ch = curl_init('http://server1-xeon.asuscomm.com/currency/?amount=1.20,from=MYR,to=SGD');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
echo $content;
Unfortunately, I get nothing use the code above. Looking for help.
Thanks.
UPDATED
$data=array(
'amount'=>1.2,
'fromCurrency'=>'MYR',
'toCurrency'=>'SGD'
);
$data_string = json_encode($data);
$ch = curl_init('http://server1-xeon.asuscomm.com/currency/WebService.asmx/YaHOO_CurrencyEx');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-type: application/json'));
$content= curl_exec($ch);
curl_close($ch);
$obj = json_decode($content);
echo $obj;
This page contains dynamic content, loaded by JavaScript. You can see it in Google Chrome for example by access view-source:http://server1-xeon.asuscomm.com/currency/?amount=1.20,from=MYR,to=SGD.
If you look closer to the source code of the page (file http://server1-xeon.asuscomm.com/currency/JQuery/app_converter.js) you'll see, that it uses this code to get exchange data under the hood:
$.ajax({type: "POST",
url: "WebService.asmx/YaHOO_CurrencyEx", // important: it's a relative URL!
data: "{amount:" + amount + ",fromCurrency:'" + from + "',toCurrency:'" + to + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function () {},
success: function (data) {
$('#results').html(' [ ' + amount + from + ' , ' + data.d.toFixed(2) + to + ' ] ');
});
So, actually you can make such request in PHP to avoid access dynamic content on the http://server1-xeon.asuscomm.com/currency/?amount=1.20,from=MYR,to=SGD page.
UPD:
I've added a more complete explanation.
By the time the page on http://server1-xeon.asuscomm.com/currency/?amount=1.20,from=MYR,to=SGD is loaded, a JavaScript code on this page (it means that it's executed on the client side, in a browser, not on your server) parses URL parameters and makes AJAX POST request to the URL http://server1-xeon.asuscomm.com/currency/WebService.asmx/YaHOO_CurrencyEx. It passes a JSON payload {amount:1.20,fromCurrency:'MYR',toCurrency:'SGD'} and gets a response like this {"d":0.390360}. So, you can just make a direct POST request to the http://server1-xeon.asuscomm.com/currency/WebService.asmx/YaHOO_CurrencyEx via curl, passing an amount, fromCurrency and toCurrency in JSON body and then decode received JSON response using json_decode($content);.
How data should look? Add this to your code from "UPDATED" and run:
$array["MYR"] = 1.2;
$array["SGD"] = doubleval($obj->d)
// Print simple array (print source for example)
echo "<pre>";
print_r($array);
echo "</pre>";
// Print true JSON-array
print_r(json_encode($array));
In web browser you will see:
Array
(
[MYR] => 1.2
[SGD] => 0.39036
)
{"MYR":1.2,"SGD":0.39036}
Can't understand your problem at this moment.
If you want print only returned value (digits), do it: echo $obj->d;

jQuery send file chunks to PHP upload to Ooyala

I have been stuck on this for over a week and I think I am long overdue for asking on here.. I am trying to get my users to upload their video files using the jQuery File Upload Plugin. We do not want to save the file on our server. The final result is having the file saved in our Backlot using the Ooyala API. I have tried various approaches and I am successful in creating the asset in Backlot and getting my upload URLs, but I do not know how to upload the file chunks using the URLs into Backlot. I have tried FileReader(), FormData(), etc. I am pasting the last code I had that created the asset, and gave me the upload URLs, but did not save any chunks into Backlot. I assume I may be getting stuck in one of my AJAX calls, but I am not very sure.
I keep getting:
Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
Here is my page with the JS for the jQuery File Upload widget by BlueImp:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/jquery.fileupload.js"></script>
</head>
<body>
<input id="fileupload" type="file" accept="video/*">
<script>
//var reader = FileReader();
var blob;
$('#fileupload').fileupload({
forceIframeTransport: true,
maxChunkSize: 500000,
type: 'POST',
add: function (e, data) {
var goUpload = true;
var ext = ['avi','flv','mkv','mov','mp4','mpg','ogm','ogv','rm','wma','wmv'];
var uploadFile = data.files[0];
var fileName = uploadFile.name;
var fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
if ($.inArray( fileExtension, ext ) == -1) {
alert('You must upload a video file only');
goUpload = false;
}
if (goUpload == true) {
$.post('../sites/all/themes/episcopal/parseUploadJSON.php', 'json=' + JSON.stringify(data.files[0]), function (result) {
var returnJSON = $.parseJSON(result);
data.filechunk = data.files[0].slice(0, 500000);
data.url = returnJSON[0];
//reader.onloadend = function(e) {
//if (e.target.readyState == FileReader.DONE) { // DONE == 2
//data.url = returnJSON[0];
// }
//}
//$.each(returnJSON, function(i, item) {
//data.url = returnJSON[0];
//blob = data.files[0].slice(0, 500000);
//console.log(blob);
//reader.readAsArrayBuffer(blob);
//data.submit();
//});
data.submit();
});
}
},//end add
submit: function (e, data) {
console.log(data); //Seems fine
//console.log($.active);
$.post('../sites/all/themes/episcopal/curlTransfer.php', data, function (result) { //fails
console.log(result);
});
return false;
}
});
</script>
</body></html>
Then there is the parseUploadJSON.php code, please keep in mind that my real code has the right Backlot keys. I am sure of this:
<?php
if(isset($_POST['json'])){
include_once('OoyalaAPI.php');
$OoyalaObj = new OoyalaApi("key", "secret",array("baseUrl"=>"https://api.ooyala.com"));
$expires = time()+15*60; //Adding 15 minutes in seconds to the current time
$file = json_decode($_POST['json']);
$responseBody = array("name" => $file->name,"file_name"=> $file->name,"asset_type" => "video","file_size" => $file->size,"chunk_size" => 500000);
$response = $OoyalaObj->post("/v2/assets",$responseBody);
$upload_urls = $OoyalaObj->get("/v2/assets/".$response->embed_code."/uploading_urls");
$url_json_string = "{";
foreach($upload_urls as $key => $url){
if($key+1 != count($upload_urls)){
$url_json_string .= '"' . $key . '":"' . $url . '",';
}else {
$url_json_string .= '"' . $key . '":"' . $url . '"';
}
}
$url_json_string .= "}";
echo $url_json_string;
}
?>
Then I have the curlTransfer.php:
<?php
echo "starting curl transfer";
echo $_POST['filechunk'] . " is the blob";
if(isset($_FILES['filechunk']) && isset($_POST['url'])){
echo "first test passed";
$url = $_POST['url'];
//print_r(file_get_contents($_FILES['filechunk']));
$content = file_get_contents($_FILES['filechunk']);
print_r($content);
$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: multipart/mixed"));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
try {
//echo 'success';
return httpRequest($ch);
}catch (Exception $e){
throw $e;
}
}
/****Code from Ooyala****/
function httpRequest($ch){
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
if(curl_error($ch)){
curl_close($ch);
return curl_error($ch);
}
$head=curl_getinfo($ch);
$content = $head["content_type"];
$code = $head["http_code"];
curl_close($ch);
}
?>
And the OoyalaApi.php is here (I saved a copy on my server):
https://github.com/ooyala/php-v2-sdk/blob/master/OoyalaApi.php
I apologize in advance if the code is messy and there's a lot of parts commented out. I have changed this code so much and I cannot get it. I appreciate all of your time and effort.
EDIT
I went back to trying FileReader out as this post Send ArrayBuffer with other string in one Ajax call through jQuery kinda worked for me, but I think it would be safer to read it using readAsArrayBuffer and now I am having trouble saving the array buffer chunks in some sort of array...
We have implemented ooyala file chunk upload in Ruby On Rails by referring this.
We have used the entire JS file as it is from this link.
https://github.com/ooyala/backlot-ingestion-library

No OpenID Server found at https://www.google.com/accounts/o8/id

Interesting enough I am using the same .php scripts on two different servers (a.com, b.com) with different results, I guess those have different configurations. While on a.com I am able to go through SSO process nicely, the b.com throws "No OpenID Server found at https://www.google.com/accounts/o8/id".
my php script looks as following:
$openid = new LightOpenID($_SERVER["HTTP_HOST"]);
$openid->required = array
(
'contact/email',
'namePerson/first',
'namePerson/last'
);
if(!$openid->mode)
{
$openid->identity = 'https://www.google.com/accounts/o8/id';
header('Location: ' . $openid->authUrl());
}
in b.com the line $openid->authUrl() throws an error saying:
No OpenID Server found at https://www.google.com/accounts/o8/id
What server configuration may cause this isse?
Luckily, server admins were able to quickly discover the config difference in php configuration allow_url_fopen = 1 solved the issue
Google has discontinued OpenID support and as of July 22nd 2015 has removed this endpoint.
The approved solution/answer has become obsolete.
Please migrate to OAuth. If using a client (javascript) login, this tutorial by google comes with a fully functional example.
this code below is another fully functional example (just tested it), but it goesone step further and integrates with a server side PHP script. please substitute your own CLIENT ID (as defined in your google developer console) and YOURDOMAIN.COM (in php).
<html lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="1111111111111111111-11111111111111111111111111111111111.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
</script>
<script>
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
userDataClear();
});
}
function disassociate() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.disconnect().then(function () {
console.log('User disconnected from association with app.');
userDataClear();
});
}
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile = googleUser.getBasicProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
// The ID token you need to pass to your backend:
var id_token = googleUser.getAuthResponse().id_token;
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://YOURDOMAIN.COM/twoStep02.php');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log('NEW Signed in Google Client ID: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
console.log("ID Token: " + id_token);
userDataDisplay(profile);
}
function userDataDisplay(profile) {
document.getElementById("foto").innerHTML = '<img src="' + profile.getImageUrl() + '"></img>';
document.getElementById("email").innerHTML = profile.getEmail();
document.getElementById("nome").innerHTML = profile.getName();
}
function userDataClear() {
document.getElementById("foto").innerHTML = ' ';
document.getElementById("email").innerHTML = ' ';
document.getElementById("nome").innerHTML = ' ';
}
</script>
</head>
<body>
<div id="login-button" class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
<div>Sign out</div>
<div>Disassociate App and Site (easily undone)</div>
<div id="foto"></div>
<div id="nome"></div>
<div id="email"></div>
</body>
</html>
and this is the php side to the jquery/ajax call (twoStep.php)
<?php
$idToken = $_POST["idtoken"];
$url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token='.$idToken;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$json = json_decode($response, true);
curl_close($ch);
$userEmail = $json["email"];
$clientId = $json["azp"];
print_r($json); // returns array console readable
?>
HINT 4 newbies: read console output by rightclicking on any element of the page and choosing "inspect element", then changing to CONSOLE tab.

Categories