Class: GoodGuide::Accounts::Base

Inherits:
Object
  • Object
show all
Includes:
IssuePreferences, Profile
Defined in:
lib/goodguide/accounts/base.rb

Constant Summary collapse

NotAuthenticatedError =
Class.new(StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Profile

#facebook?, #full_name, #given_name, #identifier, #profile_picture, #with_profile

Methods included from IssuePreferences

#issue_preferences, #update_issue_preferences

Constructor Details

#initialize(opts = {}) ⇒ Base

Returns a new instance of Base.



128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/goodguide/accounts/base.rb', line 128

def initialize(opts={})
  opts = opts.dup

  credentials = opts.delete(:credentials) || {}
  @expires_at    = credentials[:expires_at]
  @access_token  = credentials[:access_token]
  @refresh_token = credentials[:refresh_token]

  opts.each do |k, v|
    instance_variable_set("@#{k}", v)
  end
end

Instance Attribute Details

#access_tokenObject (readonly)

Returns the value of attribute access_token.



125
126
127
# File 'lib/goodguide/accounts/base.rb', line 125

def access_token
  @access_token
end

#clientObject (readonly)

Returns the value of attribute client.



124
125
126
# File 'lib/goodguide/accounts/base.rb', line 124

def client
  @client
end

#idObject (readonly)

Returns the value of attribute id.



127
128
129
# File 'lib/goodguide/accounts/base.rb', line 127

def id
  @id
end

#refresh_tokenObject (readonly)

Returns the value of attribute refresh_token.



126
127
128
# File 'lib/goodguide/accounts/base.rb', line 126

def refresh_token
  @refresh_token
end

Class Method Details

.authenticate(credentials, opts = {}) ⇒ Object

How the auth flow works:

  1. Redirect the user-agent to Account.authorize_url

  2. After authentication, the user will be redirected to your pre-configured authorization endpoint, (e.g. /sessions/authorize), with ?code=…

  3. Do something like this:

    def authorize
      # get the code from the params
      code = params[:code]
      # exchange it with the oauth2 server for an
      # access token
      credentials = User.authorize(code)
      # store credentials
      # (a hash of access_token, refresh_token, and expires_at)
      # in the session
      session[:credentials] = credentials
      # and send them on their way
      redirect_to session[:redirect] || '/'
    end
    
  4. To get the current user, do something like this:

    def current_user
      User.authenticate(session[:credentials])
    end
    


40
41
42
# File 'lib/goodguide/accounts/base.rb', line 40

def authenticate(credentials, opts={})
  new({:credentials => credentials}.merge(opts))
end

.authorize(code, options = {}) ⇒ Object

returns a credentials hash given an authorization code



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/goodguide/accounts/base.rb', line 46

def authorize(code, options={})
  access_token = client.auth_code.get_token(code, {
    :redirect_uri => config[:redirect_uri]
  }.merge(options))

  # return a credentials hash
  {
    :access_token => access_token.token,
    :refresh_token => access_token.refresh_token,
    :expires_at => access_token.expires_at
  }
end

.authorize_url(opts = {}) ⇒ Object



59
60
61
# File 'lib/goodguide/accounts/base.rb', line 59

def authorize_url(opts={})
  client.auth_code.authorize_url(opts)
end

.clientObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/goodguide/accounts/base.rb', line 89

def client
  @client ||= begin
    my_config = config.dup

    if my_config[:site]
      my_config[:site] += '/api/account'
    end

    OAuth2::Client.new(
      my_config.delete(:identifier), my_config.delete(:secret),
      my_config.merge(:ssl => {:verify => false})
    )
  end
end

.configObject



79
80
81
82
83
84
85
86
87
# File 'lib/goodguide/accounts/base.rb', line 79

def config
  return @config if instance_variable_defined? :@config

  yaml = YAML.load_file('config/goodguide_accounts.yml')

  self.config = env && yaml.key?(env) ? yaml[env] : yaml

  @config
end

.config=(conf) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/goodguide/accounts/base.rb', line 69

def config=(conf)
  # In the absence of #symbolize_keys...
  conf = conf.dup
  conf.keys.each do |k|
    conf[k.to_sym] = conf.delete(k)
  end

  @config = default_config.merge(conf)
end

.logout_url(opts = {}) ⇒ Object



63
64
65
66
67
# File 'lib/goodguide/accounts/base.rb', line 63

def logout_url(opts={})
  url = config[:site] + "/sessions/clear"
  url += "?redirect=#{CGI.escape(opts[:redirect])}" if opts[:redirect]
  url
end

Instance Method Details

#authenticated?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/goodguide/accounts/base.rb', line 163

def authenticated?
  !!(access_token and not expired?)
end

#authorized?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/goodguide/accounts/base.rb', line 159

def authorized?
  authenticated? or refreshable?
end

#base_body_optionsObject



149
150
151
152
153
# File 'lib/goodguide/accounts/base.rb', line 149

def base_body_options
  opts = {}
  opts[:bearer_token] = access_token if authorized?
  opts
end

#connectionObject



224
225
226
227
228
229
230
231
232
# File 'lib/goodguide/accounts/base.rb', line 224

def connection
  @connection ||= begin
    if authorized?
      OAuth2::AccessToken.new(self.class.client, access_token, credentials)
    else
      self.class.client
    end
  end
end

#credentialsObject



203
204
205
206
207
208
209
# File 'lib/goodguide/accounts/base.rb', line 203

def credentials
  {
    :expires_at => expires_at,
    :access_token => access_token,
    :refresh_token => refresh_token
  }
end

#endpointObject



195
196
197
198
199
200
201
# File 'lib/goodguide/accounts/base.rb', line 195

def endpoint
  if authorized?
    '/account'
  elsif profile?
    "/accounts/#{id}"
  end
end

#expired?Boolean

Returns:

  • (Boolean)


191
192
193
# File 'lib/goodguide/accounts/base.rb', line 191

def expired?
  expires_in <= 0
end

#expires_atObject



183
184
185
# File 'lib/goodguide/accounts/base.rb', line 183

def expires_at
  Time.at(@expires_at || 0)
end

#expires_inObject



187
188
189
# File 'lib/goodguide/accounts/base.rb', line 187

def expires_in
  (expires_at - Time.now).to_i
end

#guest?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/goodguide/accounts/base.rb', line 171

def guest?
  not authorized? #and not profile?
end

#needs_refresh?Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/goodguide/accounts/base.rb', line 179

def needs_refresh?
  authorized? and not authenticated?
end

#profileObject



259
260
261
# File 'lib/goodguide/accounts/base.rb', line 259

def profile
  @profile ||= guest? ? {} : get('/')['account']
end

#profile?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/goodguide/accounts/base.rb', line 167

def profile?
  profile.present?
end

#real?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/goodguide/accounts/base.rb', line 175

def real?
  not guest?
end

#refresh!Object



211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/goodguide/accounts/base.rb', line 211

def refresh!
  if refreshable?
    @connection = connection.refresh!
    update_credentials(
      :expires_at => connection.expires_at,
      :refresh_token => connection.refresh_token,
      :access_token => connection.token
    )
  end
rescue OAuth2::Error
  $!.response
end

#refreshable?Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/goodguide/accounts/base.rb', line 155

def refreshable?
  refresh_token
end

#request(verb, path, opts = {}) ⇒ Object



249
250
251
252
253
254
255
256
257
# File 'lib/goodguide/accounts/base.rb', line 249

def request(verb, path, opts={})
  path = "/#{path}" if path.is_a? Symbol

  unless opts.key?(:body) || opts.key?(:headers)
    opts = { :body => opts }
  end

  JSON.load(connection.request(verb.to_sym, endpoint + path, opts).body)
end

#update_credentials(opts = {}) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/goodguide/accounts/base.rb', line 141

def update_credentials(opts = {})
  @expires_at = opts[:expires_at]
  @access_token = opts[:access_token]
  @refresh_token = opts[:refresh_token]

  self
end