From c971c1ad2d7730c0f5b389d533a972be32fbaf49 Mon Sep 17 00:00:00 2001 From: Daniel Azuma Date: Wed, 3 Feb 2021 12:13:08 -0800 Subject: [PATCH] fix: Fix crash when using a client credential without any paths or env_vars set (#296) --- lib/googleauth/credentials.rb | 50 ++++++++++++++++++++--------- spec/googleauth/credentials_spec.rb | 5 +++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/lib/googleauth/credentials.rb b/lib/googleauth/credentials.rb index f6a315fd..bc358845 100644 --- a/lib/googleauth/credentials.rb +++ b/lib/googleauth/credentials.rb @@ -103,7 +103,6 @@ def self.token_credential_uri # Set the default token credential URI to be used when none is provided during initialization. # # @param [String] new_token_credential_uri - # @return [String] # def self.token_credential_uri= new_token_credential_uri @token_credential_uri = new_token_credential_uri @@ -125,7 +124,6 @@ def self.audience # Sets the default target audience ID to be used when none is provided during initialization. # # @param [String] new_audience - # @return [String] # def self.audience= new_audience @audience = new_audience @@ -140,7 +138,7 @@ def self.audience= new_audience # If {#scope} is set, this credential will produce access tokens. # If {#target_audience} is set, this credential will produce ID tokens. # - # @return [String, Array] + # @return [String, Array, nil] # def self.scope lookup_auth_param :scope do @@ -156,8 +154,7 @@ def self.scope # If {#scope} is set, this credential will produce access tokens. # If {#target_audience} is set, this credential will produce ID tokens. # - # @param [String, Array] new_scope - # @return [String, Array] + # @param [String, Array, nil] new_scope # def self.scope= new_scope new_scope = Array new_scope unless new_scope.nil? @@ -172,7 +169,7 @@ def self.scope= new_scope # If {#scope} is set, this credential will produce access tokens. # If {#target_audience} is set, this credential will produce ID tokens. # - # @return [String] + # @return [String, nil] # def self.target_audience lookup_auth_param :target_audience @@ -186,7 +183,7 @@ def self.target_audience # If {#scope} is set, this credential will produce access tokens. # If {#target_audience} is set, this credential will produce ID tokens. # - # @param [String] new_target_audience + # @param [String, nil] new_target_audience # def self.target_audience= new_target_audience @target_audience = new_target_audience @@ -195,11 +192,20 @@ def self.target_audience= new_target_audience ## # The environment variables to search for credentials. Values can either be a file path to the # credentials file, or the JSON contents of the credentials file. + # The env_vars will never be nil. If there are no vars, the empty array is returned. # # @return [Array] # def self.env_vars - lookup_auth_param :env_vars do + env_vars_internal || [] + end + + ## + # @private + # Internal recursive lookup for env_vars. + # + def self.env_vars_internal + lookup_auth_param :env_vars, :env_vars_internal do # Pull values when PATH_ENV_VARS or JSON_ENV_VARS constants exists. path_env_vars = lookup_local_constant :PATH_ENV_VARS json_env_vars = lookup_local_constant :JSON_ENV_VARS @@ -209,9 +215,10 @@ def self.env_vars ## # Sets the environment variables to search for credentials. + # Setting to `nil` "unsets" the value, and defaults to the superclass + # (or to the empty array if there is no superclass). # - # @param [Array] new_env_vars - # @return [Array] + # @param [String, Array, nil] new_env_vars # def self.env_vars= new_env_vars new_env_vars = Array new_env_vars unless new_env_vars.nil? @@ -220,11 +227,20 @@ def self.env_vars= new_env_vars ## # The file paths to search for credentials files. + # The paths will never be nil. If there are no paths, the empty array is returned. # # @return [Array] # def self.paths - lookup_auth_param :paths do + paths_internal || [] + end + + ## + # @private + # Internal recursive lookup for paths. + # + def self.paths_internal + lookup_auth_param :paths, :paths_internal do # Pull in values if the DEFAULT_PATHS constant exists. vals = lookup_local_constant :DEFAULT_PATHS vals ? Array(vals).flatten.uniq : nil @@ -233,9 +249,10 @@ def self.paths ## # Set the file paths to search for credentials files. + # Setting to `nil` "unsets" the value, and defaults to the superclass + # (or to the empty array if there is no superclass). # - # @param [Array] new_paths - # @return [Array] + # @param [String, Array, nil] new_paths # def self.paths= new_paths new_paths = Array new_paths unless new_paths.nil? @@ -252,14 +269,15 @@ def self.paths= new_paths # Otherwise, calls the superclass method if present. # Returns nil if all steps fail. # - # @param [Symbol] The parameter name + # @param name [Symbol] The parameter name + # @param method_name [Symbol] The lookup method name, if different # @return [Object] The value # - def self.lookup_auth_param name + def self.lookup_auth_param name, method_name = name val = instance_variable_get "@#{name}".to_sym val = yield if val.nil? && block_given? return val unless val.nil? - return superclass.send name if superclass.respond_to? name + return superclass.send method_name if superclass.respond_to? method_name nil end diff --git a/spec/googleauth/credentials_spec.rb b/spec/googleauth/credentials_spec.rb index 0994439e..17c62aab 100644 --- a/spec/googleauth/credentials_spec.rb +++ b/spec/googleauth/credentials_spec.rb @@ -82,6 +82,11 @@ def mock_signet Google::Auth::Credentials.new default_keyfile_hash, scope: "http://example.com/scope" end + it "uses empty paths and env_vars by default" do + expect(Google::Auth::Credentials.paths).to eq([]) + expect(Google::Auth::Credentials.env_vars).to eq([]) + end + describe "using CONSTANTS" do it "can be subclassed to pass in other env paths" do test_path_env_val = "/unknown/path/to/file.txt".freeze