Guzzle Http Not Logging In Laravel With Monolog - laravel

I have this example:
use Monolog\Logger;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\MessageFormatter;
public function getApiTest()
{
$stack = HandlerStack::create();
$stack->push(
Middleware::log(
new Logger('Logger'),
new MessageFormatter('{req_body} - {res_body}')
)
);
$client = new \GuzzleHttp\Client(
[
'base_uri' => 'http://apitesting.test/api/',
'handler' => $stack,
]
);
echo (string) $client->get('apitest')->getBody();
}
Which should be logging the request and response, from what I understand.
I have a custom logging channel built for logging to the database instead.. But I have now disabled it and went back to Laravel's file logging - but this is still not logging the Guzzle request/response.

It seems that the first parameter of the Middleware::log() is suppose to be the log channel that you are trying to use. For example:
$stack = HandlerStack::create();
$logChannel = app()->get('log')->channel('my-custom-channel');
$stack->push(
Middleware::log(
$logChannel,
new MessageFormatter('{req_body} - {res_body}')
)
);
That will tell the middleware which log channel that you are trying to use.

Related

How to Fix Client Error: file_get_contents(): in Cpanel with Laravel Project inside

i have problem when do seed in my laravel project in cpanel.
this is the errors
Client Error: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0
at vendor/kavist/rajaongkir/src/HttpClients/BasicClient.php:74
70▕
71▕ private function executeRequest(string $url): array
72▕ {
73▕ set_error_handler(function ($severity, $message) {
➜ 74▕ throw new BasicHttpClientException('Client Error: '.$message, $severity);
75▕ });
76▕
77▕ $rawResponse = file_get_contents($url, false, $this->context);
Please Someone help me
this is my LocationsTableSeeder.php
public function run()
{
$daftarProvinsi = RajaOngkir::provinsi()->all();
foreach ($daftarProvinsi as $provinceRow) {
Province::create([
'province_id' => $provinceRow['province_id'],
'nama' => $provinceRow['province'],
]);
$daftarKota = RajaOngkir::kota()->dariProvinsi($provinceRow['province_id'])->get();
foreach ($daftarKota as $cityRow) {
Kabupaten::create([
'province_id' => $provinceRow['province_id'],
'city_id' => $cityRow['city_id'],
'nama' => $cityRow['city_name'],
'type' => $cityRow['type'],
'postal_code' => $cityRow['postal_code'],
]);
}
}
}
It's a good practice to disable file_get_contents ability to open remote URLs (like the ones starting HTTP) on shared servers (that frequently use Cpanel) to avoid the download/injection of malicious scripts in your server.
Go to Cpanel PHP options and enable allow_url_fopen, as pointed by apokryfos, usually it's at Switch To PHP Options menu. Some providers will not allow this change via Cpanel and you might need to open a support ticket.
Usually, this option cannot be changed by ini_set or via the PHP script itself in any other way.

Unable to get Keycloak client initiated client account linking to work

The request to start the client iniated account linking fails.
The console is showing a WARN of type: CLIENT_INITIATED_ACCOUNT_LINKING_ERROR with error: invalid_token.
The url was generated as described here: https://www.keycloak.org/docs/latest/server_development/#client-initiated-account-linking, by php backend system.
Also making sure to use UTF8 encoding when generating the hash
All prerequisites as describe it the section have been fulfilled.
Im' using Keycloak 15.0.2 and Laravel with Socialite to authenticate users.
This is how the hash is generated.
$keycloack_user = Socialite::driver('keycloak')->user();
$bearerToken = $keycloack_user->token;
$tokenParts = explode(".", $bearerToken);
$tokenHeader = base64_decode($tokenParts[0]);
$tokenPayload = base64_decode($tokenParts[1]);
$jwtHeader = json_decode($tokenHeader);
$jwtPayload = json_decode($tokenPayload);
$client_id = $jwtPayload->azp;
$host = $jwtPayload->iss;
$session_state = $jwtPayload->session_state;
$nonce = Str::random(20);
$provider = "google";
$input = $nonce . $session_state . $client_id . $provider;
$utf8encoded = utf8_encode($input);
$hashed = hash('sha256', $utf8encoded);
$encoded = rtrim(strtr(base64_encode($hashed), '+/', '-_'), '=');
Then the linking url is constructed as shown below:
$redirect_uri = urlencode(...);
$full_url = $host . "/broker/". $provider ."/link?client_id=". $client_id ."&redirect_uri=". $redirect_uri ."&nonce=". $nonce ."&hash=" . $encoded;
I'm currently testing a my local machine, without using https for any of the applications. Loging in works fine and when inspecting the JWT token, the needed role mappings are present:
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
But when accessing the url it says "Invalid request" and the Keycloak console indicates the token is invalid.
Update: Solution was to return the result of the hash method as raw binary data
$hashed = hash('sha256', $utf8encoded, true);
I had to work on the same task lately but with the client implemented in JavaScript. I was also stuck for quite a while till I realized how uncommonly keycloak is expecting the encoded hash value. You need to consider following two points:
Encode the hash string into hexadecimal before base64 conversion
Replace + by - and / by _. Besides that remove trailing = symbols
Below you find a working snippet written in JS:
import sjcl from "sjcl";
hexToBase64(hexstring) {
return btoa(hexstring.match(/\w{2}/g).map(function(a) {
return String.fromCharCode(parseInt(a, 16));
}).join(""));
},
// Assume nonce, session_state, clientId, provider to be given
var data = nonce + session_state + clientId + provider;
var myBitArray = sjcl.hash.sha256.hash(data)
var hashedData = sjcl.codec.hex.fromBits(myBitArray)
var base64HashedData = this.hexToBase64(HashedData)
base64HashedData = base64HashedData.replaceAll('+','-').replaceAll('/','_').replaceAll('=','')
base64HashedData is then what you need to pass as hash query parameter to the link endpoint of keycloak.

Laravel issue Credentials are required to create a Client

I need to test send SMS to mobile I get Credentials are required to create a Client error for My Code Here
.env
TWILIO_ACCOUNT_SID=AC15...................
TWILIO_AUTH_TOKEN=c3...................
TWILIO_NUMBER=+1111...
Config\App
'twilio' => [
'TWILIO_AUTH_TOKEN' => env('TWILIO_AUTH_TOKEN'),
'TWILIO_ACCOUNT_SID' => env('TWILIO_ACCOUNT_SID'),
'TWILIO_NUMBER' => env('TWILIO_NUMBER')
],
Controller
$accountSid = env('TWILIO_ACCOUNT_SID');
$authToken = env('TWILIO_AUTH_TOKEN');
$twilioNumber = env('TWILIO_NUMBER');
$client = new Client($accountSid, $authToken);
try {
$client->messages->create(
'0020109.....',
[
"body" => 'test',
"from" => $twilioNumber
// On US phone numbers, you could send an image as well!
// 'mediaUrl' => $imageUrl
]
);
Log::info('Message sent to ' . $twilioNumber);
} catch (TwilioException $e) {
Log::error(
'Could not send SMS notification.' .
' Twilio replied with: ' . $e
);
}
Twilio developer evangelist here.
A quick read over the environment config for Laravel suggests to me that you can use the env method within your config files, as you are doing, but it's not necessarily available in application code. Since you are committing your environment variables to the config object, I think you need to use the config method instead.
$accountSid = config('TWILIO_ACCOUNT_SID');
$authToken = config('TWILIO_AUTH_TOKEN');
$twilioNumber = config('TWILIO_NUMBER');
Let me know if that helps at all.

Magento update inventory with REST

I Followed the instruction of this page http://www.magentocommerce.com/api/rest/Resources/inventory.html#RESTAPI-Resource-StockItems-HTTPMethod-PUT-stockitems--id and I have this code:
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = $apiUrl.'/stockitems/429';
$productData = json_encode(array(
'qty' => 982,
'is_in_stock' => 1
));
$headers = array('Content-Type' => 'application/json');
$oauthClient->fetch($resourceUrl, $productData, OAUTH_HTTP_METHOD_POST, $headers);
print_r($oauthClient->getLastResponseInfo());
But I get the return
[message:protected] => Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)
I tried with XML like this:
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = $apiUrl.'/stockitems/429';
$productData = '<?xml version="1.0"?>
<magento_api>
<qty>99</qty>
</magento_api>';
$headers = array('Content-Type' => 'text/xml');
$oauthClient->fetch($resourceUrl, $productData, OAUTH_HTTP_METHOD_POST, $headers);
print_r($oauthClient->getLastResponseInfo());
and I get the error:
[message:protected] => Invalid auth/bad request (got a 405, expected HTTP/1.1 20X or a redirect)
I don't know what I'm doing wrong?
Thank you for your reply.
Another way to update item's quantity is to call the /products/:id API, method = PUT, with the following payload:
{"stock_data" : {"qty" : "123"}}
You are using POST instead of PUT. HTTP Post is used for creating items in Magento, but if you update an item (or inventory, image, whatever) by id you have to use PUT.
Make sure you assigned to your admin user REST role.
Configuring Permissions Step By Step:
System -> Web Services -> REST - Roles -> Create new role
System -> Web Services -> REST - Consumers -> Create a Consumer -> Copy Key & Secret to use in your App
System -> Permissions -> Your User -> REST Role -> Select and Save your Role

Google URL Shortening API using PHP

Now I know this is a common topic that has been over the Internet especially StackOverflow. But what I do not have (or haven't yet seen) is a straight solution for the token being maintained over a session.
I'm using the Google APIs Client Library for PHP .
My Query:
I have one index.php where I fetch the user data (such as name) using the Google_Oauth2Service from the PHP client lib. The user is authenticated successfully and all goes well. Now I'd like to use the URL Shortening service and therefore I have a shorten.php where I have the code to try fetch the short URL. Some how this doesn't work.
index.php
//include google api files
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_Oauth2Service.php';
require_once 'src/contrib/Google_UrlshortenerService.php';
//start session
session_start();
$gClient = new Google_Client();
$gClient->setApplicationName('Test App');
$gClient->setClientId($google_client_id);
$gClient->setClientSecret($google_client_secret);
$gClient->setRedirectUri($google_redirect_url);
$gClient->setDeveloperKey($google_developer_key);
$google_oauthV2 = new Google_Oauth2Service($gClient);
....
....
Here I have started the session and made an object of the Google_Client. I have declared the client id, secret and all other details.
Then I get the access token on successful authentication and store it in the Session variable so that when I try to fetch the short url (using jQuery ajax) from shorten.php, I can use the existing token.
$_SESSION['token'] = $gClient->getAccessToken();
....
Now in shorten.php
session_start();
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_Oauth2Service.php';
require_once 'src/contrib/Google_UrlshortenerService.php';
$gClient = new Google_Client();
$gClient->setApplicationName('Test App');
$gClient->setClientId($google_client_id);
$gClient->setClientSecret($google_client_secret);
$gClient->setRedirectUri($google_redirect_url);
$gClient->setDeveloperKey($google_developer_key);
....
if (isset($_SESSION['token']) && $_SESSION['token']) {
// Set the access token from the session
$gClient->setAccessToken($_SESSION['token']);
$url_service = new Google_UrlshortenerService($gClient);
// Check if a URL has been passed
if (isset($_GET['url'])) {
$url = new Google_Url();
$url->longUrl = $_GET['url'];
$shortURL = $url_service->url->insert($url);
....
This is the exact line where the code breaks $shortURL = $url_service->url->insert($url); I was successful in getting the token using the Session variable and created a successful URL Service object. But just when I call the insert method, that's when it fails.
From the apache error logs :
husain#innovate:~/myprojects/web$ tail -1 /var/log/apache2/error.log | sed -e 's/\\n/\n/g'
[Thu Mar 28 00:42:35 2013] [error] [client 127.0.0.1] PHP Fatal error: Uncaught exception 'Google_ServiceException' with message 'Error calling POST https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyCxfXP-xS-QYJw-7mM4SNG3EW9ryj_Oiv4: (401) Invalid Credentials' in /home/husain/myprojects/web/apps/src/io/Google_REST.php:66
Stack trace:
#0 /home/husain/myprojects/web/apps/src/io/Google_REST.php(36): Google_REST::decodeHttpResponse(Object(Google_HttpRequest))
#1 /home/husain/myprojects/web/apps/src/service/Google_ServiceResource.php(177): Google_REST::execute(Object(Google_HttpRequest))
#2 /home/husain/myprojects/web/apps/src/contrib/Google_UrlshortenerService.php(38): Google_ServiceResource->__call('insert', Array)
#3 /home/husain/myprojects/web/apps/shorten.php(44): Google_UrlServiceResource->insert(Object(Google_Url))
#4 {main}
thrown in /home/husain/myprojects/web/apps/src/io/Google_REST.php on line 66
When I dump the Google_Client variables on the index.php and shorten.php files, this is what I get.
index.php
Google_Client Object
(
[scopes:protected] => Array
(
)
[useObjects:protected] =>
[services:protected] => Array
(
[oauth2] => Array
(
[scope] => Array
(
[0] => https://www.googleapis.com/auth/userinfo.profile
[1] => https://www.googleapis.com/auth/userinfo.email
)
)
)
[authenticated:Google_Client:private] =>
)
shorten.php
object(Google_Client)#1 (4) {
["scopes":protected]=>
array(0) {
}
["useObjects":protected]=>
bool(false)
["services":protected]=>
array(1) {
["urlshortener"]=>
array(1) {
["scope"]=>
string(44) "https://www.googleapis.com/auth/urlshortener"
}
}
["authenticated":"Google_Client":private]=>
bool(false)
}
and both aint the same so I'm assuming that there is something not right here. Help or direction please.
You're not requesting the UrlShortener scope when authenticating, that's why it's failing.
To get the scope added, you can create an UrlshortenerService before authenticating in index.php, passing the same instance of the client, as in:
//start session
session_start();
$gClient = new Google_Client();
$gClient->setApplicationName('Test App');
$gClient->setClientId($google_client_id);
$gClient->setClientSecret($google_client_secret);
$gClient->setRedirectUri($google_redirect_url);
$gClient->setDeveloperKey($google_developer_key);
$google_oauthV2 = new Google_Oauth2Service($gClient);
$url_service = new Google_UrlshortenerService($gClient);
Alternatively, you can use setScopes to override the automatically generated scope

Resources