Connecting Azure to Quickbooks Online with OAuth 2.0 - azure

To start, please keep in mind that I am not very experienced with coding and it would be greatly appreciated if any replies were made with clear instructions or links to resources that were fairly straight forward for a beginner.
With that out of the way, my current situation is that I need to move data automatically from a third party source into Quickbooks Online using Azure and I have very little idea how to set up the OAuth 2.0 connection to receive a valid token. I've done a test connection using Postman, successfully received a valid token, and have been able to send and receive data using the Quickbooks API. However, being able to do the same from inside of Azure (whether using AD or Logic Apps) escapes me. Please note that this needs to be a service-service connection with no user input required (e.g. no logins or prompts). I've tried setting up a GET request in Logic App to start the workflow to first receive the code by using the client_id, client_secret, and scope that is provided in the Quickbooks deverloper app keys section but it always comes back as permanently moved or a bad request. I think this is due to a bad URI but again, I'm not familiar with what URI I should be using in the GET request or even if the GET request is what I should be using in the first place. The next step of course would be to send the code and request the actual token.
My current research has only revealed information on authenticating to an AD app but all of the instructions seem to be mixing information from the old Azure platform making the process unusable. On the Quickbooks side, the information is all about creating Quickbooks apps for publication on their marketplace, which is not the goal here.
If anybody can help with this I'd appreciate it as I've spent the last couple of days trying to figure this out and getting nowhere.
{
"inputs": {
"method": "GET",
"uri": "xxxx", //This is what I need to know and where to find it
"headers": {
"client_id": "xxxx", //provided by quickbooks dev app
"client_secret": "xxxx", //provided by quickbooks dev app
"content-type": "application/json",
"scope": "com.intuit.quickbooks.accounting"
}
},
"recurrence": {
"frequency": "Minute",
"interval": 3
}
}
Error with current URI is "bad request" because it is missing api-version but could also be caused by the # symbol.

Related

What is the best way to call an authenticated HTTP Cloud Function from Node JS app deployed in GCP?

We have an authenticated HTTP cloud function (CF). The endpoint for this CF is public but because it is authenticated, it requires a valid identity token (id_token) to be added to the Authorization header.
We have another Node JS application that is deployed in the same Google Cloud. What we want is to call the CF from the Node application, for which we will be needing a valid id token.
The GCP documentation for authentication is too generic and does not have anything for such kind of scenario.
So what is the best way to achieve this?
Note
Like every google Kubernetes deployment, the node application has a service account attached to it which already has cloud function invoker access.
Follow Up
Before posting the question here I had already followed the same approach as #guillaume mentioned in his answer.
In my current code, I am hitting the metadata server from the Node JS application to get an id_token, and then I am sending the id_token in a header Authorization: 'Bearer [id_token]' to the CF HTTP request.
However, I am getting a 403 forbidden when I do that. I am not sure why??
I can verify the id_token fetched from the metadata server with the following endpoint.
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=[id_token]
It's a valid one.
And it has the following fields.
Decoding the id_token in https://jwt.io/ shows the same field in the payload.
{
"issued_to": "XXX",
"audience": "[CLOUD_FUNTION_URL]",
"user_id": "XXX",
"expires_in": 3570,
"issuer": "https://accounts.google.com",
"issued_at": 1610010647
}
There is no service account email field!
You have what you need in the documentation but I agree, it's not clear. It's named function-to-function authentication.
In fact, because the metadata server is deployed on each computes element on Google Cloud, you can reuse this solution everywhere (or almost everywhere! You can't generate an id_token on Cloud Build, I wrote an article and a workaround on this)
This article provides also a great workaround for local testing (because you don't have metadata server on your computer!)

Incoming Slack Webhook URL Components

Incoming Slack Webhook URL looks like https://hooks.slack.com/services/aaaaa/bbbbb/ccccc -- What is aaaaa, bbbbb, ccccc.. Can you please let us know is it possible to find what is the Slack Channel name and workspace name based on this webhook
Based on the incoming webhook alone (as a string) it's not possible, apart from the team_id mentioned in the comment above.
From my experience with only incoming-webhooks enabled and publicly distributed apps that information is available only in response after user installs the app with the standard OAuth process. Keep in mind that reponse will change depending of the scope of your application but if you ask for incoming-webhook you will get channel together with url which is incoming-webhook url. You will also get team_name and team_id which is Workspace info. You can find detailed explanation at https://api.slack.com/messaging/webhooks#incoming_webhooks_programmatic and https://api.slack.com/authentication/oauth-v2.
And here is an example of OAuth response json.
{
"ok": true,
"access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX",
"scope": "identify,bot,commands,incoming-webhook,chat:write:bot",
"user_id": "XXXXXXXX",
"team_name": "Your Workspace Name",
"team_id": "XXXXXXXX",
"incoming_webhook": {
"channel": "#channel-it-will-post-to",
"channel_id": "C05002EAE",
"configuration_url": "https://workspacename.slack.com/services/BXXXXX",
"url": "https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX"
}
So in the nutshell, as far as I know, there is no way to get information from webhook alone, but one other option, which is not directly the answer to the question is to expand your application and include web api permissions and then there is nothing stopping you to request that information independently from incoming-webhook directly from the workspace.

Error 401 (Unauthenticated) when making a request to Google Docs API

I'm trying to request the contents of a Google doc (that I own) using the Google Docs API and the contents would be read to a website. I'm making the following request in Postman:
GET https://docs.googleapis.com/v1/documents/{documentId}?key=API_KEY
where the API_KEY is a key created in Google developer dashboard and is not restricted for now. However, I'm getting the following error:
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
I have made the doc public (read-access without signing in) and enabled the Docs API in the Google developer dashboard. Further, the dashboard is registering these (failing) requests, so something is going through.The answer is probably in the error message, but to me "or other valid authentication credential" means the API key that I'm already using.
I'm asking for advice on how to make this request successfully without needing to use OAuth or server-side code.
I found a workaround answer to my problem, although it didn't solve the problem with the Docs API. I decided to request the text data from a Google Sheet instead, which works fine with
GET https://sheets.googleapis.com/v4/spreadsheets/documentId?key=API_KEY
when the sheet is public and read-only.
Yes you can open the doc programatically using a service account. You need to "share" the doc with the service account email.
Instructions on creating a service account and reading a Google doc: https://www.futurice.com/blog/read-goog-doc-using-service-account

calling microsoft graph api via another rest service

Good day!
We need a calendar facility for the project that we're working in right now. For some reason, we are limited to using the Office 365 calendar or the outlook calendar. We stumbled upon the Microsoft Graph APIs which seems to be the right tool to fulfill what we want to do. So the idea is to create a Microsoft account which will be used as the main calendar where our wrapper(wrap the microsoft graph API calls) API can pull events from and eventually disseminate to client requests.
So here is what we've done so far:
Created a Microsoft account with the domain of #outlook.com
Plotted some calendar events using the said Microsoft account
Tried to follow this guide from the Microsoft site.
We agreed to create a wrapper API which will call the Microsoft Graph APIs but before this we tried to access the said APIs via postman. The problem is that postman cannot get any response from the endpoint of the /authorize API which is need to gain an access token to finally call the respective Microsoft graph APIs.
Now we do not know if we are trying to attack this wrongly or whatever. Do you have any idea what we are missing here? Thanks in advance and I hope someone can shed light in this matter.
UPDATE:
We were able to have some progress. After some time, we bumped in the azure active directory portal. We are now able to get an access token using this URL.
https://login.microsoftonline.com/<directory-id>/oauth2/token
Now when we are accessing the actual MS Graph API endpoint that we are supposed to call, we are receiving a 401 Unauthorized response even though we are using the obtained token from the previous API call. This is the URL that we are trying to get a response:
https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2018-08-01T00:00:00.0000000&endDateTime=2018-08-31T23:59:59.0000000
This is all being done via postman first.
UPDATE:
We tried to grant every permission possible in the Azure Active Directory portal and confirmed the consent at
https://login.microsoftonline.com/<domain>.onmicrosoft.com/adminconsent?client_id=<client-id>
but unfortunately we're still hitting the 401 Unauthorized wall. In Microsoft Graph Explorer, everything is working fine. So what could be missing in our postman implementation that MS Graph Explorer is doing implicitly? Thanks in advance for any help!
UPDATE
After further reading, we've found out some important details. First, we've found out that there are two sets of APIs from Microsoft. One is the Azure Active Directory API and the other is the Microsoft Graph API. Both APIs use the same URL to get access tokens by using client credentials. Below is the URL:
https://login.microsoftonline.com/<directory-id>/oauth2/v2.0/token
Substitute the with your personal data from azure portal. Using this URL to get an access token, you need to supply some data in the request body.
client_id - client id of registered application in azure portal
client_secret - secret key of registered application in azure portal
grant_type - 'client_credentials' --> meaning you'll get an access token by using client credentials
scope - 'https://graph.microsoft.com/.default' or 'https://graph.windows.net/.default' --> this controls which API are you going to access. The first one is to access Microsoft Graph API and the other is to access Azure Active Directory API.
We are now able to get an access token and use it to access the actual API that we need. Below is the URL of the said API:
https://graph.microsoft.com/v1.0/users/<azure-tenant-name>.onmicrosoft.com/calendar/calendarView?startDateTime=2018-08-01T00:00:00.0000000&endDateTime=2018-08-31T23:59:59.0000000
Notice that the URL does not use /me because upon reading using it required a signed in user. Unfortunately we are still getting the 401 Unauthorized error but the errors did change now. We are getting to errors intermittently. Sometimes the API call would return one or the other alternately. Below are the return of the API calls.
{
"error": {
"code": "InvalidTenant",
"message": "The tenant for tenant guid '<directory-id-goes-here>' does not exist.",
"innerError": {
"request-id": "<some-request-id>",
"date": "2018-08-22T04:29:27"
}
}
}
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "<some-request-id>",
"date": "2018-08-22T04:54:11"
}
}
}
We feel we've moved a step forward. We're still not getting what we need though. Now the mystery are these 2 API call responses. What could be the reason of this? Thanks in advance for anybody's help
UPDATE
Upon even further reading we've discovered that there are authentication flows to get an access token. Depending on the API that you want to call, some authentication flows will not work on it because they need more details and security to execute themselves. So we've tried:
Client Credential Grant
Resource Owner Credential Grant
Authorize Code Grant
But still, unfortunately, we are still stuck in the previous error. We are getting 401 Unauthorized and the response payload is either InvalidTenant or UnknownError.
I just went through a similar problem yesterday, the 401 Unauthorized error.
I was trying to access the calendar of an employee via Microsoft's Graph API, but I was receiving the same response as you.
Resquest:
https://graph.microsoft.com/v1.0/users/employee-email/calendarview?startdatetime=2018-10-21T00:00:00Z&enddatetime=2018-10-27T23:59:59Z&$select=subject,categories,start,end,sensitivity
Response:
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "<request-id>",
"date": "<date>"
}
}
}
Then I decided to check if had the Office 365. He didn't. I'm just a developer, so I ask the guys from infrastructure to install Office 365 on the empleyee's machine, or add him to an enterprice account, or something like that.
After they finished, the requests to his calendar worked just fine :)

Authenticating to BigQuery REST API via OAuth2 from Node.js

Newbie trying to figure out how to get a Node.js application to authenticate and query Google BigQuery, trying to adapt this CodeLab tutorial from Java. What step might i be missing?
First I create this Oauth2 URL using my clientid:
https://accounts.google.com/o/oauth2/auth?
client_id=1047877053699-den6kbs4v3f2bft6clonsirkj1pc7t6j.apps.googleusercontent.com
&scope=https://www.googleapis.com/auth/bigquery
&redirect_uri=http://localhost:3000/oauth2callback
&access_type=offline
&response_type=code
This successfully reaches Google, which prompts
A third party service is requesting permission to access your Google Account.
Agreeing that generates a second prompt:
Nodejs_Test is requesting permission to:
View and manage your data in Google BigQuery
Agreeing to that, the callback URL is called, with a parameter accessToken.
I think the following url should list tables in my BigQuery project/dataset:
https://www.googleapis.com/bigquery/v2/projects/1047877053699/datasets/visits&accessToken=4%2FC196NizZwlNgWSt5oNqQwendmLNW.0vgUrlGJ6kMRshQV0ieZDApig3NfcgI
But calling with or without the accessToken returns the following message that "Login Required".
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
I know you can't repeat the code because of permissions, expired tokens, etc. But I wonder what step I might be missing conceptually.
Have you tried sending the accesstoken as an authorization header rather than as a url parameter?
as in
https://www.googleapis.com/bigquery/v2/projects/1047877053699/datasets/visits
Authorization: OAuth Your-access-token-here-not-urlencoded
FYI - looks like you originally used the parameter accessToken in the URL. It should instead by access_token, which looks like it works fine. Of course, Jordan's suggestion of using a Header is better if you're able to do it though-- it's more secure as it's unlikely to get logged in access logs, proxy server logs, etc.

Resources