Class: Google::Auth::ServiceAccountCredentials

Inherits:
Signet::OAuth2::Client show all
Extended by:
CredentialsLoader, JsonKeyReader
Defined in:
lib/googleauth/service_account.rb

Overview

Authenticates requests using Google's Service Account credentials via an OAuth access token.

This class allows authorizing requests for service accounts directly from credentials from a json key file downloaded from the developer console (via 'Generate new Json Key').

cf Application Default Credentials

Constant Summary collapse

TOKEN_CRED_URI =
"https://www.googleapis.com/oauth2/v4/token".freeze

Constants included from CredentialsLoader

CredentialsLoader::ACCOUNT_TYPE_VAR, CredentialsLoader::AWS_ACCESS_KEY_ID_VAR, CredentialsLoader::AWS_DEFAULT_REGION_VAR, CredentialsLoader::AWS_REGION_VAR, CredentialsLoader::AWS_SECRET_ACCESS_KEY_VAR, CredentialsLoader::AWS_SESSION_TOKEN_VAR, CredentialsLoader::CLIENT_EMAIL_VAR, CredentialsLoader::CLIENT_ID_VAR, CredentialsLoader::CLIENT_SECRET_VAR, CredentialsLoader::CLOUD_SDK_CLIENT_ID, CredentialsLoader::CREDENTIALS_FILE_NAME, CredentialsLoader::ENV_VAR, CredentialsLoader::GCLOUD_CONFIG_COMMAND, CredentialsLoader::GCLOUD_POSIX_COMMAND, CredentialsLoader::GCLOUD_WINDOWS_COMMAND, CredentialsLoader::NOT_FOUND_ERROR, CredentialsLoader::PRIVATE_KEY_VAR, CredentialsLoader::PROJECT_ID_VAR, CredentialsLoader::REFRESH_TOKEN_VAR, CredentialsLoader::SYSTEM_DEFAULT_ERROR, CredentialsLoader::WELL_KNOWN_ERROR, CredentialsLoader::WELL_KNOWN_PATH

Constants included from BaseClient

BaseClient::AUTH_METADATA_KEY

Instance Attribute Summary collapse

Attributes inherited from Signet::OAuth2::Client

#universe_domain

Attributes included from BaseClient

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CredentialsLoader

from_env, from_system_default_path, from_well_known_path, load_gcloud_project_id, make_creds

Methods included from JsonKeyReader

read_json_key

Methods inherited from Signet::OAuth2::Client

#build_default_connection, #configure_connection, #fetch_access_token!, #generate_access_token_request, #googleauth_orig_generate_access_token_request, #orig_fetch_access_token!, #retry_with_error, #token_type, #update_signet_base, #update_token!, #update_token_signet_base

Methods included from BaseClient

#apply, #expires_within?, #notify_refresh_listeners, #on_refresh, #updater_proc

Constructor Details

#initialize(options = {}) ⇒ ServiceAccountCredentials

Returns a new instance of ServiceAccountCredentials.



125
126
127
128
129
130
# File 'lib/googleauth/service_account.rb', line 125

def initialize options = {}
  @project_id = options[:project_id]
  @quota_project_id = options[:quota_project_id]
  @enable_self_signed_jwt = options[:enable_self_signed_jwt] ? true : false
  super options
end

Instance Attribute Details

#project_idObject (readonly)

Returns the value of attribute project_id.



41
42
43
# File 'lib/googleauth/service_account.rb', line 41

def project_id
  @project_id
end

#quota_project_idObject (readonly)

Returns the value of attribute quota_project_id.



42
43
44
# File 'lib/googleauth/service_account.rb', line 42

def quota_project_id
  @quota_project_id
end

Class Method Details

.make_creds(options = {}) ⇒ Object

Creates a ServiceAccountCredentials.

Raises:

  • If both scope and target_audience are specified

Parameters:

  • An IO object containing the JSON key

  • the scope(s) to access



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/googleauth/service_account.rb', line 61

def self.make_creds options = {}
  json_key_io, scope, enable_self_signed_jwt, target_audience, audience, token_credential_uri =
    options.values_at :json_key_io, :scope, :enable_self_signed_jwt, :target_audience,
                      :audience, :token_credential_uri
  raise ArgumentError, "Cannot specify both scope and target_audience" if scope && target_audience

  private_key, client_email, project_id, quota_project_id, universe_domain =
    if json_key_io
      CredentialsLoader.load_and_verify_json_key_type json_key_io, CREDENTIAL_TYPE_NAME
      read_json_key json_key_io
    else
      creds_from_env
    end
  project_id ||= CredentialsLoader.load_gcloud_project_id

  new(token_credential_uri:   token_credential_uri || TOKEN_CRED_URI,
      audience:               audience || TOKEN_CRED_URI,
      scope:                  scope,
      enable_self_signed_jwt: enable_self_signed_jwt,
      target_audience:        target_audience,
      issuer:                 client_email,
      signing_key:            OpenSSL::PKey::RSA.new(private_key),
      project_id:             project_id,
      quota_project_id:       quota_project_id,
      universe_domain:        universe_domain || "googleapis.com")
    .configure_connection(options)
end

.unescape(str) ⇒ String

Handles certain escape sequences that sometimes appear in input. Specifically, interprets the "\n" sequence for newline, and removes enclosing quotes.

Parameters:

  • The string to unescape

Returns:

  • The unescaped string



119
120
121
122
123
# File 'lib/googleauth/service_account.rb', line 119

def self.unescape str
  str = str.gsub '\n', "\n"
  str = str[1..-2] if str.start_with?('"') && str.end_with?('"')
  str
end

Instance Method Details

#apply!(a_hash, opts = {}) ⇒ Object

Extends the base class to use a transient ServiceAccountJwtHeaderCredentials for certain cases.



134
135
136
137
138
139
140
# File 'lib/googleauth/service_account.rb', line 134

def apply! a_hash, opts = {}
  if enable_self_signed_jwt?
    apply_self_signed_jwt! a_hash
  else
    super
  end
end

#duplicate(options = {}) ⇒ Object

Creates a duplicate of these credentials without the Signet::OAuth2::Client-specific transient state (e.g. cached tokens)

Parameters:

  • (defaults to: {})

    Overrides for the credentials parameters. The following keys are recognized in addition to keys in the Signet::OAuth2::Client

    • :enable_self_signed_jwt Whether the self-signed JWT should be used for the authentication
    • project_id the project id to use during the authentication
    • quota_project_id the quota project id to use during the authentication


101
102
103
104
105
106
107
108
109
110
111
# File 'lib/googleauth/service_account.rb', line 101

def duplicate options = {}
  options = deep_hash_normalize options
  super(
    {
      enable_self_signed_jwt: @enable_self_signed_jwt,
      project_id: project_id,
      quota_project_id: quota_project_id,
      logger: logger
    }.merge(options)
  )
end

#enable_self_signed_jwt?Boolean

Returns:



48
49
50
51
52
53
54
# File 'lib/googleauth/service_account.rb', line 48

def enable_self_signed_jwt?
  # Use a self-singed JWT if there's no information that can be used to
  # obtain an OAuth token, OR if there are scopes but also an assertion
  # that they are default scopes that shouldn't be used to fetch a token,
  # OR we are not in the default universe and thus OAuth isn't supported.
  target_audience.nil? && (scope.nil? || @enable_self_signed_jwt || universe_domain != "googleapis.com")
end

#needs_access_token?Boolean

Modifies this logic so it also requires self-signed-jwt to be disabled

Returns:



143
144
145
# File 'lib/googleauth/service_account.rb', line 143

def needs_access_token?
  super && !enable_self_signed_jwt?
end

#update!(options = {}) ⇒ Google::Auth::ServiceAccountCredentials

Destructively updates these credentials

This method is called by Signet::OAuth2::Client's constructor

Parameters:

  • (defaults to: {})

    Overrides for the credentials parameters. The following keys are recognized in addition to keys in the Signet::OAuth2::Client

    • :enable_self_signed_jwt Whether the self-signed JWT should be used for the authentication
    • project_id the project id to use during the authentication
    • quota_project_id the quota project id to use during the authentication

Returns:



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/googleauth/service_account.rb', line 160

def update! options = {}
  # Normalize all keys to symbols to allow indifferent access.
  options = deep_hash_normalize options

  @enable_self_signed_jwt = options[:enable_self_signed_jwt] ? true : false
  @project_id = options[:project_id] if options.key? :project_id
  @quota_project_id = options[:quota_project_id] if options.key? :quota_project_id

  super(options)

  self
end