SugarCRM REST api error - rest

I am trying to retrieve custom module data through the Sugarcrm REST api but I am not able to do so as I am not even able to login with the documentation code, I tried same thing as given in documentation
<?php
// specify the REST web service to interact with
$url = 'localhost/~jmertic/sugarcrm/service/v4_1/rest.php';
// Open a curl session for making the call
$curl = curl_init($url);
// Tell curl to use HTTP POST
curl_setopt($curl, CURLOPT_POST, true);
// Tell curl not to return headers, but do return the response
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Set the POST arguments to pass to the Sugar server
$parameters = array(
'user_auth' => array(
'user_name' => 'username',
'password' => md5('password'),
),
);
$json = json_encode($parameters);
$postArgs = array(
'method' => 'login',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => $json,
);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);
// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response);
if ( !is_object($result) ) {
die("Error handling result.\n");
}
if ( !isset($result->id) ) {
die("Error: {$result->name} - {$result->description}\n.");
}
// Get the session id
$sessionId = $result->id;
changed the username,password and url to match my setup but i get an error stating
No direct script access allowed
I tried to search this on web but couldnt find any relevant solution.
I am using sugarCRM 6.5.0RC2 version
Regards,
Anand Joshi

You probably has some defense configured on your WEB server which allows you to access only to index.php.
To verify it, try to go from the browser to your API URL: http://YOUR_DOMAIN_NAME/service/v4_1/rest.php
Or/and run from terminal: wget http://YOUR_DOMAIN_NAME/service/v4_1/rest.php
If it shows the same message, check your .httaccess on this folder or/and your web server config file.
If no, how do you run the API test script? through CLI or from browser?
Also I suggest you to use some Open Source SugarCRM REST API Wrapper. I use this one: https://github.com/asakusuma/SugarCRM-REST-API-Wrapper-Class

Shouldn't the line be this...
$url = 'http://yoursugarinstance/service/v4_1/rest.php';

Related

Connect Yii2 to another RESTful application

I have a Yii2 application. I would like to connect it to another restful webpage. So user will send data to my application, I will send them via POST request and do something according to a JSON response. How can I do the send a request / fetch response part in a yii2?
The best method would be to use curl to make end to end calls to your RESTful API, in which case you may be interested in checking out a yii2 extension for curl.
Without a Yii2 extension, we can accomplish this by creating a more general function in a controller or more preferably a model (for shared access) as exampled below:
/**
* $method e.g POST, GET, PUT
* $data = [
'param' => 'value',
]
*/
public function curlToRestApi($method, $url, $data = null)
{
$curl = curl_init();
// switch $method
switch ($method) {
case 'POST':
curl_setopt($curl, CURLOPT_POST, 1);
if($data !== null) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
// logic for other methods of interest
// .
// .
// .
default:
if ($data !== null){
$url = sprintf("%s?%s", $url, http_build_query($data));
}
}
// Authentication [Optional]
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "username:password");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
We then call this function on a need basis i.e. depending on the method and url and/or data.
It is also conveniently easy to use file_get_contents if fopen wrapper is enabled in order to access Web Service URLs.
$response = file_get_contents('http://example.com/path/to/api?param1=stack&param2=overflow');
If a JSON response is served, you can recover the php array as follows:
$response = json_decode($response, TRUE);
If an XML response is returned, then
$response = new \SimpleXMLElement($response);
However, if the API endpoint returns an HTTP error status, the file_get_contents function fails with a warning and returns null.

Laravel rest api authentication

I am a beginner with building a rest api and authentication.
I've just been reading the following and explains a very simple setup:
laravel 5 rest api basic authentication
At the bottom the article explains not to send usernames and password with headers or in the url.
My question is basicly: can anyone give me an example how to use a cUrl request with the example above?
For example:
$service_url = 'http://example.com/api/conversations';
$curl = curl_init($service_url);
$curl_post_data = array(
'user' => 'user#user.com',
'passw' => '1234'
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response = curl_exec($curl);
curl_close($curl);
Laravel is shipped with Guzzle – an advanced HTTP client library. It's probably more reasonable to use that than a low-level cURL.
To do basic auth with Guzzle:
$client = new GuzzleHttp\Client();
$response = $client->post('http://example.com/api/conversations', [
'auth' => [
'user#user.com',
'1234'
]
]);
The response will be in $response->getBody();
If your target endpoint uses SSL – it's not too bad sending the credentials in the headers, but the trendy way is to use temporary tokens (eg. API key or OAuth access token).
In addition to the accepted answer, you can also create a generic function to handle all your curl requests.
You can use the following function to call external webservices and return the data/authentication information.
/*=============================================
* Call External Webservices using CURL
*
* #param $requestURL, $header -> (OPTIONAL)
* #return json
#=============================================*/
public function curlRequest($requestURL, $headers = array())
{
$getData = curl_init($requestURL);
curl_setopt($getData, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($getData, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($getData, CURLOPT_SSL_VERIFYHOST, false);
if (count($headers) != 0) {
curl_setopt($getData, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($getData);
return json_decode($response);
}
Use case specific example to use the above function for authentication:
$requestURL = 'http://www.example.com/api/userLogin';
$userAuthInfo = [
'email'=> 'example#example.com',
'password'=>'123456'
];
$result = $this->curlRequest($requestURL, $userAuthInfo);
dd($result); //Print the Result of the Authentication request

Simulating Discourse SSO login via php curl

I'm in the process of integrating Discourse into our platform (using an iframe) and I am trying to understand what I am doing wrong and can't get SSO to authenticate my users.
I am working on symfony 1.4 and I have an action that accommodates both the logic of displaying the page (that contains the iframe) and that of logging the users in.
public function executeViewDiscussionForum(sfWebRequest $request){
$requestIsInternal = $request->getParameter('isInternal');
if($requestIsInternal==='1'){
//====Discourse will redirect here again with the payload parameters
$response = DiscourseAuthDriver::makeCurlRequest('http://****.****.com:8080');
}
$url = parse_url($response['Location']);
$cookie = $response['Set-Cookie'];
parse_str($url['query'], $params);
$sso = $params['sso'];
$signature = $params['sig'];
// load the payload passed in by Discourse
$payload = $sso;
$ssoHelper = new SSOHelper();
// this should be the same in your code and in your Discourse settings:
$secret = '****';
$ssoHelper->setSecret( $secret );
// validate the payload
if (!($ssoHelper->validatePayload($payload,$signature))) {
// invaild, deny
$this->redirect404();
}
$nonce = $ssoHelper->getNonce($payload);
// Insert your user authentication code here ...
// Required and must be unique to your application
$userId = $this->currentUser->id;
// Required and must be consistent with your application
$userEmail = $this->currentUser->getEmailAddress();
// Optional - if you don't set these, Discourse will generate suggestions
// based on the email address
$extraParameters = array(
'username' => $this->currentUser->getUsername(),
'name' => $this->currentUser->getFullname()
);
// build query string and redirect back to the Discourse site
$query = $ssoHelper->getSignInString($nonce, $userId, $userEmail, $extraParameters);
DiscourseAuthDriver::makeCurlRequest('http://*****.***.com:8080/session/sso_login?' . $query, $cookie);
}
The SSOHelper class that im using is the one found here
And the DiscourseAuthDriver::makeCurlRequest is as below:
public static function makeCurlRequest($url, $cookie=null){
$ch = curl_init($url);
if($cookie){
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Set-Cookie: ".$cookie));
curl_setopt($ch, CURLOPT_NOBODY, 1);
}
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0"); // Necessary. The server checks for a valid User-Agent.
$response = curl_exec($ch);
$header = $response;
$header = self::get_headers_from_curl_response($header);
curl_close($ch);
return $header[1];
}
If I dont have SSO enabled I can see the main discourse page loading just fine in my iframe.
The logic behind the above was that by using curl I can essentially simulate the sign in process and then serve the logged in page in the iframe but that doesnt seem to cut it as even if I manually navigate to the sign in url with the hashed parameters and everything I get the following error:
"Account login timed out, please try logging in again"
I have checked other possible answers as well as my settings and I dont have the approval option set so I thought it might be due to session information not being passed in upon requesting the login but even after adding that it doesnt seem to work.
Can anyone see what is wrong with this or identify any flaws in the logic?
I dont know how but for some reason the request url works fine today and it does authenticate my users.
In order to avoid having to mess with headers and have issues with the iframe etc, I made it so that it only uses curl to retrieve the initial url that contains the payload data.
Once I grab these I process and construct the new request based on the given payload and then pass em to a hidden frame that is making the login request (i.e. from the browser) javascript is then taking over to remove this hidden frame and load a new one that is loading the main discourse page with the user already logged in.
Hope it helps someone in the future.

Access token for a simple FQL retrieving the number of status for a page

I'm doing a really simple PHP app using the latest Facebook PHP SDK which aims to display the number of status a page of mine has.
To do so I created an app to have the app id and the app secret but after I'm kinda lost.
I thought I needed an app secret token so I first tried like this:
<?php
public function getFacebookPosts() {
require __DIR__ . '/libs/facebook-sdk/facebook.php';
$appId = 'myID';
$appSecret = 'mySecret';
$facebook = new Facebook(array(
'appId' => $appId,
'secret' => $appSecret,
));
$token = $this->getFacebookAppToken($appId, $appSecret);
try {
$jinnove = $facebook->api('/my.page');
$fql = '/fql?q=SELECT+status_id+FROM+status+WHERE+uid=' . $jinnove['id'] . '&' . $token;
var_dump($facebook->api($fql));
} catch(FacebookApiException $e) {
var_dump($fql, $e);
}
}
/**
* Function to Get Access Token from Facebook
* #param $appId
* #param $appSecret
* #return string
*/
protected function getFacebookAppToken($appId, $appSecret)
{
$args = array(
'grant_type' => 'client_credentials',
'client_id' => $appId,
'client_secret' => $appSecret
);
$ch = curl_init();
$url = 'https://graph.facebook.com/oauth/access_token';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
return $data;
}
But it returns me an error 102 with the following message: "A user access token is required to request this resource.".
So then I asked on IRC and someone told me I need a user access token to do that.
Of what I've understood a user access token can only be generated when a user explicitly log into facebook to authorize this app and renew the token sometimes.
Is that true? Is there no way to use a token which doesn't imply the user to be logged? Basically anyone can view this number of status, even people who don't have a Facebook account and I want no UI dialog at all.
For some reason, Facebook has decided that querying a status can only be done by a user.
You can get around this by querying the stream table, and only returning posts with type = 46, which are status updates:
SELECT post_id FROM stream WHERE source_id= YOUR_PAGE_ID AND type = 46 LIMIT 100
The stream table has a lot of restrictions on it. Even with a high LIMIT, you may not get all the status updates if the page has been around for a while.
You can also speed up your program by cutting the number of API calls from 3 to 1 with the following changes:
If you want to get a page's ID from its username replace = YOUR_PAGE_ID in the above query with IN (SELECT id FROM profile WHERE username = 'YOUR_PAGE_USERNAME')
You don't need the 'getFacebookAppToken()` function. The PHP SDK will automatically get you an app access token if you don't have an authenticated user.

sugarcrm REST get_entry

Can someone take a look at how I've set up this REST call? I haven't been able to find an example of this, and I can't get it to work.
It may be the blank 'link_name_to_fields_array' parameter. I have read the documentation and don't really understand that parameter. I don't know if that is causing my problem or not.
Any help would be apprecitated.
//SET UP CURL
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//parameters for get_entry call (I received a session id from a call to the login function. Using it here)
//I manually got this user 'id' form the sugarcrm database
$parameters = array(
'session'=>$result->id,
'module_name' => 'users',
'id' => '21a6a633-40de-9bf4-aa14-4f8753ea5aa2',
'select_fields' => array('user_name'),
'link_name_to_fields_array'=> array()
);
$json = json_encode($parameters);
$postArgs='method=get_entry&input_type=JSON&response_type=JSON$rest_data=' . $json;
curl_setopt($curl,CURLOPT_POSTFIELDS, $postArgs);
$result2 = curl_exec( $curl );
echo("<pre>" . print_r($result2,true) . "</pre>");
The output is "Bad data passed in; Return to Home"
You have an error in the postArgs line (replace $rest_data with &rest_data). Try with this:
$postArgs='method=get_entry&input_type=JSON&response_type=JSON&rest_data=' . $json;