Access Denied error during step 1 of Xero API OAuth2 standard authorization code flow - xero-api

I have an existing Xero app that's worked well for over a year that uses OAuth2 to connect a small number of organisations to one of three Web Apps: developer, sandbox, and production. Sandbox and production are working well. However, yesterday I started to create a new instance of the developer app and am unable to complete the first step. My app calls the following URL:
https://login.xero.com/identity/connect/authorize?response_type=code&client_id=069BFC79B7REDACTED&redirect_uri=https%3A%2F%2Fdev.addressredacted.ngrok.io%2Fcotrustee%2Fxero&scope=offline_access+accounting.transactions+accounting.settings+accounting.journals.read
This URL has the same form that has worked for over a year, just with a new client_id, but now I keep getting this error:
Access Denied
You don't have permission to access "http://authorize.xero.com/?" on this server.
Reference #18.d2fdda17.1671639885.53ec38b
I expect to be redirected to a Xero login page instead.

From the Ref# that you received, it looks like it has hit the Akamai WAF. Unfortunately the code has expired (it only has a lifetime of 24 hours) thus we are unable to check why it was blocked.
Can you contact Xero API Support - api at xero dot com - with a newer reference so we can further investigate?

Related

avoid auth token to expire

I want to use the gmail api to update myself about the status of a programm I'm running locally 24/7. Basicly once a day it should send me a status report per email from the emailaccount I created just for this case to the same account.
I've got a project set up, the api enabled, got my credentials and created a token.json file. I managed to have it send me emails yada yada yada.
I concentrated on the further development of the programm for some time and then wanted to jump back to this to test out another feature where I wanted to implement a ping me feature. I'd send myself an email asking for a ping back just to check if my program is still running.
While doing that I noticed that my token expired. I tried reading into what I can do about that. Ideally I'd like to have the program just run autonomously. I read for my case that a service account would be ideal but after setting that all up and 2 hours later after a lot of errors I read that interacting with the gmail api with a service account is only open to workspace users since I can't delegate domain-wide authority without one.
So after some further reading I read that next to the access token I created I can refresh that token with refresh tokens. for that I was trying the request function noted in the quickstart tutorial:
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
now running creds.refresh(Request())
I get this error:
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
Upon further reading here I read that refesh tokens are only available to projects whose status is set to in progress and not in testing. Projects set to testing are required to have the user manually log in at least once a week which I don't want.
Now for me verifying my project doesn't make sense since I won't have any other users using my access to the gmail api and frankly I wouldn't want that either.
What are my options here to have the script running continuously without having to manually sign in once a week? Considering also that I will be at all times the only user.
Thank you,
Florens
Your still have a few options. For one, you could get a Google Workspace account. The lowest tier would set you back around $6 per user per month. This would allow you to publish the app as internal-only and you don't need to go through the verification process, but you can only use the app with the Workspace account. You can still send emails out to any addresses, though.
If you don't want to pay, you can still set your app to Published status and you do not necessarily have to go through the verification. There are some limitations, such as the app warning that shows up when signing in and a user cap of 100 users, but since you know that the app is safe and you don't need more users you can just ignore this, Google says so in their own documentation:
What app types are not applicable for verification?
Personal Use: The app is not shared with anyone else or will be used by fewer than 100 users. Hence, you can continue using the app by bypassing the unverified app warning during sign-in.
As you already know, the refresh token expires in 7 days only when the app status is set to "testing", so as long as you have it set as "In production" and ignore the unverified app warnings, you should be able to have a normal refresh token that you can use without needing to sign in every 7 days.
Just keep in mind that other users could have access to the app but if you're careful to keep your OAuth credentials to yourself that should not be an issue.
Sources:
Unverified apps
OAuth API verification FAQs
OAuth overview

Anyone know how to fix the new OAuth2 error when trying to authenticate a PyDrive application?

I don't think this issue is specific to PyDrive, but rather Google OAuth. However, some of the solutions I've seen on stackoverflow don't seem to be transferable over to my PyDrive application, which is just a python script to upload files programmatically to a shared drive. It worked fine 2 months ago but I tried to rerun it today and it's not working. Here is the error I'm getting:
Authorisation Error
Error 400: invalid_request
You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.
You can let the app developer know that this app doesn't comply with one or more Google validation rules.
Request Details
The content in this section has been provided by the app developer. This content has not been reviewed or verified by Google.
If you’re the app developer, make sure that these request details comply with Google policies.
redirect_uri: urn:ietf:wg:oauth:2.0:oob
I am using a web application OAuth 2.0 Client ID creds on GCP. All secrets are stored in a local client_secrets.json file.
I run my script, it sends a message to the console that says
Go to the following link in your browser:
https://accounts.google.com/o/oauth2/auth?client_id=blahblahblah.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&response_type=code
Enter verification code:
How it used to work: After I click the link above, it returns a code I paste into the console and then its authenticated. FYI: I plan on running this 24/7 on a remote server.
Now: I click the link above and get the error I posted above. I've tried to change the redirect uri to 127.0.0.1 and it does allow me to auth, then I get a code in my URL, but once I copy that and paste it into the console, I get more errors.
Anyone know the solution for this?

Xero - OAuth1 to OAuth2 migration

I started working with adding migration from OAuth1a to OAuth2 inside my application and i face some problems.
This is what I've done :
I updated my partner app just like it is described here https://developer.xero.com/documentation/oauth2/migrate (added Auth2.0 redirect , got client id and secret etc ...)
I implemented token migration exactly as it is done here https://github.com/XeroAPI/xero-net-oauth2-sampletokenmigration and it works fine when OAuth1 token is valid :)
But when it is invalid and I'm doing refresh (using app updated in step 1) and call ~/oauth/migrate endpoint (using access token that i just recived after refresh step) to get OAuth2 token. I'm reciving this error "You can only migrate an OAuth1.0a connection to an OAuth2.0 connection for the currently authorised app". Also same thing happen when i create new connection (using partner applications created in in step 1) and than try to migrate this access token to Auth2.0.
Can anybody point me what I'm doing wrong ?
That is the error returned when you try to migrate to a newly created app. Are you sure you are using the tokens from the same Partner app tile in your /myapps dashboard.
It should look something like this, once you've added the correct OAuth2 redirect uri and generated your secret.

Google Analytics API authentication

I was using this code until yesterday:
$gaemail = 'my email';
$gapassword = 'my password';
$gaprofileid = 'my profile id';
require 'gapi.php';
$ga = new gapi($gaemail,$gapassword);
Today it started giving me the error:
Exception: GAPI: Failed to authenticate user.
Error: "https://developers.google.com/accounts/docs/AuthForInstalledApps " in C:\wamp\www\projects\gapi.php on line 418
Was there any changes recently regarding the authentication process?
See: GAPI: Failed to authenticate user. Permanent fix PHP
GAPI hasn't been worked on since 2009. It also appears to use client
login which was discontinued / shutdown on April 20 2015. You can no
longer use client login with Google Analytics API, you need to switch
to Oauth2 or a service account. So either the author of that project
needs to fix his code, it appears to be an open source project so you
could probably fix it for him.
You have a couple of choices. Looks like the latest version of GAPI now has oauth support - see: https://github.com/erebusnz/gapi-google-analytics-php-interface or use the Google API PHP Client (https://github.com/google/google-api-php-client).
Version 2.0 on GitHub of the GAPI has been released which support OAuth2 authentication. Google has disabled all other forms of authentication.
Note that OAuth2 will require you to create a 'service account' and then download a P12 file to upload to the server. Finally you will need to adjust the developers console, enable 'analytics API'. Finally give this new user 'Read and Analyse' permissions on the Google Analytics accounts you want to access.

How to get user data from Google API with OAuth remotely from a server?

I've been reading lots of documentation about Google API access and OAuth flow using it but I don't seem to get it working in my mind, so I want to get some help first in order to have a clear idea about how it works then I can code it using the corresponding API.
What I want to achieve is feed a Java application running in a PC with specific Google user data, like localization through Google Latitude API. In order to get this, OAuth must be used, so I need getting the user consent, then access the user data from the application running in my computer, and I don't know how to manage this.
I've already registered my application with the Google APIs Console and enabled the Google Latitude module. I've also tried the Latitude console application here and it works properly (a browser tab opened asking for a Google user; I entered it and I got the location data), but I'm having problems when trying to adapt the program flow to my needs.
In my application, the 'remote' user is supposed to send a request (a custom JSON message) to the server asking for service enable/disable, like allowing the server to track his/her position through Latitude. Then, AFAIK, the server should send to the user a URL so the user can give the consent, but I don't know how to get this URL and how the server realizes about this consent and gets the token (automatically? Google tracks this authorization process?). Once my server gets the specific user token, then I should be ready to get service data for that user using the received token.
As I said before, I've tried according to different references, but as the documentation seems to be really scattered and much of it is already deprecated, I've been unable to get it working.
Judging from your description, the installed app OAuth2 flow seems to be the right one for you.
At some point, presumably when a user is installing your desktop app, you should fire up a browser - either embedded one in your app or the default browser - and sent them to this Google OAuth2 endpoint. In your request, fill out all the parameters as required by the doc: Latitude API scope, client_id, etc. Google, as an authorization server, will take care of user authentication, session selection, and user consent. If the user grants access to her data to your API, you will receive an authorization code either in the title of the browser window or at a localhost port.
Once you have the code, you can exchange it for an access token and a refresh token. The access token is what you need to call the API and access the user's data. It is short lived though - check the expired_in parameter in the response, I believe it is 3600 sec. - so you will need to periodically ping the token endpoint with your long lived refresh token and exchange it for an access token.
You can find a more thoroough description of this flow in the doc linked above.