Remove linked account/token programmatically - actions-on-google

I created a project and enabled account linking (using authorisation code) against my oauth2 provider.
Linking an account works fine and next times Google Assistant calls my fulfilment webhook, accessToken gets passed along other user data.
However, if this token gets invalidated in my system, Google does not know about it. When this situation arises (i.e. my webhook receives a token which is now invalid) I would like to notify Google (so that it can get rid of this invalid link) and/or re-send a prompt to link your account.
I tried calling the sign-in helper (as below) but that did not work.
app.askForSignIn();
Any ideas on how to solve this?

Related

Report expired access token

I'm working to implement Google Actions, and I've came into this problem.
After successful authentication (Account Linking with OAuth) everything works fine, all of the intents (SYNC,QUERY ec...) are working.
During the test fase I've restarted the server that handles the authentication and the intents (which also holds user sessions our side) so the user session that Google has became invalid (in existent) at our side, so when a new intent is incoming with the access token (that we could say has been expired on my side) the intent fails for authentication error. And here comes the issue:
I've tried to respond with authExpired or even authFailure as described here: https://developers.google.com/actions/smarthome/develop/process-intents#error-responses
but it simply does not work. It seems like until the token does not expire on Google side, I'm not able to make it expire "intentionally". So to make it work we are forced to unlink the action or wait the expiration time than everything works as expected.
It this an intended behavior?
I hope my question was clear, if not I'm here to add more details.
Thanks,
It seems like until the token does not expire on Google side, I'm not able to make it expire "intentionally".
You are correct that this is the current behavior. Generally speaking, we expect developers to use short-lived access tokens where the expiration time is meaningful in requiring those tokens to be granted again.
Developers wishing to enable users to intentionally revoke access (outside of unlinking their account) should invalidate the refresh token provided to Google and continue to return an authFailure when those credentials are presented.

Actions on Google - Account Linking process hits Token URL before Authorize URL?

We are trying to support the 'traditional' Account Linking flow as it seems the most general purpose, gives us a chance to surface T&C's, and we thought would be most bedded in.
But testing in the Assistant mobile app for starters, it fails for most users in our Actions app in Dev - After the user sees the Google-driven pop-up in the Assistant app with the "LINK ACCOUNTS" option - They tap that option, and our authorization screen does not appear.
Actions support have had a look at our Account Linking config and can't see any problems.
A couple of test users with newer Android phones DO see our Authorization screen, but the majority do not.
If we test the Authorization URL by pasting into a browser on the same device - It always displays just fine.
What is strange - If we look in our web server logs during the failed cases, the only hits we are seeing are to our 'TOKEN URL', whereas my understanding is a newly linking user should hit our 'Authorization URL' before ever hitting Token.
The successful cases DO hit our Authorization URL first, as expected.
Feel free to pipe up if anyone can answer ANY of the following:
Any ideas what could be causing problems here?
Or ways we might investigate deeper?
Does an app need to be in Alpha testing, or anything like that before Account Linking works?
Is it normal/expected to hit the Token URL for a user that has never successfully linked accounts?
Can anyone confirm what the Token fetch response should be in that case? (Maybe we are not responding in a way that satisfies the other end)
Does anyone have a dummy/HelloWorld Account Linking web end-point we could test against? (Geeze that would be handy for the developer community!)
I don't know exactly what is going on, but there are a couple of hints about what is happening and what avenue to investigate. I'm going to assume you're doing Account Linking with OAuth only. If you are doing a combination of "Google Sign In for Assistant and OAuth", that might change some things. To address some of your questions:
What could cause the Assistant to go to the Token Endpoint instead of the Auth endpoint?
It wouldn't go to the Token Endpoint unless it already had a Token. I could think of a few possible scenarios:
If it was going to Auth, getting a token since it was already authorized, so no window would pop up. (But you indicated it isn't going to that page.)
If the account in question is already authorized to the project via some other means. You can check https://myaccount.google.com/permissions to see if it is already authorized.
If you had tested it with this account previously and it has a token from then. If so, it should be listed at https://myaccount.google.com/permissions. Probably.
If you're not using the account you think you're using on the device in question.
How to investigate this?
Once you double-check some of the more obvious things (using the right account?):
Look at what is being sent to the Token endpoint
Does the token look familiar? Is it the same between calls? Same between different accounts?
Do you log tokens being issued? Can you?
What about the other information sent along with the token such as the client_id and client_secret?
Does it need to be in Alpha?
I'm not sure. Last I checked, it did not. I do think that it no longer works in the simulator, which is annoying, but doesn't require being in Alpha.
It does make it a little more difficult to check, however, since there is no Directory page that can tell you if the account is already linked. You'll need to go to the list of linked apps for the account to remove your app if it is: https://myaccount.google.com/permissions
Is this normal?
I wouldn't think so. It shouldn't hit the Token Endpoint unless it has an auth code or refresh token to exchange. It has to have that code/token from somewhere.
How should you respond?
If you get an auth code or refresh token that is invalid, or any of the other information provided at the token endpoint doesn't match what it should, you must return HTTP error code 400 "Bad Request" and include as the body the JSON
{"error": "invalid_grant"}
This should force it to go through reauth with the user.
Is there a public test server?
Auth0 isn't exactly public, but is free for basic use, and well suited for test purposes.

Actions SDK, Linked Account: Indicating that the access_token is no longer valid (and needs to be refreshed) or that the account needs to be re-linked

We're currently working on a project that requires the users' accounts to be linked to one of our client's services via the oAuth2 authorization flow.
However, there is the possibility that tokens expire before the expires_in duration that's returned with the token from the oAuth2 token endpoint, or that the user simply revokes the token/authorization. In that case a new token needs to be fetched via the refresh-token-flow, or the Account needs to be re-linked altogether.
Is there some way for us to indicate to Google (in the HTTP response returned by the fulfilment backend, or via some other way) that the access_token is no longer valid and needs to be refreshed, or that the Account needs to be relinked?
For instance, with Alexa, it is possible to return an "Account Linking Card" in the HTTP response along with the actual speech that's read back to the user.
This "card" then starts the account linking process on Amazon's side(even if the Account was already linked before). Is there an equivalent to this in the Actions SDK?
If there is no way for us to indicate to Google that the Account Linking is no longer valid and needs to be redone or refreshed, is there at least some way to programmatically "unlink" an Account (which would then automatically trigger the Account Linking process on the next invocation)?

GWT : How to prevent client-side state from being cleared when a redirection (for e.g : OAuth2) happens?

I am implementing OAuth2 authentication for one of my GWT projects (let's call it GWT-app). The application responsible for authentication is a third-party application based on Spring Framework-3.1.2.RELEASE and uses its OAuth2 implementation included in Spring Security-3.1.3.RELEASE (let's call it OAuth-app).
GWT-app is a management application for managing user and stores. Each user has one or more manager accounts. A manager account may have one or more stores attached to it so that he can manage them altogether from one screen of the GWT-app.
It means that the user may potentially have to authenticate many times through different manager accounts to display stores by manager account on the app.
So on the StoreManagement.java page of my GWT-app, I have the following :
private final Map<String, ManagerAndStoresProxy> managerAndStores = Maps.newTreeMap(Ordering.natural());
after authentication, this map should be populated with Manager name and a List of attached stores for each.
OAUTH2 FLOW
The Authorization-code flow is used for authentication. When GWT-app wants to authenticate someone, it redirects the user to a login page on OAuth-app. The user enters his credentials and will be presented with an authorization page asking him whether he wants to allow GWT-app to access his information. If the user clicks on authorize, he is redirected back to the GWT-app with an access token.
THE PROBLEM
The only issue is that since GWT-app is redirecting the user to another application for authentication, the first time the authentication works and the map is populated correctly but if I have to authenticate another account then the previously authenticated account is cleared and can not be retrieved because of the redirection.
The question is then : how can I proceed to persist this map and retrieve it back when a second (third, fourth and so on) authentication flow is over (i.e after the url-redirection of OAuth-app).
WHAT I HAVE TRIED SO FAR
What I did so far is that when the user wants to proceed with authentication from the StoreManagement.java page, he is presented with a popup redirected to the OAuth-app authentication page. The access token is then retrieved from this popup but I have to send it back to the parent window (i.e StoreManagement.java page). This can be done via a HTTP GET parameter but this method reloads the parent page and the result is the same: the previously authenticated account is cleared.
QUESTION
What is the best way to handle this situation without clearing the previous context and without requiring any server-side session mechanism whatsoever ?
The root of the problem is using the authorization code grant; the implicit grant (aka client-side flow) would be a much better fit.
If your app is not limited by old browsers in terms of compatibility then you can try to store all necessary things in HTML5 Web Storage.

Unexpected Authorization Request in Workflow C2QB WF3.0

We have a multi-tenanted/multi-domain app and we're looking at publishing on IPP. Because of the multi-domain nature our configured endpoints in the App setup are generic and users are then redirected to their specific account once their identity is established.
The issue is with C2QB WF3.0.
The test steps are:
go here: https://appcenter.intuit.com/Home/MyApps/
on the "Launch My Apps" tab, click the app
Expected Result:
the Sign In screen for the app is displayed
The requirement is:
if not still signed into the app, sign in screen is displayed
if still signed into the app, take user into the app
The issue is that the even if the user is currently logged into our application, it still requests authorization as per this message:
"domain" is requesting some information from your Intuit account
By approving this request "domain" will be able to access your:
Name
Email Address
The workflow that it is actually following is to perform a callback to our connect url. The normal way to determine which account the callback is coming from is via the realmId, but this is not received from Intuit and therefore it needs to be requested. Once a user has completed this authorization, it will not ask again. It should be noted that we're not actually requesting a name or an email address as the screen suggests.
We've been informed by Intuit that it should not request authorization and it is not part of the workflow.
We're wondering if anyone else has encountered this problem and if there is a workaround for it.
We discussed with the Engineering teams and they confirmed what Pete has mentioned above. This is not a bug and please follow the steps as Pete has mentioned.
If you want to replicate the 'access your app with appcenter flow', you have be either logged in QBO online company file in same browser session or navigate to the app via blue dot menu from your application or run your application from localhost(.net) and then go to Appcenter and login there on same tab and then click on your app.
Since your desktop application is running, your code will be hit.
You will then get the second Auth screen only for authorizing your company file. After authorization your realm will be set in a cookie and in the code you can see its value. You can replicate this behavior via firebug and see the qbn.parentid cookie value has the realm after authorization is done.