googleauth 1.14.0 → 1.16.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 +4 -4
- data/CHANGELOG.md +30 -0
- data/Credentials.md +110 -0
- data/Errors.md +152 -0
- data/README.md +0 -1
- data/lib/googleauth/api_key.rb +9 -0
- data/lib/googleauth/application_default.rb +3 -1
- data/lib/googleauth/base_client.rb +5 -0
- data/lib/googleauth/bearer_token.rb +16 -2
- data/lib/googleauth/client_id.rb +9 -5
- data/lib/googleauth/compute_engine.rb +64 -18
- data/lib/googleauth/credentials.rb +67 -35
- data/lib/googleauth/credentials_loader.rb +24 -4
- data/lib/googleauth/default_credentials.rb +67 -32
- data/lib/googleauth/errors.rb +117 -0
- data/lib/googleauth/external_account/aws_credentials.rb +85 -18
- data/lib/googleauth/external_account/base_credentials.rb +31 -2
- data/lib/googleauth/external_account/external_account_utils.rb +15 -4
- data/lib/googleauth/external_account/identity_pool_credentials.rb +40 -15
- data/lib/googleauth/external_account/pluggable_credentials.rb +34 -19
- data/lib/googleauth/external_account.rb +44 -6
- data/lib/googleauth/iam.rb +19 -3
- data/lib/googleauth/id_tokens/errors.rb +13 -7
- data/lib/googleauth/id_tokens/key_sources.rb +13 -7
- data/lib/googleauth/id_tokens/verifier.rb +2 -3
- data/lib/googleauth/id_tokens.rb +4 -4
- data/lib/googleauth/impersonated_service_account.rb +117 -18
- data/lib/googleauth/json_key_reader.rb +11 -2
- data/lib/googleauth/oauth2/sts_client.rb +9 -4
- data/lib/googleauth/scope_util.rb +1 -1
- data/lib/googleauth/service_account.rb +37 -10
- data/lib/googleauth/service_account_jwt_header.rb +9 -2
- data/lib/googleauth/signet.rb +24 -6
- data/lib/googleauth/user_authorizer.rb +35 -7
- data/lib/googleauth/user_refresh.rb +42 -16
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +46 -9
- data/lib/googleauth.rb +1 -0
- metadata +8 -5
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
require "forwardable"
|
|
16
16
|
require "json"
|
|
17
|
+
require "pathname"
|
|
17
18
|
require "signet/oauth_2/client"
|
|
19
|
+
require "multi_json"
|
|
18
20
|
|
|
19
21
|
require "googleauth/credentials_loader"
|
|
22
|
+
require "googleauth/errors"
|
|
20
23
|
|
|
21
24
|
module Google
|
|
22
25
|
module Auth
|
|
@@ -357,12 +360,13 @@ module Google
|
|
|
357
360
|
# Creates a new Credentials instance with the provided auth credentials, and with the default
|
|
358
361
|
# values configured on the class.
|
|
359
362
|
#
|
|
360
|
-
# @param [String, Hash,
|
|
363
|
+
# @param [String, Pathname, Hash, Google::Auth::BaseClient] source_creds
|
|
361
364
|
# The source of credentials. It can be provided as one of the following:
|
|
362
365
|
#
|
|
363
|
-
# * The path to a JSON keyfile (as a `String`)
|
|
366
|
+
# * The path to a JSON keyfile (as a `String` or a `Pathname`)
|
|
364
367
|
# * The contents of a JSON keyfile (as a `Hash`)
|
|
365
|
-
# * A `
|
|
368
|
+
# * A `Google::Auth::BaseClient` credentials object, including but not limited to
|
|
369
|
+
# a `Signet::OAuth2::Client` object.
|
|
366
370
|
# * Any credentials object that supports the methods this wrapper delegates to an inner client.
|
|
367
371
|
#
|
|
368
372
|
# If this parameter is an object (`Signet::OAuth2::Client` or other) it will be used as an inner client.
|
|
@@ -391,14 +395,20 @@ module Google
|
|
|
391
395
|
# parameters of the `Signet::OAuth2::Client`, such as connection parameters,
|
|
392
396
|
# timeouts, etc.
|
|
393
397
|
#
|
|
398
|
+
# @raise [Google::Auth::InitializationError] If source_creds is nil
|
|
399
|
+
# @raise [ArgumentError] If both scope and target_audience are specified
|
|
400
|
+
#
|
|
394
401
|
def initialize source_creds, options = {}
|
|
395
|
-
|
|
402
|
+
if source_creds.nil?
|
|
403
|
+
raise InitializationError,
|
|
404
|
+
"The source credentials passed to Google::Auth::Credentials.new were nil."
|
|
405
|
+
end
|
|
396
406
|
|
|
397
407
|
options = symbolize_hash_keys options
|
|
398
408
|
@project_id = options[:project_id] || options[:project]
|
|
399
409
|
@quota_project_id = options[:quota_project_id]
|
|
400
410
|
case source_creds
|
|
401
|
-
when String
|
|
411
|
+
when String, Pathname
|
|
402
412
|
update_from_filepath source_creds, options
|
|
403
413
|
when Hash
|
|
404
414
|
update_from_hash source_creds, options
|
|
@@ -499,17 +509,61 @@ module Google
|
|
|
499
509
|
token_credential_uri: options[:token_credential_uri] || token_credential_uri,
|
|
500
510
|
audience: options[:audience] || audience
|
|
501
511
|
}
|
|
502
|
-
|
|
512
|
+
|
|
513
|
+
# Determine the class, which consumes the IO stream
|
|
514
|
+
json_key, clz = Google::Auth::DefaultCredentials.determine_creds_class creds_input[:json_key_io]
|
|
515
|
+
|
|
516
|
+
# Re-serialize the parsed JSON and replace the IO stream in creds_input
|
|
517
|
+
creds_input[:json_key_io] = StringIO.new MultiJson.dump(json_key)
|
|
518
|
+
|
|
519
|
+
client = clz.make_creds creds_input
|
|
503
520
|
options = options.select { |k, _v| k == :logger }
|
|
504
521
|
new client, options
|
|
505
522
|
end
|
|
506
523
|
|
|
524
|
+
# @private
|
|
525
|
+
# Initializes the Signet client.
|
|
526
|
+
def self.init_client hash, options = {}
|
|
527
|
+
options = update_client_options options
|
|
528
|
+
io = StringIO.new JSON.generate hash
|
|
529
|
+
|
|
530
|
+
# Determine the class, which consumes the IO stream
|
|
531
|
+
json_key, clz = Google::Auth::DefaultCredentials.determine_creds_class io
|
|
532
|
+
|
|
533
|
+
# Re-serialize the parsed JSON and create a new IO stream.
|
|
534
|
+
new_io = StringIO.new MultiJson.dump(json_key)
|
|
535
|
+
|
|
536
|
+
clz.make_creds options.merge!(json_key_io: new_io)
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# @private
|
|
540
|
+
# Updates client options with defaults from the credential class
|
|
541
|
+
#
|
|
542
|
+
# @param [Hash] options Options to update
|
|
543
|
+
# @return [Hash] Updated options hash
|
|
544
|
+
# @raise [ArgumentError] If both scope and target_audience are specified
|
|
545
|
+
def self.update_client_options options
|
|
546
|
+
options = options.dup
|
|
547
|
+
|
|
548
|
+
# options have higher priority over constructor defaults
|
|
549
|
+
options[:token_credential_uri] ||= token_credential_uri
|
|
550
|
+
options[:audience] ||= audience
|
|
551
|
+
options[:scope] ||= scope
|
|
552
|
+
options[:target_audience] ||= target_audience
|
|
553
|
+
|
|
554
|
+
if !Array(options[:scope]).empty? && options[:target_audience]
|
|
555
|
+
raise ArgumentError, "Cannot specify both scope and target_audience"
|
|
556
|
+
end
|
|
557
|
+
options.delete :scope unless options[:target_audience].nil?
|
|
558
|
+
|
|
559
|
+
options
|
|
560
|
+
end
|
|
561
|
+
|
|
507
562
|
private_class_method :from_env_vars,
|
|
508
563
|
:from_default_paths,
|
|
509
564
|
:from_application_default,
|
|
510
565
|
:from_io
|
|
511
566
|
|
|
512
|
-
|
|
513
567
|
# Creates a duplicate of these credentials. This method tries to create the duplicate of the
|
|
514
568
|
# wrapped credentials if they support duplication and use them as is if they don't.
|
|
515
569
|
#
|
|
@@ -554,17 +608,12 @@ module Google
|
|
|
554
608
|
protected
|
|
555
609
|
|
|
556
610
|
# Verify that the keyfile argument is a file.
|
|
611
|
+
#
|
|
612
|
+
# @param [String] keyfile Path to the keyfile
|
|
613
|
+
# @raise [Google::Auth::InitializationError] If the keyfile does not exist
|
|
557
614
|
def verify_keyfile_exists! keyfile
|
|
558
615
|
exists = ::File.file? keyfile
|
|
559
|
-
raise "The keyfile '#{keyfile}' is not a valid file." unless exists
|
|
560
|
-
end
|
|
561
|
-
|
|
562
|
-
# Initializes the Signet client.
|
|
563
|
-
def init_client hash, options = {}
|
|
564
|
-
options = update_client_options options
|
|
565
|
-
io = StringIO.new JSON.generate hash
|
|
566
|
-
options.merge! json_key_io: io
|
|
567
|
-
Google::Auth::DefaultCredentials.make_creds options
|
|
616
|
+
raise InitializationError, "The keyfile '#{keyfile}' is not a valid file." unless exists
|
|
568
617
|
end
|
|
569
618
|
|
|
570
619
|
# returns a new Hash with string keys instead of symbol keys.
|
|
@@ -577,23 +626,6 @@ module Google
|
|
|
577
626
|
hash.to_h.transform_keys(&:to_sym)
|
|
578
627
|
end
|
|
579
628
|
|
|
580
|
-
def update_client_options options
|
|
581
|
-
options = options.dup
|
|
582
|
-
|
|
583
|
-
# options have higher priority over constructor defaults
|
|
584
|
-
options[:token_credential_uri] ||= self.class.token_credential_uri
|
|
585
|
-
options[:audience] ||= self.class.audience
|
|
586
|
-
options[:scope] ||= self.class.scope
|
|
587
|
-
options[:target_audience] ||= self.class.target_audience
|
|
588
|
-
|
|
589
|
-
if !Array(options[:scope]).empty? && options[:target_audience]
|
|
590
|
-
raise ArgumentError, "Cannot specify both scope and target_audience"
|
|
591
|
-
end
|
|
592
|
-
options.delete :scope unless options[:target_audience].nil?
|
|
593
|
-
|
|
594
|
-
options
|
|
595
|
-
end
|
|
596
|
-
|
|
597
629
|
def update_from_client client
|
|
598
630
|
@project_id ||= client.project_id if client.respond_to? :project_id
|
|
599
631
|
@quota_project_id ||= client.quota_project_id if client.respond_to? :quota_project_id
|
|
@@ -607,7 +639,7 @@ module Google
|
|
|
607
639
|
hash["target_audience"] ||= options[:target_audience]
|
|
608
640
|
@project_id ||= hash["project_id"] || hash["project"]
|
|
609
641
|
@quota_project_id ||= hash["quota_project_id"]
|
|
610
|
-
@client = init_client hash, options
|
|
642
|
+
@client = self.class.init_client hash, options
|
|
611
643
|
end
|
|
612
644
|
|
|
613
645
|
def update_from_filepath path, options
|
|
@@ -617,7 +649,7 @@ module Google
|
|
|
617
649
|
json["target_audience"] ||= options[:target_audience]
|
|
618
650
|
@project_id ||= json["project_id"] || json["project"]
|
|
619
651
|
@quota_project_id ||= json["quota_project_id"]
|
|
620
|
-
@client = init_client json, options
|
|
652
|
+
@client = self.class.init_client json, options
|
|
621
653
|
end
|
|
622
654
|
|
|
623
655
|
def setup_logging logger: :default
|
|
@@ -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.
|
|
@@ -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
|
|
@@ -153,6 +158,21 @@ module Google
|
|
|
153
158
|
nil
|
|
154
159
|
end
|
|
155
160
|
|
|
161
|
+
# @private
|
|
162
|
+
# Loads a JSON key from an IO object, verifies its type, and rewinds the IO.
|
|
163
|
+
#
|
|
164
|
+
# @param json_key_io [IO] An IO object containing the JSON key.
|
|
165
|
+
# @param expected_type [String] The expected credential type name.
|
|
166
|
+
# @raise [Google::Auth::InitializationError] If the JSON key type does not match the expected type.
|
|
167
|
+
def load_and_verify_json_key_type json_key_io, expected_type
|
|
168
|
+
json_key = MultiJson.load json_key_io.read
|
|
169
|
+
json_key_io.rewind # Rewind the stream so it can be read again.
|
|
170
|
+
return if json_key["type"] == expected_type
|
|
171
|
+
raise Google::Auth::InitializationError,
|
|
172
|
+
"The provided credentials were not of type '#{expected_type}'. " \
|
|
173
|
+
"Instead, the type was '#{json_key['type']}'."
|
|
174
|
+
end
|
|
175
|
+
|
|
156
176
|
private
|
|
157
177
|
|
|
158
178
|
def interpret_options scope, options
|
|
@@ -16,10 +16,12 @@ require "multi_json"
|
|
|
16
16
|
require "stringio"
|
|
17
17
|
|
|
18
18
|
require "googleauth/credentials_loader"
|
|
19
|
+
require "googleauth/errors"
|
|
19
20
|
require "googleauth/external_account"
|
|
20
21
|
require "googleauth/service_account"
|
|
21
22
|
require "googleauth/service_account_jwt_header"
|
|
22
23
|
require "googleauth/user_refresh"
|
|
24
|
+
require "googleauth/impersonated_service_account"
|
|
23
25
|
|
|
24
26
|
module Google
|
|
25
27
|
# Module Auth provides classes that provide Google-specific authorization
|
|
@@ -42,50 +44,83 @@ module Google
|
|
|
42
44
|
# information, refer to [Validate credential configurations from external
|
|
43
45
|
# sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
|
|
44
46
|
#
|
|
47
|
+
# @deprecated This method is deprecated and will be removed in a future version.
|
|
48
|
+
# Please use the `make_creds` method on the specific credential class you intend to load,
|
|
49
|
+
# e.g., `Google::Auth::ServiceAccountCredentials.make_creds`.
|
|
50
|
+
#
|
|
51
|
+
# This method does not validate the credential configuration. The security
|
|
52
|
+
# risk occurs when a credential configuration is accepted from a source that
|
|
53
|
+
# is not under your control and used without validation on your side.
|
|
54
|
+
#
|
|
55
|
+
# If you know that you will be loading credential configurations of a
|
|
56
|
+
# specific type, it is recommended to use a credential-type-specific
|
|
57
|
+
# `make_creds` method.
|
|
58
|
+
# This will ensure that an unexpected credential type with potential for
|
|
59
|
+
# malicious intent is not loaded unintentionally. You might still have to do
|
|
60
|
+
# validation for certain credential types. Please follow the recommendation
|
|
61
|
+
# for that method. For example, if you want to load only service accounts,
|
|
62
|
+
# you can use:
|
|
63
|
+
# ```
|
|
64
|
+
# creds = Google::Auth::ServiceAccountCredentials.make_creds
|
|
65
|
+
# ```
|
|
66
|
+
# @see Google::Auth::ServiceAccountCredentials.make_creds
|
|
67
|
+
#
|
|
68
|
+
# If you are loading your credential configuration from an untrusted source and have
|
|
69
|
+
# not mitigated the risks (e.g. by validating the configuration yourself), make
|
|
70
|
+
# these changes as soon as possible to prevent security risks to your environment.
|
|
71
|
+
#
|
|
72
|
+
# Regardless of the method used, it is always your responsibility to validate
|
|
73
|
+
# configurations received from external sources.
|
|
74
|
+
#
|
|
75
|
+
# See https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.
|
|
76
|
+
#
|
|
77
|
+
# @param options [Hash] Options for creating the credentials
|
|
78
|
+
# @return [Google::Auth::Credentials] The credentials instance
|
|
79
|
+
# @raise [Google::Auth::InitializationError] If the credentials cannot be determined
|
|
45
80
|
def self.make_creds options = {}
|
|
46
81
|
json_key_io = options[:json_key_io]
|
|
47
|
-
|
|
48
|
-
|
|
82
|
+
json_key, clz = determine_creds_class json_key_io
|
|
83
|
+
if json_key
|
|
49
84
|
io = StringIO.new MultiJson.dump(json_key)
|
|
50
85
|
clz.make_creds options.merge(json_key_io: io)
|
|
51
86
|
else
|
|
52
|
-
clz = read_creds
|
|
53
87
|
clz.make_creds options
|
|
54
88
|
end
|
|
55
89
|
end
|
|
56
90
|
|
|
57
|
-
def self.read_creds
|
|
58
|
-
env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
|
|
59
|
-
type = ENV[env_var]
|
|
60
|
-
raise "#{env_var} is undefined in env" unless type
|
|
61
|
-
case type
|
|
62
|
-
when "service_account"
|
|
63
|
-
ServiceAccountCredentials
|
|
64
|
-
when "authorized_user"
|
|
65
|
-
UserRefreshCredentials
|
|
66
|
-
when "external_account"
|
|
67
|
-
ExternalAccount::Credentials
|
|
68
|
-
else
|
|
69
|
-
raise "credentials type '#{type}' is not supported"
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
91
|
# Reads the input json and determines which creds class to use.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
[
|
|
92
|
+
#
|
|
93
|
+
# @param json_key_io [IO, nil] An optional IO object containing the JSON key.
|
|
94
|
+
# If nil, the credential type is determined from environment variables.
|
|
95
|
+
# @return [Array(Hash, Class)] The JSON key (or nil if from environment) and the credential class to use
|
|
96
|
+
# @raise [Google::Auth::InitializationError] If the JSON is missing the type field or has an unsupported type,
|
|
97
|
+
# or if the environment variable is undefined or unsupported.
|
|
98
|
+
def self.determine_creds_class json_key_io = nil
|
|
99
|
+
if json_key_io
|
|
100
|
+
json_key = MultiJson.load json_key_io.read
|
|
101
|
+
key = "type"
|
|
102
|
+
raise InitializationError, "the json is missing the '#{key}' field" unless json_key.key? key
|
|
103
|
+
type = json_key[key]
|
|
86
104
|
else
|
|
87
|
-
|
|
105
|
+
env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
|
|
106
|
+
type = ENV[env_var]
|
|
107
|
+
raise InitializationError, "#{env_var} is undefined in env" unless type
|
|
108
|
+
json_key = nil
|
|
88
109
|
end
|
|
110
|
+
|
|
111
|
+
clz = case type
|
|
112
|
+
when ServiceAccountCredentials::CREDENTIAL_TYPE_NAME
|
|
113
|
+
ServiceAccountCredentials
|
|
114
|
+
when UserRefreshCredentials::CREDENTIAL_TYPE_NAME
|
|
115
|
+
UserRefreshCredentials
|
|
116
|
+
when ExternalAccount::Credentials::CREDENTIAL_TYPE_NAME
|
|
117
|
+
ExternalAccount::Credentials
|
|
118
|
+
when ImpersonatedServiceAccountCredentials::CREDENTIAL_TYPE_NAME
|
|
119
|
+
ImpersonatedServiceAccountCredentials
|
|
120
|
+
else
|
|
121
|
+
raise InitializationError, "credentials type '#{type}' is not supported"
|
|
122
|
+
end
|
|
123
|
+
[json_key, clz]
|
|
89
124
|
end
|
|
90
125
|
end
|
|
91
126
|
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
|