googleauth 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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