Related
I am currently writing a piece of code to interface with an API in Python. Supplied by the company that hosts the API is a PHP script that logs into the API given the correct username and password, retrieved the current event ID (JSON format), and then logs out. This works perfectly.
Currently, I am in the process of writing a script in Python to do the very same thing, the current code is shown below. It logs in and out successfully, however, when it tries to retrieve the current event ID I get the status code 404, suggesting that the URL doesn't exist, despite this same URL working with the PHP code.
PHP Code:
define('BASE_URL', 'https://website.api.com/');
define('API_USER', 'username');
define('API_PASS', 'password');
$cookiefile = tempnam(__DIR__, "cookies");
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile);
$loginParams = array(
'username' => API_USER,
'password' => API_PASS
);
$obj = CurlPost($ch, BASE_URL . '/api/login', $loginParams);
if( $obj->success )
{
echo 'API login successful.' . PHP_EOL;
}
$obj = CurlGet($ch, BASE_URL . '/api/current-event-id');
echo 'API current event ID: ' . $obj->currentEventId . PHP_EOL;
// logout of the API
$obj = CurlGet($ch, BASE_URL . '/api/logout' );
if( $obj->success )
{
echo 'Logged out successfully.' . PHP_EOL;
}
curl_close($ch);
exit(0);
// -------------------------------------------------------------------------
// Functions
// -------------------------------------------------------------------------
// Run cURL post and decode the returned JSON object.
function CurlPost($ch, $url, $params)
{
$query = http_build_query($params);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, count($query));
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$output=curl_exec($ch);
$obj = json_decode($output);
return $obj;
}
// Run cURL get and decode the returned JSON object.
function CurlGet($ch, $url)
{
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
$output=curl_exec($ch);
$obj = json_decode($output);
return $obj;
}
Python Code:
import requests
BASE_URL = 'https://website.api.com/';
API_USER = "username";
API_PASS = "password";
headers = {'content-type': 'application/json'}
PARAMS = {'username':API_USER,'password':API_PASS}
session = requests.Session()
# Login
resp = session.post(BASE_URL + '/api/login',data=PARAMS)
if resp.status_code != 200:
print("*** ERROR ***: Login failed.")
else:
print("API login successful.")
resp = session.get(BASE_URL + '/api/current-event-id', headers=headers)
print(resp.status_code)
print(resp.text)
# Logout
resp = session.get(BASE_URL + '/api/logout')
if resp.status_code != 200:
print("*** ERROR ***: Logout failed.")
else:
print("API logout successful.")
It's ideal to change BASE_URL to:
'https://website.api.com'
the code looks fine to me when compared to php and should normally work.(Shouldn't you be passing some kind of authentication like a token?).
try debugging your API using postman.
It turns out that my API will only accept cookies transferred in the header, so I wrote a slight hack that dumped the cookiejar into a string that could be sent in the header file.
cookies = json.dumps(requests.utils.dict_from_cookiejar(resp.cookies));
cookies = cookies.replace('"', '')
cookies = cookies.replace('{', '')
cookies = cookies.replace('}', '')
cookies = cookies.replace(': ', '=')
cookies = cookies.replace(',', ';')
headers = {'Cookie':cookies}
resp = session.get(BASE_URL + '/api/current-event-id', headers=headers)
I'm trying to implement this exact feature on my web app as used by whm.
Please check this image
I read documentation for Single Sign On api and came up with following code:
<?php
// This can also be the reseller who owns the cPanel user.
$whmusername = "resellerusername";
$whmpassword = "abctesting";
// The user on whose behalf the API call runs.
$cpanel_user = "normaluser"; //under reseller
$query = "https://domainname.com:2087/json-api/create_user_session?api.version=1&user=$cpanel_user&service=cpaneld";
$curl = curl_init(); // Create Curl Object.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // Allow self-signed certificates...
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // and certificates that don't match the hostname.
curl_setopt($curl, CURLOPT_HEADER, false); // Do not include header in output
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // Return contents of transfer on curl_exec.
$header[0] = "Authorization: Basic " . base64_encode($whmusername.":".$whmpassword) . "\n\r";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // Set the username and password.
curl_setopt($curl, CURLOPT_URL, $query); // Execute the query.
$result = curl_exec($curl);
if ($result == false) {
error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");
// log error if curl exec fails
}
$decoded_response = json_decode( $result, true );
print_r($decoded_response);
$session_url = $decoded_response['data']['url'];
$cookie_jar = 'cookie.txt';
curl_setopt($curl, CURLOPT_HTTPHEADER, null); // Unset the authentication header.
curl_setopt($curl, CURLOPT_COOKIESESSION, true); // Initiate a new cookie session.
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_jar); // Set the cookie jar.
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_jar); // Set the cookie file.
curl_setopt($curl, CURLOPT_URL, $session_url); // Set the query url to the session login url.
$result = curl_exec($curl); // Execute the session login call.
if ($result == false) {
error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");
// Log an error if curl_exec fails.
}
$session_url = preg_replace( '{/login(?:/)??.*}', '', $session_url ); // make $session_url = https://10.0.0.1/$session_key
$query = "$session_url/execute/Ftp/list_ftp";
curl_setopt($curl, CURLOPT_URL, $query); // Change the query url to use the UAPI call.
$result = curl_exec($curl); // Execute the UAPI call.
if ($result == false) {
error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");
// log error if curl exec fails
}
curl_close($curl);
print $result;
?>
I get this as output:
Array
(
[data] => Array
(
[url] => https://domainname.com:2083/cpsess5326278746/login/?session=normaluser%3azRtR0RzLZ5owYZin%3acreate_user_session%2c4597fa33ff7ce68f3fdab84d9f3a51a1
[session] => normaluser:zRtR0RzLZ5owYZin:create_user_session,4597fa33ff7ce68f3fdab84d9f3a51a1
[expires] => 1490532538
[cp_security_token] => /cpsess5326278746
[service] => cpaneld
)
[metadata] => Array
(
[result] => 1
[command] => create_user_session
[version] => 1
[reason] => Created session
)
)
<br />
<b>Warning</b>: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument in <b>C:\xampp\htdocs\cpanel-api\open-cpanel.php</b> on line <b>34</b><br />
{"messages":null,"data":[{"homedir":"/home/normaluser","type":"main","user":"normaluser"},{"type":"logaccess","homedir":"/usr/local/apache/domlogs/normaluser","user":"normaluser_logs"}],"errors":null,"status":1,"metadata":{"transformed":1}}
but when I use this url in browser https://domainname.com:2083/cpsess5326278746/login/?session=normaluser%3azRtR0RzLZ5owYZin%3acreate_user_session%2c4597fa33ff7ce68f3fdab84d9f3a51a1,
it don't log me in to cPanel.
I've noticed that whm redirect page have following html code which logs user in:
<html slick-uniqueid="3"><head><meta http-equiv="refresh" content="2;URL=https://domainname.com:2083/cpsess7055670446/login/?session=normaluser:7PMD2WWAjnQc_cDL,e691a31623f55cf37ee32a63a390fb08"></head><body>
</body></html>
so how do I generate url like whm generates and log in user to cPanel (ie: open cpanel with normaluser logged in to it)?
You can try this. It`s work for me.
// This can also be the reseller who owns the cPanel user.
$whmusername = "resellerusername";
$whmpassword = "abctesting";
// The user on whose behalf the API call runs.
$cpanel_user = "normaluser"; //under reseller
$query = "https://$hostname:2087/json-api/create_user_session?api.version=1&user=$cpanel_user&service=cpaneld";
$curl = curl_init(); // Create Curl Object.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // Allow self-signed certificates...
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // and certificates that don't match the hostname.
curl_setopt($curl, CURLOPT_HEADER, false); // Do not include header in output
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // Return contents of transfer on curl_exec.
$header[0] = "Authorization: Basic " . base64_encode($whmusername . ":" . $whmpassword) . "\n\r";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // Set the username and password.
curl_setopt($curl, CURLOPT_URL, $query); // Execute the query.
$result = curl_exec($curl);
if ($result == false) {
error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");
return response()->json(['error' => 'There is a problem, Please try again.']);
}
$decoded_response = json_decode( $result, true );
//Access denied
if (isset($decoded_response['cpanelresult'])){
if($decoded_response['cpanelresult']['data']['result'] == 0)
return response()->json(['error' => 'Action Failed Unable to auto-login. Please contact support']);
}
//Invalid username
if ($decoded_response['metadata']['result'] == 0) return response()->json(['error' => 'Unable to login']);
//$targetURL = $decoded_response['data']['url'];
//return response()->json(['target_url' => $targetURL]);
curl_close($curl);
print $result;
I am probably barking at the wrong tree and I will need so pointing into correct direction. I am building WIFI portal. In essence:
User puts details in.
Details are being sent through cURL to REST post call.
<?php
include 'functions.php';
session_start();
$user_mac = $_SESSION["id"]; //user's mac address
$ap_mac = $_SESSION["ap"]; //AP mac
$ssid = $_SESSION["ssid"]; //ssid the user is on (POST 2.3.2)
$time = $_SESSION["t"]; //time the user attempted a request of the portal
$url = $_SESSION["url"]; //url the user attempted to reach
$sesh = $_SESSION["rand"];
/*
//Check what gets send
echo $user_mac;
echo '<br/>';
echo $ap_mac;
echo '<br/>';
echo $ssid;
echo '<br/>';
echo $time;
echo '<br/>';
echo $url;
echo '<br/>';
echo $sesh;
echo '<br/>';
echo $_POST["EMAIL"];
*/
$ch = curl_init();
$service_url = 'https://blablabla.com/rest/wifi/post_test';
$parm = array(
'KEY' => '1',
'BOOKING_ID' => $_POST["BOOKING_ID"],
'GUEST_NAME' => $_POST["GUEST_NAME"],
'EMAIL' => $_POST["EMAIL"],
'AP_MAC' => $ap_mac,
'USER_MAC' => $user_mac,
'SSID' => $ssid,
'REACH_ID' => $url,
'LOG_TIME' => $time,
'SESH_ID'=> $sesh
);
curl_setopt($ch, CURLOPT_URL,$service_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($parm));
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// get the reposne from serv
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
$jsonString = json_encode($server_output, true);
$data = json_decode($jsonString);
//show the response
echo '<pre>',print_r($data),'</pre>';
curl_close ($ch);
$macreturned = $data[0]['usermac'];
$macreturned1 = $jsonString[0]["usermac"];
echo $macreturned;
echo $macreturned1;
$status = $jsonString[0]["Status"];
$status_id = (int)$status;
IF ($status_id == 1 ) {
echo "Access denied.";
}
ELSE
{
echo "Access provided.";
sendAuthorization($macreturned,10);
}
curl_close ($ch);
?>
Oracle DB process the input.
DB sent response to portal in form o JSON string with data like MAC address and session length.
{
"Status":"2",
"usermac":"11:11:11:11:11",
"Return message":"Whoa we are in",
"sesh_length":"14400",
"sesh_id":"4568"
}
Oracle DB process the input.
{
"Status":"2",
"usermac":"11:11:11:11:11",
"Return message":"Whoa we are in",
"sesh_length":"14400",
"sesh_id":"4568"
}
DB sent response to portal in form o JSON string with data like MAC address and session length.
Depending on status output it executes another call through function sendAuthorization
<?php
function sendAuthorization($id, $minutes)
{
$unifiServer = "https://1.1.1.1";
$unifiUser = "Admin";
$unifiPass = "Admin";
// Start Curl for login
$ch = curl_init();
// We are posting data
curl_setopt($ch, CURLOPT_POST, TRUE);
// Set up cookies
$cookie_file = "/tmp/unifi_cookie";
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
// Allow Self Signed Certs
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// Force SSL3 only
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
// Login to the UniFi controller
curl_setopt($ch, CURLOPT_URL, "$unifiServer/login");
curl_setopt($ch, CURLOPT_POSTFIELDS,
"login=login&username=$unifiUser&password=$unifiPass");
// send login command
curl_exec ($ch);
// Send user to authorize and the time allowed
$data = json_encode(array(
'cmd'=>'authorize-guest',
'mac'=>$id,
'minutes'=>$minutes));
// Send the command to the API
curl_setopt($ch, CURLOPT_URL, $unifiServer.'/api/cmd/stamgr');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'json='.$data);
curl_exec ($ch);
// Logout of the UniFi Controller
curl_setopt($ch, CURLOPT_URL, $unifiServer.'/logout');
curl_exec ($ch);
curl_close ($ch);
unset($ch);
}
?>
Now this is when it stops working. I need to talk back to controller so I need to execute another function passing two elements usermac with sesh_length using cURL. However after receiving JSON from server something on PHP side of things is stopping executing another cURL function.
Now there are info about multiple cURL scripts running but I need to carry out call CALL depending on results from initial call.
Any help greatly appreciated, I dont work on this side of things so I know very little about PHP and cURL.
I have a problem with google's geocoding api:
I have an address which should be converted to latitude and longitude by google geocoding api using cURL. You will see my code below. It worked fine, however suddenly it stopped working and I got an "OVER_QUERY_LIMIT" answer. I looked it up and it normally happens if api is requested more than 2500 times a day. This is impossible, because my website is just upon finishing and has about 20-40 geocode requests per day.
So what is really the problem that "OVER_QUERY_LIMIT" occurs? Is something wrong with my code that somehow google blocks it?!
ini_set('allow_url_fopen', true);
$CookiePath = 'mycookiepath/geocookie.txt';
$userAgent = "mysite.com";
$ListURLRoot = "http://maps.googleapis.com/maps/api/geocode/json";
$ListURLSuffix = '&sensor=false';
$Curl_Obj = curl_init(); // Setup cURL
curl_setopt($Curl_Obj, CURLOPT_COOKIEJAR, $CookiePath);
curl_setopt($Curl_Obj, CURLOPT_USERAGENT, $userAgent);
curl_setopt($Curl_Obj, CURLOPT_HEADER, 0);
curl_setopt($Curl_Obj, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($Curl_Obj, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($Curl_Obj, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($Curl_Obj, CURLOPT_TIMEOUT, 30);
curl_setopt($Curl_Obj, CURLOPT_POST, 0);
$stAddr = str_replace(' ','+', $ast);
$City = str_replace(' ','+', $ac);
$address = "$stAddr,+$City,+{$aco},+{$ap}";
$address = str_replace(' ', '+', $address);
$ListURL = "{$ListURLRoot}?address=$address$ListURLSuffix";
curl_setopt ($Curl_Obj, CURLOPT_URL, $ListURL);
$output = curl_exec ($Curl_Obj);
GetLocation($output);
function GetLocation($output) {
global $db_connect;
$Loc = json_decode($output, true);
if(isset($Loc)) {
$i = 1;
while ($Loc['status']=="OVER_QUERY_LIMIT") {
if ($i > 14) {
echo "Geocode failed!";
exit();
}
sleep(1);
$i++;
}
if(isset($Loc['status']) && stristr($Loc['status'], 'OK')) {
if(isset($Loc['results'][0]['geometry']['location'])) {
$Lat = $Loc['results'][0]['geometry']['location']['lat'];
$Lng = $Loc['results'][0]['geometry']['location']['lng'];
}
}
else {
error_log($Loc['status'], 0);
echo "Unknown error occured!";
exit();
}
}
}
Thanks in advance!
Mostly it's a Google problem. Try to avoid server side geocodeing. Instead use a client side javascript solver.
I'm new to REST and I'm trying to develop a web app that will connect with JIRA from one sid (already covered) and with HP's ALM from the other side.
what I'm attempting to accomplish right now is basic authentication to ALM with PHP but can't seem to progress.
here is my code:
$handle=curl_init('http://192.168.1.7:8081');
$headers = array(
'Accept: application/xml',
'Content-Type: application/xml',
'Authorization: Basic YWRtaW46MTIzNA==',
);
$username='admin';
$password='1234';
$url = 'http://192.168.1.7:8081/qcbin/authentication-point/login.jsp';
curl_setopt_array(
$handle,
array(
CURLOPT_URL=>'http://192.168.1.7:8081/qcbin/rest/domains/default/projects/Ticomsoft/defects?login-form-required=y',
//CURLOPT_COOKIEFILE=>$ckfile,
CURLOPT_POST=>true,
//CURLOPT_HTTPGET =>true,
CURLOPT_COOKIEJAR=>$ckfile,
CURLOPT_VERBOSE=>1,
//CURLOPT_POSTFIELDS=>,
//CURLOPT_GETFIELDS=>'j_username=admin&j_password=1234&redirect-url=http://192.168.1.7:8081/myUiResource.jsps',
CURLOPT_SSL_VERIFYHOST=> 0,
CURLOPT_SSL_VERIFYPEER=> 0,
CURLOPT_RETURNTRANSFER=>true,
CURLOPT_FOLLOWLOCATION=>true,
CURLOPT_HEADER=>false,
CURLOPT_HTTPHEADER=> $headers,
CURLOPT_AUTOREFERER=>true
//CURLOPT_COOKIE=>
//CURLOPT_USERPWD=>"admin:yahala"
//CURLOPT_CUSTOMREQUEST=>"POST"
)
);
$result=curl_exec($handle);
$ch_error = curl_error($handle);
$response = curl_getinfo($handle);
print_r($response);
if ($ch_error) {
echo "cURL Error: $ch_error";
} else {
//var_dump(json_decode($result, true));
echo $result;
}
curl_close($handle);
?>
as you can see there is a lot of garbage as my trial and error progressed.
Here we go. I followed the QC Rest API documentation to study the order that QC expects requests to be made. I've tested it against ALM11. I'm new to cURL as well, but this should get you in and working......
<?php
//create a new cURL resource
$qc = curl_init();
//create a cookie file
$ckfile = tempnam ("/tmp", "CURLCOOKIE");
//set URL and other appropriate options
curl_setopt($qc, CURLOPT_URL, "http://qualityCenter:8080/qcbin/rest/is-authenticated");
curl_setopt($qc, CURLOPT_HEADER, 0);
curl_setopt($qc, CURLOPT_HTTPGET, 1);
curl_setopt($qc, CURLOPT_RETURNTRANSFER, 1);
//grab the URL and pass it to the browser
$result = curl_exec($qc);
$response = curl_getinfo($qc);
//401 Not authenticated (as expected)
//We need to pass the Authorization: Basic headers to authenticate url with the
//Correct credentials.
//Store the returned cookfile into $ckfile
//Then use the cookie when we need it......
if($response[http_code] == '401')
{
$url = "http://qualityCenter:8080/qcbin/authentication-point/authenticate";
$credentials = "qc_username:qc_password";
$headers = array("GET /HTTP/1.1","Authorization: Basic ". base64_encode($credentials));
curl_setopt($qc, CURLOPT_URL, $url);
curl_setopt($qc, CURLOPT_HTTPGET,1); //Not sure we need these again as set above?
curl_setopt($qc, CURLOPT_HTTPHEADER, $headers);
//Set the cookie
curl_setopt($qc, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt($qc, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($qc);
$response = curl_getinfo($qc);
//The response will be 200
if($response[http_code] == '200')
{
//Use the cookie for subsequent calls...
curl_setopt($qc, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($qc, CURLOPT_RETURNTRANSFER, true);
curl_setopt($qc, CURLOPT_URL, "http://qualityCenter:8080/qcbin/rest/domains/Your_Domain/projects/Your_Project/defects");
//In this example we are retrieving the xml so...
$xml = simplexml_load_string(curl_exec($qc));
print_r($xml);
//Call Logout
logout($qc,"http://qualityCenter:8080/qcbin/authentication-point/logout");
}
else
{
echo "Authentication failed";
}
}
else
{
echo "Not sure what happened?!";
}
//Close cURL resource, and free up system resources
curl_close($qc);
function logout($qc, $url)
{
curl_setopt($qc, CURLOPT_URL, $url);
curl_setopt($qc, CURLOPT_HEADER, 0);
curl_setopt($qc, CURLOPT_HTTPGET,1);
curl_setopt($qc, CURLOPT_RETURNTRANSFER, 1);
//grab the URL and pass it to the browser
$result = curl_exec($qc);
}
?>
Let me know if it worked!
Thanks,
Rich
one of the important things to keep in mind is after authenticating you must do the following
POST /qcbin/rest/site-session
with cookies LWSSO
this will return QCSession and XSRF-TOKEN which are needed to perform any operations
Here is my solution in Perl for this problem: The authentication step is performed first, setting the cookie for the next libcurl request which then can be performed with no problems. This is a version for background jobs. For a dialog application, the credentials could be passed through from the user's input instead. Also, I had to do this with https instead of http. The Perl program also shows how to instruct curl for https (there is a very good how-to on http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/ ).
#!/usr/bin/perl
# This script accesses, as a proxy, the REST API of the HP quality center
# Running it without query parameter, the complete list of defects is returned
# A query parameter, e.g. 'query={id[2283]}' will be passed as is to the HP QC API
# We are using the libcurl wrapper WWW::Curl::Easy
# The access is https, so a certificate has to be passed to libcurl
# The main point for using curl, however, is the authentication procedure:
# HP requires a preparative call to a special authentication service
# The authentication ticket will then be passed back as a cookie
# Only with this ticket, the real GET request on the defects can be performed
use WWW::Curl::Easy;
use strict;
use warnings;
use constant {
URL_QC_DEFECTS => "https://[QC DOMAIN]/qcbin/rest/domains/[DOMAIN]/projects/[PROJECT]/defects/",
URL_QC_AUTH => "https://[QC DOMAIN]/qcbin/authentication-point/authenticate",
PATH_CERT => "[PATH TO CREDENTIALS]" # contains certificate and credentials, see below
};
doRequest( URL_QC_DEFECTS . "?" . $ENV{QUERY_STRING} );
return 0;
sub doRequest {
my ($url,$cookies,$response) = (shift,"","");
eval {
my $curl = get_curl_instance(\$cookies,\$response);
authenticate( $curl );
get( $curl, $url );
if ($response =~ /.*?(<\?xml\b.*)/s) {
print "Content-Type:text/xml\n\n";
print $1;
}
else {
die "The response from HP QC is not in XML format";
}
};
if ($#) {
print "Content-Type:text/plain\n\n$#";
}
}
sub get_curl_instance {
my ($cookie,$response) = #_;
my $curl = WWW::Curl::Easy->new( );
open( my $cookiefile, ">", $cookie) or die "$!";
$curl->setopt( CURLOPT_COOKIEFILE, $cookiefile );
open( my $responsefile, ">", $response) or die "$!";
$curl->setopt( CURLOPT_WRITEDATA, $responsefile );
$curl->setopt( CURLOPT_SSL_VERIFYPEER, 1);
$curl->setopt( CURLOPT_SSL_VERIFYHOST, 2);
$curl->setopt( CURLOPT_CAINFO, cert() );
$curl->setopt( CURLOPT_FOLLOWLOCATION, 1 );
return $curl;
}
sub authenticate {
my $curl = shift;
my ($rc,$status);
$curl->setopt( CURLOPT_URL, URL_QC_AUTH );
$curl->setopt( CURLOPT_USERPWD, cred( ) );
if (($rc = $curl->perform( )) != 0) {
die "Error Code $rc in curl->perform( ) on URL " . URL_QC_AUTH;
}
if (($status=$curl->getinfo(CURLINFO_HTTP_CODE))!="200") {
die "HTTP-Statuscode $status from authentication call";
}
}
sub get {
my ($curl,$url) = #_;
my ($rc,$status);
$curl->setopt( CURLOPT_URL, $url );
$curl->setopt( CURLOPT_HEADER, { Accept => "text/xml" } );
if (($rc = $curl->perform( )) != 0) {
die "Error Code $rc from defects request";
}
if (($status=$curl->getinfo(CURLINFO_HTTP_CODE))!="200") {
die "HTTP Statuscode $status from defects request";
}
}
sub cred {
open CRED, PATH_CERT . '/.cred_qc' or die "Can't open credentials file: $!";
chomp( my $cred = <CRED>);
close CRED;
return $cred;
}
sub cert {
return PATH_CERT . '/qc.migros.net.crt';
}
As an alternative to Sohaib's answer concerning the need to POST to /qcbin/rest/site-session after authenticating, you can do both in one step by POSTing to /qcbin/api/authentication/sign-in , as per the below:
"There are four cookies that come back, and in ALM 12.53 the authentication point has changed ( but the documentation has not so it sends you to the wrong place ! )
So, send a POST request with BASIC authentication, base64 encoded username / password to /qcbin/api/authentication/sign-in and you will get back
LWSSO_COOKIE_KEY
QCSESSION
ALM_USER
XSRF_TOKEN
include these with all your subsequent GETS and PUTS and you should be OK."
(This answer is taken from https://community.microfocus.com/t5/ALM-QC-User-Discussions/Authentication-fails-when-trying-to-pull-data-from-ALM-server/td-p/940921, and worked for me in a similar context).