googleauth 1.14.0 → 1.17.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 +49 -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 +15 -7
- data/lib/googleauth/compute_engine.rb +64 -18
- data/lib/googleauth/credentials.rb +66 -35
- data/lib/googleauth/credentials_loader.rb +30 -5
- data/lib/googleauth/default_credentials.rb +69 -34
- data/lib/googleauth/errors.rb +117 -0
- data/lib/googleauth/external_account/aws_credentials.rb +87 -19
- data/lib/googleauth/external_account/base_credentials.rb +34 -4
- data/lib/googleauth/external_account/external_account_utils.rb +17 -5
- data/lib/googleauth/external_account/identity_pool_credentials.rb +42 -16
- data/lib/googleauth/external_account/pluggable_credentials.rb +37 -21
- data/lib/googleauth/external_account.rb +53 -7
- data/lib/googleauth/iam.rb +20 -4
- 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 +119 -19
- data/lib/googleauth/json_key_reader.rb +17 -3
- data/lib/googleauth/oauth2/sts_client.rb +12 -6
- data/lib/googleauth/scope_util.rb +2 -2
- data/lib/googleauth/service_account.rb +55 -21
- data/lib/googleauth/service_account_jwt_header.rb +9 -2
- data/lib/googleauth/signet.rb +30 -10
- data/lib/googleauth/user_authorizer.rb +38 -10
- data/lib/googleauth/user_refresh.rb +54 -19
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +54 -17
- data/lib/googleauth.rb +1 -0
- metadata +22 -19
|
@@ -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,
|
|
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 `
|
|
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
|
-
|
|
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
|
|
@@ -499,17 +508,61 @@ module Google
|
|
|
499
508
|
token_credential_uri: options[:token_credential_uri] || token_credential_uri,
|
|
500
509
|
audience: options[:audience] || audience
|
|
501
510
|
}
|
|
502
|
-
|
|
511
|
+
|
|
512
|
+
# Determine the class, which consumes the IO stream
|
|
513
|
+
json_key, clz = Google::Auth::DefaultCredentials.determine_creds_class creds_input[:json_key_io]
|
|
514
|
+
|
|
515
|
+
# Re-serialize the parsed JSON and replace the IO stream in creds_input
|
|
516
|
+
creds_input[:json_key_io] = StringIO.new JSON.generate(json_key)
|
|
517
|
+
|
|
518
|
+
client = clz.make_creds creds_input
|
|
503
519
|
options = options.select { |k, _v| k == :logger }
|
|
504
520
|
new client, options
|
|
505
521
|
end
|
|
506
522
|
|
|
523
|
+
# @private
|
|
524
|
+
# Initializes the Signet client.
|
|
525
|
+
def self.init_client hash, options = {}
|
|
526
|
+
options = update_client_options options
|
|
527
|
+
io = StringIO.new JSON.generate hash
|
|
528
|
+
|
|
529
|
+
# Determine the class, which consumes the IO stream
|
|
530
|
+
json_key, clz = Google::Auth::DefaultCredentials.determine_creds_class io
|
|
531
|
+
|
|
532
|
+
# Re-serialize the parsed JSON and create a new IO stream.
|
|
533
|
+
new_io = StringIO.new JSON.generate(json_key)
|
|
534
|
+
|
|
535
|
+
clz.make_creds options.merge!(json_key_io: new_io)
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# @private
|
|
539
|
+
# Updates client options with defaults from the credential class
|
|
540
|
+
#
|
|
541
|
+
# @param [Hash] options Options to update
|
|
542
|
+
# @return [Hash] Updated options hash
|
|
543
|
+
# @raise [ArgumentError] If both scope and target_audience are specified
|
|
544
|
+
def self.update_client_options options
|
|
545
|
+
options = options.dup
|
|
546
|
+
|
|
547
|
+
# options have higher priority over constructor defaults
|
|
548
|
+
options[:token_credential_uri] ||= token_credential_uri
|
|
549
|
+
options[:audience] ||= audience
|
|
550
|
+
options[:scope] ||= scope
|
|
551
|
+
options[:target_audience] ||= target_audience
|
|
552
|
+
|
|
553
|
+
if !Array(options[:scope]).empty? && options[:target_audience]
|
|
554
|
+
raise ArgumentError, "Cannot specify both scope and target_audience"
|
|
555
|
+
end
|
|
556
|
+
options.delete :scope unless options[:target_audience].nil?
|
|
557
|
+
|
|
558
|
+
options
|
|
559
|
+
end
|
|
560
|
+
|
|
507
561
|
private_class_method :from_env_vars,
|
|
508
562
|
:from_default_paths,
|
|
509
563
|
:from_application_default,
|
|
510
564
|
:from_io
|
|
511
565
|
|
|
512
|
-
|
|
513
566
|
# Creates a duplicate of these credentials. This method tries to create the duplicate of the
|
|
514
567
|
# wrapped credentials if they support duplication and use them as is if they don't.
|
|
515
568
|
#
|
|
@@ -554,17 +607,12 @@ module Google
|
|
|
554
607
|
protected
|
|
555
608
|
|
|
556
609
|
# Verify that the keyfile argument is a file.
|
|
610
|
+
#
|
|
611
|
+
# @param [String] keyfile Path to the keyfile
|
|
612
|
+
# @raise [Google::Auth::InitializationError] If the keyfile does not exist
|
|
557
613
|
def verify_keyfile_exists! keyfile
|
|
558
614
|
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
|
|
615
|
+
raise InitializationError, "The keyfile '#{keyfile}' is not a valid file." unless exists
|
|
568
616
|
end
|
|
569
617
|
|
|
570
618
|
# returns a new Hash with string keys instead of symbol keys.
|
|
@@ -577,23 +625,6 @@ module Google
|
|
|
577
625
|
hash.to_h.transform_keys(&:to_sym)
|
|
578
626
|
end
|
|
579
627
|
|
|
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
628
|
def update_from_client client
|
|
598
629
|
@project_id ||= client.project_id if client.respond_to? :project_id
|
|
599
630
|
@quota_project_id ||= client.quota_project_id if client.respond_to? :quota_project_id
|
|
@@ -607,7 +638,7 @@ module Google
|
|
|
607
638
|
hash["target_audience"] ||= options[:target_audience]
|
|
608
639
|
@project_id ||= hash["project_id"] || hash["project"]
|
|
609
640
|
@quota_project_id ||= hash["quota_project_id"]
|
|
610
|
-
@client = init_client hash, options
|
|
641
|
+
@client = self.class.init_client hash, options
|
|
611
642
|
end
|
|
612
643
|
|
|
613
644
|
def update_from_filepath path, options
|
|
@@ -617,7 +648,7 @@ module Google
|
|
|
617
648
|
json["target_audience"] ||= options[:target_audience]
|
|
618
649
|
@project_id ||= json["project_id"] || json["project"]
|
|
619
650
|
@quota_project_id ||= json["quota_project_id"]
|
|
620
|
-
@client = init_client json, options
|
|
651
|
+
@client = self.class.init_client json, options
|
|
621
652
|
end
|
|
622
653
|
|
|
623
654
|
def setup_logging logger: :default
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
require "os"
|
|
16
16
|
require "rbconfig"
|
|
17
|
+
require "json"
|
|
18
|
+
|
|
19
|
+
require "googleauth/errors"
|
|
17
20
|
|
|
18
21
|
module Google
|
|
19
22
|
# Module Auth provides classes that provide Google-specific authorization
|
|
@@ -71,11 +74,12 @@ module Google
|
|
|
71
74
|
# The following keys are recognized:
|
|
72
75
|
# * `:default_connection` The connection object to use.
|
|
73
76
|
# * `:connection_builder` A `Proc` that returns a connection.
|
|
77
|
+
# @raise [Google::Auth::InitializationError] If the credentials file cannot be read
|
|
74
78
|
def from_env scope = nil, options = {}
|
|
75
79
|
options = interpret_options scope, options
|
|
76
80
|
if ENV.key?(ENV_VAR) && !ENV[ENV_VAR].empty?
|
|
77
81
|
path = ENV[ENV_VAR]
|
|
78
|
-
raise "file #{path} does not exist" unless File.exist? path
|
|
82
|
+
raise InitializationError, "file #{path} does not exist" unless File.exist? path
|
|
79
83
|
File.open path do |f|
|
|
80
84
|
return make_creds options.merge(json_key_io: f)
|
|
81
85
|
end
|
|
@@ -83,7 +87,7 @@ module Google
|
|
|
83
87
|
make_creds options
|
|
84
88
|
end
|
|
85
89
|
rescue StandardError => e
|
|
86
|
-
raise "#{NOT_FOUND_ERROR}: #{e}"
|
|
90
|
+
raise InitializationError, "#{NOT_FOUND_ERROR}: #{e}"
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
# Creates an instance from a well known path.
|
|
@@ -97,6 +101,7 @@ module Google
|
|
|
97
101
|
# The following keys are recognized:
|
|
98
102
|
# * `:default_connection` The connection object to use.
|
|
99
103
|
# * `:connection_builder` A `Proc` that returns a connection.
|
|
104
|
+
# @raise [Google::Auth::InitializationError] If the credentials file cannot be read
|
|
100
105
|
def from_well_known_path scope = nil, options = {}
|
|
101
106
|
options = interpret_options scope, options
|
|
102
107
|
home_var = OS.windows? ? "APPDATA" : "HOME"
|
|
@@ -109,7 +114,7 @@ module Google
|
|
|
109
114
|
return make_creds options.merge(json_key_io: f)
|
|
110
115
|
end
|
|
111
116
|
rescue StandardError => e
|
|
112
|
-
raise "#{WELL_KNOWN_ERROR}: #{e}"
|
|
117
|
+
raise InitializationError, "#{WELL_KNOWN_ERROR}: #{e}"
|
|
113
118
|
end
|
|
114
119
|
|
|
115
120
|
# Creates an instance from the system default path
|
|
@@ -123,6 +128,7 @@ module Google
|
|
|
123
128
|
# The following keys are recognized:
|
|
124
129
|
# * `:default_connection` The connection object to use.
|
|
125
130
|
# * `:connection_builder` A `Proc` that returns a connection.
|
|
131
|
+
# @raise [Google::Auth::InitializationError] If the credentials file cannot be read or is invalid
|
|
126
132
|
def from_system_default_path scope = nil, options = {}
|
|
127
133
|
options = interpret_options scope, options
|
|
128
134
|
if OS.windows?
|
|
@@ -137,7 +143,7 @@ module Google
|
|
|
137
143
|
return make_creds options.merge(json_key_io: f)
|
|
138
144
|
end
|
|
139
145
|
rescue StandardError => e
|
|
140
|
-
raise "#{SYSTEM_DEFAULT_ERROR}: #{e}"
|
|
146
|
+
raise InitializationError, "#{SYSTEM_DEFAULT_ERROR}: #{e}"
|
|
141
147
|
end
|
|
142
148
|
|
|
143
149
|
module_function
|
|
@@ -147,12 +153,31 @@ module Google
|
|
|
147
153
|
gcloud = GCLOUD_WINDOWS_COMMAND if OS.windows?
|
|
148
154
|
gcloud = GCLOUD_POSIX_COMMAND unless OS.windows?
|
|
149
155
|
gcloud_json = IO.popen("#{gcloud} #{GCLOUD_CONFIG_COMMAND}", err: :close, &:read)
|
|
150
|
-
config =
|
|
156
|
+
config = JSON.parse gcloud_json
|
|
151
157
|
config["configuration"]["properties"]["core"]["project"]
|
|
152
158
|
rescue StandardError
|
|
153
159
|
nil
|
|
154
160
|
end
|
|
155
161
|
|
|
162
|
+
# @private
|
|
163
|
+
# Loads a JSON key from an IO object, verifies its type, and rewinds the IO.
|
|
164
|
+
#
|
|
165
|
+
# @param json_key_io [IO] An IO object containing the JSON key.
|
|
166
|
+
# @param expected_type [String] The expected credential type name.
|
|
167
|
+
# @raise [Google::Auth::InitializationError] If the JSON key type does not match the expected type.
|
|
168
|
+
def load_and_verify_json_key_type json_key_io, expected_type
|
|
169
|
+
begin
|
|
170
|
+
json_key = JSON.parse json_key_io.read
|
|
171
|
+
rescue JSON::ParserError => e
|
|
172
|
+
raise Google::Auth::InitializationError, "Invalid JSON keyfile format: #{e.message}"
|
|
173
|
+
end
|
|
174
|
+
json_key_io.rewind # Rewind the stream so it can be read again.
|
|
175
|
+
return if json_key["type"] == expected_type
|
|
176
|
+
raise Google::Auth::InitializationError,
|
|
177
|
+
"The provided credentials were not of type '#{expected_type}'. " \
|
|
178
|
+
"Instead, the type was '#{json_key['type']}'."
|
|
179
|
+
end
|
|
180
|
+
|
|
156
181
|
private
|
|
157
182
|
|
|
158
183
|
def interpret_options scope, options
|
|
@@ -12,14 +12,16 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
require "
|
|
15
|
+
require "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
|
-
|
|
49
|
-
io = StringIO.new
|
|
82
|
+
json_key, clz = determine_creds_class json_key_io
|
|
83
|
+
if json_key
|
|
84
|
+
io = StringIO.new JSON.generate(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 = JSON.parse 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
|