Class: Google::Auth::UserRefreshCredentials

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

Overview

Authenticates requests using User Refresh credentials.

This class allows authorizing requests from user refresh tokens.

This the end of the result of a 3LO flow. E.g, the end result of 'gcloud auth login' saves a file with these contents in well known location

cf Application Default Credentials

Constant Summary collapse

TOKEN_CRED_URI =
"https://oauth2.googleapis.com/token".freeze
AUTHORIZATION_URI =
"https://accounts.google.com/o/oauth2/auth".freeze
REVOKE_TOKEN_URI =
"https://oauth2.googleapis.com/revoke".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

authorized_user_env_vars?, from_env, from_system_default_path, from_well_known_path, interpret_options, load_gcloud_project_id, make_creds, service_account_env_vars?

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, #apply!, #expires_within?, #needs_access_token?, #notify_refresh_listeners, #on_refresh, #updater_proc

Constructor Details

#initialize(options = {}) ⇒ UserRefreshCredentials

Returns a new instance of UserRefreshCredentials.



97
98
99
100
101
102
103
104
105
# File 'lib/googleauth/user_refresh.rb', line 97

def initialize options = {}
  options ||= {}
  options[:token_credential_uri] ||= TOKEN_CRED_URI
  options[:authorization_uri] ||= AUTHORIZATION_URI
  @project_id = options[:project_id]
  @project_id ||= CredentialsLoader.load_gcloud_project_id
  @quota_project_id = options[:quota_project_id]
  super options
end

Instance Attribute Details

#project_idObject (readonly)

Returns the value of attribute project_id.



39
40
41
# File 'lib/googleauth/user_refresh.rb', line 39

def project_id
  @project_id
end

#quota_project_idObject (readonly)

Returns the value of attribute quota_project_id.



40
41
42
# File 'lib/googleauth/user_refresh.rb', line 40

def quota_project_id
  @quota_project_id
end

Class Method Details

.make_creds(options = {}) ⇒ Object

Create a UserRefreshCredentials.

Parameters:

  • An IO object containing the JSON key

  • the scope(s) to access



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/googleauth/user_refresh.rb', line 50

def self.make_creds options = {} # rubocop:disable Metrics/MethodLength
  json_key_io, scope = options.values_at :json_key_io, :scope
  user_creds = if json_key_io
                 json_key = MultiJson.load json_key_io.read
                 if json_key.key? "type"
                   json_key_io.rewind
                 else # Defaults to class credential 'type' if missing.
                   json_key["type"] = CREDENTIAL_TYPE_NAME
                   json_key_io = StringIO.new MultiJson.dump(json_key)
                 end
                 CredentialsLoader.load_and_verify_json_key_type json_key_io, CREDENTIAL_TYPE_NAME
                 read_json_key json_key_io
               else
                 {
                   "client_id"     => ENV[CredentialsLoader::CLIENT_ID_VAR],
                   "client_secret" => ENV[CredentialsLoader::CLIENT_SECRET_VAR],
                   "refresh_token" => ENV[CredentialsLoader::REFRESH_TOKEN_VAR],
                   "project_id"    => ENV[CredentialsLoader::PROJECT_ID_VAR],
                   "quota_project_id" => nil,
                   "universe_domain" => nil
                 }
               end
  new(token_credential_uri: TOKEN_CRED_URI,
      client_id:            user_creds["client_id"],
      client_secret:        user_creds["client_secret"],
      refresh_token:        user_creds["refresh_token"],
      project_id:           user_creds["project_id"],
      quota_project_id:     user_creds["quota_project_id"],
      scope:                scope,
      universe_domain:      user_creds["universe_domain"] || "googleapis.com")
    .configure_connection(options)
end

.read_json_key(json_key_io) ⇒ Hash

Reads a JSON key from an IO object and extracts required fields.

Raises:

  • If the JSON is missing required fields

Parameters:

  • An IO object containing the JSON key

Returns:

  • The parsed JSON key



88
89
90
91
92
93
94
95
# File 'lib/googleauth/user_refresh.rb', line 88

def self.read_json_key json_key_io
  json_key = MultiJson.load json_key_io.read
  wanted = ["client_id", "client_secret", "refresh_token"]
  wanted.each do |key|
    raise InitializationError, "the json is missing the #{key} field" unless json_key.key? key
  end
  json_key
end

Instance Method Details

#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

    • project_id the project id to use during the authentication
    • quota_project_id the quota project id to use during the authentication


117
118
119
120
121
122
123
124
125
# File 'lib/googleauth/user_refresh.rb', line 117

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

#includes_scope?(required_scope) ⇒ Boolean

Verifies that a credential grants the requested scope

Parameters:

  • Scope to verify

Returns:

  • True if scope is granted



158
159
160
161
162
# File 'lib/googleauth/user_refresh.rb', line 158

def includes_scope? required_scope
  missing_scope = Google::Auth::ScopeUtil.normalize(required_scope) -
                  Google::Auth::ScopeUtil.normalize(scope)
  missing_scope.empty?
end

#revoke!(options = {}) ⇒ Object

Revokes the credential

Options Hash (options):

  • :connection (Faraday::Connection)

    The connection to use

Raises:

  • If the revocation request fails

Parameters:

  • (defaults to: {})

    Options for revoking the credential



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/googleauth/user_refresh.rb', line 132

def revoke! options = {}
  c = options[:connection] || Faraday.default_connection

  retry_with_error do
    resp = c.post(REVOKE_TOKEN_URI, token: refresh_token || access_token)
    case resp.status
    when 200
      self.access_token = nil
      self.refresh_token = nil
      self.expires_at = 0
    else
      raise AuthorizationError.with_details(
        "Unexpected error code #{resp.status}",
        credential_type_name: self.class.name,
        principal: principal
      )
    end
  end
end

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

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

    • project_id the project id to use during the authentication
    • quota_project_id the quota project id to use during the authentication

Returns:



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/googleauth/user_refresh.rb', line 175

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

  @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