google cloud authenticating to the wrong project ID - authentication

I'm trying to follow the quick start code for using the perspective API but the code fails because it keeps defaulting to another project.
I have already created an appropriate service account for project A, which is my intended project. I downloaded the corresponding SA key file and my API key is affiliated with project A. But every time I run this code (at the line discovery.build()) I get an error message because it's using project B and this service is only enabled for project A.
from googleapiclient import discovery
from google.oauth2 import service_account
import os
API_KEY = 'myapikey'
SA_FILE = 'my_sa_keyfile.json'
scopes = ['https://www.googleapis.com/auth/cloud-platform']
credentials = service_account.Credentials.from_service_account_file(
SA_FILE,
scopes=scopes)
client = discovery.build(
"commentanalyzer",
"v1alpha1",
credentials=credentials,
developerKey=API_KEY,
discoveryServiceUrl="https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1",
static_discovery=False,
)
There's no place in discovery.build() to set my project ID. What am I doing wrong?

Related

Google Colab - connecting to Google Cloud Storage does not create an adc.json file since few days

For the recent few days I have been struggling with the following problem on Google Colab
Upon entering the produced link and entering my credentials the usual text to copy is not there.
Instead I get this window
Afterwards the connection to the google cloud storage looks like this . The project number 522309567947 is not my project and I do not understand why its appearing there.
After entering my project ID I am able to connect to my google cloud storage account but the adc.json file with client_id, client_secret and refresh token is not produced. I need this file to connect my tensorflow to my google cloud storage.
The following code will create an error because the adc.json does not exist.
Is there any solution to my problem? Or any workaround to get the adc.json file?
The following code, should fix the issue you see:
!gcloud auth application-default login --no-launch-browser
The real hint is the project number 522309567947, which is probably the project number for the project Collab is hosted in. This means that it's not an authentication issue but a client project id or quota project id configuration issue.
Setting your quota project would probably resolve the issue:
!gcloud auth application-default set-quota-project your-project-id
The solution for me was to explicitly set the quota project id when creating the client:
from google.cloud import bigquery_datatransfer
from google.cloud import bigquery_datatransfer_v1
from google.api_core.client_options import ClientOptions
options = ClientOptions(quota_project_id="your-project-id")
transfer_client = bigquery_datatransfer.DataTransferServiceClient(client_options=options)
parent = transfer_client.common_location_path(project=project, location="europe")
configs = transfer_client.list_transfer_configs(parent=parent)
print("Got the following configs:")
for config in configs:
print(f"\tID: {config.name}, Schedule: {config.schedule}")

Authentication issues on Colab/Bigquery

I use BigQuery from Colab for a long time, and since 2020 my account is on Google's enhanced security program. Until yesterday I had no issues authenticating with
from google.colab import auth
auth.authenticate_user()
Now, though, I get a 400 error. These are the details it gives:
access_type: offline
login_hint: (email)
response_type: none gsession
redirect_uri: https://colab.research.google.com/tun/m/auth-user-ephem
state: {"token":"(token)","endpoint":"(endpoint)","scopes":["openid","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/drive"]}
hd: (domain)
prompt: consent
client_id: (client_id)
scope: openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/drive
My question: are there configurations on the auth to allow for authenticating?
I've encountered this problem too. It seems that Google have changed the authentication procedure so that you (or your organisation) have to add colaboratory to the list of apps with permission to access your account.
However, there's also a way to revert to the old authentication behaviour which works without any special permissions:
import os
os.environ['USE_AUTH_EPHEM'] = '0'
from google.colab import auth
auth.authenticate_user()
If you look at the source code of the authenticate_user() function, you can see that it reads the USE_AUTH_EPHEM environment variable to decide whether to use the old or new authentication flow.
Update:
An alternative (and possibly more future-proof) way to authenticate is by running the following line in Colab.
!gcloud auth login --no-browser --update-adc
This requires you to have the Google Cloud CLI installed on your local machine, then just follow the instructions. If all goes well you'll be able to access BigQuery from within Colab without needing to call auth.authenticate_user() at all.
You may try the below alternative approach wherein you will upload your json key file (for authentication) in Google Drive, then mount it to Google Colab and then explicitly use it in your python code to authenticate your BigQuery API request.
from google.cloud import bigquery
from google.oauth2 import service_account
from google.colab import drive
import json
# Construct a BigQuery client object.
drive.mount('/content/drive/') # Mount to google drive
# Define full path from Google Drive.
# This example, the json key file is in /MyDrive/keys/
key_path = '/content/drive/MyDrive/keys/your-json-file.json'
credentials = service_account.Credentials.from_service_account_file(
filename=key_path, scopes=["https://www.googleapis.com/auth/cloud-platform"],
)
client = bigquery.Client(credentials=credentials, project=credentials.project_id,)
query = """
SELECT name, SUM(number) as total_people
FROM `bigquery-public-data.usa_names.usa_1910_2013`
WHERE state = 'TX'
GROUP BY name, state
ORDER BY total_people DESC
LIMIT 20
"""
query_job = client.query(query) # Make an API request.
print("The query data:")
for row in query_job:
# Row values can be accessed by field name or index.
print("name={}, count={}".format(row[0], row["total_people"]))
Below is the result of my above sample code when executed in Google Colab:

Upload file to Microsoft OneDrive using graph SDK using asp.net core

I am trying to upload a file to OneDrive using Graph SDK for .Net Core from worker service.
Basically, some files are created at random time and those files needs to be uploaded to specified path on OneDrive from worker service at midnight every day.
I have following information stored in appconfig.json file in application:
ClientID
ClientSecret
TenantID
I have checked samples on various sites but could not find how to upload files using above ID and Secret. I believe there must but some kind of authProvider that I could initialize using above ID and Secret.
I also checked miscrosoft's documentation but coudl not find any example on how to upload file using SDK with ID and Secret.
https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online
Additional Point
Upload new file
Overwrite if file already exists(hope that graph already supports this)
file size is < 4MB
path format /folder1/folder2/filename.pdf
Any help would be appreciated.
Remember to assign Application permission (Client credentials flow) to the app registration. See Application permission to Microsoft Graph.
You can use Client credentials provider.
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantID)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
Upload small file (<4M):
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
using var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes("The contents of the file goes here."));
await graphClient.Users[{upn or userID}].Drive.Items["{item-id}"].Content
.Request()
.PutAsync<DriveItem>(stream);
If you want to upload large file, see Upload large files with an upload session.
UPDATE:
Use Install-Package Microsoft.Graph.Auth -IncludePrerelease in Tools -> NuGet Package Manager -> Package Manager Console.
It supports both uploading a new file and replacing an existing item.
For how to get the items id, please refer to Get a file or folder.
For example, get the item id of /folder1/folder2 (have a quick test in Microsoft Graph Explorer):
GET https://graph.microsoft.com/v1.0/users/{userID}/drive/root:/folder1:/children
It will list all the children in folder1, including folder2. Then you can find item id of folder2.
UPDATE 2:
Client credentials provider is application identity while all the providers below are user identity.
Since you want to access personal OneDrive (including user identity), you could choose Authorization code provider or Interactive provider.
Authorization code provider: you need to implement interactively sign-in for your web app and use this provider.
Interactive provider: you can easily use this provider to implement interactively sign-in in a console app.
You can have a quick test with the second provider.
Please note that you should add the Delegated (personal Microsoft account) permissions into the app registration. See Delegated permission to Microsoft Graph.
And in this case, you should modify all graphClient.Users[{upn or userID}] to graphClient.Me in your code.
I'm afraid that you have to implement sign-in interactively auth flow to access personal OneDrive.

Problems working with Google Calendar Api V3 and PHP

I'm just trying to make a little, simple application (that i already made two years ago in Objective-C with api V1) that presents a screen with time of event and description and a button : "insert event in your calendar".
Every user has, obviously, to configure the application with his google username and password.
The app simplifies some process using the first calendar available.
I had infinite problem trying to do it with javascript (this app will be made in html5), so, looking at docs, I ended up trying to make a back-end on my server in php5 (thought it could be easier...ohohoho).
So, i read docs from here : https://developers.google.com/google-apps/calendar/
What i did :
1)
Get to the Google Developers Console.
Created a project.
I now have this (not real keys):
OAuth 2.0
Client ID 352xxxyy9.apps.googleusercontent.com
Email address 3527xxxy#developer.gserviceaccount.com
Service Account
Client ID 3523xxxyy419-vpfgdfg9u77s0.apps.googleusercontent.com
Email address 35ssss9-zzzzsnhavna78ea0b9gvn6a9u77s0#developer.gserviceaccount.com
Public key fingerprints :ac15ddfxdffrtg5565fgfg545r
2)
I installed Google APIs Client Library for PHP (beta) in my server.
doc says:
Using the Google APIs Client Library for PHP requires that you download the PHP source. In the future, packages will be provided. Refer to the project page for more details.
Run the following commands to download and install the source: svn blaj blah blah.
I copied the entire source in my server. Easy :)
Then..
3) You can now import the classes you will need using the following statements:
require_once "../src/apiClient.php";
require_once "../src/contrib/apiCalendarService.php";
Ok, i'll insert them in my php script !
4)" Configure your app"
You must instantiate a client to make requests to the API. All requests to the Google Calendar API require authorization.
The following code demonstrates how to configure an authorized service object using OAuth 2.0 for native applications. For more information, see Authorize Requests.
To find your project's client ID and client secret, do the following:
Go to the Google Developers Console.
Select a project.
In the sidebar on the left, select APIs & auth. In the displayed list of APIs, make sure the Google Calendar API status is set to ON.
In the sidebar on the left, select Credentials.
Find the lines labeled Client ID and Client secret. Note that there may be a client ID without a client secret, for use with Compute Engine and App Engine; in that case, create a new client ID and client secret by selecting Create New Client ID.
Edit the src/config.php file to put in your developer API information.
global $apiConfig;
$apiConfig = array(
// Site name to show in Google's OAuth authentication screen
'site_name' => 'www.example.org',
// OAuth2 Setting, you can get these keys in Google Developers Console
'oauth2_client_id' => 'YOUR_CLIENT_ID',
'oauth2_client_secret' => 'YOUR_CLIENT_SECRET',
'oauth2_redirect_uri' => 'YOUR_REDIRECT_URL',
// The developer key; you get this from Google Developers Console
'developer_key' => 'YOUR_DEVELOPER_KEY',
...
// Which Authentication, Storage and HTTP IO classes to use.
'authClass' => 'apiOAuth2',
....
// Definition of service specific values like scopes, OAuth token URLs, etc
'services' => array(
'calendar' => array('scope' => 'https://www.googleapis.com/auth/calendar'),
)
);
But they are DIFFERENT from the key i have, what's wrong ????
What are client secrets ? redirect_url??
Please help.
I think you need to setup a service account access as described here:
https://code.google.com/p/google-api-php-client/wiki/OAuth2#Service_Accounts
I had difficulties to get it work as I made many trial and errors and my cache got filled with non-working token.
If ever you find yourself not able to access the calendar even after following all the steps, try to change this line of code:
$client->setAssertionCredentials(new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/prediction'),$key));
to this:
$client->setAssertionCredentials(new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/prediction'),$key, 'notasecret','http://oauth.net/grant_type/jwt/1.0/bearer',false,false));
The last false tells AssertionCredential class to not use any cache. I did it once and then it worked with it set to true afterward.
First go here https://console.developers.google.com/project that is where you configure your app...
Click on your project, then on the left side you will see APIs & Auth, click on Credentials. You will need to create your OAuth, and Public API Access keys.
Once you have done that you will then enter those into the appropriate client_id, secret, redirect etc.
The redirect uri is the same page your app is on, its the page the user gets sent back to after authorizing.
I had the same problem.
On this page, when you click on the Create new Client Id, choose Web application and it shoudl give you the client secret key as well.
https://console.developers.google.com/project
Add a project etc.
Hope it helps

Cannot get service account authorization to work on GCS script using Python client lib APIs

In attempting to write a python script to access GCS using service-based authorization, I have come up with the following. Note that 'key' is the contents of my p12 file.
I am attempting to just read the list of buckets on my account. I have successfully created one bucket using the web interface to GCS, and can see that with gsutil.
When I execute the code below I get a 403 error. At first I thought I was not authorized correctly, but I tried from this very useful web page (which uses web-based authorization), and it works correctly. https://developers.google.com/apis-explorer/#p/storage/v1beta1/storage.buckets.list?projectId=&_h=2&
When I look at the headers and query string and compare them to the keaders and query of the website-generated request I see that there is no authorization header, and that there is no key= tag in the query string. I suppose I thought that the credential authorization would have taken care of this for me.
What am I doing wrong?
code:
credentials = SignedJwtAssertionCredentials(
'xxx-my-long-email-from-the-console#developer.gserviceaccount.com',
key,
scope='https://www.googleapis.com/auth/devstorage.full_control')
http = httplib2.Http()
http = credentials.authorize(http)
service = build("storage", "v1beta1", http=http)
# Build the request
request = service.buckets().list(projectId="159910083329")
# Diagnostic
pprint.pprint(request.headers)
pprint.pprint(request.to_json())
# Do it!
response = request.execute()
When I try to execute I get the 403.
I got this working, however, the code I used is not fundamentally different from the snippet you posted. Just in case you'd like to diff my version with yours, attached below is a complete copy of a Python program that worked for me. I initially got a 403, just like you, which was due to inheriting your project id :). After updating that value to use my project ID, I got a correct bucket listing. Two things to check:
Make sure the project id you are using is correct and has the "Google Cloud Storage JSON API" enabled on the Google Developer Console "Services" tab (it's a different service from the other Google Cloud Storage API).
Make sure you are loading the service accounts private key exactly as it came from the developer's console. I would recommend reading it into memory from the file you downloaded, as I've done here, rather than trying to copy it into a string literal in your code.
#!/usr/bin/env python
import pprint
import oauth2client
from oauth2client.client import SignedJwtAssertionCredentials
import httplib2
from apiclient.discovery import build
f = open('key.p12', 'r')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(
'REDACTED',
key,
scope='https://www.googleapis.com/auth/devstorage.full_control')
http = httplib2.Http()
http = credentials.authorize(http)
service = build("storage", "v1beta1", http=http)
# Build the request
request = service.buckets().list(projectId="REDACTED")
# Diagnostic
pprint.pprint(request.headers)
pprint.pprint(request.to_json())
# Do it!
response = request.execute()
pprint.pprint(response)