Client credentials invalid error for external API authentication, when credentials are correct in Processmaker - api

I am trying to obtain the authentication token from the Processmaker to use the APIs. I have used the same API call which works perfectly fine in the test environment, with production urls and respective client id and client secret. But, I am getting below error, although the username and password of the account is correct.
Request:
{
"grant_type": "password",
"scope": "*",
"client_id": "xxxxxx",
"client_secret":"7777777",
"username": "username",
"password": "password"
}
Response:
{
"error": "invalid_client",
"error_description": "The client credentials are invalid"
}
I have tried below steps. But still the same error.
Create a new account without AD user account as the account used in test environment is not a domain account
Change the role of account to 'System Administrator' which is similar to the account in test
**While registering the client to use the APIs, we didn't use the Callback URL as it is optional (we did not configure it in the test environment as well)
Some help is really appreciated, as I have no clue what else to check between the environment to resolve this issue.

I am not sure if you are trying to call API from ProcessMaker to RPA or RPA to ProcessMaker.
For ProcessMaker to RPA:
Using Script: I have built a ProcessMaker script in PHP and with appropriate script configuration, you will be able to run the RPA bot from ProcessMaker.
<?php
/*
* Yo. This script is developed by Abhishek Kadam.
* This script is sufficient to run all the Microbots.
* The Script Configuration contains "release_key" which is the Process ID,
* "robot_id" which is to identify where to run the Bot, "orch_unit_id" which is the folder name
* and "orch_url" which stands for Orchestrator URL. To Run the bot, All the configurations are required.
*/
//******ASSIGNING VARIABLES*****
$client_id = $config['client_id']; // $config to get data from Script Configuration
$refresh_token = $config['refresh_token'];
$release_key = $config['release_key'];
$robot_id = $config['robot_id'];
$orch_url = $config['orch_url'];
$orch_unit_id = $config["orch_unit_id"];
//****** GET ACCESS TOKENS USING CLIENT ID AND REFRESH TOKENS******
$access_token = getAccessToken($client_id,$refresh_token);
$output_response = runBot($access_token,$release_key,$robot_id,$orch_url,$orch_unit_id);
//pass the Access token to runbot() and run the bot ez-pz!
function getAccessToken($client_id,$refresh_token){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://account.uipath.com/oauth/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"{\r\n \"grant_type\": \"refresh_token\",\r\n \"client_id\": \"".$client_id."\",\r\n \"refresh_token\": \"".$refresh_token."\"\r\n}",
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
$responseDecode = json_decode($response);
$accessToken= $responseDecode -> access_token; //get the access token
return $accessToken;
}
function runBot($access_token,$release_key,$robot_id,$orch_url,$orch_unit_id){
$curl = curl_init(); //Not sure if it's the right way to initialize or not but meh, it works :P
curl_setopt_array($curl, array(
CURLOPT_URL => $orch_url."/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"{ \"startInfo\":\r\n { \"ReleaseKey\": \"".$release_key."\",\r\n \"Strategy\": \"Specific\",\r\n \"RobotIds\": [ ".$robot_id."],\r\n \"JobsCount\": 0,\r\n \"Source\": \"Manual\" \r\n } \r\n}",
// Release key and Robot ID can be concatenated and passed as an argument(once I figure out how to get arguments in PM 4 scripts)
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Authorization: Bearer ".$access_token,
"X-UIPATH-OrganizationUnitId: ".$orch_unit_id
//There's another way to use the Access token. For now, I found this more helpful.
//As the document is TL;DR. https://www.php.net/manual/en/function.curl-setopt.php
),
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
//echo $response; //Print Response cuz why not? ;)
}
return [$access_token];
?>
I had used the UiPath RPA tool for this without mentioning any callback URL.
Using Data Connectors: Create Data Connectors in ProcessMaker. I prefer to using the Postman application before creating DC. Refer: Postman to UiPath Bot
For RPA Bot to ProcessMaker
In ProcessMaker documentation you can see the Swagger Link for your particular instance. The Swagger Documentation for ProcessMaker was not really helpful. There are few mistakes in the documentation provided.
For ease, I did import the API collection in Postman and proceeded with creating variables: baseURL & accessToken
baseURL: Your URL (https://something.processmaker.net)
ADD /api/1.0
/api/1.0 (https://something.processmaker.net/api/1.0)
Now the URL is correct. Also while sending the request make sure Params are not empty.
Note: For Access Token, Admin --> Users --> Edit --> API Tokens --> Create new Token --> Copy Token.
In Processmaker 4, API tokens are available for individual Users.
I hope this will help you in a way. Thanks!

Related

Shopware 6 API call error: "The user credentials were incorrect"

we have an issue with API calls. As the subject says, we cannot access the backend API with credentials.
Our customer's production and staging instances run Shopware 6.2.3 and we program plugins for Shopware. So now we want to update the customer's instances to 6.4.x.x. We also have a freshly instaled dev instance (6.4.13.0) which we use for testing our own plugins for SW 6.4.
Now we are facing an issue we cannot explain. We took a copy of the production and updated it from 6.2.3 to 6.4.13.0 which worked without any major issues. But our API call always fail with this error:
{"errors":[{"code":"6","status":"400","title":"The user credentials were incorrect.","detail":null}]}
The credentials are definitely correct, we can use them for logging into the backend.
The same error occurs when we use Curl with the same payload. On our 6.4 dev instance (see above) the Curl command and our plugin both work flawlessly and are able to get an access token.
This is the Curl command we used for testing:
curl --request POST --url https://our-domain.example/api/oauth/token --header 'Authorization: ' --header 'Content-Type: application/json' --data '{"grant_type": "password", "username": "xxxxx", "password": "xxxxxxxx", "client_id": "administration"}'
This is the code our developer wrote; it works perfectly on the 6.4 dev instance:
private function _getToken($domain, $username, $pass)
{
if ($domain[strlen($domain)-1] !== "/")
{
$domain .= "/";
}
$endpoint = $domain . "api/oauth/token";
$config = [];
if (strpos($endpoint, "https") > -1) {
$config = ['verify' => false];
}
$client = new Client($config);
$json_encode = json_encode([
'username' => $username,
'password' => $pass,
'grant_type' => 'password',
"client_id" => "administration",
]);
$response = $client->request('POST', $endpoint, [
'body' => $json_encode,
"headers" => ["Content-Type" => "application/json"]
]);
return json_decode($response->getBody())->access_token;
}
To rule out there was a problem with the Shopware update to 6.4, we tested the API call on the untouched production and staging instances and voilĂ : same error, but with a small difference. It throws an error 401 except 400.
So something is obviously wrong with the 6.2.3 instances.
Any idea what we can check? Is there anything inside the Shopware core or database that prevents API authentication?
Any help is greatly appreciated! Thanks in advance!
Nevermind, we found out what the problem was. Curl had an issue with verifying the (still valid) SSL certificate. So we tried to renew it and Let'sEncrypt failed because the web server was lacking an IPv6 address. So we added it to the virtual host, renewed the certificate and now the API call gives us the token.

Oauth error invalid_request: Could not find Shopify API application with api_key Shopify error

I am receiving this error immediately after installing my app in my dev store when attempting to exchange the temporary access code for a permanent token.
Oauth error invalid_request: Could not find Shopify API application with api_key
I'm using below code
$client = new Client();
$response = $client->request(
'POST',
"https://{$store}/admin/oauth/access_token",
[
'form_params' => [
'client_id' => $api_key,
'client_secret' => $secret_key,
'code' => $query['code']
]
]
);
$data = json_decode($response->getBody()->getContents(), true);
$access_token = $data['access_token'];
Any help is much appreciated. Thanks!

Jawbone UP API oAuth and Access Tokens

I have started digging into Jawbone's UP API today and everything seems to go fine throughout the authentication process. The problem is that, once I get an access token back, it's always the same token, it doesn't work in any of my requests, and I can't change it with the refresh_token endpoint.
oAuth setup:
$url_params = array(
'response_type' => 'code',
'client_id' => CLIENT_ID,
'scope' => array('basic_read', 'extended_read', 'move_read'),
'redirect_uri' => 'https://my-site.com/up_auth.php',
);
These are the parameters attached to the https://jawbone.com/auth/oauth2/auth URL and I get sent to Jawbone and prompted as expected. When I accept the authorization I get kicked back to my-site.com as expected with the code in the URL. I then use the code like so
$params = array(
'client_id' => CLIENT_ID,
'client_secret' => APP_SECRET,
'grant_type' => 'authorization_code',
'code' => $code,
);
And attach those parameters to https://jawbone.com/auth/oauth2/token and finally get kicked back to my server with something similar to:
{
"access_token": "REALLY_LONG_STRING",
"token_type": "Bearer",
"expires_in": 31536000,
"refresh_token": "ANOTHER_REALLY_LONG_STRING"
}
When I use access_token to try and get a response like this
$headers = array(
'Host: my-site.rhcloud.com',
'Connection: Keep-Alive',
'Accept: application/json',
"Authorization: Bearer {$_REQUEST['access_token']}",
);
$ch = curl_init('https://jawbone.com/nudge/api/v.1.1/users/#me/moves');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$o = curl_exec($ch);
curl_close($ch);
var_dump($o);
from the API, this is the response every time:
{
"meta": {
"code": 401,
"error_detail": "You must be logged in to perform that action",
"error_type": "authentication_error",
"message": "Unauthorized"
},
"data": {
}
}
The token never changes, even in a private browsing session, and even if I successfully refresh using the provided refresh_token and the proper API call - the call succeeds, but Jawbone gives me back the same token. If I test the same flow through the Jawbone API Console, the Bearer token in the request headers is different from the one I get here. Note that I get the same access_token when I attempt the same process with my wife's Jawbone credentials as well.
Finally figured out what was going on and heard back from Jawbone about it. It turns out that they have collisions on the backend if you use the same auth with two different clients.
For anyone else that runs into this problem, don't use the same login in two different contexts simultaneously as it will reset auths in weird ways.
In our case, we have test user accounts that are often shared between devs since it is sometimes hard to get real data unless you have the actual device. This was causing 'duplicate' logins that made Jawbone code freak out.
We got confirmation from a Jawbone dev who ran into the same problem when developing an internal app.....

Firebase GET data via REST API PHP CURL

Trying to do a simple read via PHP cURL. I can read my data successfully if my security rules let everyone in e.g.
{
"rules": {
".read": true,
".write": true
}
}
However if I restrict read/write to a specific username e.g.
{
"rules": {
".read": "auth.username == 'admin'",
".write": "auth.username == 'admin'"
}
}
I get permission denied.
The code is as follows...
require('JWT.php');
$secret = 'MY_FIREBASE_SECRET';
$data = array('username' => 'admin');
$token = JWT::encode($data, $secret);
$url = "https://MY_FIREBASE.firebaseio.com/messages.json?auth=$token";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url
));
$response = curl_exec($curl);
Its worth noting, if I just use my FB secret instead of a token in the URL I am able to successfully read the data (auth=$secret). I have also successfully tested reading the data in the Forge simulator using "custom auth" e.g. {'username': 'admin'}
I'm using the PHP JWT library: https://github.com/luciferous/jwt/blob/master/JWT.php
Not sure if I'm getting permission denied because my cURL call is not correct or I'm not constructing the token properly. I have tried using POST and GET via cURL but I'm getting the same result.
Any suggestions would be much appreciated...
Thanks for the super quick response Andrew. I tried your suggestion. Unfortunately, I'm still getting 'permission denied'. Here is my updated code...
require('JWT.php');
$secret = 'my-secret';
$user = array( 'v' => 0, 'iat' => time(), 'd' => array('username' => 'admin', 'type' => 'admin', 'fullname' => 'Administrator'));
$token = JWT::encode($user, $secret);
$curl = curl_init();
$url = "https://myfirebase.firebaseio.com/messages.json?auth=$token";
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url
));
$response = curl_exec($curl);
curl_close($curl);
I did get this working by changing the .read rule for our data to
"auth != null" - but that doesn't seem to quite as secure...
For reference our data structure is simply
+ myfirebase
+ messages
- 000001 = "this is the 1st test message"
- 000002 = "this is the 2nd test message"
BTW: Our application will only have 1 user reading/writing data. If I can not get the token to work... Is there a better way to authenticate calls via the REST API without resorting to passing our secret key in the URL? e.g. &auth='my-secret'
The Firebase JWT has some structure to it that is missing here. There's a detailed explanation of what should be in these auth tokens here:
https://www.firebase.com/docs/security/jwt-auth-token-format.html
Here is a snippet with the appropriate structure.
require_once('JWT.php');
$fbSecret = 'your-secret';
$user = array( 'v' => 0, 'iat' => <timestamp>,
'd' => array('username' => 'jimbob', 'type' => 'admin',\
'fullname' => 'Jim Bob')
);
$token = JWT::encode($user, $fbSecret);
Note that the "d" field contains the actual payload. "v", and "iat" are also required. "iat" should be the number of seconds since the epoch (it's the number that (new Date()).getTime() returns in Javascript).

CapsuleCRM API ColdFusion Wrapper

Looking for a ColdFusion version of the following PHP API wrapper for CapsuleCRM:
<?php
// The data you want to send to Capsule CRM in xml format
// SEE http://capsulecrm.com/help/page/javelin_api_party
I'm understanding that this variable contains the XML string...
$myxml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n
<person>\n
<title>Mr</title>\n
<firstName>Test12</firstName>\n
<lastName>Tester12</lastName>\n
<jobTitle>Chairman</jobTitle>\n
<organisationName>Big Company</organisationName>\n
<about>Testing</about>\n
</person>";
// The URL to connect with (note the /api/ that's needed and note it's person rather than party)
// SEE: http://capsulecrm.com/help/page/api_gettingstarted/
$capsulepage = 'https://sample.capsulecrm.com/api/person';
However, I don't know how to initiate cURL in ColdFusion.
// Initialise the session and return a cURL handle to pass to other cURL functions.
$ch = curl_init($capsulepage);
What does the 'curl_setopt_array' function do exactly? Is there a CF equivalent?
// set appropriate options NB these are the minimum necessary to achieve a post with a useful response
// ...can and should add more in a real application such as
// timeout CURLOPT_CONNECTTIMEOUT
// and useragent CURLOPT_USERAGENT
// replace 1234567890123456789 with your own API token from your user preferences page
$options = array(CURLOPT_USERPWD => '1234567890123456789:x',
CURLOPT_HTTPHEADER => array('Content-Type: text/xml'),
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $myxml
);
curl_setopt_array($ch, $options);
// Do the POST and collect the response for future printing etc then close the session
$response = curl_exec($ch);
$responseInfo = curl_getinfo($ch);
curl_close($ch);
?>
I could be wrong, but that looks like a basic http post. The equivalent in CF is cfhttp. To pass parameters/headers (ie curl_setopt_array) use cfhttpparam.