Power BI - Get JWT Token from Basic authentication - api

I'm getting a token from a REST API with Postman with this request:
URL:
https://www.wathever.com/fmi/data/v1/databases/sessions
Headers:
Authorization: Basic (binary generated by Postman)==
Postman-Token: <calculated when request is sent>
Content-Length: 0
Host: <calculated when request is sent>
User-Agent: PostmanRuntime/7.26.2
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/json
and I succesfully get a token:
{
"response": {
"token": "fff***********************3ecfc7f01a*****716"
},
"messages": [
{
"code": "0",
"message": "OK"
}
]
}
Now, I'm trying to get the token through Power BI with the following code (credential anonymous):
let server = "https://www.wathever.com/fmi/data/v1/databases/",
database = "thedatabase",
username = "username",
psw = "apassword",
url = server & database & "/sessions",
bytes = Text.ToBinary(username & ":" & psw),
encoded = Binary.ToText(bytes, BinaryEncoding.Base64),
body = "",
data = Json.Document(Web.Contents(url,
[
Headers = [
#"Authorization"=("base64-encoded " &encoded),
#"Content-Type"="application/json"
]
]))
in
data
But I get the following error message:
We couldn't authenticate with the credentials provided. Please try
again.
I also tried to connect with credential basic, without passing headers, but I get the following message:
DataSource.Error: Web.Contents failed to get contents from
'https://www.wathever.com/fmi/data/v1/databases/sessions' (405):
Method Not Allowed
Any idea of what I am missing?
Thanks!

Related

How to send multipart/form-data for image binary with Python requests lib (with CRLF chars)?

I'm trying to upload a local image to the Medium /images endpoint (documented here).
Their example request looks like:
Host: api.medium.com
Authorization: Bearer 181d415f34379af07b2c11d144dfbe35d
Content-Type: multipart/form-data; boundary=FormBoundaryXYZ
Accept: application/json
Accept-Charset: utf-8
--FormBoundaryXYZ
Content-Disposition: form-data; name="image"; filename="filename.png"
Content-Type: image/png
IMAGE_DATA
--FormBoundaryXYZ--
The type of image data is never specified, but I'm assuming it's raw binary based on this very similar API call from Ancestry for uploading images.
Currently, I have:
headers['Content-Type'] = 'multipart/form-data; boundary=FormBoundaryXYZ'
imageData = '''--FormBoundaryXYZ
Content-Disposition: form-data; name="image"; filename="filename.jpg"
Content-Type: image/jpeg
0000000000000011111111111111111111111111
0000000000000011111111111111111111111111
0000000000000011111111111111111111111111
0000000000000000011111111111111111111111
0000000000000000000111111111111111111111
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000001000000000000000000
0000000000000000000100000000000000000000
0000000000000000010000000000000000000000
0000000000000000000000000000000000000000
0000000010000000000000000000000000000000
0000000000001100000000000000000000000000
0000000000000100000001000000000000000000
0000000000000000000001000000000000000010
0000000000000000001001111111110000000001
0000000000000000000000100110000000000000
0000000000000000000000000001110000000000
0000000000000000011110001111111101100000
0000000000000000111111111111111111111111
0000000001000001111111111111111111111111
0000000000000011111111111111111111111111
0000000100001011111111111111111111111111
0000001100000001111111111111111111111111
0000110000000000000000000000000000000000
0001000000000000000000000000000000000000
--FormBoundaryXYZ--'''
def post_image(imgData):
req = r.post(base_url+'/images', headers=headers, data=imgData)
res = req.json()
return res
print(json.dumps(post_image(imageData), indent=2))
When executed, I get the error response:
{
"errors": [
{
"message": "Expected CR Received 10",
"code": -1
}
]
}
The documentation mentions
All lines in the body must be terminated with \r\n.
and I know that the "10" in the response must be the "\n", so I'm missing the "\r". I've tried explicitly adding "\r\n" to the end of each line termination, but then I get an error like
{
"errors": [
{
"message": "Expected alphabetic character, received 10",
"code": -1
}
]
}
Or
{
"errors": [
{
"message": "stream ended unexpectedly",
"code": -1
}
]
}
depending on where I place the /r/n or remove it.
My question is: Is there a way to format this that I'm missing or overthinking? I'm hoping I'm just inexperienced in multipart/form-data encoding and I could be doing this programmatically instead.
Thanks! I'd be happy to add details if needed!
(As a side note: I got the image's binary data with the dcode.fr/binary-image tool.)

GCP API - OAuth 2.0 from Postman

I have developed an Python webapp on GCP App Engine.
I want to use OAuth 2.0 client ID as an authentication for my app.
In APIs & Services -> Credentials there is an OAuth 2.0 client ID with my app URL added as Authorized redirect URIs.
My Postman access token configuration looks like the following:
And authorization configuration:
Despite that I am getting following response: Status: 401 Unauthorized
Info from the header: WWW-Authenticate: Bearer, error="invalid_token"
Response body:
{
"code": 16,
"message": "JWT validation failed: Bad JWT format: Invalid JSON in header",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "auth"
}
]
}
What I am doing wrong? How should I troubleshoot this?
EDIT: Adding request
POST /parse HTTP/1.1
Host: [my_app_name].appspot.com
Content-length: 0
Content-type: application/json
Authorization: Bearer [token_generated_by_postman]

Get shopify analytics token programmatically

How do you get the token needed to make a request to the Shopify analytics API?
For example:
POST https://analytics.shopify.com/queries?beta=true
REQUEST BODY:
token: HOW_DO_I_GET_THIS?
q[]: SHOW+total_visitors+AS+%22total_visitors...
source: shopify-reports
I've tried using OAuth, but it seems to be a different token entirely.
You have to request Shopify Core GraphQL to get analyticsToken.
POST /admin/internal/web/graphql/core HTTP/1.1
Host: [[STORE_NAME]].myshopify.com
Accept: application/json
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
content-type: application/json
X-CSRF-Token: [[CSRF_TOKEN]]
Origin: https://[[STORE_NAME]].myshopify.com
Connection: close
Cookie: [[COOKIE]]
{ "query": "{ shop { analyticsToken } }" }
Since the request requires CSRF Token & Cookie, it's not programmatic at all.
For additional information please check the Examples for Testing in the Shopify Admin page.

Outlook Add-in REST call error

I'm trying to mark (flag) a message using the Outlook rest API, but I keep getting error messages. I've tried with different rest URLs but it doesn't help - the errors just varies.
Important values in the manifest for allowing this I believe are:
<Requirements>
<Sets>
<Set Name="Mailbox" MinVersion="1.1" />
</Sets>
</Requirements>
...
<Permissions>ReadWriteItem</Permissions>
<Rule xsi:type="RuleCollection" Mode="Or">
<Rule xsi:type="ItemIs" ItemType="Message" FormType="Read" />
</Rule>
...
<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
<Requirements>
<bt:Sets DefaultMinVersion="1.3">
<bt:Set Name="Mailbox" />
</bt:Sets>
</Requirements>
Here is the part I'm trying to do that causes error:
Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, function (result)
{
if (result.status === "succeeded")
{
var accessToken = result.value;
var itemId = getItemRestId();
var restUrl = Office.context.mailbox.restUrl + "/api/v2.0/messages/" + itemId;
var request = {
url: restUrl,
type: "PATCH",
dataType: 'json',
data: { "Flag": { "FlagStatus": "Flagged" } },
headers: {
"Authorization": "Bearer " + accessToken,
"Conntent-Type": "application/json"
}
};
$.ajax(request)
.done(function (item)
{
// dome something
})
.fail(function (error)
{
// handle error
});
}
else
{
// handle error
}
});
function getItemRestId()
{
if (Office.context.mailbox.diagnostics.hostName === 'OutlookIOS')
{
return Office.context.mailbox.item.itemId;
}
else
{
return Office.context.mailbox.convertToRestId(
Office.context.mailbox.item.itemId,
Office.MailboxEnums.RestVersion.Beta
);
}
}
This code above will result in the error:
{"readyState":4,"responseText":"","status":404,"statusText":"Not Found"}
If I try to JSON.stringify() the data attribute of the request I get:
{"readyState":4,"responseText":"","status":404,"statusText":"Not Found"}
If I change the rest URL to (seen in older samples):
'https://outlook.office.com/api/beta/me/messages/'+ itemId;
And the headers attribute of the request to (seen in older samples):
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
}
Then I get the following error instead:
{
"readyState": 4,
"responseText": "{\"error\":{\"code\":\"ErrorAccessDenied\",\"message\":\"The api you are trying to access does not support item scoped OAuth.\"}}",
"responseJSON": {
"error": {
"code": "ErrorAccessDenied",
"message": "The api you are trying to access does not support item scoped OAuth."
}
},
"status": 403,
"statusText": "Forbidden"
}
Can anyone see what I'm doing wrong or missing here?
I'm debugging in Outlook 2016 and the account is Office 365.
UPDATE: Fiddler outputs
Here is the request my own sample sends (results in 403 Forbidden)
Exact error: {"error":{"code":"ErrorAccessDenied","message":"The api you are trying to access does not support item scoped OAuth."}}
PATCH https://outlook.office.com/api/beta/me/messages/AAMkAGNmMDllMTVhLTI3ZDctNDYxZS05ZWM5LTA3ZWQzMzYyNDBiOABGAAAAAAD6OQOAoKyKT6R02yYFe0bIBwD5fUzv7OgQQYAILztCFSSWAALg591rAAC382lxTQ2HQpUKZsAGTeWVAARPu37CAAA= HTTP/1.1
Content-Type: application/json
Accept: application/json, text/javascript, */*; q=0.01
Authorization: Bearer <long token code removed...>
Referer: https://localhost:44394/MessageRead.html?_host_Info=Outlook$Win32$16.02$da-DK
Accept-Language: da-DK
Origin: https://localhost:44394
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: outlook.office.com
Content-Length: 33
Connection: Keep-Alive
Cache-Control: no-cache
{"Flag":{"FlagStatus":"Flagged"}}
Here is the request the demo project sends (results in 200 OK)
PATCH https://outlook.office.com/api/beta/me/messages/AAMkAGNmMDllMTVhLTI3ZDctNDYxZS05ZWM5LTA3ZWQzMzYyNDBiOABGAAAAAAD6OQOAoKyKT6R02yYFe0bIBwD5fUzv7OgQQYAILztCFSSWAALg591rAAC382lxTQ2HQpUKZsAGTeWVAARPu37CAAA= HTTP/1.1
Content-Type: application/json
Accept: application/json, text/javascript, */*; q=0.01
Authorization: Bearer <long token code removed...>
Referer: https://<company.domain.com>:1443/outlookaddindemo/RestCaller/RestCaller.html?_host_Info=Outlook$Win32$16.02$da-DK
Accept-Language: da-DK
Origin: https://<company.domain.com>:1443
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: outlook.office.com
Content-Length: 47
Connection: Keep-Alive
Cache-Control: no-cache
{
"Flag": {
"FlagStatus": "Flagged"
}
}
The only difference I can see is that the 2nd request payload seems formatted for reading while data wise being identical to the previous one.
I can't seem to find the problem here - I even made sure that both projects use the same version of JQuery.
If you need write access to the item via REST, you need to specify ReadWriteMailbox in the Permissions element in your manifest. Despite it's name, ReadWriteItem doesn't give you a token with the proper scope. Any permission level other than ReadWriteMailbox gives an item-scoped token, and as the error says, the operation you're trying to do doesn't support item-scoped OAuth.
See https://learn.microsoft.com/en-us/outlook/add-ins/use-rest-api for details, but here's the relevant bit:
Add-in permissions and token scope
It is important to consider what level of access your add-in will need via the REST APIs. In most cases, the token returned by getCallbackTokenAsync will provide read-only access to the current item only. This is true even if your add-in specifies the ReadWriteItem permission level in its manifest.
If your add-in will require write access to the current item or other items in the user's mailbox, your add-in must specify the ReadWriteMailbox permission level in its manifest. In this case, the token returned will contain read/write access to the user's messages, events, and contacts.

OneDrive Expects Boundary for Content-Type: application/json

This is a recent development. We run integration tests against this API on every commit.
POST https://apis.live.net/v5.0/me/skydrive
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"name": "My example folder"
}
Response:
{
"error": {
"code": "request_header_invalid",
"message": "The header 'Content-Type' is missing the required parameter: 'boundary'."
}
}
Requiring a boundary for an application/json content-type is just wrong. But lets try it:
POST https://apis.live.net/v5.0/me/skydrive
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json; boundary=idontactuallybelonghere
{
"name": "My example folder"
}
Response:
{
"error": {
"code": "request_header_invalid",
"message": "The header 'Content-Type' is missing the required parameter: 'boundary'."
}
}
Are you trying to create a folder? That error sounds like it thinks you're trying to upload a file using a multipart/form-data POST.
Are you using the exact URL as in your example? I tried that exact request against my account and it worked. I was able to reproduce your error, though, by using a URL that ends in '/files' like I would for a file upload.