prussiap
prussiap

Reputation: 687

google/apis/drive_v2 authentication on new google Drive authentication. I also hope to avoid frustration with google-api-client

First my question is about getting google drive_v2 authentication working and creating new files etc with my rails 4.2 app. I have the rails app with devise/omniauth2 and google working just fine. I have activated in the google dev console both web auth and google API auth. Both client secrets are downloaded and working.

So having said that. I need my rails app in offline access to be able to use, create, and delete goole Docs and Spreadsheets. I've set the scope for .drive, setup offline access etc.

I've EVEN written code that works just fine if I go in the google playground and get a new access token to use.

My first problem is the ability to get my refresh_token and authenticate or get a new one using the google-api-client (version 0.9pre3 so people aren't confused)

In order to use the new google api I needed to comment out google drive since it seemed that all the APIs where combined into the client.

gem 'omniauth-google-oauth2'
#gem 'google_drive'
gem 'google-api-client', '0.9.pre3'

I'm stuck on the authentication/authorization step and I'm feeling rather dumb about it.

So sample code on the github repo for the api here, or the google dev site here lead me to believe this works.

require 'google/apis/drive_v2'

Drive = Google::Apis::DriveV2 # Alias the module
drive = Drive::DriveService.new
drive.authorization = authorization # See Googleauth or Signet libraries

or

drive.authorization = Google::Auth.get_application_default([Drive::AUTH_DRIVE])

of course what is authorization? According to the docs I go here.

Running the example code below: require 'googleauth'

Get the environment configured authorization

scopes =  ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute']
authorization = Google::Auth.get_application_default(scopes)

leads to:

authorization = Google::Auth.get_application_default(scopes)
RuntimeError: Could not load the default credentials. Browse to
https://developers.google.com/accounts/docs/application-default-credentials
for more information
from /Users/prussiap/.gem/ruby/2.2.0/gems/googleauth-0.4.2/lib/googleauth.rb:116:in `get_application_default'

Probably due to my confusion or stupidity.

The other method displayed in the google dev site docs linked above and the service accounts seem like the way to go aka here.

But nothing works. I've seen a smattering of these client_secrets too

client_secrets = Google::APIClient::ClientSecrets.load
authorization = client_secrets.to_authorization

of course that .load breaks on it's own as it expects a magical file path or file name but nothing I fed it worked

Any sample code that allows me to either use my client_secret for service account or oauth2 (web app) but without any fancy redirects would be fantastic and really help..

Now for others new to the google api please read below. I feel like I'm dumb for not seeing this or noticing it but maybe this info can help you guys when I raised the issue on the github repo I was confused..

Apparently the google API-client for ruby is totally different from < 0.9pre1 or greater then that. So is the documentation.

SO if you are reading this type of code and are reading these docs:

require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'

APPLICATION_NAME = 'Drive API Quickstart'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials',
                             "drive-quickstart.json")
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly

Then you're using < 0.9pre1 (I'm pretty sure)

Otherwise you see my code above with the drive_v2, then remove your google_drive gem because it's rolled into one api and read this doc.

I hope this helps others.

And any help on my authentication problem including using service vs api vs other type of account with some sample code for making authentication and then authenticating with a refresh token. Would be fantastic.

Upvotes: 5

Views: 1519

Answers (3)

Lev Lukomskyi
Lev Lukomskyi

Reputation: 6667

Here is code I used to save db backups to google drive, maybe it would help:

require 'google/apis/drive_v2'
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = "#{Rails.root}/config/google_api_credentials.json"
drive = Google::Apis::DriveV2::DriveService.new
drive.authorization = Google::Auth.get_application_default([Google::Apis::DriveV2::AUTH_DRIVE_FILE])

metadata = {title: File.basename(archive_path, '.sql.bz2')}
file = drive.insert_file(metadata, upload_source: archive_path, content_type: 'application/x-bzip2')

perm_id = drive.get_permission_id_for_email('[email protected]')
perm = Google::Apis::DriveV2::Permission.new(role: 'writer', id: perm_id.id, type: 'user')
drive.insert_permission(file.id, perm)

Upvotes: 1

Vijay Subramani
Vijay Subramani

Reputation: 21

I was running on Windows OS and ran into this issue. Turns out there is a bug in the ruby auth library for detecting the OS.

https://github.com/google/google-auth-library-ruby/issues/55

If you pull down the latest version of the the googleauth gem either directly or indirectly through google-api-client, you will get the fix.

Upvotes: 0

Matt Cahill
Matt Cahill

Reputation: 61

I just ran into the same problem -- I haven't resolved it totally, but I got past this particular error by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable, and pointing it to a service account key file -- this is not the same as the client_secrets that worked for earlier versions of the API.

Google's instructions in their documentation: Application Default Credentials: How They Work lays this out, but the important note is that "service account" is a different auth method than client_secrets.

First, go to the Developers Console API Credentials page for your project and pick an existing/create a new "Service account key". Assume we've put the downloaded .json file in /path/to/svc_acct_auth.json

In your ruby code, add the line:

ENV["GOOGLE_APPLICATION_CREDENTIALS"] = '/path/to/svc_acct_auth.json'

That should get the service to return properly and get you past that runtime error. Granted, I'm still having trouble executing the calls I need through this auth system, but hey! I've graduated to newer & better error messages.

Upvotes: 6

Related Questions