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



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.



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:



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)



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



160
161
162
163
164
# File 'lib/googleauth/user_refresh.rb', line 160

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:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# 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

    resp.body
  end
end

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

Destructively updates these credentials

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



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

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