diff --git a/CHANGELOG.md b/CHANGELOG.md index b92ba7eae..3acda434d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.8.3 +* Adds support for authorization via Application Default Credentials. +# Adds support for tracking coverage on coveralls.io + # 0.8.2 * Fixes for file storage and missing cacerts file diff --git a/README.md b/README.md index afb6bc531..510ae817e 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,19 @@ Credentials can be managed at the connection level, as shown, or supplied on a p For server-to-server interactions, like those between a web application and Google Cloud Storage, Prediction, or BigQuery APIs, use service accounts. +As of version 0.8.3, service accounts can be configured using +[Application Default Credentials][1], which rely on the credentials being +available in a well-known location. If the credentials are not present +and it's being used on a Compute Engine VM, it will use the VM's default credentials. + +```ruby +client.authorization = :google_app_default # in a later version, this will become the default +client.authorization.fetch_access_token! +client.execute(...) +``` + +This is simpler API to use than in previous versions, although that is still available: + ```ruby key = Google::APIClient::KeyUtils.load_from_pkcs12('client.p12', 'notasecret') client.authorization = Signet::OAuth2::Client.new( @@ -201,3 +214,5 @@ See the full list of [samples on Github](https://github.com/google/google-api-ru ## Support Please [report bugs at the project on Github](https://github.com/google/google-api-ruby-client/issues). Don't hesitate to [ask questions](http://stackoverflow.com/questions/tagged/google-api-ruby-client) about the client or APIs on [StackOverflow](http://stackoverflow.com). + +[1]: https://developers.google.com/accounts/docs/application-default-credentials diff --git a/Rakefile b/Rakefile index 01e62ddd6..dca3b0903 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,9 @@ +# -*- ruby -*- lib_dir = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib_dir) $LOAD_PATH.uniq! +require 'bundler/gem_tasks' require 'rubygems' require 'rake' diff --git a/google-api-client.gemspec b/google-api-client.gemspec index 3a81293d4..6764697f4 100644 --- a/google-api-client.gemspec +++ b/google-api-client.gemspec @@ -26,7 +26,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'addressable', '~> 2.3' s.add_runtime_dependency 'signet', '~> 0.6' s.add_runtime_dependency 'faraday', '~> 0.9' - s.add_runtime_dependency 'googleauth', '~> 0.1' + s.add_runtime_dependency 'googleauth', '~> 0.3' s.add_runtime_dependency 'multi_json', '~> 1.10' s.add_runtime_dependency 'autoparse', "~> 0.3" s.add_runtime_dependency 'extlib', '~> 0.9' @@ -38,5 +38,6 @@ Gem::Specification.new do |s| s.add_development_dependency 'yard', '~> 0.8' s.add_development_dependency 'rspec', '~> 3.1' s.add_development_dependency 'kramdown', '~> 1.5' - s.add_development_dependency 'simplecov', '~> 0.9' + s.add_development_dependency 'simplecov', '~> 0.9.2' + s.add_development_dependency 'coveralls', '~> 0.7.11' end diff --git a/lib/google/api_client.rb b/lib/google/api_client.rb index 1b602b603..367b1e040 100644 --- a/lib/google/api_client.rb +++ b/lib/google/api_client.rb @@ -41,7 +41,7 @@ module Google # This class manages APIs communication. class APIClient include Google::APIClient::Logging - + ## # Creates a new Google API client. # @@ -58,7 +58,7 @@ module Google # # @option options [Boolean] :auto_refresh_token (true) # The setting that controls whether or not the api client attempts to - # refresh authorization when a 401 is hit in #execute. If the token does + # refresh authorization when a 401 is hit in #execute. If the token does # not support it, this option is ignored. # @option options [String] :application_name # The name of the application using the client. @@ -86,7 +86,7 @@ module Google # Pass through of options to set on the Faraday connection def initialize(options={}) logger.debug { "#{self.class} - Initializing client with options #{options}" } - + # Normalize key to String to allow indifferent access. options = options.inject({}) do |accu, (key, value)| accu[key.to_sym] = value @@ -182,7 +182,7 @@ module Google ) when :google_app_default require 'googleauth' - new_authorization = Google::Auth.get_application_default(nil) + new_authorization = Google::Auth.get_application_default when :oauth_2 require 'signet/oauth_2/client' @@ -214,7 +214,7 @@ module Google ## # The setting that controls whether or not the api client attempts to - # refresh authorization when a 401 is hit in #execute. + # refresh authorization when a 401 is hit in #execute. # # @return [Boolean] attr_accessor :auto_refresh_token @@ -261,7 +261,7 @@ module Google ## # Number of times to retry on recoverable errors - # + # # @return [FixNum] # Number of retries attr_accessor :retries @@ -471,7 +471,7 @@ module Google # Verifies an ID token against a server certificate. Used to ensure that # an ID token supplied by an untrusted client-side mechanism is valid. # Raises an error if the token is invalid or missing. - # + # # @deprecated Use the google-id-token gem for verifying JWTs def verify_id_token! require 'jwt' @@ -580,7 +580,7 @@ module Google # - (TrueClass, FalseClass) :authenticated (default: true) - # `true` if the request must be signed or somehow # authenticated, `false` otherwise. - # - (TrueClass, FalseClass) :gzip (default: true) - + # - (TrueClass, FalseClass) :gzip (default: true) - # `true` if gzip enabled, `false` otherwise. # - (FixNum) :retries - # # of times to retry on recoverable errors @@ -620,7 +620,7 @@ module Google options.update(params.shift) if params.size > 0 request = self.generate_request(options) end - + request.headers['User-Agent'] ||= '' + self.user_agent unless self.user_agent.nil? request.headers['Accept-Encoding'] ||= 'gzip' unless options[:gzip] == false request.headers['Content-Type'] ||= '' @@ -629,11 +629,11 @@ module Google connection = options[:connection] || self.connection request.authorization = options[:authorization] || self.authorization unless options[:authenticated] == false - + tries = 1 + (options[:retries] || self.retries) attempt = 0 - Retriable.retriable :tries => tries, + Retriable.retriable :tries => tries, :on => [TransmissionError], :on_retry => client_error_handler, :interval => lambda {|attempts| (2 ** attempts) + rand} do @@ -642,7 +642,7 @@ module Google # This 2nd level retriable only catches auth errors, and supports 1 retry, which allows # auth to be re-attempted without having to retry all sorts of other failures like # NotFound, etc - Retriable.retriable :tries => ((expired_auth_retry || tries > 1) && attempt == 1) ? 2 : 1, + Retriable.retriable :tries => ((expired_auth_retry || tries > 1) && attempt == 1) ? 2 : 1, :on => [AuthorizationError], :on_retry => authorization_error_handler(request.authorization) do result = request.send(connection, true) @@ -709,7 +709,7 @@ module Google end return Addressable::Template.new(@base_uri + template).expand(mapping) end - + ## # Returns on proc for special processing of retries for authorization errors @@ -719,7 +719,7 @@ module Google # OAuth 2 credentials # @return [Proc] def authorization_error_handler(authorization) - can_refresh = authorization.respond_to?(:refresh_token) && auto_refresh_token + can_refresh = authorization.respond_to?(:refresh_token) && auto_refresh_token Proc.new do |exception, tries| next unless exception.kind_of?(AuthorizationError) if can_refresh diff --git a/lib/google/api_client/version.rb b/lib/google/api_client/version.rb index 228fa1444..070528b18 100644 --- a/lib/google/api_client/version.rb +++ b/lib/google/api_client/version.rb @@ -18,7 +18,7 @@ module Google module VERSION MAJOR = 0 MINOR = 8 - TINY = 2 + TINY = 3 PATCH = nil STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.') end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 902276c14..1c64a4e8c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,7 +6,9 @@ require 'faraday' begin require 'simplecov' + require 'coveralls' + SimpleCov.formatter = Coveralls::SimpleCov::Formatter SimpleCov.start rescue LoadError # SimpleCov missing, so just run specs with no coverage.