Class: Google::Auth::UserAuthorizer

Inherits:
Object
  • Object
show all
Defined in:
lib/googleauth/user_authorizer.rb

Overview

Handles an interactive 3-Legged-OAuth2 (3LO) user consent authorization.

Example usage for a simple command line app:

credentials = authorizer.get_credentials(user_id)
if credentials.nil?
  url = authorizer.get_authorization_url(
    base_url: OOB_URI)
  puts "Open the following URL in the browser and enter the " +
       "resulting code after authorization"
  puts url
  code = gets
  credentials = authorizer.get_and_store_credentials_from_code(
    user_id: user_id, code: code, base_url: OOB_URI)
end
# Credentials ready to use, call APIs
...

Direct Known Subclasses

WebUserAuthorizer

Constant Summary collapse

MISMATCHED_CLIENT_ID_ERROR =
'Token client ID of %s does not match configured client id %s'.freeze
NIL_CLIENT_ID_ERROR =
'Client id can not be nil.'.freeze
NIL_SCOPE_ERROR =
'Scope can not be nil.'.freeze
NIL_USER_ID_ERROR =
'User ID can not be nil.'.freeze
NIL_TOKEN_STORE_ERROR =
'Can not call method if token store is nil'.freeze
MISSING_ABSOLUTE_URL_ERROR =
'Absolute base url required for relative callback url "%s"'.freeze

Instance Method Summary collapse

Constructor Details

#initialize(client_id, scope, token_store, callback_uri = nil) ⇒ UserAuthorizer

Initialize the authorizer


75
76
77
78
79
80
81
82
83
# File 'lib/googleauth/user_authorizer.rb', line 75

def initialize(client_id, scope, token_store, callback_uri = nil)
  raise NIL_CLIENT_ID_ERROR if client_id.nil?
  raise NIL_SCOPE_ERROR if scope.nil?

  @client_id = client_id
  @scope = Array(scope)
  @token_store = token_store
  @callback_uri = callback_uri || '/oauth2callback'
end

Instance Method Details

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

Exchanges an authorization code returned in the oauth callback. Additionally, stores the resulting credentials in the token store if the exchange is successful.


199
200
201
202
# File 'lib/googleauth/user_authorizer.rb', line 199

def get_and_store_credentials_from_code(options = {})
  credentials = get_credentials_from_code(options)
  store_credentials(options[:user_id], credentials)
end

#get_authorization_url(options = {}) ⇒ String

Build the URL for requesting authorization.


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/googleauth/user_authorizer.rb', line 100

def get_authorization_url(options = {})
  scope = options[:scope] || @scope
  credentials = UserRefreshCredentials.new(
    client_id: @client_id.id,
    client_secret: @client_id.secret,
    scope: scope
  )
  redirect_uri = redirect_uri_for(options[:base_url])
  url = credentials.authorization_uri(access_type: 'offline',
                                      redirect_uri: redirect_uri,
                                      approval_prompt: 'force',
                                      state: options[:state],
                                      include_granted_scopes: true,
                                      login_hint: options[:login_hint])
  url.to_s
end

#get_credentials(user_id, scope = nil) ⇒ Google::Auth::UserRefreshCredentials

Fetch stored credentials for the user.


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/googleauth/user_authorizer.rb', line 126

def get_credentials(user_id, scope = nil)
  saved_token = stored_token(user_id)
  return nil if saved_token.nil?
  data = MultiJson.load(saved_token)

  if data.fetch('client_id', @client_id.id) != @client_id.id
    raise sprintf(MISMATCHED_CLIENT_ID_ERROR,
                  data['client_id'], @client_id.id)
  end

  credentials = UserRefreshCredentials.new(
    client_id: @client_id.id,
    client_secret: @client_id.secret,
    scope: data['scope'] || @scope,
    access_token: data['access_token'],
    refresh_token: data['refresh_token'],
    expires_at: data.fetch('expiration_time_millis', 0) / 1000
  )
  scope ||= @scope
  if credentials.includes_scope?(scope)
    return monitor_credentials(user_id, credentials)
  end
  nil
end

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

Exchanges an authorization code returned in the oauth callback


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/googleauth/user_authorizer.rb', line 166

def get_credentials_from_code(options = {})
  user_id = options[:user_id]
  code = options[:code]
  scope = options[:scope] || @scope
  base_url = options[:base_url]
  credentials = UserRefreshCredentials.new(
    client_id: @client_id.id,
    client_secret: @client_id.secret,
    redirect_uri: redirect_uri_for(base_url),
    scope: scope
  )
  credentials.code = code
  credentials.fetch_access_token!({})
  monitor_credentials(user_id, credentials)
end

#revoke_authorization(user_id) ⇒ Object

Revokes a user's credentials. This both revokes the actual grant as well as removes the token from the token store.


209
210
211
212
213
214
215
216
217
218
219
# File 'lib/googleauth/user_authorizer.rb', line 209

def revoke_authorization(user_id)
  credentials = get_credentials(user_id)
  if credentials
    begin
      @token_store.delete(user_id)
    ensure
      credentials.revoke!
    end
  end
  nil
end

#store_credentials(user_id, credentials) ⇒ Object

Store credentials for a user. Generally not required to be called directly, but may be used to migrate tokens from one store to another.


229
230
231
232
233
234
235
236
237
238
239
# File 'lib/googleauth/user_authorizer.rb', line 229

def store_credentials(user_id, credentials)
  json = MultiJson.dump(
    client_id: credentials.client_id,
    access_token: credentials.access_token,
    refresh_token: credentials.refresh_token,
    scope: credentials.scope,
    expiration_time_millis: credentials.expires_at.to_i * 1000
  )
  @token_store.store(user_id, json)
  credentials
end