Firebase GET data via REST API PHP CURL - api

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).

Related

woocommerce rest authentication can't return json result in callback

I am using Woocommerce rest API to auto-generate an API key and get result back in json. I followed the woocommerce documentation and I successfully was able to log into woocommerce and generate key, but the problem is, the json that should be posted in callback URL, is null, I can't retrieve it, all I get is null. I have been struggling with this error for a week now, any ideas? here is my code:
<?php
$shop = $_GET['shop'];
$store_url = 'https://'.$shop;
$endpoint = '/wc-auth/v1/authorize';
$params = [
'app_name' => 'appname',
'scope' => 'read_write',
'user_id' => 123,
'return_url' => 'https://appname.app/dashboard/success.php',
'callback_url' => 'https://appname.app/dashboard/success.php'
];
$query_string = http_build_query( $params );
header("Location: " .$store_url . $endpoint . '?' . $query_string);
?>
and this is my callback page:
<?php
ini_set("allow_url_fopen", 1);
$data = json_decode(file_get_contents('php://input'), true);
print_r($data);

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

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!

Setting up a Discord oauth2 login on my website (with PHP?)

So I'm having troubles learning how to set up a login through discord on my site. I've been browsing for literally hours and haven't been able to find anything I understand...
At the moment, I have created the discord application, giving me a client ID and client secret, as well as a link back to my localhost:
https://discordapp.com/api/oauth2/authorize?client_id=550631359337594881&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=identify
At the moment I have it set up to redirect from a button to that URL, which then sends me to discord to accept. It then returns me to http://localhost?code=CODE_HERE
However, I don't know what I am supposed to do with this code. I am trying to set it up so that it will show the person's username with hashtag thing, and their profile picture.
I am currently using HTML, CSS, JS, and PHP on the site, but I think I might need to use something else, but I don't know how to set that up, or what it is I need. I am running my local server with XAMPP. I'd prefer if it is just PHP, but I'm open to other options.
Does anyone know how I can convert the code to a username + image?
Thanks in advance!
Try this
Credits to: eslachance
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)
error_reporting(E_ALL);
define('OAUTH2_CLIENT_ID', '1234567890'); //Your client Id
define('OAUTH2_CLIENT_SECRET', 'verysecretclientcode'); //Your secret client code
$authorizeURL = 'https://discordapp.com/api/oauth2/authorize';
$tokenURL = 'https://discordapp.com/api/oauth2/token';
$apiURLBase = 'https://discordapp.com/api/users/#me';
session_start();
// Start the login process by sending the user to Discord's authorization page
if(get('action') == 'login') {
$params = array(
'client_id' => OAUTH2_CLIENT_ID,
'redirect_uri' => 'https://yoursite.location/ifyouneedit',
'response_type' => 'code',
'scope' => 'identify guilds'
);
// Redirect the user to Discord's authorization page
header('Location: https://discordapp.com/api/oauth2/authorize' . '?' . http_build_query($params));
die();
}
// When Discord redirects the user back here, there will be a "code" and "state" parameter in the query string
if(get('code')) {
// Exchange the auth code for a token
$token = apiRequest($tokenURL, array(
"grant_type" => "authorization_code",
'client_id' => OAUTH2_CLIENT_ID,
'client_secret' => OAUTH2_CLIENT_SECRET,
'redirect_uri' => 'https://yoursite.location/ifyouneedit',
'code' => get('code')
));
$logout_token = $token->access_token;
$_SESSION['access_token'] = $token->access_token;
header('Location: ' . $_SERVER['PHP_SELF']);
}
if(session('access_token')) {
$user = apiRequest($apiURLBase);
echo '<h3>Logged In</h3>';
echo '<h4>Welcome, ' . $user->username . '</h4>';
echo '<pre>';
print_r($user);
echo '</pre>';
} else {
echo '<h3>Not logged in</h3>';
echo '<p>Log In</p>';
}
if(get('action') == 'logout') {
// This must to logout you, but it didn't worked(
$params = array(
'access_token' => $logout_token
);
// Redirect the user to Discord's revoke page
header('Location: https://discordapp.com/api/oauth2/token/revoke' . '?' . http_build_query($params));
die();
}
function apiRequest($url, $post=FALSE, $headers=array()) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$headers[] = 'Accept: application/json';
if(session('access_token'))
$headers[] = 'Authorization: Bearer ' . session('access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
return json_decode($response);
}
function get($key, $default=NULL) {
return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}
function session($key, $default=NULL) {
return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default;
}
?>
You have the code which is used to authenticate with many endpoints of the discord API. You need the http://discordapp.com/api/users/#me Endpoint. You authenticate with the Authorization Header. Take a look at the Developer Portal to find out more about your endpoint

Is it still possible to use Itunes Connect API endpoints instead of Java Reporter tool?

Prior to the newest Itunes Connect update all requests were HTTP requests made through Curl in our application. After the update, Apple is recommending to use their new reporter tool.
https://github.com/mikebarlow/itc-reporter I want to do something similar to this if possible. This supposedly works without the reporter tool and it looks like it is still just making HTTP requests. I won't use this code in my project because it requires us to update PHP version which we have planned for another time.
Is it possible to make simple HTTP requests using Curl to get data? I don't want to use Guzzle if I don't have to!
$json = '{"userid":"{{USERNAME}}","password":"{{PASSWORD}}","version":"2.0","mode":"Robot.XML","account":"{{VENDOR_ID}}","queryInput":"[p=Reporter.properties, Sales.getReport, {{VENDOR_ID}},Sales,Summary,Weekly,20170108]"}'
CURLOPT_URL => 'https://reportingitc-reporter.apple.com/reportservice/sales/v1',
CURLOPT_HEADER => false,
CURLOPT_HTTPHEADER => array('Accept: text/xml, text/plain', 'Content-Type: text/xml, text/plain'),
CURLOPT_USERAGENT => 'Java/1.8.0_92',
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
this is the request I've made while testing and when I run it I get the HTML response saying "Forbidden, You do not have access to this page"
I tried this while urlencoding username and password but I get the same result. I would love to be able to still get this data using Curl or we will have to work on adding the reporter tool into our application.
the postfield just needed to be changed accordingly
function build_json_request(, $access_token, $account_id,
$args_arr=array())
{
$args = $args_arr;
$json = array(
'accesstoken' => urlencode($access_token),
'version' => '2.2',
'mode' => 'Robot.XML',
'account' => $account_id
);
$queryInput = array(
'p=Reporter.properties',
array_shift($args)
);
if(! empty($args))
$queryInput[] = implode(',', $args);
$json['queryInput'] = '[' . implode(', ', $queryInput) . ']';
return json_encode($json);
}
$json = build_json_request('Sales.getReport', $access_token, $account_id, array('Sales.getReport', $vendor_id, 'Sales', 'Summary', 'Daily', $date) );
$output = process_curl(array(
CURLOPT_URL => 'https://reportingitc-reporter.apple.com/reportservice/sales/v1',
CURLOPT_HEADER => false,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => 'jsonRequest='.$json,
));

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.