Skip to content

Commit

Permalink
expose project_id method
Browse files Browse the repository at this point in the history
  • Loading branch information
BigTailWolf committed Mar 18, 2023
1 parent a4acba7 commit ba8349e
Showing 1 changed file with 66 additions and 6 deletions.
72 changes: 66 additions & 6 deletions lib/googleauth/external_account/base_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ module BaseCredentials
# Contains all methods needed for all external account credentials.
# Other credentials should call `base_setup` during initialization
# And should define the :retrieve_subject_token method

# External account JSON type identifier.
EXTERNAL_ACCOUNT_JSON_TYPE = "external_account".freeze
# The token exchange grant_type used for exchanging credentials.
STS_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange".freeze
# The token exchange requested_token_type. This is always an access_token.
STS_REQUESTED_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token".freeze
# Cloud resource manager URL used to retrieve project information.
CLOUD_RESOURCE_MANAGER = "https://cloudresourcemanager.googleapis.com/v1/projects/".freeze
# Default IAM_SCOPE
IAM_SCOPE = [
"https://www.googleapis.com/auth/iam".freeze
].freeze

include BaseClient
include Helpers::Connection

Expand Down Expand Up @@ -62,13 +76,56 @@ def fetch_access_token! _options = {}
notify_refresh_listeners
end

private
##
# Retrieves the project ID corresponding to the workload identity or workforce pool.
# For workforce pool credentials, it returns the project ID corresponding to
# the workforce_pool_user_project.
# When not determinable, None is returned.
#
# The resource may not have permission (resourcemanager.projects.get) to
# call this API or the required scopes may not be selected:
# https://cloud.google.com/resource-manager/reference/rest/v1/projects/get#authorization-scopes
#
# @return [string|nil]
# The project ID corresponding to the workload identity pool or workforce pool if determinable.
#
def project_id
return @project_id unless @project_id.nil?
project_number = self.project_number || self._workforce_pool_user_project

# if we missing either project number or scope, we won't retrieve project_id
return nil if project_number.nil? || @scope.nil?

url = CLOUD_RESOURCE_MANAGER + project_number

response = connection.get url do |req|
req.headers["Authorization"] = "Bearer #{@access_token}"
req.headers["Content-Type"] = "application/json"
end

STS_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange".freeze
STS_REQUESTED_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token".freeze
IAM_SCOPE = [
"https://www.googleapis.com/auth/iam".freeze
].freeze
if response.status == 200
response_data = MultiJson.load(response.body, :symbolize_keys => true)
@project_id = response_data[:projectId]
end

@project_id
end

##
# Retrieve the project number corresponding to workload identity pool
# STS audience pattern:
# //iam.googleapis.com/projects/$PROJECT_NUMBER/locations/...
#
# @return [string|nil]
#
def project_number
segments = @audience.split('/')
idx = segments.index('projects')
return nil if idx.nil? || idx + 1 == segments.size
segments[idx + 1]
end

private

def token_type
# This method is needed for BaseClient
Expand All @@ -84,6 +141,9 @@ def base_setup options
@token_url = options[:token_url]
@service_account_impersonation_url = options[:service_account_impersonation_url]

@quota_project_id = options[:quota_project_id]
@project_id = nil

@expires_at = nil
@access_token = nil

Expand Down

0 comments on commit ba8349e

Please sign in to comment.