Twinfield do you need sessions if using oAuth? - oauth-2.0

I’m updating a third party app that currently integrates with Twinfield using the session’s method with username and password to use the oAuth method.
In confused by the documentation though... do I still need to use the sessions or when using oAuth do I just call the endpoint(s) by passing the access token in the header as normal?
Also their Soap definition has four properties, the usual ClientID and Secret but also accessSecret? What’s that?

TLDR: you no longer need to use the sessions and SelectCompany; when you have the access token you can use that and the company code directly in the header.
You can obtain the access token as described here.
The documentation is a bit unclear on how to use the access token in your calls.
In the old username/password/session flow, you referred to a SessionID in the SOAP Header, and you would do a SelectCompany call to select the relevant target ("administratie").
In the OAuth flow, the SessionID is no longer relevant. Once you obtained a valid access token, you should set that in the header using the AccessToken field.
Instead of the old SelectCompany call, you can set the CompanyCode directly in the header. So if you have obtained an access token eyWhatANiceToken, and want to retrieve data for company "My Company BV [130001]" you have set AccessToken to eyWhatANiceToken and CompanyCode to 130001 in the header.
You can request the available codes using the list offices call

Related

Google oauth2Client.getToken is not returning id_token for other users

I'm implementing Google's 'code model' of Oauth2 and having trouble getting users' email - I wonder if this is a scopes problem or my misunderstanding about how to set up the code model. This sequence of events is already working:
Client loads https://accounts.google.com/gsi/client
Client starts call to google.accounts.oauth2.initCodeClient
Client gets code
Client passes code to one of my server endpoints
Server has an oauth2Client set up using the config with client_id, client_secret, and redirect URL = 'postmessage'
Server exchanges the code from the client for tokens
Server does oauth2Client.setCredentials(tokens) - this contains an access_token, which is enough for the client to make API calls to, e.g., retrieve the user's Google Calendar
Server is able to do oauth2Client.getTokenInfo(tokens.access_token);
There are various places along the way that involve scopes; I am probably getting something confused here. The client's initial call (step 2 above) uses
scope: 'https://www.googleapis.com/auth/calendar',
My code path on the server does define scopes anywhere.
In GCP, my project is set up with scopes
calendar.calendarlist.readonly, calendar.readonly and calendar.events.readonly
openid
/auth/userinfo.email
Here's the problem I'm encountering: when I go through this flow as a user and oauth with the account that owns the GCP project (this is a Google Workspace email, in case that matters), the tokens object that the server receives (step 6 above) has access_token, refresh_token and id_token - the id_token can be decoded to yield the user's email, and the user's email is also in the response to oauth2Client.getTokenInfo(token.access_token).
However, when I go through the flow with my other (personal) Gmail account, the tokens object that the server receives is missing the id_token but has the access and refresh tokens. Question 1: why are the responses different?
Question 2: How can I get the email of the user on the server in the personal Gmail account case? I've tried having the server make a call to https://www.googleapis.com/oauth2/v2/userinfo?fields=id,email,name,picture with the access_token, but this fails. I am not sure if I'm supposed to declare scopes for oauth2Client somehow, or tap a Google API using a different method on the server.
I think I've had a breakthrough: in step 2 in my original post, when I did "Client starts call to google.accounts.oauth2.initCodeClient", I had set the scope of initCodeClient to just the calendar scope. When I changed it instead to scope: 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email openid', (scope takes a space-delimited list in this case), it allowed my server call to get the id_token for this user and oauth2Client.getTokenInfo to get a response with the user's email in it.
When I updated the scopes like that, the popup asking for authorization also updated to request all the scopes I wanted - previously, it was only asking for the Calendar scope, so it makes sense Google didn't want to return the email.
What I still don't understand is why my previous setup was working for the account that owns the GCP project. In other words, when I was first building it out with that owner account, the client was only noting the Calendar scope while the server was asking for all three scopes (ie there was a mismatch), and the server was still able to get an id_token and the user's email in getTokenInfo. Maybe the owner account has some special privilege?

Does PHPMailer with oauth2-google use get_oauth_token

We’ve implemented PHPMailer with oauth2-google (via GitHub): no problem.
But I am trying to understand the logic behind the use of the get_oauth_token grant code.
When run standalone, it simply ‘loops’ to the authorization endpoint and back to get an authorization token and then uses this to request an access token and a refresh token from the token endpoint. Developer then pastes the refresh token as a parameter in the instantiation of PHPMailer’s OAuth wrapper class. All very straightforward.
My puzzle is whether:
get_oauth_token.php is then used by PHPMailer OAuth plus theLeague’s OAuth-client
or
whether the latter get authorization and access tokens (and if necessary a new refresh token) themselves without calling get_oauth_token.
The redirectURI (i.e. the URI of get_oauth_token) is not passed to the Google provider instantiation in the PHPMailer published example, and our working (so far...) implementation doesn’t do so either. So I assume it doesn’t use get_oauth_token or any similar callback mechanism since the redirect URI necessary would need to be defined in advance to Google Developer console in the way it is for get_oauth_token itself. But thephpleague / oauth2-google's Readme.md indicates that one should be specified.
However … theLeague’s OAuth-client’s Abstract Provider class includes a __construct to set some options that include redirectUri. Later on in getAuthorizationParameters it sets a redirectUri if one hasn’t been provided, and redirectUri is used in e.g GetAcccessToken.
Can anyone shed light on exactly how redirectURI is being used in this context?
The redirectUri is required in order for Google to redirect back to the originating website to complete the OAuth transaction, after the user logs into Google. Once the access and refresh tokens are available, the redirectUri will (probably) never be used, unless the refresh token is invalidated.
I don't understand what any of this has to do with PHPMailer, so I can't answer that part of the question.

Automate Oauth process of receiving Slack access token for Web API

I am working with the Slack oAuth API.
When I do a GET on https://slack.com/oauth/authorize passing my client_id, and the scope, I get html reponse asking for workspace URL.
After that I need to sign in and provide my password before code is returned which I can use to renew my temporary token
My question is: How can I automate the process of providing workspace URL, username and password? I need to get the code return after authentication (the temporary token) so that I can call https://slack.com/api/oauth.access to renew my token
My reasoning is that if I have access (from the app I created) to: App ID, Client ID, Client Secret, Signing Secret and Verification Token there should be a way for me make simple API call to get code or is my understanding of the slack OAuth flow wrong?
NB: I have taken a look at https://api.slack.com/docs/oauth but I was not able to get it done. I am also aware that I can make the /signin and /checkcookie to get this done but it involves parsing HTML response for parameter values needed to make subsequent calls. I just feel there a simpler way to do it.
This Stackoverflow question is not a duplicate because is it mainly referred to a case of not having an app created; In my case, I have an app created.

How can I get the quantity_available field to be returned from calls to the EventBrite API?

The Eventbrite documentation on the ticket object indicates that it can contain a quantity_available or quantity_sold field, but that to see either of these fields "requires authentication". It doesn't give any more detail than that, though, and when I make calls to the event_search method using my app key, the tickets objects in the returned events do not contain quantity_available or quantity_sold keys.
What authentication is required to see these fields? Are they only visible to the owners of the event, or is it possible in some way for me to have the API return the number of tickets available for somebody else's event?
If this is not possible through the API, is the number of tickets remaining for an event publicly visible anywhere else on Eventbrite where I could get to it with a web scraper?
This needs to be called as an expansion. There are some more details here:
https://groups.google.com/forum/#!msg/eventbrite-api/sjMO-gV8-Go/uzw7GHq2_SEJ
Basically, calling it like so will populate the proper fields using your Apps OAuth token in python3:
import requests
eventbrite_response = requests.get(
"https://www.eventbriteapi.com/v3/events/<YOUR EVENT ID HERE>/?expand=ticket_classes",
headers = {
"Authorization": "Bearer <YOUR APP OAUTH TOKEN>",
},
verify = True, # Verify SSL certificate
)
print(eventbrite_response.json()['ticket_classes'][0]['quantity_sold'])
You can tailor the print function at the end to include more of the json data if you wish.
In order to read or write private data using the Eventbrite API, you will need to supply additional user-authentication tokens. This extra information lets Eventbrite know who should be authorized to access private data (including quantity_available and quantity_sold values) during the request.
Whenever you provide additional user access tokens, both public and private data will be available.
Authentication parameters include:
app_key: An application key (also referred to as an API key), identifies the application that is contacting the API. All API requests must include some form of application identification. If this is the only authentication token provided, the API request will be limited to publicly available data. Application keys have a default rate-limit of 1000 requests per day. You can get and manage your API keys here: https://www.eventbrite.com/api/key/
access_token: Recommended. OAuth2 access tokens are tied to a user account and an application key. Since the user-authorized application can also be identified via this token, it is the only authentication parameter that does not require an application key to be provided as well. Be careful not to expose these tokens to other users! Additional request headers are required when using access_tokens to contact our API: “Authorization: Bearer YOUR_ACCESS_TOKEN_HERE“. You can learn more about how to configure your application for OAuth2.0 here: http://developer.eventbrite.com/doc/authentication/oauth2/
user_key: Each Eventbrite account has an associated user_key. This token provides access to the related user’s account data, in addition to our publicly available data. This authentication method is preferred for use-cases that require private data-access where OAuth2.0 workflows are not possible. This token unlocks sensitive information, so be very careful not to expose this token to other users!
Here is an example of an API call that is using both the app_key and user_key parameters to return private data (remember to substitute in your own app_key and user_key):
https://www.eventbrite.com/json/user_list_events -G -d app_key=APPKEY -d user_key=USERKEY
You can also see the authentication documentation here: http://developer.eventbrite.com/doc/authentication/

Rails API authentication - sanity check and advise

I want to create a Rails application which exposes an API to be consumed by only authorised client applications (will be mobile apps for iOS / android). I've not started working on the app yet, but the primary method of accessing the underlying data will be through the api. I've been looking at using the grape gem, but would need to add an authentication layer to it. I was thinking about using devise and adding another model for storing client details, api key and secret key. Upon sign in through the api, the api key and secret are returned. The API key is transmitted with each request, but the secret key is not. Instead, it is used to sign each request; the request parameters are ordered by name, hashed using the secret key as the hash key. This signature is then added as a parameter to the request.
Does this system of authentication sound logical and secure?
I tried to prototype the system earlier, but ran into difficulty signing up a user using JSON with devise. At first I was getting a CSRF error. I then turned off protect_from_forgery and was getting another error. Is it safe to turn this off if I am authenticating in this way?
Yes you can turn off rails CSRF protection since you are using a different authenticity method as long as a date or timestamp is always inside the parameters that are being signed. You can use this to compare the request time to the server time and make sure you aren't undergoing a replay attack.
protect_from_forgery helps you protect your HTML forms. If you're consuming JSON from mobile clients, you don't need it.
Here's what I would do if I were you:
on user's account page, have a button that says "(re)generate API key"
client then embeds this key into his calling code and passes with each request.
your API server checks whether this API key can be used with this client id.
Very easy to implement and serves well.
Signing parameters also works and I used it in several projects with success. But it increases code complexity without any real gain (secret key is on the client, attacker already knows it).

Resources