1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# Copyright 2014 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This file is now considered DEPRECATED.
# Libraries that depend on google-cloud-core ~> 1.1 should not use this file.
# Keep the implementation in place to remain compatible with so older gems.
require "json"
require "signet/oauth_2/client"
require "forwardable"
require "googleauth"
module Google
module Cloud
##
# @private
# Represents the OAuth 2.0 signing logic.
# This class is intended to be inherited by API-specific classes
# which overrides the SCOPE constant.
class Credentials
TOKEN_CREDENTIAL_URI = "https://accounts.google.com/o/oauth2/token"
AUDIENCE = "https://accounts.google.com/o/oauth2/token"
SCOPE = []
PATH_ENV_VARS = %w[GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE]
JSON_ENV_VARS = %w[GOOGLE_CLOUD_KEYFILE_JSON GCLOUD_KEYFILE_JSON]
DEFAULT_PATHS = ["~/.config/gcloud/application_default_credentials.json"]
attr_accessor :client
##
# Delegate client methods to the client object.
extend Forwardable
def_delegators :@client,
:token_credential_uri, :audience,
:scope, :issuer, :signing_key
def initialize keyfile, scope: nil
verify_keyfile_provided! keyfile
if keyfile.is_a? Signet::OAuth2::Client
@client = keyfile
elsif keyfile.is_a? Hash
hash = stringify_hash_keys keyfile
hash["scope"] ||= scope
@client = init_client hash
else
verify_keyfile_exists! keyfile
json = JSON.parse ::File.read(keyfile)
json["scope"] ||= scope
@client = init_client json
end
@client.fetch_access_token!
end
##
# Returns the default credentials.
#
def self.default scope: nil
env = ->(v) { ENV[v] }
json = ->(v) { JSON.parse ENV[v] rescue nil unless ENV[v].nil? }
path = ->(p) { ::File.file? p }
# First try to find keyfile file from environment variables.
self::PATH_ENV_VARS.map(&env).compact.select(&path).each do |file|
return new file, scope: scope
end
# Second try to find keyfile json from environment variables.
self::JSON_ENV_VARS.map(&json).compact.each do |hash|
return new hash, scope: scope
end
# Third try to find keyfile file from known file paths.
self::DEFAULT_PATHS.select(&path).each do |file|
return new file, scope: scope
end
# Finally get instantiated client from Google::Auth.
scope ||= self::SCOPE
client = Google::Auth.get_application_default scope
new client
end
protected
##
# Verify that the keyfile argument is provided.
def verify_keyfile_provided! keyfile
raise "You must provide a keyfile to connect with." if keyfile.nil?
end
##
# Verify that the keyfile argument is a file.
def verify_keyfile_exists! keyfile
exists = ::File.file? keyfile
raise "The keyfile '#{keyfile}' is not a valid file." unless exists
end
##
# Initializes the Signet client.
def init_client keyfile
client_opts = client_options keyfile
Signet::OAuth2::Client.new client_opts
end
##
# returns a new Hash with string keys instead of symbol keys.
def stringify_hash_keys hash
Hash[hash.map { |k, v| [k.to_s, v] }]
end
def client_options options
# Keyfile options have higher priority over constructor defaults
options["token_credential_uri"] ||= self.class::TOKEN_CREDENTIAL_URI
options["audience"] ||= self.class::AUDIENCE
options["scope"] ||= self.class::SCOPE
# client options for initializing signet client
{ token_credential_uri: options["token_credential_uri"],
audience: options["audience"],
scope: Array(options["scope"]),
issuer: options["client_email"],
signing_key: OpenSSL::PKey::RSA.new(options["private_key"]) }
end
end
end
end
|