googleauth 1.13.1 → 1.15.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/Credentials.md +106 -0
  4. data/Errors.md +152 -0
  5. data/README.md +1 -1
  6. data/lib/googleauth/api_key.rb +164 -0
  7. data/lib/googleauth/application_default.rb +3 -1
  8. data/lib/googleauth/base_client.rb +5 -0
  9. data/lib/googleauth/bearer_token.rb +162 -0
  10. data/lib/googleauth/client_id.rb +9 -5
  11. data/lib/googleauth/compute_engine.rb +65 -19
  12. data/lib/googleauth/credentials.rb +23 -6
  13. data/lib/googleauth/credentials_loader.rb +11 -6
  14. data/lib/googleauth/default_credentials.rb +18 -6
  15. data/lib/googleauth/errors.rb +117 -0
  16. data/lib/googleauth/external_account/aws_credentials.rb +85 -18
  17. data/lib/googleauth/external_account/base_credentials.rb +31 -2
  18. data/lib/googleauth/external_account/external_account_utils.rb +15 -4
  19. data/lib/googleauth/external_account/identity_pool_credentials.rb +40 -15
  20. data/lib/googleauth/external_account/pluggable_credentials.rb +34 -19
  21. data/lib/googleauth/external_account.rb +30 -6
  22. data/lib/googleauth/helpers/connection.rb +7 -1
  23. data/lib/googleauth/iam.rb +19 -3
  24. data/lib/googleauth/id_tokens/errors.rb +13 -7
  25. data/lib/googleauth/id_tokens/key_sources.rb +13 -7
  26. data/lib/googleauth/id_tokens/verifier.rb +2 -3
  27. data/lib/googleauth/id_tokens.rb +4 -4
  28. data/lib/googleauth/impersonated_service_account.rb +64 -17
  29. data/lib/googleauth/json_key_reader.rb +11 -2
  30. data/lib/googleauth/oauth2/sts_client.rb +9 -4
  31. data/lib/googleauth/scope_util.rb +1 -1
  32. data/lib/googleauth/service_account.rb +17 -160
  33. data/lib/googleauth/service_account_jwt_header.rb +187 -0
  34. data/lib/googleauth/signet.rb +24 -6
  35. data/lib/googleauth/user_authorizer.rb +35 -7
  36. data/lib/googleauth/user_refresh.rb +25 -7
  37. data/lib/googleauth/version.rb +1 -1
  38. data/lib/googleauth/web_user_authorizer.rb +46 -9
  39. data/lib/googleauth.rb +8 -0
  40. metadata +14 -8
@@ -14,6 +14,7 @@
14
14
 
15
15
  require "multi_json"
16
16
  require "googleauth/credentials_loader"
17
+ require "googleauth/errors"
17
18
 
18
19
  module Google
19
20
  module Auth
@@ -62,10 +63,11 @@ module Google
62
63
  # @note Direct instantiation is discouraged to avoid embedding IDs
63
64
  # and secrets in source. See {#from_file} to load from
64
65
  # `client_secrets.json` files.
66
+ # @raise [Google::Auth::InitializationError] If id or secret is nil
65
67
  #
66
68
  def initialize id, secret
67
- raise "Client id can not be nil" if id.nil?
68
- raise "Client secret can not be nil" if secret.nil?
69
+ raise InitializationError, "Client id can not be nil" if id.nil?
70
+ raise InitializationError, "Client secret can not be nil" if secret.nil?
69
71
  @id = id
70
72
  @secret = secret
71
73
  end
@@ -77,9 +79,10 @@ module Google
77
79
  # @param [String, File] file
78
80
  # Path of file to read from
79
81
  # @return [Google::Auth::ClientID]
82
+ # @raise [Google::Auth::InitializationError] If file is nil
80
83
  #
81
84
  def self.from_file file
82
- raise "File can not be nil." if file.nil?
85
+ raise InitializationError, "File can not be nil." if file.nil?
83
86
  File.open file.to_s do |f|
84
87
  json = f.read
85
88
  config = MultiJson.load json
@@ -94,11 +97,12 @@ module Google
94
97
  # @param [hash] config
95
98
  # Parsed contents of the JSON file
96
99
  # @return [Google::Auth::ClientID]
100
+ # @raise [Google::Auth::InitializationError] If config is nil or missing required elements
97
101
  #
98
102
  def self.from_hash config
99
- raise "Hash can not be nil." if config.nil?
103
+ raise InitializationError, "Hash can not be nil." if config.nil?
100
104
  raw_detail = config[INSTALLED_APP] || config[WEB_APP]
101
- raise MISSING_TOP_LEVEL_ELEMENT_ERROR if raw_detail.nil?
105
+ raise InitializationError, MISSING_TOP_LEVEL_ELEMENT_ERROR if raw_detail.nil?
102
106
  ClientId.new raw_detail[CLIENT_ID], raw_detail[CLIENT_SECRET]
103
107
  end
104
108
  end
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require "google-cloud-env"
16
+ require "googleauth/errors"
16
17
  require "googleauth/signet"
17
18
 
18
19
  module Google
@@ -87,7 +88,7 @@ module Google
87
88
  def initialize options = {}
88
89
  # Override the constructor to remember whether the universe domain was
89
90
  # overridden by a constructor argument.
90
- @universe_domain_overridden = options["universe_domain"] || options[:universe_domain] ? true : false
91
+ @universe_domain_overridden = options["universe_domain"] || options[:universe_domain]
91
92
  # TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
92
93
  @disable_universe_domain_check = true
93
94
  super options
@@ -126,31 +127,25 @@ module Google
126
127
 
127
128
  # Overrides the super class method to change how access tokens are
128
129
  # fetched.
130
+ #
131
+ # @param [Hash] _options Options for token fetch (not used)
132
+ # @return [Hash] The token data hash
133
+ # @raise [Google::Auth::UnexpectedStatusError] On unexpected HTTP status codes
134
+ # @raise [Google::Auth::AuthorizationError] If metadata server is unavailable or returns error
129
135
  def fetch_access_token _options = {}
130
- query, entry =
131
- if token_type == :id_token
132
- [{ "audience" => target_audience, "format" => "full" }, "service-accounts/default/identity"]
133
- else
134
- [{}, "service-accounts/default/token"]
135
- end
136
- query[:scopes] = Array(scope).join "," if scope
136
+ query, entry = build_metadata_request_params
137
137
  begin
138
138
  log_fetch_query
139
139
  resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
140
140
  log_fetch_resp resp
141
- case resp.status
142
- when 200
143
- build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
144
- when 403, 500
145
- raise Signet::UnexpectedStatusError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
146
- when 404
147
- raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
148
- else
149
- raise Signet::AuthorizationError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
150
- end
141
+ handle_metadata_response resp
151
142
  rescue Google::Cloud::Env::MetadataServerNotResponding => e
152
143
  log_fetch_err e
153
- raise Signet::AuthorizationError, e.message
144
+ raise AuthorizationError.with_details(
145
+ e.message,
146
+ credential_type_name: self.class.name,
147
+ principal: principal
148
+ )
154
149
  end
155
150
  end
156
151
 
@@ -175,8 +170,47 @@ module Google
175
170
  self
176
171
  end
177
172
 
173
+ # Returns the principal identifier for GCE credentials
174
+ # @private
175
+ # @return [Symbol] :gce to represent Google Compute Engine identity
176
+ def principal
177
+ :gce_metadata
178
+ end
179
+
178
180
  private
179
181
 
182
+ # @private
183
+ # Builds query parameters and endpoint for metadata request
184
+ # @return [Array] The query parameters and endpoint path
185
+ def build_metadata_request_params
186
+ query, entry =
187
+ if token_type == :id_token
188
+ [{ "audience" => target_audience, "format" => "full" }, "service-accounts/default/identity"]
189
+ else
190
+ [{}, "service-accounts/default/token"]
191
+ end
192
+ query[:scopes] = Array(scope).join "," if scope
193
+ [query, entry]
194
+ end
195
+
196
+ # @private
197
+ # Handles the response from the metadata server
198
+ # @param [Google::Cloud::Env::MetadataResponse] resp The metadata server response
199
+ # @return [Hash] The token hash on success
200
+ # @raise [Google::Auth::UnexpectedStatusError, Google::Auth::AuthorizationError] On error
201
+ def handle_metadata_response resp
202
+ case resp.status
203
+ when 200
204
+ build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
205
+ when 403, 500
206
+ raise Signet::UnexpectedStatusError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
207
+ when 404
208
+ raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
209
+ else
210
+ raise Signet::AuthorizationError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
211
+ end
212
+ end
213
+
180
214
  def log_fetch_query
181
215
  if token_type == :id_token
182
216
  logger&.info do
@@ -213,6 +247,18 @@ module Google
213
247
  end
214
248
  end
215
249
 
250
+ # Constructs a token hash from the metadata server response
251
+ #
252
+ # @private
253
+ # @param [String] body The response body from the metadata server
254
+ # @param [String] content_type The content type of the response
255
+ # @param [Float] retrieval_time The monotonic time when the response was retrieved
256
+ #
257
+ # @return [Hash] A hash containing:
258
+ # - access_token/id_token: The actual token depending on what was requested
259
+ # - token_type: The type of token (usually "Bearer")
260
+ # - expires_in: Seconds until token expiration (adjusted for freshness)
261
+ # - universe_domain: The universe domain for the token (if not overridden)
216
262
  def build_token_hash body, content_type, retrieval_time
217
263
  hash =
218
264
  if ["text/html", "application/text"].include? content_type
@@ -14,9 +14,11 @@
14
14
 
15
15
  require "forwardable"
16
16
  require "json"
17
+ require "pathname"
17
18
  require "signet/oauth_2/client"
18
19
 
19
20
  require "googleauth/credentials_loader"
21
+ require "googleauth/errors"
20
22
 
21
23
  module Google
22
24
  module Auth
@@ -357,12 +359,13 @@ module Google
357
359
  # Creates a new Credentials instance with the provided auth credentials, and with the default
358
360
  # values configured on the class.
359
361
  #
360
- # @param [String, Hash, Signet::OAuth2::Client] source_creds
362
+ # @param [String, Pathname, Hash, Google::Auth::BaseClient] source_creds
361
363
  # The source of credentials. It can be provided as one of the following:
362
364
  #
363
- # * The path to a JSON keyfile (as a `String`)
365
+ # * The path to a JSON keyfile (as a `String` or a `Pathname`)
364
366
  # * The contents of a JSON keyfile (as a `Hash`)
365
- # * A `Signet::OAuth2::Client` credentials object
367
+ # * A `Google::Auth::BaseClient` credentials object, including but not limited to
368
+ # a `Signet::OAuth2::Client` object.
366
369
  # * Any credentials object that supports the methods this wrapper delegates to an inner client.
367
370
  #
368
371
  # If this parameter is an object (`Signet::OAuth2::Client` or other) it will be used as an inner client.
@@ -391,14 +394,20 @@ module Google
391
394
  # parameters of the `Signet::OAuth2::Client`, such as connection parameters,
392
395
  # timeouts, etc.
393
396
  #
397
+ # @raise [Google::Auth::InitializationError] If source_creds is nil
398
+ # @raise [ArgumentError] If both scope and target_audience are specified
399
+ #
394
400
  def initialize source_creds, options = {}
395
- raise "The source credentials passed to Google::Auth::Credentials.new were nil." if source_creds.nil?
401
+ if source_creds.nil?
402
+ raise InitializationError,
403
+ "The source credentials passed to Google::Auth::Credentials.new were nil."
404
+ end
396
405
 
397
406
  options = symbolize_hash_keys options
398
407
  @project_id = options[:project_id] || options[:project]
399
408
  @quota_project_id = options[:quota_project_id]
400
409
  case source_creds
401
- when String
410
+ when String, Pathname
402
411
  update_from_filepath source_creds, options
403
412
  when Hash
404
413
  update_from_hash source_creds, options
@@ -554,9 +563,12 @@ module Google
554
563
  protected
555
564
 
556
565
  # Verify that the keyfile argument is a file.
566
+ #
567
+ # @param [String] keyfile Path to the keyfile
568
+ # @raise [Google::Auth::InitializationError] If the keyfile does not exist
557
569
  def verify_keyfile_exists! keyfile
558
570
  exists = ::File.file? keyfile
559
- raise "The keyfile '#{keyfile}' is not a valid file." unless exists
571
+ raise InitializationError, "The keyfile '#{keyfile}' is not a valid file." unless exists
560
572
  end
561
573
 
562
574
  # Initializes the Signet client.
@@ -577,6 +589,11 @@ module Google
577
589
  hash.to_h.transform_keys(&:to_sym)
578
590
  end
579
591
 
592
+ # Updates client options with defaults from the credential class
593
+ #
594
+ # @param [Hash] options Options to update
595
+ # @return [Hash] Updated options hash
596
+ # @raise [ArgumentError] If both scope and target_audience are specified
580
597
  def update_client_options options
581
598
  options = options.dup
582
599
 
@@ -15,6 +15,8 @@
15
15
  require "os"
16
16
  require "rbconfig"
17
17
 
18
+ require "googleauth/errors"
19
+
18
20
  module Google
19
21
  # Module Auth provides classes that provide Google-specific authorization
20
22
  # used to access Google APIs.
@@ -37,7 +39,7 @@ module Google
37
39
  AWS_SESSION_TOKEN_VAR = "AWS_SESSION_TOKEN".freeze
38
40
  GCLOUD_POSIX_COMMAND = "gcloud".freeze
39
41
  GCLOUD_WINDOWS_COMMAND = "gcloud.cmd".freeze
40
- GCLOUD_CONFIG_COMMAND = "config config-helper --format json --verbosity none".freeze
42
+ GCLOUD_CONFIG_COMMAND = "config config-helper --format json --verbosity none --quiet".freeze
41
43
 
42
44
  CREDENTIALS_FILE_NAME = "application_default_credentials.json".freeze
43
45
  NOT_FOUND_ERROR = "Unable to read the credential file specified by #{ENV_VAR}".freeze
@@ -71,11 +73,12 @@ module Google
71
73
  # The following keys are recognized:
72
74
  # * `:default_connection` The connection object to use.
73
75
  # * `:connection_builder` A `Proc` that returns a connection.
76
+ # @raise [Google::Auth::InitializationError] If the credentials file cannot be read
74
77
  def from_env scope = nil, options = {}
75
78
  options = interpret_options scope, options
76
79
  if ENV.key?(ENV_VAR) && !ENV[ENV_VAR].empty?
77
80
  path = ENV[ENV_VAR]
78
- raise "file #{path} does not exist" unless File.exist? path
81
+ raise InitializationError, "file #{path} does not exist" unless File.exist? path
79
82
  File.open path do |f|
80
83
  return make_creds options.merge(json_key_io: f)
81
84
  end
@@ -83,7 +86,7 @@ module Google
83
86
  make_creds options
84
87
  end
85
88
  rescue StandardError => e
86
- raise "#{NOT_FOUND_ERROR}: #{e}"
89
+ raise InitializationError, "#{NOT_FOUND_ERROR}: #{e}"
87
90
  end
88
91
 
89
92
  # Creates an instance from a well known path.
@@ -97,6 +100,7 @@ module Google
97
100
  # The following keys are recognized:
98
101
  # * `:default_connection` The connection object to use.
99
102
  # * `:connection_builder` A `Proc` that returns a connection.
103
+ # @raise [Google::Auth::InitializationError] If the credentials file cannot be read
100
104
  def from_well_known_path scope = nil, options = {}
101
105
  options = interpret_options scope, options
102
106
  home_var = OS.windows? ? "APPDATA" : "HOME"
@@ -109,7 +113,7 @@ module Google
109
113
  return make_creds options.merge(json_key_io: f)
110
114
  end
111
115
  rescue StandardError => e
112
- raise "#{WELL_KNOWN_ERROR}: #{e}"
116
+ raise InitializationError, "#{WELL_KNOWN_ERROR}: #{e}"
113
117
  end
114
118
 
115
119
  # Creates an instance from the system default path
@@ -123,6 +127,7 @@ module Google
123
127
  # The following keys are recognized:
124
128
  # * `:default_connection` The connection object to use.
125
129
  # * `:connection_builder` A `Proc` that returns a connection.
130
+ # @raise [Google::Auth::InitializationError] If the credentials file cannot be read or is invalid
126
131
  def from_system_default_path scope = nil, options = {}
127
132
  options = interpret_options scope, options
128
133
  if OS.windows?
@@ -137,7 +142,7 @@ module Google
137
142
  return make_creds options.merge(json_key_io: f)
138
143
  end
139
144
  rescue StandardError => e
140
- raise "#{SYSTEM_DEFAULT_ERROR}: #{e}"
145
+ raise InitializationError, "#{SYSTEM_DEFAULT_ERROR}: #{e}"
141
146
  end
142
147
 
143
148
  module_function
@@ -146,7 +151,7 @@ module Google
146
151
  def load_gcloud_project_id
147
152
  gcloud = GCLOUD_WINDOWS_COMMAND if OS.windows?
148
153
  gcloud = GCLOUD_POSIX_COMMAND unless OS.windows?
149
- gcloud_json = IO.popen("#{gcloud} #{GCLOUD_CONFIG_COMMAND}", in: :close, err: :close, &:read)
154
+ gcloud_json = IO.popen("#{gcloud} #{GCLOUD_CONFIG_COMMAND}", err: :close, &:read)
150
155
  config = MultiJson.load gcloud_json
151
156
  config["configuration"]["properties"]["core"]["project"]
152
157
  rescue StandardError
@@ -16,10 +16,11 @@ require "multi_json"
16
16
  require "stringio"
17
17
 
18
18
  require "googleauth/credentials_loader"
19
+ require "googleauth/errors"
20
+ require "googleauth/external_account"
19
21
  require "googleauth/service_account"
22
+ require "googleauth/service_account_jwt_header"
20
23
  require "googleauth/user_refresh"
21
- require "googleauth/external_account"
22
- require "googleauth/impersonated_service_account"
23
24
 
24
25
  module Google
25
26
  # Module Auth provides classes that provide Google-specific authorization
@@ -42,6 +43,9 @@ module Google
42
43
  # information, refer to [Validate credential configurations from external
43
44
  # sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
44
45
  #
46
+ # @param options [Hash] Options for creating the credentials
47
+ # @return [Google::Auth::Credentials] The credentials instance
48
+ # @raise [Google::Auth::InitializationError] If the credentials cannot be determined
45
49
  def self.make_creds options = {}
46
50
  json_key_io = options[:json_key_io]
47
51
  if json_key_io
@@ -54,10 +58,14 @@ module Google
54
58
  end
55
59
  end
56
60
 
61
+ # Reads the credential type from environment and returns the appropriate class
62
+ #
63
+ # @return [Class] The credential class to use
64
+ # @raise [Google::Auth::InitializationError] If the credentials type is undefined or unsupported
57
65
  def self.read_creds
58
66
  env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
59
67
  type = ENV[env_var]
60
- raise "#{env_var} is undefined in env" unless type
68
+ raise InitializationError, "#{env_var} is undefined in env" unless type
61
69
  case type
62
70
  when "service_account"
63
71
  ServiceAccountCredentials
@@ -66,15 +74,19 @@ module Google
66
74
  when "external_account"
67
75
  ExternalAccount::Credentials
68
76
  else
69
- raise "credentials type '#{type}' is not supported"
77
+ raise InitializationError, "credentials type '#{type}' is not supported"
70
78
  end
71
79
  end
72
80
 
73
81
  # Reads the input json and determines which creds class to use.
82
+ #
83
+ # @param json_key_io [IO] An IO object containing the JSON key
84
+ # @return [Array(Hash, Class)] The JSON key and the credential class to use
85
+ # @raise [Google::Auth::InitializationError] If the JSON is missing the type field or has an unsupported type
74
86
  def self.determine_creds_class json_key_io
75
87
  json_key = MultiJson.load json_key_io.read
76
88
  key = "type"
77
- raise "the json is missing the '#{key}' field" unless json_key.key? key
89
+ raise InitializationError, "the json is missing the '#{key}' field" unless json_key.key? key
78
90
  type = json_key[key]
79
91
  case type
80
92
  when "service_account"
@@ -84,7 +96,7 @@ module Google
84
96
  when "external_account"
85
97
  [json_key, ExternalAccount::Credentials]
86
98
  else
87
- raise "credentials type '#{type}' is not supported"
99
+ raise InitializationError, "credentials type '#{type}' is not supported"
88
100
  end
89
101
  end
90
102
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "signet/oauth_2/client"
4
+
5
+ # Copyright 2025 Google LLC
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ module Google
20
+ module Auth
21
+ ##
22
+ # Error mixin module for Google Auth errors
23
+ # All Google Auth errors should include this module
24
+ #
25
+ module Error; end
26
+
27
+ ##
28
+ # Mixin module that contains detailed error information
29
+ # typically this is available if credentials initialization
30
+ # succeeds and credentials object is valid
31
+ #
32
+ module DetailedError
33
+ include Error
34
+
35
+ # The type of the credentials that the error was originated from
36
+ # @return [String, nil] The class name of the credential that raised the error
37
+ attr_reader :credential_type_name
38
+
39
+ # The principal for the authentication flow. Typically obtained from credentials
40
+ # @return [String, Symbol, nil] The principal identifier associated with the credentials
41
+ attr_reader :principal
42
+
43
+ # All details passed in the options hash when creating the error
44
+ # @return [Hash] Additional details about the error
45
+ attr_reader :details
46
+
47
+ # @private
48
+ def self.included base
49
+ base.extend ClassMethods
50
+ end
51
+
52
+ # Class methods to be added to including classes
53
+ module ClassMethods
54
+ # Creates a new error with detailed information
55
+ # @param message [String] The error message
56
+ # @param credential_type_name [String] The credential type that raised the error
57
+ # @param principal [String, Symbol] The principal for the authentication flow
58
+ # @return [Error] The new error with details
59
+ def with_details message, credential_type_name:, principal:
60
+ new(message).tap do |error|
61
+ error.instance_variable_set :@credential_type_name, credential_type_name
62
+ error.instance_variable_set :@principal, principal
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ ##
69
+ # Error raised during Credentials initialization.
70
+ # All new code should use this instead of ArgumentError during initializtion.
71
+ #
72
+ class InitializationError < StandardError
73
+ include Error
74
+ end
75
+
76
+ ##
77
+ # Generic error raised during operation of Credentials
78
+ # This should be used for all purposes not covered by other errors.
79
+ #
80
+ class CredentialsError < StandardError
81
+ include DetailedError
82
+ end
83
+
84
+ ##
85
+ # An error indicating the remote server refused to authorize the client.
86
+ # Maintains backward compatibility with Signet.
87
+ #
88
+ # Should not be used in the new code, even when wrapping `Signet::AuthorizationError`.
89
+ # New code should use CredentialsError instead.
90
+ #
91
+ class AuthorizationError < Signet::AuthorizationError
92
+ include DetailedError
93
+ end
94
+
95
+ ##
96
+ # An error indicating that the server sent an unexpected http status.
97
+ # Maintains backward compatibility with Signet.
98
+ #
99
+ # Should not be used in the new code, even when wrapping `Signet::UnexpectedStatusError`.
100
+ # New code should use CredentialsError instead.
101
+ #
102
+ class UnexpectedStatusError < Signet::UnexpectedStatusError
103
+ include DetailedError
104
+ end
105
+
106
+ ##
107
+ # An error indicating the client failed to parse a value.
108
+ # Maintains backward compatibility with Signet.
109
+ #
110
+ # Should not be used in the new code, even when wrapping `Signet::ParseError`.
111
+ # New code should use CredentialsError instead.
112
+ #
113
+ class ParseError < Signet::ParseError
114
+ include DetailedError
115
+ end
116
+ end
117
+ end