googleauth 1.8.1 → 1.9.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.
Potentially problematic release.
This version of googleauth might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/googleauth/application_default.rb +1 -5
- data/lib/googleauth/compute_engine.rb +43 -40
- data/lib/googleauth/credentials.rb +13 -6
- data/lib/googleauth/external_account/base_credentials.rb +3 -2
- data/lib/googleauth/external_account.rb +2 -1
- data/lib/googleauth/json_key_reader.rb +2 -1
- data/lib/googleauth/service_account.rb +11 -5
- data/lib/googleauth/signet.rb +12 -0
- data/lib/googleauth/user_refresh.rb +4 -2
- data/lib/googleauth/version.rb +1 -1
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9993f17d33eb7e12e34c5c865560e1352081f9ddebfd46f595bfc81cbef8465
|
4
|
+
data.tar.gz: 55a1521b2e5057c1a95cbb2cb61a9b3293d362a338cb684c0ab08a646deed75c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78f4e0778cdd6f52c7898b2da5db2e5824553aaec8b83585fbdeac1ec9d88267cf1fad3d7428d87408782f758b54b9ca8216ba3f4fb0d18c0844acf511de31f1
|
7
|
+
data.tar.gz: b6d0a6c0437a9ce59984638415e86b907231051e01044a9f1e810851ee951542ba0f5528a2d945b4e99084426b0336864840c812d154a6267ba93be781d34fda
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 1.9.0 (2023-12-07)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Include universe_domain in credentials ([#460](https://github.com/googleapis/google-auth-library-ruby/issues/460))
|
8
|
+
* Use google-cloud-env for more robust Metadata Service access ([#459](https://github.com/googleapis/google-auth-library-ruby/issues/459))
|
9
|
+
|
3
10
|
### 1.8.1 (2023-09-19)
|
4
11
|
|
5
12
|
#### Documentation
|
@@ -55,11 +55,7 @@ module Google
|
|
55
55
|
DefaultCredentials.from_well_known_path(scope, options) ||
|
56
56
|
DefaultCredentials.from_system_default_path(scope, options)
|
57
57
|
return creds unless creds.nil?
|
58
|
-
unless GCECredentials.on_gce? options
|
59
|
-
# Clear cache of the result of GCECredentials.on_gce?
|
60
|
-
GCECredentials.reset_cache
|
61
|
-
raise NOT_FOUND_ERROR
|
62
|
-
end
|
58
|
+
raise NOT_FOUND_ERROR unless GCECredentials.on_gce? options
|
63
59
|
GCECredentials.new options.merge(scope: scope)
|
64
60
|
end
|
65
61
|
end
|
@@ -12,7 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require "
|
15
|
+
require "google-cloud-env"
|
16
16
|
require "googleauth/signet"
|
17
17
|
|
18
18
|
module Google
|
@@ -33,83 +33,69 @@ module Google
|
|
33
33
|
# Extends Signet::OAuth2::Client so that the auth token is obtained from
|
34
34
|
# the GCE metadata server.
|
35
35
|
class GCECredentials < Signet::OAuth2::Client
|
36
|
-
#
|
37
|
-
# systems.
|
36
|
+
# @private Unused and deprecated but retained to prevent breaking changes
|
38
37
|
DEFAULT_METADATA_HOST = "169.254.169.254".freeze
|
39
38
|
|
40
|
-
# @private Unused and deprecated
|
39
|
+
# @private Unused and deprecated but retained to prevent breaking changes
|
41
40
|
COMPUTE_AUTH_TOKEN_URI =
|
42
41
|
"http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token".freeze
|
43
|
-
# @private Unused and deprecated
|
42
|
+
# @private Unused and deprecated but retained to prevent breaking changes
|
44
43
|
COMPUTE_ID_TOKEN_URI =
|
45
44
|
"http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity".freeze
|
46
|
-
# @private Unused and deprecated
|
45
|
+
# @private Unused and deprecated but retained to prevent breaking changes
|
47
46
|
COMPUTE_CHECK_URI = "http://169.254.169.254".freeze
|
48
47
|
|
49
|
-
@on_gce_cache = {}
|
50
|
-
|
51
48
|
class << self
|
49
|
+
# @private Unused and deprecated
|
52
50
|
def metadata_host
|
53
51
|
ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
|
54
52
|
end
|
55
53
|
|
54
|
+
# @private Unused and deprecated
|
56
55
|
def compute_check_uri
|
57
56
|
"http://#{metadata_host}".freeze
|
58
57
|
end
|
59
58
|
|
59
|
+
# @private Unused and deprecated
|
60
60
|
def compute_auth_token_uri
|
61
61
|
"#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze
|
62
62
|
end
|
63
63
|
|
64
|
+
# @private Unused and deprecated
|
64
65
|
def compute_id_token_uri
|
65
66
|
"#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze
|
66
67
|
end
|
67
68
|
|
68
69
|
# Detect if this appear to be a GCE instance, by checking if metadata
|
69
70
|
# is available.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@on_gce_cache.fetch options do
|
74
|
-
@on_gce_cache[options] = begin
|
75
|
-
# TODO: This should use google-cloud-env instead.
|
76
|
-
c = options[:connection] || Faraday.default_connection
|
77
|
-
headers = { "Metadata-Flavor" => "Google" }
|
78
|
-
resp = c.get compute_check_uri, nil, headers do |req|
|
79
|
-
req.options.timeout = 1.0
|
80
|
-
req.options.open_timeout = 0.1
|
81
|
-
end
|
82
|
-
return false unless resp.status == 200
|
83
|
-
resp.headers["Metadata-Flavor"] == "Google"
|
84
|
-
rescue Faraday::TimeoutError, Faraday::ConnectionFailed
|
85
|
-
false
|
86
|
-
end
|
87
|
-
end
|
71
|
+
# The parameters are deprecated and unused.
|
72
|
+
def on_gce? _options = {}, _reload = false # rubocop:disable Style/OptionalBooleanParameter
|
73
|
+
Google::Cloud.env.metadata?
|
88
74
|
end
|
89
75
|
|
90
76
|
def reset_cache
|
91
|
-
|
77
|
+
Google::Cloud.env.compute_metadata.reset_existence!
|
78
|
+
Google::Cloud.env.compute_metadata.cache.expire_all!
|
92
79
|
end
|
93
80
|
alias unmemoize_all reset_cache
|
94
81
|
end
|
95
82
|
|
96
83
|
# Overrides the super class method to change how access tokens are
|
97
84
|
# fetched.
|
98
|
-
def fetch_access_token
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
query
|
104
|
-
|
85
|
+
def fetch_access_token _options = {}
|
86
|
+
if token_type == :id_token
|
87
|
+
query = { "audience" => target_audience, "format" => "full" }
|
88
|
+
entry = "service-accounts/default/identity"
|
89
|
+
else
|
90
|
+
query = {}
|
91
|
+
entry = "service-accounts/default/token"
|
92
|
+
end
|
93
|
+
query[:scopes] = Array(scope).join "," if scope
|
94
|
+
begin
|
95
|
+
resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
|
105
96
|
case resp.status
|
106
97
|
when 200
|
107
|
-
|
108
|
-
if ["text/html", "application/text"].include? content_type
|
109
|
-
{ (target_audience ? "id_token" : "access_token") => resp.body }
|
110
|
-
else
|
111
|
-
Signet::OAuth2.parse_credentials resp.body, content_type
|
112
|
-
end
|
98
|
+
build_token_hash resp.body, resp.headers["content-type"]
|
113
99
|
when 403, 500
|
114
100
|
msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
|
115
101
|
raise Signet::UnexpectedStatusError, msg
|
@@ -119,8 +105,25 @@ module Google
|
|
119
105
|
msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
|
120
106
|
raise Signet::AuthorizationError, msg
|
121
107
|
end
|
108
|
+
rescue Google::Cloud::Env::MetadataServerNotResponding => e
|
109
|
+
raise Signet::AuthorizationError, e.message
|
122
110
|
end
|
123
111
|
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def build_token_hash body, content_type
|
116
|
+
hash =
|
117
|
+
if ["text/html", "application/text"].include? content_type
|
118
|
+
{ token_type.to_s => body }
|
119
|
+
else
|
120
|
+
Signet::OAuth2.parse_credentials body, content_type
|
121
|
+
end
|
122
|
+
universe_domain = Google::Cloud.env.lookup_metadata "universe", "universe_domain"
|
123
|
+
universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
|
124
|
+
hash["universe_domain"] = universe_domain.strip
|
125
|
+
hash
|
126
|
+
end
|
124
127
|
end
|
125
128
|
end
|
126
129
|
end
|
@@ -259,7 +259,7 @@ module Google
|
|
259
259
|
# @return [Object] The value
|
260
260
|
#
|
261
261
|
def self.lookup_auth_param name, method_name = name
|
262
|
-
val = instance_variable_get "@#{name}"
|
262
|
+
val = instance_variable_get :"@#{name}"
|
263
263
|
val = yield if val.nil? && block_given?
|
264
264
|
return val unless val.nil?
|
265
265
|
return superclass.send method_name if superclass.respond_to? method_name
|
@@ -328,9 +328,13 @@ module Google
|
|
328
328
|
# @return [Proc] Returns a reference to the {Signet::OAuth2::Client#apply} method,
|
329
329
|
# suitable for passing as a closure.
|
330
330
|
#
|
331
|
+
# @!attribute [rw] universe_domain
|
332
|
+
# @return [String] The universe domain issuing these credentials.
|
333
|
+
#
|
331
334
|
def_delegators :@client,
|
332
335
|
:token_credential_uri, :audience,
|
333
|
-
:scope, :issuer, :signing_key, :updater_proc, :target_audience
|
336
|
+
:scope, :issuer, :signing_key, :updater_proc, :target_audience,
|
337
|
+
:universe_domain, :universe_domain=
|
334
338
|
|
335
339
|
##
|
336
340
|
# Creates a new Credentials instance with the provided auth credentials, and with the default
|
@@ -506,12 +510,15 @@ module Google
|
|
506
510
|
|
507
511
|
needs_scope = options["target_audience"].nil?
|
508
512
|
# client options for initializing signet client
|
509
|
-
{
|
513
|
+
{
|
514
|
+
token_credential_uri: options["token_credential_uri"],
|
510
515
|
audience: options["audience"],
|
511
516
|
scope: (needs_scope ? Array(options["scope"]) : nil),
|
512
517
|
target_audience: options["target_audience"],
|
513
518
|
issuer: options["client_email"],
|
514
|
-
signing_key: OpenSSL::PKey::RSA.new(options["private_key"])
|
519
|
+
signing_key: OpenSSL::PKey::RSA.new(options["private_key"]),
|
520
|
+
universe_domain: options["universe_domain"] || "googleapis.com"
|
521
|
+
}
|
515
522
|
end
|
516
523
|
|
517
524
|
# rubocop:enable Metrics/AbcSize
|
@@ -526,7 +533,7 @@ module Google
|
|
526
533
|
hash = stringify_hash_keys hash
|
527
534
|
hash["scope"] ||= options[:scope]
|
528
535
|
hash["target_audience"] ||= options[:target_audience]
|
529
|
-
@project_id ||=
|
536
|
+
@project_id ||= hash["project_id"] || hash["project"]
|
530
537
|
@quota_project_id ||= hash["quota_project_id"]
|
531
538
|
@client = init_client hash, options
|
532
539
|
end
|
@@ -536,7 +543,7 @@ module Google
|
|
536
543
|
json = JSON.parse ::File.read(path)
|
537
544
|
json["scope"] ||= options[:scope]
|
538
545
|
json["target_audience"] ||= options[:target_audience]
|
539
|
-
@project_id ||=
|
546
|
+
@project_id ||= json["project_id"] || json["project"]
|
540
547
|
@quota_project_id ||= json["quota_project_id"]
|
541
548
|
@client = init_client json, options
|
542
549
|
end
|
@@ -42,6 +42,7 @@ module Google
|
|
42
42
|
|
43
43
|
attr_reader :expires_at
|
44
44
|
attr_accessor :access_token
|
45
|
+
attr_accessor :universe_domain
|
45
46
|
|
46
47
|
def expires_within? seconds
|
47
48
|
# This method is needed for BaseClient
|
@@ -85,8 +86,7 @@ module Google
|
|
85
86
|
# true if the credentials represent a workforce pool.
|
86
87
|
# false if they represent a workload.
|
87
88
|
def is_workforce_pool?
|
88
|
-
|
89
|
-
/#{pattern}/.match?(@audience || "")
|
89
|
+
%r{/iam\.googleapis\.com/locations/[^/]+/workforcePools/}.match?(@audience || "")
|
90
90
|
end
|
91
91
|
|
92
92
|
private
|
@@ -111,6 +111,7 @@ module Google
|
|
111
111
|
@quota_project_id = options[:quota_project_id]
|
112
112
|
@project_id = nil
|
113
113
|
@workforce_pool_user_project = options[:workforce_pool_user_project]
|
114
|
+
@universe_domain = options[:universe_domain] || "googleapis.com"
|
114
115
|
|
115
116
|
@expires_at = nil
|
116
117
|
@access_token = nil
|
@@ -73,7 +73,8 @@ module Google
|
|
73
73
|
subject_token_type: user_creds[:subject_token_type],
|
74
74
|
token_url: user_creds[:token_url],
|
75
75
|
credential_source: user_creds[:credential_source],
|
76
|
-
service_account_impersonation_url: user_creds[:service_account_impersonation_url]
|
76
|
+
service_account_impersonation_url: user_creds[:service_account_impersonation_url],
|
77
|
+
universe_domain: user_creds[:universe_domain]
|
77
78
|
)
|
78
79
|
end
|
79
80
|
|
@@ -53,12 +53,13 @@ module Google
|
|
53
53
|
raise ArgumentError, "Cannot specify both scope and target_audience" if scope && target_audience
|
54
54
|
|
55
55
|
if json_key_io
|
56
|
-
private_key, client_email, project_id, quota_project_id = read_json_key json_key_io
|
56
|
+
private_key, client_email, project_id, quota_project_id, universe_domain = read_json_key json_key_io
|
57
57
|
else
|
58
58
|
private_key = unescape ENV[CredentialsLoader::PRIVATE_KEY_VAR]
|
59
59
|
client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
|
60
60
|
project_id = ENV[CredentialsLoader::PROJECT_ID_VAR]
|
61
61
|
quota_project_id = nil
|
62
|
+
universe_domain = nil
|
62
63
|
end
|
63
64
|
project_id ||= CredentialsLoader.load_gcloud_project_id
|
64
65
|
|
@@ -70,7 +71,8 @@ module Google
|
|
70
71
|
issuer: client_email,
|
71
72
|
signing_key: OpenSSL::PKey::RSA.new(private_key),
|
72
73
|
project_id: project_id,
|
73
|
-
quota_project_id: quota_project_id
|
74
|
+
quota_project_id: quota_project_id,
|
75
|
+
universe_domain: universe_domain || "googleapis.com")
|
74
76
|
.configure_connection(options)
|
75
77
|
end
|
76
78
|
|
@@ -95,8 +97,9 @@ module Google
|
|
95
97
|
def apply! a_hash, opts = {}
|
96
98
|
# Use a self-singed JWT if there's no information that can be used to
|
97
99
|
# obtain an OAuth token, OR if there are scopes but also an assertion
|
98
|
-
# that they are default scopes that shouldn't be used to fetch a token
|
99
|
-
|
100
|
+
# that they are default scopes that shouldn't be used to fetch a token,
|
101
|
+
# OR we are not in the default universe and thus OAuth isn't supported.
|
102
|
+
if target_audience.nil? && (scope.nil? || enable_self_signed_jwt? || universe_domain != "googleapis.com")
|
100
103
|
apply_self_signed_jwt! a_hash
|
101
104
|
else
|
102
105
|
super
|
@@ -138,6 +141,7 @@ module Google
|
|
138
141
|
extend JsonKeyReader
|
139
142
|
attr_reader :project_id
|
140
143
|
attr_reader :quota_project_id
|
144
|
+
attr_accessor :universe_domain
|
141
145
|
|
142
146
|
# Create a ServiceAccountJwtHeaderCredentials.
|
143
147
|
#
|
@@ -154,14 +158,16 @@ module Google
|
|
154
158
|
def initialize options = {}
|
155
159
|
json_key_io = options[:json_key_io]
|
156
160
|
if json_key_io
|
157
|
-
@private_key, @issuer, @project_id, @quota_project_id =
|
161
|
+
@private_key, @issuer, @project_id, @quota_project_id, @universe_domain =
|
158
162
|
self.class.read_json_key json_key_io
|
159
163
|
else
|
160
164
|
@private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
|
161
165
|
@issuer = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
|
162
166
|
@project_id = ENV[CredentialsLoader::PROJECT_ID_VAR]
|
163
167
|
@quota_project_id = nil
|
168
|
+
@universe_domain = nil
|
164
169
|
end
|
170
|
+
@universe_domain ||= "googleapis.com"
|
165
171
|
@project_id ||= CredentialsLoader.load_gcloud_project_id
|
166
172
|
@signing_key = OpenSSL::PKey::RSA.new @private_key
|
167
173
|
@scope = options[:scope]
|
data/lib/googleauth/signet.rb
CHANGED
@@ -25,6 +25,15 @@ module Signet
|
|
25
25
|
class Client
|
26
26
|
include Google::Auth::BaseClient
|
27
27
|
|
28
|
+
alias update_token_signet_base update_token!
|
29
|
+
|
30
|
+
def update_token! options = {}
|
31
|
+
options = deep_hash_normalize options
|
32
|
+
update_token_signet_base options
|
33
|
+
self.universe_domain = options[:universe_domain] if options.key? :universe_domain
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
28
37
|
def configure_connection options
|
29
38
|
@connection_info =
|
30
39
|
options[:connection_builder] || options[:default_connection]
|
@@ -36,6 +45,9 @@ module Signet
|
|
36
45
|
target_audience ? :id_token : :access_token
|
37
46
|
end
|
38
47
|
|
48
|
+
# Set the universe domain
|
49
|
+
attr_accessor :universe_domain
|
50
|
+
|
39
51
|
alias orig_fetch_access_token! fetch_access_token!
|
40
52
|
def fetch_access_token! options = {}
|
41
53
|
unless options[:connection]
|
@@ -50,7 +50,8 @@ module Google
|
|
50
50
|
"client_secret" => ENV[CredentialsLoader::CLIENT_SECRET_VAR],
|
51
51
|
"refresh_token" => ENV[CredentialsLoader::REFRESH_TOKEN_VAR],
|
52
52
|
"project_id" => ENV[CredentialsLoader::PROJECT_ID_VAR],
|
53
|
-
"quota_project_id" => nil
|
53
|
+
"quota_project_id" => nil,
|
54
|
+
"universe_domain" => nil
|
54
55
|
}
|
55
56
|
new(token_credential_uri: TOKEN_CRED_URI,
|
56
57
|
client_id: user_creds["client_id"],
|
@@ -58,7 +59,8 @@ module Google
|
|
58
59
|
refresh_token: user_creds["refresh_token"],
|
59
60
|
project_id: user_creds["project_id"],
|
60
61
|
quota_project_id: user_creds["quota_project_id"],
|
61
|
-
scope: scope
|
62
|
+
scope: scope,
|
63
|
+
universe_domain: user_creds["universe_domain"] || "googleapis.com")
|
62
64
|
.configure_connection(options)
|
63
65
|
end
|
64
66
|
|
data/lib/googleauth/version.rb
CHANGED
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.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Emiola
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '1.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 3.a
|
@@ -26,10 +26,30 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0
|
29
|
+
version: '1.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 3.a
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: google-cloud-env
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.0.1
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.0.1
|
33
53
|
- !ruby/object:Gem::Dependency
|
34
54
|
name: jwt
|
35
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,7 +185,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
185
|
requirements:
|
166
186
|
- - ">="
|
167
187
|
- !ruby/object:Gem::Version
|
168
|
-
version: '2.
|
188
|
+
version: '2.7'
|
169
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
190
|
requirements:
|
171
191
|
- - ">="
|