Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 60 additions & 21 deletions lib/gcloud/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
require "json"
require "signet/oauth_2/client"
require "forwardable"
require "googleauth"

module Gcloud
##
Expand All @@ -25,6 +26,7 @@ class Credentials #:nodoc:
TOKEN_CREDENTIAL_URI = "https://accounts.google.com/o/oauth2/token"
AUDIENCE = "https://accounts.google.com/o/oauth2/token"
SCOPE = []
ENV_VARS = ["GOOGLE_CLOUD_KEYFILE"]

attr_accessor :client

Expand All @@ -36,23 +38,59 @@ class Credentials #:nodoc:
:scope, :issuer, :signing_key

def initialize keyfile, options = {}
if keyfile.nil?
fail "You must provide a keyfile to connect with."
elsif !::File.exist?(keyfile)
fail "The keyfile '#{keyfile}' is not a valid file."
if keyfile.is_a? Signet::OAuth2::Client
@client = keyfile
else
@client = init_client keyfile, options
end
@client.fetch_access_token!
end

# Turn keys to strings
options = stringify_hash_keys options
# Constructor options override default options
options = default_options.merge options
# Keyfile options override everything
options = options.merge JSON.parse(::File.read(keyfile))
init_signet_client! options
##
# Returns the default credentials.
#
def self.default
self::ENV_VARS.each do |env_var|
keyfile = ENV[env_var].to_s
return new keyfile if ::File.file? keyfile
end
return new sdk_default_creds if ::File.file? sdk_default_creds
client = Google::Auth.get_application_default self::SCOPE
new client
end

##
# The filepath of the default application credentials used by
# the gcloud SDK.
#
# This file is created when running <tt>gcloud auth login</tt>
def self.sdk_default_creds #:nodoc:
# This method will likely be moved once we gain better
# support for running in a GCE environment.
sdk_creds = "~/.config/gcloud/application_default_credentials.json"
File.expand_path sdk_creds
end

protected

##
# Initializes the Signet client.
def init_client keyfile, options
verify_keyfile! keyfile
client_opts = client_options keyfile, options
Signet::OAuth2::Client.new client_opts
end

##
# Initializes the Signet client.
def verify_keyfile! keyfile
if keyfile.nil?
fail "You must provide a keyfile to connect with."
elsif !::File.file?(keyfile)
fail "The keyfile '#{keyfile}' is not a valid file."
end
end

##
# returns a new Hash with string keys instead of symbol keys.
def stringify_hash_keys hash
Expand All @@ -67,19 +105,20 @@ def default_options
"scope" => self.class::SCOPE }
end

##
# Initializes the Signet client.
def init_signet_client! options
client_opts = {
token_credential_uri: options["token_credential_uri"],
def client_options keyfile, options
# Turn keys to strings
options = stringify_hash_keys options
# Constructor options override default options
options = default_options.merge options
# Keyfile options override everything
options = options.merge JSON.parse(::File.read(keyfile))

# client options for initializing signet client
{ token_credential_uri: options["token_credential_uri"],
audience: options["audience"],
scope: options["scope"],
issuer: options["client_email"],
signing_key: OpenSSL::PKey::RSA.new(options["private_key"])
}

@client = Signet::OAuth2::Client.new client_opts
@client.fetch_access_token!
signing_key: OpenSSL::PKey::RSA.new(options["private_key"]) }
end
end
end
8 changes: 6 additions & 2 deletions lib/gcloud/datastore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ module Gcloud
#
# See Gcloud::Datastore::Dataset
def self.datastore project = ENV["DATASTORE_PROJECT"],
keyfile = ENV["DATASTORE_KEYFILE"]
credentials = Gcloud::Datastore::Credentials.new keyfile
keyfile = nil
if keyfile.nil?
credentials = Gcloud::Datastore::Credentials.default
else
credentials = Gcloud::Datastore::Credentials.new keyfile
end
Gcloud::Datastore::Dataset.new project, credentials
end

Expand Down
1 change: 1 addition & 0 deletions lib/gcloud/datastore/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Datastore
class Credentials < Gcloud::Credentials #:nodoc:
SCOPE = ["https://www.googleapis.com/auth/datastore",
"https://www.googleapis.com/auth/userinfo.email"]
ENV_VARS = ["DATASTORE_KEYFILE"]

##
# Sign Oauth2 API calls.
Expand Down
8 changes: 6 additions & 2 deletions lib/gcloud/storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ module Gcloud
#
# See Gcloud::Storage::Project
def self.storage project = ENV["STORAGE_PROJECT"],
keyfile = ENV["STORAGE_KEYFILE"]
credentials = Gcloud::Storage::Credentials.new keyfile
keyfile = nil
if keyfile.nil?
credentials = Gcloud::Storage::Credentials.default
else
credentials = Gcloud::Storage::Credentials.new keyfile
end
Gcloud::Storage::Project.new project, credentials
end

Expand Down
2 changes: 1 addition & 1 deletion lib/gcloud/storage/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def create_file file, path = nil, options = {}
ensure_connection!
# TODO: Raise if file doesn't exist
# ensure_file_exists!
fail unless ::File.exist? file
fail unless ::File.file? file

options[:acl] = File::Acl.predefined_rule_for options[:acl]

Expand Down
1 change: 1 addition & 0 deletions lib/gcloud/storage/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module Storage
# Represents the Oauth2 signing logic for Storage.
class Credentials < Gcloud::Credentials #:nodoc:
SCOPE = ["https://www.googleapis.com/auth/devstorage.full_control"]
ENV_VARS = ["STORAGE_KEYFILE"]
end
end
end
2 changes: 1 addition & 1 deletion test/gcloud/datastore/test_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
client_mock = Minitest::Mock.new
client_mock.expect :fetch_access_token!, true
Signet::OAuth2::Client.stub :new, client_mock do
File.stub :exist?, true do
File.stub :file?, true do
File.stub :read, keyfile_json do
credz = Gcloud::Datastore::Credentials.new "fake.json"
end
Expand Down