From 2317d33c2f38ee33de1ba3940cab1440d58bf9da Mon Sep 17 00:00:00 2001 From: Ferran Rodenas Date: Sun, 25 Jan 2015 19:33:48 -0800 Subject: [PATCH] [google] Add support for JSON key format --- lib/fog/google/compute.rb | 3 +- lib/fog/google/core.rb | 54 ++++++++++++++++++++++++++++-------- lib/fog/google/dns.rb | 3 +- lib/fog/google/monitoring.rb | 2 +- lib/fog/google/sql.rb | 2 +- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/fog/google/compute.rb b/lib/fog/google/compute.rb index 624bf616c..7663ac728 100644 --- a/lib/fog/google/compute.rb +++ b/lib/fog/google/compute.rb @@ -4,7 +4,8 @@ module Fog module Compute class Google < Fog::Service requires :google_project - recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string, :google_client + recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string, + :google_client, :google_json_key_location, :google_json_key_string GOOGLE_COMPUTE_API_VERSION = 'v1' GOOGLE_COMPUTE_BASE_URL = 'https://www.googleapis.com/compute/' diff --git a/lib/fog/google/core.rb b/lib/fog/google/core.rb index 7a22d5f13..2e89cc6cd 100644 --- a/lib/fog/google/core.rb +++ b/lib/fog/google/core.rb @@ -45,6 +45,8 @@ module Fog # @option options [String] :google_client_email A @developer.gserviceaccount.com email address to use # @option options [String] :google_key_location The location of a pkcs12 key file # @option options [String] :google_key_string The content of the pkcs12 key file + # @option options [String] :google_json_key_location The location of a JSON key file + # @option options [String] :google_json_key_string The content of the JSON key file # @option options [String] :google_api_scope_url The access scope URLs # @option options [String] :app_name The app name to set in the user agent # @option options [String] :app_version The app version to set in the user agent @@ -64,19 +66,14 @@ module Fog client = options[:google_client] return client unless client.nil? + # Create a signing key + signing_key = create_signing_key(options) + # Validate required arguments unless options[:google_client_email] raise ArgumentError.new('Missing required arguments: google_client_email') end - if options[:google_key_location] - google_key = File.expand_path(options[:google_key_location]) - elsif options[:google_key_string] - google_key = options[:google_key_string] - else - raise ArgumentError.new('Missing required arguments: google_key_location or google_key_string') - end - unless options[:google_api_scope_url] raise ArgumentError.new('Missing required arguments: google_api_scope_url') end @@ -84,23 +81,56 @@ module Fog # Create a new Google API Client self.new_pk12_google_client( options[:google_client_email], - google_key, + signing_key, options[:google_api_scope_url], options[:app_name], options[:app_version] ) end + ## + # Creates a Google signing key + # + def create_signing_key(options) + if options[:google_json_key_location] || options[:google_json_key_string] + if options[:google_json_key_location] + json_key_location = File.expand_path(options[:google_json_key_location]) + json_key = File.open(json_key_location, 'r') { |file| file.read } + else + json_key = options[:google_json_key_string] + end + + json_key_hash = Fog::JSON.decode(json_key) + unless json_key_hash.has_key?('client_email') || json_key_hash.has_key?('private_key') + raise ArgumentError.new('Invalid Google JSON key') + end + + options[:google_client_email] = json_key_hash['client_email'] + ::Google::APIClient::KeyUtils.load_from_pem(json_key_hash['private_key'], 'notasecret') + elsif options[:google_key_location] || options[:google_key_string] + if options[:google_key_location] + google_key = File.expand_path(options[:google_key_location]) + else + google_key = options[:google_key_string] + end + + ::Google::APIClient::KeyUtils.load_from_pkcs12(google_key, 'notasecret') + else + raise ArgumentError.new('Missing required arguments: google_key_location, google_key_string, ' \ + 'google_json_key_location or google_json_key_string') + end + end + ## # Create a Google API Client with a user email and a pkcs12 key # # @param [String] google_client_email A @developer.gserviceaccount.com email address to use - # @param [String] google_key An absolute location to a pkcs12 key file or the content of the file itself + # @param [OpenSSL::PKey] signing_key The private key for signing # @param [String] google_api_scope_url Access scope URLs # @param [String] app_name The app name to set in the user agent # @param [String] app_version The app version to set in the user agent # @return [Google::APIClient] Google API Client - def new_pk12_google_client(google_client_email, google_key, google_api_scope_url, app_name = nil, app_version = nil) + def new_pk12_google_client(google_client_email, signing_key, google_api_scope_url, app_name = nil, app_version = nil) application_name = app_name.nil? ? 'fog' : "#{app_name}/#{app_version || '0.0.0'} fog" api_client_options = { :application_name => application_name, @@ -115,7 +145,7 @@ module Fog :client_x509_cert_url => "https://www.googleapis.com/robot/v1/metadata/x509/#{google_client_email}", :issuer => google_client_email, :scope => google_api_scope_url, - :signing_key => ::Google::APIClient::KeyUtils.load_from_pkcs12(google_key, 'notasecret'), + :signing_key => signing_key, :token_credential_uri => 'https://accounts.google.com/o/oauth2/token', } ) diff --git a/lib/fog/google/dns.rb b/lib/fog/google/dns.rb index c4ae348cb..5a6c3920a 100644 --- a/lib/fog/google/dns.rb +++ b/lib/fog/google/dns.rb @@ -4,7 +4,8 @@ module Fog module DNS class Google < Fog::Service requires :google_project - recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string, :google_client + recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string, + :google_client, :google_json_key_location, :google_json_key_string GOOGLE_DNS_API_VERSION = 'v1beta1' GOOGLE_DNS_BASE_URL = 'https://www.googleapis.com/dns/' diff --git a/lib/fog/google/monitoring.rb b/lib/fog/google/monitoring.rb index de68bfba6..a6578ac53 100644 --- a/lib/fog/google/monitoring.rb +++ b/lib/fog/google/monitoring.rb @@ -5,7 +5,7 @@ module Fog class Monitoring < Fog::Service requires :google_project recognizes :google_client_email, :google_key_location, :google_key_string, :google_client, - :app_name, :app_version + :app_name, :app_version, :google_json_key_location, :google_json_key_string GOOGLE_MONITORING_API_VERSION = 'v2beta1' GOOGLE_MONITORING_BASE_URL = 'https://www.googleapis.com/cloudmonitoring/' diff --git a/lib/fog/google/sql.rb b/lib/fog/google/sql.rb index 9d36d0009..0c5c84135 100644 --- a/lib/fog/google/sql.rb +++ b/lib/fog/google/sql.rb @@ -5,7 +5,7 @@ module Fog class SQL < Fog::Service requires :google_project recognizes :google_client_email, :google_key_location, :google_key_string, :google_client, - :app_name, :app_version + :app_name, :app_version, :google_json_key_location, :google_json_key_string GOOGLE_SQL_API_VERSION = 'v1beta3' GOOGLE_SQL_BASE_URL = 'https://www.googleapis.com/sql/'