From 516c1728cb85616737eb5e54c6d20312513b8928 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 8 Jun 2026 20:33:17 +0000 Subject: [PATCH] fix: repair impersonated email helper (#577) --- .../external_account_utils.rb | 9 +--- .../external_account_utils_spec.rb | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 spec/googleauth/external_account/external_account_utils_spec.rb diff --git a/lib/googleauth/external_account/external_account_utils.rb b/lib/googleauth/external_account/external_account_utils.rb index fe45df18..734426fa 100644 --- a/lib/googleauth/external_account/external_account_utils.rb +++ b/lib/googleauth/external_account/external_account_utils.rb @@ -101,13 +101,8 @@ def normalize_timestamp time # service_account_impersonation_url, or nil if it cannot be determined def service_account_email return nil if @service_account_impersonation_url.nil? - start_idx = @service_account_impersonation_url.rindex "/" - end_idx = @service_account_impersonation_url.index ":generateAccessToken" - if start_idx != -1 && end_idx != -1 && start_idx < end_idx - start_idx += 1 - return @service_account_impersonation_url[start_idx..end_idx] - end - nil + match = @service_account_impersonation_url.match %r{serviceAccounts/([^:]+):generateAccessToken$} + match[1] if match end end end diff --git a/spec/googleauth/external_account/external_account_utils_spec.rb b/spec/googleauth/external_account/external_account_utils_spec.rb new file mode 100644 index 00000000..5b84d6ed --- /dev/null +++ b/spec/googleauth/external_account/external_account_utils_spec.rb @@ -0,0 +1,51 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "spec_helper" +require "googleauth" + +describe Google::Auth::ExternalAccount::ExternalAccountUtils do + let(:dummy_class) do + Class.new do + include Google::Auth::ExternalAccount::ExternalAccountUtils + attr_accessor :service_account_impersonation_url + end + end + let(:instance) { dummy_class.new } + + describe "#service_account_email" do + context "when impersonation URL is present" do + it "extracts the email correctly without a trailing colon" do + instance.service_account_impersonation_url = + "https://us-east1-iamcredentials.googleapis.com/v1/projects/-/" \ + "serviceAccounts/service-1234@project-name.iam.gserviceaccount.com:generateAccessToken" + expect(instance.service_account_email).to eq("service-1234@project-name.iam.gserviceaccount.com") + end + end + + context "when impersonation URL is nil" do + it "returns nil" do + instance.service_account_impersonation_url = nil + expect(instance.service_account_email).to be_nil + end + end + + context "when impersonation URL format is invalid" do + it "returns nil" do + instance.service_account_impersonation_url = "https://invalid/format/url" + expect(instance.service_account_email).to be_nil + end + end + end +end