googleauth 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 105a3281fcd2fa4a6a90f122c62e3f852f9c116172edd83c9ac759a93ff8ba78
4
- data.tar.gz: 40078f9fc7910a259496f600d84a50d97722e62cf5c125a9c74f1994a2620553
3
+ metadata.gz: 3e646bac53d9ec3282d73ffc1110581dbd52a36d89a5ad3e78d2d7b6cb998f6c
4
+ data.tar.gz: ed9f5ff32c8a8093dbfba02266c2f50544572dda9ed5e77e081ff6eabdcd2ac4
5
5
  SHA512:
6
- metadata.gz: 8693833fa1fe3ae6a95e24e35131167ff0a8ecca9704038c93939d181360f9b75bb8d0987914daaf2cd804d7ae82b49e78df3a2d8084fc4dc8d0a620e2b7d21b
7
- data.tar.gz: 8d1658ef226f85c084b317454bd24dda581eb439d89946fcbc1b3fa2f9393a086bb5b668cd2ba18d8eb8feb3323682101907651ce51aae3273de14c350d5f8f1
6
+ metadata.gz: b4bf425795f1274eee8197d50bf2d8ec433881eee828081ee8e4ec6b078357b6a1c1a72b177dd81e0fa91170f0aad69dc5c937e134b813215caec095630259bd
7
+ data.tar.gz: 216d5d6ae1dbc594247686eec49447a3a7a3dac7ccea3d5245ee6571ae446c1186bfd7ac41223f8d0f325abe5b444162a66248c4b2c8bc5e5d5cf5b3a4e5ff67
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+
5
+ ---
6
+
7
+ Thanks for stopping by to let us know something could be better!
8
+
9
+ **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
10
+
11
+ Please run down the following list and make sure you've tried the usual "quick fixes":
12
+
13
+ - Search the issues already opened: https://github.com/googleapis/google-auth-library-ruby/issues
14
+ - Search Stack Overflow: https://stackoverflow.com/questions/tagged/google-auth-library-ruby
15
+
16
+ If you are still having issues, please be sure to include as much information as possible:
17
+
18
+ #### Environment details
19
+
20
+ - OS:
21
+ - Ruby version:
22
+ - Gem name and version:
23
+
24
+ #### Steps to reproduce
25
+
26
+ 1. ...
27
+
28
+ #### Code example
29
+
30
+ ```ruby
31
+ # example
32
+ ```
33
+
34
+ Making sure to follow these steps will guarantee the quickest resolution possible.
35
+
36
+ Thanks!
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this library
4
+
5
+ ---
6
+
7
+ Thanks for stopping by to let us know something could be better!
8
+
9
+ **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
10
+
11
+ **Is your feature request related to a problem? Please describe.**
12
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
13
+
14
+ **Describe the solution you'd like**
15
+ A clear and concise description of what you want to happen.
16
+
17
+ **Describe alternatives you've considered**
18
+ A clear and concise description of any alternative solutions or features you've considered.
19
+
20
+ **Additional context**
21
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: Support request
3
+ about: If you have a support contract with Google, please create an issue in the Google Cloud Support console.
4
+
5
+ ---
6
+
7
+ **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
@@ -20,7 +20,7 @@ ruby --version
20
20
  # https://github.com/bundler/bundler/issues/6154
21
21
  export BUNDLE_GEMFILE=
22
22
 
23
- RUBY_VERSIONS=("2.3.7" "2.4.4" "2.5.1")
23
+ RUBY_VERSIONS=("2.3.8" "2.4.5" "2.5.3")
24
24
 
25
25
  # Capture failures
26
26
  EXIT_STATUS=0 # everything passed
@@ -11,6 +11,8 @@ Metrics/CyclomaticComplexity:
11
11
  Max: 8
12
12
  Metrics/MethodLength:
13
13
  Max: 20
14
+ Metrics/ModuleLength:
15
+ Max: 150
14
16
  Metrics/ClassLength:
15
17
  Enabled: false
16
18
  Layout/IndentHeredoc:
@@ -1,3 +1,8 @@
1
+ ## 0.8.0 (2019/01/02)
2
+
3
+ * Support connection options :default_connection and :connection_builder when creating credentials that need to refresh OAuth tokens. This lets clients provide connection objects with custom settings, such as proxies, needed for the client environment.
4
+ * Removed an unnecessary warning about project IDs.
5
+
1
6
  ## 0.7.1 (2018/10/25)
2
7
 
3
8
  * Make load_gcloud_project_id module function.
@@ -52,11 +52,21 @@ ERROR_MESSAGE
52
52
  # scope is ignored.
53
53
  #
54
54
  # @param scope [string|array|nil] the scope(s) to access
55
- # @param options [hash] allows override of the connection being used
55
+ # @param options [Hash] Connection options. These may be used to configure
56
+ # the `Faraday::Connection` used for outgoing HTTP requests. For
57
+ # example, if a connection proxy must be used in the current network,
58
+ # you may provide a connection with with the needed proxy options.
59
+ # The following keys are recognized:
60
+ # * `:default_connection` The connection object to use for token
61
+ # refresh requests.
62
+ # * `:connection_builder` A `Proc` that creates and returns a
63
+ # connection to use for token refresh requests.
64
+ # * `:connection` The connection to use to determine whether GCE
65
+ # metadata credentials are available.
56
66
  def get_application_default(scope = nil, options = {})
57
- creds = DefaultCredentials.from_env(scope) ||
58
- DefaultCredentials.from_well_known_path(scope) ||
59
- DefaultCredentials.from_system_default_path(scope)
67
+ creds = DefaultCredentials.from_env(scope, options) ||
68
+ DefaultCredentials.from_well_known_path(scope, options) ||
69
+ DefaultCredentials.from_system_default_path(scope, options)
60
70
  return creds unless creds.nil?
61
71
  unless GCECredentials.on_gce?(options)
62
72
  # Clear cache of the result of GCECredentials.on_gce?
@@ -87,10 +87,9 @@ ERROR
87
87
  # fetched.
88
88
  def fetch_access_token(options = {})
89
89
  c = options[:connection] || Faraday.default_connection
90
- c.headers = { 'Metadata-Flavor' => 'Google' }
91
-
92
90
  retry_with_error do
93
- resp = c.get(COMPUTE_AUTH_TOKEN_URI)
91
+ headers = { 'Metadata-Flavor' => 'Google' }
92
+ resp = c.get(COMPUTE_AUTH_TOKEN_URI, nil, headers)
94
93
  case resp.status
95
94
  when 200
96
95
  Signet::OAuth2.parse_credentials(resp.body,
@@ -66,14 +66,14 @@ module Google
66
66
  elsif keyfile.is_a? Hash
67
67
  hash = stringify_hash_keys keyfile
68
68
  hash['scope'] ||= scope
69
- @client = init_client hash
69
+ @client = init_client hash, options
70
70
  @project_id ||= (hash['project_id'] || hash['project'])
71
71
  else
72
72
  verify_keyfile_exists! keyfile
73
73
  json = JSON.parse ::File.read(keyfile)
74
74
  json['scope'] ||= scope
75
75
  @project_id ||= (json['project_id'] || json['project'])
76
- @client = init_client json
76
+ @client = init_client json, options
77
77
  end
78
78
  CredentialsLoader.warn_if_cloud_sdk_credentials @client.client_id
79
79
  @project_id ||= CredentialsLoader.load_gcloud_project_id
@@ -85,33 +85,32 @@ module Google
85
85
  # previously stated locations do not contain keyfile information,
86
86
  # this method defaults to use the application default.
87
87
  def self.default(options = {})
88
- scope = options[:scope]
89
88
  # First try to find keyfile file from environment variables.
90
- client = from_path_vars scope
89
+ client = from_path_vars options
91
90
 
92
91
  # Second try to find keyfile json from environment variables.
93
- client ||= from_json_vars scope
92
+ client ||= from_json_vars options
94
93
 
95
94
  # Third try to find keyfile file from known file paths.
96
- client ||= from_default_paths scope
95
+ client ||= from_default_paths options
97
96
 
98
97
  # Finally get instantiated client from Google::Auth
99
- client ||= from_application_default scope
98
+ client ||= from_application_default options
100
99
  client
101
100
  end
102
101
 
103
- def self.from_path_vars(scope)
102
+ def self.from_path_vars(options)
104
103
  self::PATH_ENV_VARS
105
104
  .map { |v| ENV[v] }
106
105
  .compact
107
106
  .select { |p| ::File.file? p }
108
107
  .each do |file|
109
- return new file, scope: scope
108
+ return new file, options
110
109
  end
111
110
  nil
112
111
  end
113
112
 
114
- def self.from_json_vars(scope)
113
+ def self.from_json_vars(options)
115
114
  json = lambda do |v|
116
115
  unless ENV[v].nil?
117
116
  begin
@@ -122,24 +121,24 @@ module Google
122
121
  end
123
122
  end
124
123
  self::JSON_ENV_VARS.map(&json).compact.each do |hash|
125
- return new hash, scope: scope
124
+ return new hash, options
126
125
  end
127
126
  nil
128
127
  end
129
128
 
130
- def self.from_default_paths(scope)
129
+ def self.from_default_paths(options)
131
130
  self::DEFAULT_PATHS
132
131
  .select { |p| ::File.file? p }
133
132
  .each do |file|
134
- return new file, scope: scope
133
+ return new file, options
135
134
  end
136
135
  nil
137
136
  end
138
137
 
139
- def self.from_application_default(scope)
140
- scope ||= self::SCOPE
138
+ def self.from_application_default(options)
139
+ scope = options[:scope] || self::SCOPE
141
140
  client = Google::Auth.get_application_default scope
142
- new client
141
+ new client, options
143
142
  end
144
143
  private_class_method :from_path_vars,
145
144
  :from_json_vars,
@@ -161,9 +160,10 @@ module Google
161
160
  end
162
161
 
163
162
  # Initializes the Signet client.
164
- def init_client(keyfile)
163
+ def init_client(keyfile, connection_options = {})
165
164
  client_opts = client_options keyfile
166
- Signet::OAuth2::Client.new client_opts
165
+ Signet::OAuth2::Client.new(client_opts)
166
+ .configure_connection(connection_options)
167
167
  end
168
168
 
169
169
  # returns a new Hash with string keys instead of symbol keys.
@@ -76,22 +76,35 @@ module Google
76
76
  # By default, it calls #new on the current class, but this behaviour can
77
77
  # be modified, allowing different instances to be created.
78
78
  def make_creds(*args)
79
- new(*args)
79
+ creds = new(*args)
80
+ if creds.respond_to?(:configure_connection) && args.size == 1
81
+ creds = creds.configure_connection(args[0])
82
+ end
83
+ creds
80
84
  end
81
85
 
82
86
  # Creates an instance from the path specified in an environment
83
87
  # variable.
84
88
  #
85
89
  # @param scope [string|array|nil] the scope(s) to access
86
- def from_env(scope = nil)
90
+ # @param options [Hash] Connection options. These may be used to configure
91
+ # how OAuth tokens are retrieved, by providing a suitable
92
+ # `Faraday::Connection`. For example, if a connection proxy must be
93
+ # used in the current network, you may provide a connection with
94
+ # with the needed proxy options.
95
+ # The following keys are recognized:
96
+ # * `:default_connection` The connection object to use.
97
+ # * `:connection_builder` A `Proc` that returns a connection.
98
+ def from_env(scope = nil, options = {})
99
+ options = interpret_options scope, options
87
100
  if ENV.key?(ENV_VAR)
88
101
  path = ENV[ENV_VAR]
89
102
  raise "file #{path} does not exist" unless File.exist?(path)
90
103
  File.open(path) do |f|
91
- return make_creds(json_key_io: f, scope: scope)
104
+ return make_creds(options.merge(json_key_io: f))
92
105
  end
93
106
  elsif service_account_env_vars? || authorized_user_env_vars?
94
- return make_creds(scope: scope)
107
+ return make_creds(options)
95
108
  end
96
109
  rescue StandardError => e
97
110
  raise "#{NOT_FOUND_ERROR}: #{e}"
@@ -100,7 +113,16 @@ module Google
100
113
  # Creates an instance from a well known path.
101
114
  #
102
115
  # @param scope [string|array|nil] the scope(s) to access
103
- def from_well_known_path(scope = nil)
116
+ # @param options [Hash] Connection options. These may be used to configure
117
+ # how OAuth tokens are retrieved, by providing a suitable
118
+ # `Faraday::Connection`. For example, if a connection proxy must be
119
+ # used in the current network, you may provide a connection with
120
+ # with the needed proxy options.
121
+ # The following keys are recognized:
122
+ # * `:default_connection` The connection object to use.
123
+ # * `:connection_builder` A `Proc` that returns a connection.
124
+ def from_well_known_path(scope = nil, options = {})
125
+ options = interpret_options scope, options
104
126
  home_var = OS.windows? ? 'APPDATA' : 'HOME'
105
127
  base = WELL_KNOWN_PATH
106
128
  root = ENV[home_var].nil? ? '' : ENV[home_var]
@@ -108,7 +130,7 @@ module Google
108
130
  path = File.join(root, base)
109
131
  return nil unless File.exist?(path)
110
132
  File.open(path) do |f|
111
- return make_creds(json_key_io: f, scope: scope)
133
+ return make_creds(options.merge(json_key_io: f))
112
134
  end
113
135
  rescue StandardError => e
114
136
  raise "#{WELL_KNOWN_ERROR}: #{e}"
@@ -117,7 +139,16 @@ module Google
117
139
  # Creates an instance from the system default path
118
140
  #
119
141
  # @param scope [string|array|nil] the scope(s) to access
120
- def from_system_default_path(scope = nil)
142
+ # @param options [Hash] Connection options. These may be used to configure
143
+ # how OAuth tokens are retrieved, by providing a suitable
144
+ # `Faraday::Connection`. For example, if a connection proxy must be
145
+ # used in the current network, you may provide a connection with
146
+ # with the needed proxy options.
147
+ # The following keys are recognized:
148
+ # * `:default_connection` The connection object to use.
149
+ # * `:connection_builder` A `Proc` that returns a connection.
150
+ def from_system_default_path(scope = nil, options = {})
151
+ options = interpret_options scope, options
121
152
  if OS.windows?
122
153
  return nil unless ENV['ProgramData']
123
154
  prefix = File.join(ENV['ProgramData'], 'Google/Auth')
@@ -127,7 +158,7 @@ module Google
127
158
  path = File.join(prefix, CREDENTIALS_FILE_NAME)
128
159
  return nil unless File.exist?(path)
129
160
  File.open(path) do |f|
130
- return make_creds(json_key_io: f, scope: scope)
161
+ return make_creds(options.merge(json_key_io: f))
131
162
  end
132
163
  rescue StandardError => e
133
164
  raise "#{SYSTEM_DEFAULT_ERROR}: #{e}"
@@ -139,18 +170,31 @@ module Google
139
170
  end
140
171
  module_function :warn_if_cloud_sdk_credentials
141
172
 
173
+ # Finds project_id from gcloud CLI configuration
142
174
  def load_gcloud_project_id
143
175
  gcloud = GCLOUD_WINDOWS_COMMAND if OS.windows?
144
176
  gcloud = GCLOUD_POSIX_COMMAND unless OS.windows?
145
177
  config = MultiJson.load(`#{gcloud} #{GCLOUD_CONFIG_COMMAND}`)
146
178
  config['configuration']['properties']['core']['project']
147
179
  rescue
148
- warn 'Unable to determine project id.'
180
+ nil
149
181
  end
150
182
  module_function :load_gcloud_project_id
151
183
 
152
184
  private
153
185
 
186
+ def interpret_options(scope, options)
187
+ if scope.is_a? Hash
188
+ options = scope
189
+ scope = nil
190
+ end
191
+ if scope && !options[:scope]
192
+ options.merge(scope: scope)
193
+ else
194
+ options
195
+ end
196
+ end
197
+
154
198
  def service_account_env_vars?
155
199
  ([PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR] - ENV.keys).empty?
156
200
  end
@@ -46,16 +46,16 @@ module Google
46
46
  # override CredentialsLoader#make_creds to use the class determined by
47
47
  # loading the json.
48
48
  def self.make_creds(options = {})
49
- json_key_io, scope = options.values_at(:json_key_io, :scope)
49
+ json_key_io = options[:json_key_io]
50
50
  if json_key_io
51
51
  json_key, clz = determine_creds_class(json_key_io)
52
52
  warn_if_cloud_sdk_credentials json_key['client_id']
53
- clz.make_creds(json_key_io: StringIO.new(MultiJson.dump(json_key)),
54
- scope: scope)
53
+ io = StringIO.new(MultiJson.dump(json_key))
54
+ clz.make_creds(options.merge(json_key_io: io))
55
55
  else
56
56
  warn_if_cloud_sdk_credentials ENV[CredentialsLoader::CLIENT_ID_VAR]
57
57
  clz = read_creds
58
- clz.make_creds(scope: scope)
58
+ clz.make_creds(options)
59
59
  end
60
60
  end
61
61
 
@@ -73,6 +73,7 @@ module Google
73
73
  issuer: client_email,
74
74
  signing_key: OpenSSL::PKey::RSA.new(private_key),
75
75
  project_id: project_id)
76
+ .configure_connection(options)
76
77
  end
77
78
 
78
79
  # Handles certain escape sequences that sometimes appear in input.
@@ -38,6 +38,12 @@ module Signet
38
38
  # This reopens Client to add #apply and #apply! methods which update a
39
39
  # hash with the fetched authentication token.
40
40
  class Client
41
+ def configure_connection(options)
42
+ @connection_info =
43
+ options[:connection_builder] || options[:default_connection]
44
+ self
45
+ end
46
+
41
47
  # Updates a_hash updated with the authentication token
42
48
  def apply!(a_hash, opts = {})
43
49
  # fetch the access token there is currently not one, or if the client
@@ -66,6 +72,10 @@ module Signet
66
72
 
67
73
  alias orig_fetch_access_token! fetch_access_token!
68
74
  def fetch_access_token!(options = {})
75
+ unless options[:connection]
76
+ connection = build_default_connection
77
+ options = options.merge(connection: connection) if connection
78
+ end
69
79
  info = orig_fetch_access_token!(options)
70
80
  notify_refresh_listeners
71
81
  info
@@ -78,6 +88,16 @@ module Signet
78
88
  end
79
89
  end
80
90
 
91
+ def build_default_connection
92
+ if !defined?(@connection_info)
93
+ nil
94
+ elsif @connection_info.respond_to? :call
95
+ @connection_info.call
96
+ else
97
+ @connection_info
98
+ end
99
+ end
100
+
81
101
  def retry_with_error(max_retry_count = 5)
82
102
  retry_count = 0
83
103
 
@@ -72,6 +72,7 @@ module Google
72
72
  refresh_token: user_creds['refresh_token'],
73
73
  project_id: user_creds['project_id'],
74
74
  scope: scope)
75
+ .configure_connection(options)
75
76
  end
76
77
 
77
78
  # Reads the client_id, client_secret and refresh_token fields from the
@@ -31,6 +31,6 @@ module Google
31
31
  # Module Auth provides classes that provide Google-specific authorization
32
32
  # used to access Google APIs.
33
33
  module Auth
34
- VERSION = '0.7.1'.freeze
34
+ VERSION = '0.8.0'.freeze
35
35
  end
36
36
  end
@@ -47,6 +47,7 @@ describe Google::Auth::Credentials, :private do
47
47
 
48
48
  it 'uses a default scope' do
49
49
  mocked_signet = double('Signet::OAuth2::Client')
50
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
50
51
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
51
52
  allow(mocked_signet).to receive(:client_id)
52
53
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -64,6 +65,7 @@ describe Google::Auth::Credentials, :private do
64
65
 
65
66
  it 'uses a custom scope' do
66
67
  mocked_signet = double('Signet::OAuth2::Client')
68
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
67
69
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
68
70
  allow(mocked_signet).to receive(:client_id)
69
71
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -96,6 +98,7 @@ describe Google::Auth::Credentials, :private do
96
98
  allow(::File).to receive(:file?).with(TEST_PATH_ENV_VAL) { false }
97
99
 
98
100
  mocked_signet = double('Signet::OAuth2::Client')
101
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
99
102
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
100
103
  allow(mocked_signet).to receive(:client_id)
101
104
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -129,6 +132,7 @@ describe Google::Auth::Credentials, :private do
129
132
  allow(::File).to receive(:read).with('/unknown/path/to/file.txt') { JSON.generate(default_keyfile_hash) }
130
133
 
131
134
  mocked_signet = double('Signet::OAuth2::Client')
135
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
132
136
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
133
137
  allow(mocked_signet).to receive(:client_id)
134
138
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -161,6 +165,7 @@ describe Google::Auth::Credentials, :private do
161
165
  allow(::ENV).to receive(:[]).with('JSON_ENV_TEST') { JSON.generate(default_keyfile_hash) }
162
166
 
163
167
  mocked_signet = double('Signet::OAuth2::Client')
168
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
164
169
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
165
170
  allow(mocked_signet).to receive(:client_id)
166
171
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -194,6 +199,7 @@ describe Google::Auth::Credentials, :private do
194
199
  allow(::File).to receive(:read).with('~/default/path/to/file.txt') { JSON.generate(default_keyfile_hash) }
195
200
 
196
201
  mocked_signet = double('Signet::OAuth2::Client')
202
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
197
203
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
198
204
  allow(mocked_signet).to receive(:client_id)
199
205
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
@@ -226,6 +232,7 @@ describe Google::Auth::Credentials, :private do
226
232
  allow(::File).to receive(:file?).with('~/default/path/to/file.txt') { false }
227
233
 
228
234
  mocked_signet = double('Signet::OAuth2::Client')
235
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
229
236
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
230
237
  allow(mocked_signet).to receive(:client_id)
231
238
  allow(Google::Auth).to receive(:get_application_default) do |scope|
@@ -253,6 +260,7 @@ describe Google::Auth::Credentials, :private do
253
260
 
254
261
  it 'warns when cloud sdk credentials are used' do
255
262
  mocked_signet = double('Signet::OAuth2::Client')
263
+ allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
256
264
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
257
265
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
258
266
  mocked_signet
@@ -100,6 +100,19 @@ describe '#get_application_default' do
100
100
  end
101
101
  end
102
102
 
103
+ it "propagates default_connection option" do
104
+ Dir.mktmpdir do |dir|
105
+ key_path = File.join(dir, 'my_cert_file')
106
+ FileUtils.mkdir_p(File.dirname(key_path))
107
+ File.write(key_path, cred_json_text)
108
+ ENV[@var_name] = key_path
109
+ connection = Faraday.new(headers: {"User-Agent" => "hello"})
110
+ opts = options.merge(default_connection: connection)
111
+ creds = Google::Auth.get_application_default(@scope, opts)
112
+ expect(creds.build_default_connection).to be connection
113
+ end
114
+ end
115
+
103
116
  it 'succeeds with default file without GOOGLE_APPLICATION_CREDENTIALS' do
104
117
  ENV.delete(@var_name) unless ENV[@var_name].nil?
105
118
  Dir.mktmpdir do |dir|
@@ -229,6 +229,14 @@ describe Google::Auth::ServiceAccountCredentials do
229
229
  ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
230
230
  expect(@clz.from_env(@scope)).to_not be_nil
231
231
  end
232
+
233
+ it "propagates default_connection option" do
234
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
235
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
236
+ connection = Faraday.new(headers: {"User-Agent" => "hello"})
237
+ creds = @clz.from_env(@scope, default_connection: connection)
238
+ expect(creds.build_default_connection).to be connection
239
+ end
232
240
  end
233
241
 
234
242
  describe '#from_well_known_path' do
@@ -274,6 +282,20 @@ describe Google::Auth::ServiceAccountCredentials do
274
282
  expect(credentials.project_id).to eq(cred_json[:project_id])
275
283
  end
276
284
  end
285
+
286
+ it "propagates default_connection option" do
287
+ Dir.mktmpdir do |dir|
288
+ key_path = File.join(dir, '.config', @known_path)
289
+ key_path = File.join(dir, WELL_KNOWN_PATH) if OS.windows?
290
+ FileUtils.mkdir_p(File.dirname(key_path))
291
+ File.write(key_path, cred_json_text)
292
+ ENV['HOME'] = dir
293
+ ENV['APPDATA'] = dir
294
+ connection = Faraday.new(headers: {"User-Agent" => "hello"})
295
+ creds = @clz.from_well_known_path(@scope, default_connection: connection)
296
+ expect(creds.build_default_connection).to be connection
297
+ end
298
+ end
277
299
  end
278
300
 
279
301
  describe '#from_system_default_path' do
@@ -305,6 +327,18 @@ describe Google::Auth::ServiceAccountCredentials do
305
327
  File.delete(@path)
306
328
  end
307
329
  end
330
+
331
+ it "propagates default_connection option" do
332
+ FakeFS do
333
+ ENV['ProgramData'] = '/etc'
334
+ FileUtils.mkdir_p(File.dirname(@path))
335
+ File.write(@path, cred_json_text)
336
+ connection = Faraday.new(headers: {"User-Agent" => "hello"})
337
+ creds = @clz.from_system_default_path(@scope, default_connection: connection)
338
+ expect(creds.build_default_connection).to be connection
339
+ File.delete(@path)
340
+ end
341
+ end
308
342
  end
309
343
  end
310
344
 
@@ -60,14 +60,45 @@ describe Signet::OAuth2::Client do
60
60
  @key.public_key, true,
61
61
  algorithm: 'RS256')
62
62
  end
63
+ with_params = {body: hash_including(
64
+ "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer")}
65
+ if opts[:user_agent]
66
+ with_params[:headers] = {"User-Agent" => opts[:user_agent]}
67
+ end
63
68
  stub_request(:post, 'https://oauth2.googleapis.com/token')
64
- .with(body: hash_including(
65
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'
66
- ), &blk)
69
+ .with(with_params, &blk)
67
70
  .to_return(body: body,
68
71
  status: 200,
69
72
  headers: { 'Content-Type' => 'application/json' })
70
73
  end
71
74
 
72
75
  it_behaves_like 'apply/apply! are OK'
76
+
77
+ describe "#configure_connection" do
78
+ it "honors default_connection" do
79
+ token = "1/abcdef1234567890"
80
+ stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/1.0"
81
+ conn = Faraday.new headers: {"User-Agent" => "RubyRocks/1.0"}
82
+ @client.configure_connection(default_connection: conn)
83
+ md = { foo: "bar" }
84
+ @client.apply!(md)
85
+ want = { foo: "bar", authorization: "Bearer #{token}" }
86
+ expect(md).to eq(want)
87
+ expect(stub).to have_been_requested
88
+ end
89
+
90
+ it "honors connection_builder" do
91
+ token = "1/abcdef1234567890"
92
+ stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/2.0"
93
+ connection_builder = proc do
94
+ Faraday.new headers: {"User-Agent" => "RubyRocks/2.0"}
95
+ end
96
+ @client.configure_connection(connection_builder: connection_builder)
97
+ md = { foo: "bar" }
98
+ @client.apply!(md)
99
+ want = { foo: "bar", authorization: "Bearer #{token}" }
100
+ expect(md).to eq(want)
101
+ expect(stub).to have_been_requested
102
+ end
103
+ end
73
104
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googleauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Emiola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-26 00:00:00.000000000 Z
11
+ date: 2019-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -115,6 +115,10 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
+ - ".github/CONTRIBUTING.md"
119
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
120
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
121
+ - ".github/ISSUE_TEMPLATE/support_request.md"
118
122
  - ".gitignore"
119
123
  - ".kokoro/build.bat"
120
124
  - ".kokoro/build.sh"
@@ -135,7 +139,6 @@ files:
135
139
  - ".travis.yml"
136
140
  - CHANGELOG.md
137
141
  - CODE_OF_CONDUCT.md
138
- - CONTRIBUTING.md
139
142
  - COPYING
140
143
  - Gemfile
141
144
  - README.md