lib/koala.rb in koala-0.4.1 vs lib/koala.rb in koala-0.5.0
- old
+ new
@@ -104,11 +104,11 @@
# Most write operations require extended permissions. For example,
# publishing wall posts requires the "publish_stream" permission. See
# http://developers.facebook.com/docs/authentication/ for details about
# extended permissions.
- raise GraphAPIError.new(nil, "Write operations require an access token") unless @access_token
+ raise GraphAPIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token
api("#{parent_object}/#{connection_name}", args, "post")
end
def put_wall_post(message, attachment = {}, profile_id = "me")
# Writes a wall post to the given profile's wall.
@@ -159,27 +159,28 @@
# and cause JSON.parse to fail
# so we account for that
response = JSON.parse("[#{result}]")[0]
# check for errors
- if response.is_a?(Hash) && error = response["error"]
- raise GraphAPIError.new(error["code"], error["message"])
+ if response.is_a?(Hash) && error_details = response["error"]
+ raise GraphAPIError.new(error_details)
end
response
end
end
class GraphAPIError < Exception
- attr_accessor :code
- def initialize(code, message)
- super(message)
- self.code = code
+ attr_accessor :fb_error_type
+ def initialize(details = {})
+ self.fb_error_type = details["type"]
+ super("#{fb_error_type}: #{details["message"]}")
end
end
- class OAuth
+ class OAuth
+ attr_accessor :app_id, :app_secret, :oauth_callback_url
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
@@ -205,30 +206,64 @@
# 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"].to_i == 0 || Time.now.to_i < components["expires"].to_i) ? components : nil
+ 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
+ alias_method :get_user_from_cookies, :get_user_from_cookie
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
- def url_for_access_token(code, callback = @oauth_callback_url)
+ def url_for_access_token(code, options = {})
# Creates the URL for the token corresponding to a given code generated by Facebook
+ if options.is_a?(String) # changing the arguments
+ puts "Deprecation warning: url_for_access_token now takes an options hash as the second argument; pass the callback as :callback."
+ options = {:callback => options}
+ end
+ 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
+
+ def parse_access_token(response_text)
+ components = response_text.split("&").inject({}) do |hash, bit|
+ key, value = bit.split("=")
+ hash.merge!(key => value)
+ end
+ components
+ end
+
+ def fetch_token_string(code)
+ Koala.make_request("oauth/access_token", {
+ :client_id => @app_id,
+ :redirect_uri => @oauth_callback_url,
+ :client_secret => @app_secret,
+ :code => code
+ }, "get")
+ end
+
+ def get_access_token(code)
+ result = fetch_token_string(code)
+
+ # if we have an error, parse the error JSON and raise an error
+ raise GraphAPIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/
+ # otherwise, parse the access token
+ parse_access_token(result)
end
end
end
# finally, set up the http service Koala methods used to make requests
\ No newline at end of file