Gnome Shell Extension: Send Request with Authorization Bearer Headers - authentication

I am trying to build a gnome shell extension (using gjs) that I need to communicate with an external REST API. In order to do so, I need to accompany my requests with the header: Authorization: Bearer <token> and with a Content-Type: application/json.
I have looked all over for questions like this and I did find some similar ones but none of them works. The documentation is not helpful at all, and, if anything, it has only confused me more.
With curl I could send that request as follows:
curl -X GET -H "Authorization: Bearer <token>" -H "Content-Type: application/json" <url>
So far, I have only created extensions that send simple GET requests with no headers. Then I would do the following:
const Soup = imports.gi.Soup;
let soupSyncSession = new Soup.SessionSync();
let message = Soup.Message.new('GET', url);
let responseCode = soupSyncSession.send_message(message);
let res;
if(responseCode == 200) {
res = JSON.parse(message['response-body'].data);
}
Any idea on how I can add the headers? Any help would be appreciated!

EDIT:
By using #ptomato's answer I ended up using the following code:
function send_request(url, type='GET') {
let message = Soup.Message.new(type, url);
message.request_headers.append(
'Authorization',
`Bearer ${token}`
)
message.request_headers.set_content_type("application/json", null);
let responseCode = soupSyncSession.send_message(message);
let out;
if(responseCode == 200) {
try {
out = JSON.parse(message['response-body'].data);
} catch(error) {
log(error);
}
}
return out;
}
Initial Comment:
So, I managed to find a workaround but it is not efficient and so I will not mark it as the accepted answer. If anyone knows how to answer my question using Soup, please answer!
My workaround involves using the imports.misc.util file which includes the function spawnCommandLine for executing shell commands. So, I used curl in order to download the json to a file (the path variable below):
Util.spawnCommandLine(`/usr/bin/curl -X ${type} -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" ${url} -o ${path}`);
and then I read the contents by using the following:
let text = GLib.file_get_contents(path)[1];
let json_result = JSON.parse(text);
This is not efficient at all and there should be an easier way around. But, until that is found, I hope this will be able to help someone else.

message.request_headers is a Soup.MessageHeaders object to which you can append() the authorization and content type headers.
Additionally there is a convenient set_content_type() method for the content type header specifically.

Related

Get SQL results from DB2 on cloud to Power Query via API

I try to connect to db2 on cloud via Excel Power Query.
Based on documentation this is format of curl request:
curl -X POST https://hostname.com/dbapi/v4/sql_query_export -H 'authorization: Bearer MyToken' -H 'content-type: text/csv' -d '{"command":"select * from mytable"}'
I tried to go via GUI but this gives me error
I am pretty sure I am not doing it right, but I could not even google how to pass my parameters.
Could someone please navigate how to assembly M code for this?
I tried this according to #nfgl answer
let
body = [#"command"="select * from mytable"]
,json = Json.FromValue(body)
,wc = Web.Contents("https://hostname.com/dbapi/v4/sql_query_export", [Headers=[#"content-type"="text/csv", authorization="Bearer XXX"]])
,Source = Csv.Document(wc,[Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv])
in
Source
However cannot go around credentials ui anonymously:
When I try Web API with token:
BTW, everything works with python:
import http.client
conn = http.client.HTTPSConnection("hostname.com")
payload = "{\"command\":\"select * from mytable\"}"
headers = {
'content-type': "text/csv",
'authorization': "Bearer XXX"
}
conn.request("POST", "/dbapi/v4/sql_query_export", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
You can't do it via GUI, command JSON must be in request content, and content-type is the one you send, ie JSON, open advanced editor and do something like this
let
url = "https://showcase.api.linx.twenty57.net/UnixTime/fromunixtimestamp",
body = [#"UnixTimeStamp"= 1589772280, #"Timezone"=""],
json = Json.FromValue(body),
wc = Web.Contents(url, [Headers=[#"Content-Type"="application/json"], Content=json]),
Source = Csv.Document(wc,[Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv])
in
Source

Linking to Fidel API via Flutter http.dart package

probably a basic question, but I'm new to this:
I am trying to link to the Fidel test API environment. They give examples (https://reference.fidel.uk/reference#get-transaction) of how to do this via cURL. In this case the example is:
curl -X GET \
https://api.fidel.uk/v1/transactions/84782884-6ab8-4885-820f-4cd081dd658f \
-H 'Content-Type: application/json' \
-H 'Fidel-Key: sk_test_50ea90b6-2a3b-4a56-814d-1bc592ba4d63'
If I run this in my terminal it works perfectly. But I can't get anything back if I try to run the same in my browser, or if I try to run it via the http.dart package in Flutter, which is where I need it to run eventually.
In Flutter I am writing it as:
void getData() async {
Response response = await get(
"https://api.fidel.uk/v1/transactions/84782884-6ab8-4885-820f-4cd081dd658f \'Content-Type: application/json' \'Fidel-Key: sk_test_50ea90b6-2a3b-4a56-814d-1bc592ba4d63'");
print(response.body);
}
I am sure it's a syntax thing that I don't understand. Any help would be appreciated.
It was just syntax! I solved by saying
Response response = await get(
'https://api.fidel.uk/v1/transactions/84782884-6ab8-4885-820f-4cd081dd658f',
headers: {
'Content-Type': 'application/json',
'Fidel-Key': 'sk_test_50ea90b6-2a3b-4a56-814d-1bc592ba4d63',
});
Will leave here in case anyone else, like me, gets stuck on the basics.

Segment.io HTTP API not collecting events

The documentation and help for this particular Segment.io is limited and sparse, so I hope it's OK to ask in here.
I have just set up a Segment.io workspace and a HTTP API source
Per the docs, I sent some POST requests (with Postman) to the https://api.segment.io/v1/track and https://api.segment.io/v1/page endpoints. The requests were structured like this:
curl -X POST \
https://api.segment.io/v1/track \
-H 'Accept: */*' \
-H 'Authorization: My4w3s0m3k3y' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'Host: api.segment.io' \
-H 'Postman-Token: 474d7fbe-15af-43d2-b629-61e15945e662,2c3d5fbe-2c09-4fe6-b7ea-a04e3221201b' \
-H 'User-Agent: PostmanRuntime/7.11.0' \
-H 'accept-encoding: gzip, deflate' \
-H 'cache-control: no-cache' \
-H 'content-length: 117' \
-d '{
"userId": "abc123",
"event": "My tests",
"properties": {
"name": "test 1"
}
}'
which all returned a 200 response and the following message:
{
"success": true
}
However, when I got to my dashboard, no events have been recorded.
The debugger is also empty
What am I missing here?
It looks like your write key isn't base64 encoded. When you encode your write key, remember to add the : at the end of it, before it's encoded.
Also, for the Authorization key:value, be sure to add Basic before the encoded write key. So your Authorization key:value would look like:
Authorization: Basic {encoded write key}
An example from the segment documentation:
In practice that means taking a Segment source Write Key,'abc123', as the username, adding a colon, and then the password field is left empty. After base64 encoding 'abc123:' becomes 'YWJjMTIzOg=='; and this is passed in the authorization header like so: 'Authorization: Basic YWJjMTIzOg=='.
I have been dealing with the same issue.
I found the solution as Todd said.
You should add a header Authorization: Basic + base64 encoding write key.
So, you look for the Segment source setting and get the write key.
After that, i have used an online base64 encoding tool to encode my write key.
Finally, you should add this header (Authorization) with 'Basic' and the encoded write key.
You should be able to see the tracked event in the Debugging panel in Segment web page.
I hope this helps!
You can try this code
const { promisify } = require("util");
var Analytics = require("analytics-node");
var analytics = new Analytics("xxxxxxxxxxxxxxxxxxxxxxx", {
flushAt: 1,
});
const [identify, track] = [
analytics.identify.bind(analytics),
analytics.track.bind(analytics),
].map(promisify);
console.log("user id: ", req.body.event.app_user_id);
let app_user_id = req.body.event.app_user_id;
let period_type = req.body.event.period_type;
let expiration_at_ms = req.body.event.expiration_at_ms;
let ret = "Initial";
try {
await identify({
userId: app_user_id,
traits: {
period_type: period_type,
expiration_at_ms: expiration_at_ms,
},
});
ret = "Done : Sengment done";
} catch (err) {
console.log("err: ", err);
ret = "Error : " + err;
}
return {
rafsan: ret,
};
Try to clear your browser's cache or use a different browser. I had the same problem and worked for me.
Hope this helps.

PUT requests to upload a file in form data Using karate

I've tried to write equivalent karate script for below curl request
curl -X PUT \
'http://localhost:8055/uploadfile' \
-H 'content-type: multipart/form-data;' \
-F code=#/Users/test/Downloads/Next.zip
Tried karate script
Given path 'uploadfile'
#Given header Content-Type = 'multipart/form-data'
And form field code = '/Users/test/Downloads/Next.zip'
#And multipart file code = { read: '/Users/test/Downloads/Next.zip' , contentType: 'application/zip' }
When method PUT
Then status 200
Am I doing something mistake here (tried different things)? Still not getting expected API response.
FYI : I've got that curl command from postman and it is working fine.
It is hard to tell with the limited info you have provided. Try this:
Given url 'http://localhost:8055/uploadfile'
And multipart file code = { read: 'file:/Users/test/Downloads/Next.zip', filename: 'Next.zip', contentType: 'application/zip' }
When method put
If you are still stuck follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue (or use postman ;)

Using Taxee.io API

I'm trying to access the Taxee.io API using the request npm module. The documentation is slightly poor and the difference between the Mashape info and the website's info is confusing.
https://taxee.io/
The docs have one example of a request here.
curl 'https://taxee.io/api/v2/calculate/2017' -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBUElfS0VZX01BTkFHRVIiLCJodHRwOi8vdGF4ZWUuaW8vdXNlcl9pZCI6IjU4NDQ4MTA4Mzg2NjhhMTU4ZDU0ZmIzNSIsImh0dHA6Ly90YXhlZS5pby9zY29wZXMiOlsiYXBpIl0sImlhdCI6MTQ5OTA1MzU0NX0.pOwC5JEC7trLaaZVgHHGu_rvN0-EGa3RMm8BgJ-M9gk' -H 'Content-Type: application/x-www-form-urlencoded' --data 'state=NC&filing_status=married&pay_periods=26&pay_rate=116500&exemptions=2'
I however want to use the request npm module and am struggling to bridge the gap in how it will work in my express app.
const request = require('request');
request.post('https://taxee.io/api/v2/calculate/2017', {
'auth': {
'Bearer': 'mykey'
}
});
This is what I have thus far. Any help is appreciated.
Keep in mind that properties are case sensitive in JavaScript. You must pass the bearer token under the key bearer and not Bearer.
To replicate the Content-type and pass data, use the form support of the library.
E.g. like this:
{
auth: {
bearer: '<token>',
},
form: {
state: 'NC',
// ...
},
}