Skip to content

Commit

Permalink
fix: update expires_in for cached metadata-retrieved tokens (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
dazuma committed Dec 12, 2023
1 parent 5e678ed commit 5a6b321
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
2 changes: 1 addition & 1 deletion googleauth.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Gem::Specification.new do |gem|
gem.required_ruby_version = ">= 2.7"

gem.add_dependency "faraday", ">= 1.0", "< 3.a"
gem.add_dependency "google-cloud-env", "~> 2.0", ">= 2.0.1"
gem.add_dependency "google-cloud-env", "~> 2.1"
gem.add_dependency "jwt", ">= 1.4", "< 3.0"
gem.add_dependency "multi_json", "~> 1.11"
gem.add_dependency "os", ">= 0.9", "< 2.0"
Expand Down
13 changes: 11 additions & 2 deletions lib/googleauth/compute_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def fetch_access_token _options = {}
resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
case resp.status
when 200
build_token_hash resp.body, resp.headers["content-type"]
build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
when 403, 500
msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
raise Signet::UnexpectedStatusError, msg
Expand All @@ -112,7 +112,7 @@ def fetch_access_token _options = {}

private

def build_token_hash body, content_type
def build_token_hash body, content_type, retrieval_time
hash =
if ["text/html", "application/text"].include? content_type
{ token_type.to_s => body }
Expand All @@ -122,6 +122,15 @@ def build_token_hash body, content_type
universe_domain = Google::Cloud.env.lookup_metadata "universe", "universe_domain"
universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
hash["universe_domain"] = universe_domain.strip
# The response might have been cached, which means expires_in might be
# stale. Update it based on the time since the data was retrieved.
# We also ensure expires_in is conservative; subtracting at least 1
# second to offset any skew from metadata server latency.
if hash["expires_in"].is_a? Numeric
offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
hash["expires_in"] -= offset if offset.positive?
hash["expires_in"] = 0 if hash["expires_in"].negative?
end
hash
end
end
Expand Down
9 changes: 9 additions & 0 deletions spec/googleauth/compute_engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ def make_auth_stubs opts
@client.fetch_access_token!
expect(@client.universe_domain).to eq("googleapis.com")
end

it "returns a consistent expiry using cached data" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expiry = @client.expires_at
sleep 1
@client.fetch_access_token!
expect(@client.expires_at.to_f).to be_within(0.1).of(expiry.to_f)
end
end

context "custom universe" do
Expand Down
2 changes: 1 addition & 1 deletion spec/googleauth/external_account_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

describe Google::Auth::ExternalAccount::Credentials do

describe "universe_domain checks", :focus do
describe "universe_domain checks" do
before :example do
@tempfile = Tempfile.new("aws")
end
Expand Down

0 comments on commit 5a6b321

Please sign in to comment.