Class: Koala::Facebook::OAuth

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app_id, app_secret, oauth_callback_url = nil) ⇒ OAuth

Returns a new instance of OAuth.



108
109
110
111
112
# File 'lib/koala.rb', line 108

def initialize(app_id, app_secret, oauth_callback_url = nil)
  @app_id = app_id
  @app_secret = app_secret
  @oauth_callback_url = oauth_callback_url 
end

Instance Attribute Details

#app_idObject (readonly)

Returns the value of attribute app_id.



107
108
109
# File 'lib/koala.rb', line 107

def app_id
  @app_id
end

#app_secretObject (readonly)

Returns the value of attribute app_secret.



107
108
109
# File 'lib/koala.rb', line 107

def app_secret
  @app_secret
end

#oauth_callback_urlObject (readonly)

Returns the value of attribute oauth_callback_url.



107
108
109
# File 'lib/koala.rb', line 107

def oauth_callback_url
  @oauth_callback_url
end

Instance Method Details

#get_access_token(code) ⇒ Object



178
179
180
181
182
183
# File 'lib/koala.rb', line 178

def get_access_token(code)
  # upstream methods will throw errors if needed
  if info = get_access_token_info(code) 
    string = info["access_token"]        
  end
end

#get_access_token_info(code) ⇒ Object



172
173
174
175
176
# File 'lib/koala.rb', line 172

def get_access_token_info(code)
  # convenience method to get a parsed token from Facebook for a given code
  # should this require an OAuth callback URL?
  get_token_from_server(:code => code, :redirect_uri => @oauth_callback_url)
end

#get_app_access_tokenObject



190
191
192
193
194
# File 'lib/koala.rb', line 190

def get_app_access_token
  if info = get_app_access_token_info
    string = info["access_token"] 
  end
end

#get_app_access_token_infoObject



185
186
187
188
# File 'lib/koala.rb', line 185

def get_app_access_token_info
  # convenience method to get a the application's sessionless access token 
  get_token_from_server({:type => 'client_cred'}, true)
end

#get_token_from_session_key(session) ⇒ Object



235
236
237
238
239
# File 'lib/koala.rb', line 235

def get_token_from_session_key(session)
  # convenience method for a single key
  # gets the overlaoded strings automatically
  get_tokens_from_session_keys([session])[0]
end

#get_token_info_from_session_keys(sessions) ⇒ Object

from session keys



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/koala.rb', line 212

def get_token_info_from_session_keys(sessions)
  # fetch the OAuth tokens from Facebook
  response = fetch_token_string({
    :type => 'client_cred',
    :sessions => sessions.join(",")
  }, true, "exchange_sessions")
  
  # get_token_from_session_key should return an empty body if an empty string or nil is provided
  # if invalid tokens are provided, it returns an array of nulls, which is a valid result
  if response == ""
    raise APIError.new("ArgumentError", "get_token_from_session_key received an error (empty response body) for sessions #{sessions.inspect}!")
  end
  
  JSON.parse(response)
end

#get_tokens_from_session_keys(sessions) ⇒ Object



228
229
230
231
232
233
# File 'lib/koala.rb', line 228

def get_tokens_from_session_keys(sessions)
  # get the original hash results
  results = get_token_info_from_session_keys(sessions)
  # now recollect them as just the access tokens
  results.collect { |r| string = r["access_token"] }
end


144
145
146
147
148
# File 'lib/koala.rb', line 144

def get_user_from_cookie(cookies)
  if info = (cookies)
    string = info["uid"]
  end
end


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/koala.rb', line 114

def (cookie_hash)
  # Parses the cookie set by the official Facebook JavaScript SDK.
  # 
  # cookies should be a Hash, like the one Rails provides
  # 
  # If the user is logged in via Facebook, we return a dictionary with the
  # keys "uid" and "access_token". The former is the user's Facebook ID,
  # and the latter can be used to make authenticated requests to the Graph API.
  # If the user is not logged in, we return None.
  # 
  # Download the official Facebook JavaScript SDK at
  # http://github.com/facebook/connect-js/. Read more about Facebook
  # authentication at http://developers.facebook.com/docs/authentication/.

  if fb_cookie = cookie_hash["fbs_" + @app_id.to_s]
    # remove the opening/closing quote
    fb_cookie = fb_cookie.gsub(/\"/, "")

    # since we no longer get individual cookies, we have to separate out the components ourselves
    components = {}
    fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}

    # generate the signature and make sure it matches what we expect
    auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
    sig = Digest::MD5.hexdigest(auth_string + @app_secret)          
    sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
  end
end

#parse_signed_request(request) ⇒ Object

signed_request



197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/koala.rb', line 197

def parse_signed_request(request)
  # Facebook's signed requests come in two parts -- the signature and the data payload
  encoded_sig, payload = request.split(".")
  
  sig = base64_url_decode(encoded_sig)

  # if the signature matches, return the data, decoded and parsed as JSON
  if OpenSSL::HMAC.digest("sha256", @app_secret, payload) == sig
    JSON.parse(base64_url_decode(payload))
  else
    nil
  end
end

#url_for_access_token(code, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


165
166
167
168
169
170
# File 'lib/koala.rb', line 165

def url_for_access_token(code, options = {})
  # Creates the URL for the token corresponding to a given code generated by Facebook
  callback = options[:callback] || @oauth_callback_url
  raise ArgumentError, "url_for_access_token must get a callback either from the OAuth object or in the parameters!" unless callback
  "https://#{GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@app_secret}&code=#{code}"
end

#url_for_oauth_code(options = {}) ⇒ Object

URLs

Raises:

  • (ArgumentError)


153
154
155
156
157
158
159
160
161
162
163
# File 'lib/koala.rb', line 153

def url_for_oauth_code(options = {})
  # for permissions, see http://developers.facebook.com/docs/authentication/permissions
  permissions = options[:permissions]
  scope = permissions ? "&scope=#{permissions.is_a?(Array) ? permissions.join(",") : permissions}" : ""

  callback = options[:callback] || @oauth_callback_url
  raise ArgumentError, "url_for_oauth_code must get a callback either from the OAuth object or in the options!" unless callback

  # Creates the URL for oauth authorization for a given callback and optional set of permissions
  "https://#{GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}#{scope}"    
end