googleauth 1.11.0 → 1.12.2

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: 4912a601c0a234fa9faf150d7461cab993f775b715f6ac7d19db017ceae74e6d
4
- data.tar.gz: e08da21e12d58260944079d068a04099fa0c812eb486e760a3ab12dd002700f4
3
+ metadata.gz: 34f510693238aa2d0ac63fb3d7a91f8685d34dc9962e33952220b6ee8845beef
4
+ data.tar.gz: 97d0eb5127ac1c609740d8b422b2002bd8f983043ff1a11cc09130c3c650d30f
5
5
  SHA512:
6
- metadata.gz: b0346fcaf38cb783fd4d22f0734994298d63dfa1a89fd34df4d4f42b87160de410e34c93ab4773c3bbaf03b41160f10e3fd5bc0fa137d1ab6fb5dce15f72ba53
7
- data.tar.gz: c5ff10a04491e9f56dff9bcea24c67398e67713efc89c2d378075621da837b59c5fdbd36c0b97d5753fd0358befe8ce2ceacc86af1cce0a1c54d609d916903c6
6
+ metadata.gz: 821238707fdf60880359514bc2385a273b4d16fe6bc6bd8ad804fcd36d2255667ad4a4dd39e7fabbd5f422367208a7fc7b74949943cda444481a8da3edfd16e2
7
+ data.tar.gz: 792636b6a808d5c93dc7a3883a7c7d1e62cbb3d8b33b76e4da025cdbdac8cbd915c1cd4c5e1e698a58173d6fb2840e7623bd8c2a5673edc69113b662486029c4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Release History
2
2
 
3
+ ### 1.12.2 (2024-12-19)
4
+
5
+ #### Bug Fixes
6
+
7
+ * GCECredentials lazily fetches from the metadata server to ensure a universe domain is known ([#509](https://github.com/googleapis/google-auth-library-ruby/issues/509))
8
+
9
+ ### 1.12.1 (2024-12-17)
10
+
11
+ #### Bug Fixes
12
+
13
+ * Restored previous behavior where the apply! method returns the auth header ([#506](https://github.com/googleapis/google-auth-library-ruby/issues/506))
14
+
15
+ ### 1.12.0 (2024-12-05)
16
+
17
+ #### Features
18
+
19
+ * provided opt-in debug logging ([#490](https://github.com/googleapis/google-auth-library-ruby/issues/490))
20
+
21
+ ### 1.11.2 (2024-10-23)
22
+
23
+ #### Bug Fixes
24
+
25
+ * Temporarily disable universe domain query from GCE metadata server ([#493](https://github.com/googleapis/google-auth-library-ruby/issues/493))
26
+ * Use updated metadata path for universe-domain ([#496](https://github.com/googleapis/google-auth-library-ruby/issues/496))
27
+
28
+ ### 1.11.1 (2024-10-04)
29
+
30
+ #### Bug Fixes
31
+
32
+ * Fixed parsing of expiration timestamp from ID tokens ([#492](https://github.com/googleapis/google-auth-library-ruby/issues/492))
33
+ * Use NoMethodError instead of NotImplementedError for unimplemented base class methods ([#487](https://github.com/googleapis/google-auth-library-ruby/issues/487))
34
+
3
35
  ### 1.11.0 (2024-02-09)
4
36
 
5
37
  #### Features
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "google/logging/message"
16
+
15
17
  module Google
16
18
  # Module Auth provides classes that provide Google-specific authorization
17
19
  # used to access Google APIs.
@@ -29,7 +31,14 @@ module Google
29
31
  # fetch the access token there is currently not one, or if the client
30
32
  # has expired
31
33
  fetch_access_token! opts if needs_access_token?
32
- a_hash[AUTH_METADATA_KEY] = "Bearer #{send token_type}"
34
+ token = send token_type
35
+ a_hash[AUTH_METADATA_KEY] = "Bearer #{token}"
36
+ logger&.debug do
37
+ hash = Digest::SHA256.hexdigest token
38
+ Google::Logging::Message.from message: "Sending auth token. (sha256:#{hash})"
39
+ end
40
+
41
+ a_hash[AUTH_METADATA_KEY]
33
42
  end
34
43
 
35
44
  # Returns a clone of a_hash updated with the authentication token
@@ -63,17 +72,20 @@ module Google
63
72
  end
64
73
 
65
74
  def expires_within?
66
- raise NotImplementedError
75
+ raise NoMethodError, "expires_within? not implemented"
67
76
  end
68
77
 
78
+ # The logger used to log operations on this client, such as token refresh.
79
+ attr_accessor :logger
80
+
69
81
  private
70
82
 
71
83
  def token_type
72
- raise NotImplementedError
84
+ raise NoMethodError, "token_type not implemented"
73
85
  end
74
86
 
75
87
  def fetch_access_token!
76
- raise NotImplementedError
88
+ raise NoMethodError, "fetch_access_token! not implemented"
77
89
  end
78
90
  end
79
91
  end
@@ -80,69 +80,144 @@ module Google
80
80
  alias unmemoize_all reset_cache
81
81
  end
82
82
 
83
+ # @private Temporary; remove when universe domain metadata endpoint is stable (see b/349488459).
84
+ attr_accessor :disable_universe_domain_check
85
+
83
86
  # Construct a GCECredentials
84
87
  def initialize options = {}
85
88
  # Override the constructor to remember whether the universe domain was
86
89
  # overridden by a constructor argument.
87
90
  @universe_domain_overridden = options["universe_domain"] || options[:universe_domain] ? true : false
91
+ # TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
92
+ @disable_universe_domain_check = true
88
93
  super options
89
94
  end
90
95
 
96
+ # @private
97
+ # Overrides universe_domain getter to fetch lazily if it hasn't been
98
+ # fetched yet. This is necessary specifically for Compute Engine because
99
+ # the universe comes from the metadata service, and isn't known
100
+ # immediately on credential construction. All other credential types read
101
+ # the universe from their json key or other immediate input.
102
+ def universe_domain
103
+ value = super
104
+ return value unless value.nil?
105
+ fetch_access_token!
106
+ super
107
+ end
108
+
91
109
  # Overrides the super class method to change how access tokens are
92
110
  # fetched.
93
111
  def fetch_access_token _options = {}
94
- if token_type == :id_token
95
- query = { "audience" => target_audience, "format" => "full" }
96
- entry = "service-accounts/default/identity"
97
- else
98
- query = {}
99
- entry = "service-accounts/default/token"
100
- end
112
+ query, entry =
113
+ if token_type == :id_token
114
+ [{ "audience" => target_audience, "format" => "full" }, "service-accounts/default/identity"]
115
+ else
116
+ [{}, "service-accounts/default/token"]
117
+ end
101
118
  query[:scopes] = Array(scope).join "," if scope
102
119
  begin
120
+ log_fetch_query
103
121
  resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
122
+ log_fetch_resp resp
104
123
  case resp.status
105
124
  when 200
106
125
  build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
107
126
  when 403, 500
108
- msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
109
- raise Signet::UnexpectedStatusError, msg
127
+ raise Signet::UnexpectedStatusError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
110
128
  when 404
111
129
  raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
112
130
  else
113
- msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
114
- raise Signet::AuthorizationError, msg
131
+ raise Signet::AuthorizationError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
115
132
  end
116
133
  rescue Google::Cloud::Env::MetadataServerNotResponding => e
134
+ log_fetch_err e
117
135
  raise Signet::AuthorizationError, e.message
118
136
  end
119
137
  end
120
138
 
121
139
  private
122
140
 
141
+ def log_fetch_query
142
+ if token_type == :id_token
143
+ logger&.info do
144
+ Google::Logging::Message.from(
145
+ message: "Requesting id token from MDS with aud=#{target_audience}",
146
+ "credentialsId" => object_id
147
+ )
148
+ end
149
+ else
150
+ logger&.info do
151
+ Google::Logging::Message.from(
152
+ message: "Requesting access token from MDS",
153
+ "credentialsId" => object_id
154
+ )
155
+ end
156
+ end
157
+ end
158
+
159
+ def log_fetch_resp resp
160
+ logger&.info do
161
+ Google::Logging::Message.from(
162
+ message: "Received #{resp.status} from MDS",
163
+ "credentialsId" => object_id
164
+ )
165
+ end
166
+ end
167
+
168
+ def log_fetch_err _err
169
+ logger&.info do
170
+ Google::Logging::Message.from(
171
+ message: "MDS did not respond to token request",
172
+ "credentialsId" => object_id
173
+ )
174
+ end
175
+ end
176
+
123
177
  def build_token_hash body, content_type, retrieval_time
124
178
  hash =
125
179
  if ["text/html", "application/text"].include? content_type
126
- { token_type.to_s => body }
180
+ parse_encoded_token body
127
181
  else
128
182
  Signet::OAuth2.parse_credentials body, content_type
129
183
  end
130
- unless @universe_domain_overridden
131
- universe_domain = Google::Cloud.env.lookup_metadata "universe", "universe_domain"
132
- universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
133
- hash["universe_domain"] = universe_domain.strip
134
- end
135
- # The response might have been cached, which means expires_in might be
136
- # stale. Update it based on the time since the data was retrieved.
137
- # We also ensure expires_in is conservative; subtracting at least 1
138
- # second to offset any skew from metadata server latency.
139
- if hash["expires_in"].is_a? Numeric
140
- offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
141
- hash["expires_in"] -= offset if offset.positive?
142
- hash["expires_in"] = 0 if hash["expires_in"].negative?
184
+ add_universe_domain_to hash
185
+ adjust_for_stale_expires_in hash, retrieval_time
186
+ hash
187
+ end
188
+
189
+ def parse_encoded_token body
190
+ hash = { token_type.to_s => body }
191
+ if token_type == :id_token
192
+ expires_at = expires_at_from_id_token body
193
+ hash["expires_at"] = expires_at if expires_at
143
194
  end
144
195
  hash
145
196
  end
197
+
198
+ def add_universe_domain_to hash
199
+ return if @universe_domain_overridden
200
+ universe_domain =
201
+ if disable_universe_domain_check
202
+ # TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
203
+ "googleapis.com"
204
+ else
205
+ Google::Cloud.env.lookup_metadata "universe", "universe-domain"
206
+ end
207
+ universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
208
+ hash["universe_domain"] = universe_domain.strip
209
+ end
210
+
211
+ # The response might have been cached, which means expires_in might be
212
+ # stale. Update it based on the time since the data was retrieved.
213
+ # We also ensure expires_in is conservative; subtracting at least 1
214
+ # second to offset any skew from metadata server latency.
215
+ def adjust_for_stale_expires_in hash, retrieval_time
216
+ return unless hash["expires_in"].is_a? Numeric
217
+ offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
218
+ hash["expires_in"] -= offset if offset.positive?
219
+ hash["expires_in"] = 0 if hash["expires_in"].negative?
220
+ end
146
221
  end
147
222
  end
148
223
  end
@@ -299,6 +299,12 @@ module Google
299
299
  #
300
300
  attr_reader :quota_project_id
301
301
 
302
+ # @private Temporary; remove when universe domain metadata endpoint is stable (see b/349488459).
303
+ def disable_universe_domain_check
304
+ return false unless @client.respond_to? :disable_universe_domain_check
305
+ @client.disable_universe_domain_check
306
+ end
307
+
302
308
  # @private Delegate client methods to the client object.
303
309
  extend Forwardable
304
310
 
@@ -331,10 +337,13 @@ module Google
331
337
  # @!attribute [rw] universe_domain
332
338
  # @return [String] The universe domain issuing these credentials.
333
339
  #
340
+ # @!attribute [rw] logger
341
+ # @return [Logger] The logger used to log credential operations such as token refresh.
342
+ #
334
343
  def_delegators :@client,
335
344
  :token_credential_uri, :audience,
336
345
  :scope, :issuer, :signing_key, :updater_proc, :target_audience,
337
- :universe_domain, :universe_domain=
346
+ :universe_domain, :universe_domain=, :logger, :logger=
338
347
 
339
348
  ##
340
349
  # Creates a new Credentials instance with the provided auth credentials, and with the default
@@ -343,16 +352,17 @@ module Google
343
352
  # @param [String, Hash, Signet::OAuth2::Client] keyfile
344
353
  # The keyfile can be provided as one of the following:
345
354
  #
346
- # * The path to a JSON keyfile (as a +String+)
347
- # * The contents of a JSON keyfile (as a +Hash+)
348
- # * A +Signet::OAuth2::Client+ object
355
+ # * The path to a JSON keyfile (as a `String`)
356
+ # * The contents of a JSON keyfile (as a `Hash`)
357
+ # * A `Signet::OAuth2::Client` object
349
358
  # @param [Hash] options
350
359
  # The options for configuring the credentials instance. The following is supported:
351
360
  #
352
- # * +:scope+ - the scope for the client
353
- # * +"project_id"+ (and optionally +"project"+) - the project identifier for the client
354
- # * +:connection_builder+ - the connection builder to use for the client
355
- # * +:default_connection+ - the default connection to use for the client
361
+ # * `:scope` - the scope for the client
362
+ # * `project_id` (and optionally `project`) - the project identifier for the client
363
+ # * `:connection_builder` - the connection builder to use for the client
364
+ # * `:default_connection` - the default connection to use for the client
365
+ # * `:logger` - the logger used to log credential operations such as token refresh.
356
366
  #
357
367
  def initialize keyfile, options = {}
358
368
  verify_keyfile_provided! keyfile
@@ -367,8 +377,8 @@ module Google
367
377
  else
368
378
  update_from_filepath keyfile, options
369
379
  end
380
+ setup_logging logger: options.fetch(:logger, :default)
370
381
  @project_id ||= CredentialsLoader.load_gcloud_project_id
371
- @client.fetch_access_token! if @client.needs_access_token?
372
382
  @env_vars = nil
373
383
  @paths = nil
374
384
  @scope = nil
@@ -462,7 +472,8 @@ module Google
462
472
  audience: options[:audience] || audience
463
473
  }
464
474
  client = Google::Auth::DefaultCredentials.make_creds creds_input
465
- new client
475
+ options = options.select { |k, _v| k == :logger }
476
+ new client, options
466
477
  end
467
478
 
468
479
  private_class_method :from_env_vars,
@@ -543,6 +554,23 @@ module Google
543
554
  @quota_project_id ||= json["quota_project_id"]
544
555
  @client = init_client json, options
545
556
  end
557
+
558
+ def setup_logging logger: :default
559
+ return unless @client.respond_to? :logger=
560
+ logging_env = ENV["GOOGLE_SDK_RUBY_LOGGING_GEMS"].to_s.downcase
561
+ if ["false", "none"].include? logging_env
562
+ logger = nil
563
+ elsif @client.logger
564
+ logger = @client.logger
565
+ elsif logger == :default
566
+ logger = nil
567
+ if ["true", "all"].include?(logging_env) || logging_env.split(",").include?("googleauth")
568
+ formatter = Google::Logging::StructuredFormatter.new if Google::Cloud::Env.get.logging_agent_expected?
569
+ logger = Logger.new $stderr, progname: "googleauth", formatter: formatter
570
+ end
571
+ end
572
+ @client.logger = logger
573
+ end
546
574
  end
547
575
  end
548
576
  end
@@ -76,7 +76,7 @@ module Google
76
76
  # The retrieved subject token.
77
77
  #
78
78
  def retrieve_subject_token!
79
- raise NotImplementedError
79
+ raise NoMethodError, "retrieve_subject_token! not implemented"
80
80
  end
81
81
 
82
82
  # Returns whether the credentials represent a workforce pool (True) or
@@ -129,7 +129,7 @@ module Google
129
129
  if @client_id.nil? && @workforce_pool_user_project
130
130
  additional_options = { userProject: @workforce_pool_user_project }
131
131
  end
132
- @sts_client.exchange_token(
132
+ token_request = {
133
133
  audience: @audience,
134
134
  grant_type: STS_GRANT_TYPE,
135
135
  subject_token: retrieve_subject_token!,
@@ -137,10 +137,31 @@ module Google
137
137
  scopes: @service_account_impersonation_url ? IAM_SCOPE : @scope,
138
138
  requested_token_type: STS_REQUESTED_TOKEN_TYPE,
139
139
  additional_options: additional_options
140
- )
140
+ }
141
+ log_token_request token_request
142
+ @sts_client.exchange_token token_request
143
+ end
144
+
145
+ def log_token_request token_request
146
+ logger&.info do
147
+ Google::Logging::Message.from(
148
+ message: "Requesting access token from #{token_request[:grant_type]}",
149
+ "credentialsId" => object_id
150
+ )
151
+ end
152
+ logger&.debug do
153
+ digest = Digest::SHA256.hexdigest token_request[:subject_token].to_s
154
+ loggable_request = token_request.merge subject_token: "(sha256:#{digest})"
155
+ Google::Logging::Message.from(
156
+ message: "Request data",
157
+ "request" => loggable_request,
158
+ "credentialsId" => object_id
159
+ )
160
+ end
141
161
  end
142
162
 
143
163
  def get_impersonated_access_token token, _options = {}
164
+ log_impersonated_token_request token
144
165
  response = connection.post @service_account_impersonation_url do |req|
145
166
  req.headers["Authorization"] = "Bearer #{token}"
146
167
  req.headers["Content-Type"] = "application/json"
@@ -153,6 +174,16 @@ module Google
153
174
 
154
175
  MultiJson.load response.body
155
176
  end
177
+
178
+ def log_impersonated_token_request original_token
179
+ logger&.info do
180
+ digest = Digest::SHA256.hexdigest original_token
181
+ Google::Logging::Message.from(
182
+ message: "Requesting impersonated access token with original token (sha256:#{digest})",
183
+ "credentialsId" => object_id
184
+ )
185
+ end
186
+ end
156
187
  end
157
188
  end
158
189
  end
@@ -168,7 +168,6 @@ module Google
168
168
  aud: nil,
169
169
  azp: nil,
170
170
  iss: OIDC_ISSUERS
171
-
172
171
  verifier = Verifier.new key_source: oidc_key_source,
173
172
  aud: aud,
174
173
  azp: azp,
@@ -206,7 +205,6 @@ module Google
206
205
  aud: nil,
207
206
  azp: nil,
208
207
  iss: IAP_ISSUERS
209
-
210
208
  verifier = Verifier.new key_source: iap_key_source,
211
209
  aud: aud,
212
210
  azp: azp,
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "google/logging/message"
15
16
  require "googleauth/signet"
16
17
  require "googleauth/credentials_loader"
17
18
  require "googleauth/json_key_reader"
@@ -123,6 +124,7 @@ module Google
123
124
  }
124
125
  key_io = StringIO.new MultiJson.dump(cred_json)
125
126
  alt = ServiceAccountJwtHeaderCredentials.make_creds json_key_io: key_io, scope: scope
127
+ alt.logger = logger
126
128
  alt.apply! a_hash
127
129
  end
128
130
  end
@@ -147,6 +149,7 @@ module Google
147
149
  attr_reader :project_id
148
150
  attr_reader :quota_project_id
149
151
  attr_accessor :universe_domain
152
+ attr_accessor :logger
150
153
 
151
154
  # Create a ServiceAccountJwtHeaderCredentials.
152
155
  #
@@ -187,10 +190,14 @@ module Google
187
190
  return a_hash if jwt_aud_uri.nil? && @scope.nil?
188
191
  jwt_token = new_jwt_token jwt_aud_uri, opts
189
192
  a_hash[AUTH_METADATA_KEY] = "Bearer #{jwt_token}"
193
+ logger&.debug do
194
+ hash = Digest::SHA256.hexdigest jwt_token
195
+ Google::Logging::Message.from message: "Sending JWT auth token. (sha256:#{hash})"
196
+ end
190
197
  a_hash
191
198
  end
192
199
 
193
- # Returns a clone of a_hash updated with the authoriation header
200
+ # Returns a clone of a_hash updated with the authorization header
194
201
  def apply a_hash, opts = {}
195
202
  a_copy = a_hash.clone
196
203
  apply! a_copy, opts
@@ -219,6 +226,10 @@ module Google
219
226
  assertion["scope"] = Array(@scope).join " " if @scope
220
227
  assertion["aud"] = jwt_aud_uri if jwt_aud_uri
221
228
 
229
+ logger&.debug do
230
+ Google::Logging::Message.from message: "JWT assertion: #{assertion}"
231
+ end
232
+
222
233
  JWT.encode assertion, @signing_key, SIGNING_ALGORITHM
223
234
  end
224
235
 
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "base64"
16
+ require "json"
15
17
  require "signet/oauth_2/client"
16
18
  require "googleauth/base_client"
17
19
 
@@ -29,6 +31,8 @@ module Signet
29
31
 
30
32
  def update_token! options = {}
31
33
  options = deep_hash_normalize options
34
+ id_token_expires_at = expires_at_from_id_token options[:id_token]
35
+ options[:expires_at] = id_token_expires_at if id_token_expires_at
32
36
  update_token_signet_base options
33
37
  self.universe_domain = options[:universe_domain] if options.key? :universe_domain
34
38
  self
@@ -61,6 +65,24 @@ module Signet
61
65
  info
62
66
  end
63
67
 
68
+ alias googleauth_orig_generate_access_token_request generate_access_token_request
69
+ def generate_access_token_request options = {}
70
+ parameters = googleauth_orig_generate_access_token_request options
71
+ logger&.info do
72
+ Google::Logging::Message.from(
73
+ message: "Requesting access token from #{parameters['grant_type']}",
74
+ "credentialsId" => object_id
75
+ )
76
+ end
77
+ logger&.debug do
78
+ Google::Logging::Message.from(
79
+ message: "Token fetch params: #{parameters}",
80
+ "credentialsId" => object_id
81
+ )
82
+ end
83
+ parameters
84
+ end
85
+
64
86
  def build_default_connection
65
87
  if !defined?(@connection_info)
66
88
  nil
@@ -75,20 +97,81 @@ module Signet
75
97
  retry_count = 0
76
98
 
77
99
  begin
78
- yield
100
+ yield.tap { |resp| log_response resp }
79
101
  rescue StandardError => e
80
- raise e if e.is_a?(Signet::AuthorizationError) || e.is_a?(Signet::ParseError)
102
+ if e.is_a?(Signet::AuthorizationError) || e.is_a?(Signet::ParseError)
103
+ log_auth_error e
104
+ raise e
105
+ end
81
106
 
82
107
  if retry_count < max_retry_count
108
+ log_transient_error e
83
109
  retry_count += 1
84
110
  sleep retry_count * 0.3
85
111
  retry
86
112
  else
113
+ log_retries_exhausted e
87
114
  msg = "Unexpected error: #{e.inspect}"
88
115
  raise Signet::AuthorizationError, msg
89
116
  end
90
117
  end
91
118
  end
119
+
120
+ private
121
+
122
+ def expires_at_from_id_token id_token
123
+ match = /^[\w=-]+\.([\w=-]+)\.[\w=-]+$/.match id_token.to_s
124
+ return unless match
125
+ json = JSON.parse Base64.urlsafe_decode64 match[1]
126
+ return unless json.key? "exp"
127
+ Time.at json["exp"].to_i
128
+ rescue StandardError
129
+ # Shouldn't happen unless we get a garbled ID token
130
+ nil
131
+ end
132
+
133
+ def log_response token_response
134
+ response_hash = JSON.parse token_response rescue {}
135
+ if response_hash["access_token"]
136
+ digest = Digest::SHA256.hexdigest response_hash["access_token"]
137
+ response_hash["access_token"] = "(sha256:#{digest})"
138
+ end
139
+ if response_hash["id_token"]
140
+ digest = Digest::SHA256.hexdigest response_hash["id_token"]
141
+ response_hash["id_token"] = "(sha256:#{digest})"
142
+ end
143
+ Google::Logging::Message.from(
144
+ message: "Received auth token response: #{response_hash}",
145
+ "credentialsId" => object_id
146
+ )
147
+ end
148
+
149
+ def log_auth_error err
150
+ logger&.info do
151
+ Google::Logging::Message.from(
152
+ message: "Auth error when fetching auth token: #{err}",
153
+ "credentialsId" => object_id
154
+ )
155
+ end
156
+ end
157
+
158
+ def log_transient_error err
159
+ logger&.info do
160
+ Google::Logging::Message.from(
161
+ message: "Transient error when fetching auth token: #{err}",
162
+ "credentialsId" => object_id
163
+ )
164
+ end
165
+ end
166
+
167
+ def log_retries_exhausted err
168
+ logger&.info do
169
+ Google::Logging::Message.from(
170
+ message: "Exhausted retries when fetching auth token: #{err}",
171
+ "credentialsId" => object_id
172
+ )
173
+ end
174
+ end
92
175
  end
93
176
  end
94
177
  end
@@ -29,7 +29,7 @@ module Google
29
29
  # @return [String]
30
30
  # The loaded token data.
31
31
  def load _id
32
- raise "Not implemented"
32
+ raise NoMethodError, "load not implemented"
33
33
  end
34
34
 
35
35
  # Put the token data into storage for the given ID.
@@ -39,7 +39,7 @@ module Google
39
39
  # @param [String] token
40
40
  # The token data to store.
41
41
  def store _id, _token
42
- raise "Not implemented"
42
+ raise NoMethodError, "store not implemented"
43
43
  end
44
44
 
45
45
  # Remove the token data from storage for the given ID.
@@ -47,7 +47,7 @@ module Google
47
47
  # @param [String] id
48
48
  # ID of the token data to delete
49
49
  def delete _id
50
- raise "Not implemented"
50
+ raise NoMethodError, "delete not implemented"
51
51
  end
52
52
  end
53
53
  end
@@ -16,6 +16,6 @@ module Google
16
16
  # Module Auth provides classes that provide Google-specific authorization
17
17
  # used to access Google APIs.
18
18
  module Auth
19
- VERSION = "1.11.0".freeze
19
+ VERSION = "1.12.2".freeze
20
20
  end
21
21
  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: 1.11.0
4
+ version: 1.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Emiola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-14 00:00:00.000000000 Z
11
+ date: 2024-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -36,14 +36,28 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '2.1'
39
+ version: '2.2'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '2.1'
46
+ version: '2.2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: google-logging-utils
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.1'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: jwt
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -186,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
200
  - !ruby/object:Gem::Version
187
201
  version: '0'
188
202
  requirements: []
189
- rubygems_version: 3.5.3
203
+ rubygems_version: 3.5.23
190
204
  signing_key:
191
205
  specification_version: 4
192
206
  summary: Google Auth Library for Ruby