Zoho CRM API v2- Current user API (users?type=CurrentUser) returns 403 - zoho

We are using Zohocrm api v2 for getting currently logged in user. It works fine for most of the logins.
But we are getting 403 for one of the user account.
URL https://www.zohoapis.com/crm/v2/users?type=CurrentUser
HEADERS {Authorization=Zoho-oauthtoken 1000.786ecda99xxxx}
Response
{"code":"NO_PERMISSION","details":{"permissions":["Crm_Implied_Api_Access"]},"message":"permission
denied","status":"error"}
Response Code 403
Note: From the same zoho team other 2 users were able to login.
Please suggest.

Just adding the steps with which I tried in Postman. It works for me.
If at all any of the steps are different from yours, you could try these steps instead.
Add the client to get client secret
Generate auth token giving client id and secret (and scopes)
After this step, oauth permission request page will be shown, asking user to confirm access to Accounts User Profile and CRM users info. Both have to be accepted.
Use the latest generated token in postman
Execute API GET

Related

How to get new acess token from refres token for google api in postman

I am trying to get new access token from my refresh token for google drive api. In my google playground it works but when I want to create the same request in postman or my code it doesn't work and I always get error "Invalid grand type". I don't know to find what is problem.
google developers playground
postman headers and body
You need to understand that there is three steps to the Oauth2 dance.
step one is requesting access of the user and getting the authorization code.
HTTP GET https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
Note &response_type=code tells the server you want an authorization code returned.
step two is to exchange that code for an access token and refresh token.
POST https://accounts.google.com/o/oauth2/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
Note the part where it says &grant_type=authorization_code. this tells the server you are giving them an authorization code.
3 the final step is refreshing your access token.
POST https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Note &grant_type=refresh_token you are telling the server you are sending them a refresh token.
You appear to be sending a refresh token with the wrong grant type.
I have a video on how to set up postman to use google oauth2
How to set up Oauth2 in PostMan.
Google 3 Legged OAuth2 Flow
Note: Due to a recent change with Making Google OAuth interactions safer by using more secure OAuth flows redirect uri of urn:ietf:wg:oauth:2.0:oob is going to stop working soon.

Error 400: invalid_scope Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]

So I'm trying to use the Home Graph API by calling the API endpoint
https://homegraph.googleapis.com/v1/devices:requestSync
It is a HTTP POST request and it needs an ACCESS_TOKEN and service account key.
Getting the service account key is easily done as per Google's documentation. The issue is getting the ACCESS_TOKEN.
As per this documentation by Google, I need to get ACCESS_TOKEN created using the following scope of permissions
https://www.googleapis.com/auth/homegraph
I opened OAuth 2.0 Playground to request a developer temporary ACCESS_TOKEN for testing. I wrote all the necessary urls and in scope I wrote this-
scope is written to be authorized
Now after this, I am navigated to my Authorization URL (ie, Google's sign in page). I login with email id and password.
If credentials are correct and scope mentioned is valid then I should have been redirected to OAuth playground page with authorization code which I would have exchanged for access token and refresh token.
But, what actually happens is after I enter my credentials, I get following error and I am never redirected to Oauth Playground page-
Authorization Error
Error 400: invalid_scope
Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]
Request Details
access_type=offline
o2v=2
response_type=code
redirect_uri=https://developers.google.com/oauthplayground
prompt=consent
client_id=xxxxxxxxx.apps.googleusercontent.com
scope=https://www.googleapis.com/auth/homegraph**
I searched a lot online too, but couldn't find the actual reason.
So due to this issue with scope, I am not able to get ACCESS_TOKEN.
I have followed Google's documentation and the scope was mentioned there.
This is the pic from oauth 2.0 playground settings- OAuth 2.0 configuration
The issue is that you, a user, should not be getting and sending an access token. The service account should be getting and sending an access token. This is to make sure your service is authorized to talk to the Home Graph API.
You indicated you logged into the OAuth playground with "userid and password". But service accounts don't have passwords.
If you are using one of Google's libraries, it will take care of getting the access token for you, and this is the easiest way to do so. If you are just testing and need an access token, you can use something like oauth2l to get the access token based on the service account credentials.
I had implemented the REST approach to call HomeGraph Report State as below.
We need to follow the below steps:
Create a service account for your project and safely store the json file
Using the service account JSON, get the access token from Google
Using Oauth 2.0 token as Bearer authorization, invoke Report State API
Step 1:
This is straightforward. Please follow the steps in the below link
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1
Step 2:
Refer below code to get the Access token using service account json
GoogleCredentials credentials = GoogleCredentials
.fromStream(Helper.class.getClassLoader().getResourceAsStream("smart-home-key.json"))
.createScoped("https://www.googleapis.com/auth/homegraph");
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
return token.getTokenValue();
Step 3:
Invoke Report State API
curl -X POST -H "Authorization: Bearer [[Access token from Step 2]]"
-H "Content-Type: application/json"
-d #request-body.json
"https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
Reference Links :
https://developers.google.com/assistant/smarthome/develop/report-state#http-post
https://cloud.google.com/endpoints/docs/openapi/service-account-authentication
https://developers.google.com/identity/protocols/oauth2/service-account#httprest_1
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1

Alexa skill account linking with Google APIs credentials, problem refreshing token

I'm having some problems with the Alexa account linking authorization.
These are the steps I followed:
I got the credentials (client id, client secret...) from the Google Cloud Console
Setup on the Alexa Developer Console, using 'Auth Code Grant' as authorization grant type
Activated the skill on my Alexa application and successfully logged in with my Google account
Now I got the access token in the request, in handler_input.request_envelope.context.system.user.access_token
The problem is that the access token expires after one hour and Alexa does not manage the refreshment of the token.
What should I do to avoid having to ask my users to login every time after one hour? Should I use Implicit grant as authorization type? Should I get a refresh token somehow?
Additional info: it's a custom skill that connects to an AWS Lambda using Python3
While #pinoyyid's answer was correct, it didn't provide a solution so I'm posting one for future reference.
The problem was indeed that Amazon servers did not receive a refresh token from Google, thus making it impossible to refresh the access token after its expiration time of one hour.
Following this link and other Amazon forum posts, I got to a working solution.
Amazon Alexa developer console 'Account Linking' configuration:
Authorization grant type: Auth Code Grant
Authorization URI: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline (even though the one from the google credentials was not v2, it shouldn't make a difference)
The access type is very important because, as documentation goes:
Set the [access_type] value to offline if your application needs to refresh access tokens when the user is not present at the browser. [...] This value instructs the Google authorization server to return a refresh token and an access token the first time that your application exchanges an authorization code for tokens.
Access Token URI: https://accounts.google.com/o/oauth2/token
Client ID & Secret: downloaded on Google Cloud Platform
Client Authentication Scheme: HTTP Basic
Domain List: google.com and googleapis.com
Default access Token Expiration Time: left empty
Now, after doing this and saving the configuration, be aware that you might not notice the change, as, from here:
When Alexa uses the refresh token to retrieve a new access token for an existing user, Alexa uses the access token URI that was configured at the time the user linked their account. Therefore, if you change the access token URI later, users who linked their accounts before continue to use the old URI for retrieving updated tokens. The users must unlink and re-link accounts to switch to the new access token URI.
So, in order to complete the procedure:
Deactivate your skill
Go to the Google third party applications that have access to your data and remove your Google Project associated
Reactivate your skill and login again (if done correctly it should ask you the permissions for the scope you specified in the Alexa developer console again
Done! after one hour you should re-try and it should have a renewed access token
Additional Info
I found that many suggested to retrieve the refresh token, I don't believe this is possible because, even if Google sends it, it's Amazon that stores it and uses it to refresh the access token.
EDIT:
This works fine for developing and testing but I discovered here that for publication purposes you must own the landing page that you redirect your users to. For me it was just necessary to create a simple HTML page hosted in a public S3 bucket that would redirect the request to the Authorization URI I wrote before, while the Access Token URI must remain the Google one.
Have you read https://developer.amazon.com/docs/account-linking/configure-authorization-code-grant.html ?
My guess is that the Refresh Token is missing because you have already auithorised the app. The RT is only issued once. Try going into https://myaccount.google.com/permissions?utm_source=google-account&utm_medium=web to revoke the permission and try again.

Insert User in Google Directory with Service Account

I wrote a PHP application which tries to create an User in my Google Directory. I don't use the Google Libraries. I succeded making requests to the Android Enterprise API. I can enroll and unenroll Enterprise Service Accounts with my MSA. So I assume my Code for the JWT and Requests work.
I created a Service Account and enabled "Domain Wide Delegation" and added the following permission "https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.group" to my API Client under the "Manage API client access" windows.
My Service Account has the status role "Editor" in the "Permissions for project" windows.
So first my script gets the Bearer token from the Google Server, for that I create a JWT and encrypt it with my private key.
The Token contains the following fields
"iss" => sacname#projectname.iam.gserviceaccount.com
"scope" => "https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.group"
"aud" => "https://www.googleapis.com/oauth2/v4/token",
"exp" => timestamp+3000,
"iat" => timestamp
When I do that request I get a bearer token, but when I use that token to make the insert request I always get the message "Not Authorized to access this resource/api" with an HTTP 403.
When I add the field "sub" to my JWT and specify the email of the Project admin "admin#mydomain.com" I can't even get the bearer token, then I get a 401 error with the following message "Unauthorized client or scope in request."
After that I tried something "easy", I just wanted to get a list of all users in my directory. But the Google Server just reponds with an "bad request" error. I got the same error with the API Explorer which is on API Page. Maybe the API is broken ? At least the API Explorer should work.
https://developers.google.com/admin-sdk/directory/v1/reference/users/list
Do you have some ideas why I can't create users with my service account ?
(I had to insert some spaces in the scopes and urls because I'm not allowed to post more than two links)
Greetings
Philip
Adding the sub claim is the right thing to do, because you must impersonate a super admin to use Directory API. If you get a "Unauthorized client or scope in request" response, that might be because there's a typo in the service account client ID you used to authorize (or the scopes), or that not enough time has passed (it usually propagates within a few minutes, but could take up to 24 hours).
See JWT error codes for more details on possible errors and causes.
Do you have some ideas why I can't create users with my service account?
Yes. Your service account seems to have no authority to create users. Check your Service Account's role in GDC to check if it's Owner, Editor, Viewer,etc. The scope of what they can do depends on that. Watch this Google video for a live demo.
Also, try to read more on Using OAuth 2.0 for Server to Server Applications.

Error 403 "you are not authorized to access this API " Email setting API

I am writing a code in salesforce to update Email signature using the API documentation mentioned in https://developers.google.com/admin-sdk/email-settings/. I am using a 3 legged approach.
Considering that this is an API for domain admins, My questions is
can a user ( non - admin) provide authorization for this API ?.
And can the access token returned as a result of this authorization be used to update his email signature. ?
Right now I am getting an Error 403- "you are not authorized to access this API
Note that this is working fine if a domain admin provide authorization and his access token is used to update his/ any user's email signature
Thanks for your help
With the new updates on the GMAIL Api you can get the user signature by using the method "Users.settings.sendAs: get" explained here https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs/get and it does not require the user to be an admin. This method returns a Users.settings.sendAs resource in the response body and this resource contains the property signature which you can manipulate.
Hope it helps!

Resources