lib/fgraph/rails/fgraph_helper.rb in fgraph-0.6.2 vs lib/fgraph/rails/fgraph_helper.rb in fgraph-0.7.0

- old
+ new

@@ -1,89 +1,99 @@ module FGraph module Rails - module FGraphHelper - - # Access FGraph.config initialized with values set in <tt>[RAILS_ROOT]/config/fgraph.yml</tt>. - def fgraph_config - FGraph.config || {} - end + module FGraphHelper + + # Access FGraph.config initialized with values set in <tt>[RAILS_ROOT]/config/fgraph.yml</tt>. + def fgraph_config + FGraph.config || {} + end - # Return Facebook session, default to retrieve session from cookies. - def fgraph_session(app_id = fgraph_config['app_id'], - app_secret = fgraph_config['app_secret']) - - return @fgraph_session if @fgraph_session - @fgraph_session = fgraph_session_cookies(app_id, app_secret) - end - - # Return Facebook session cookies. - def fgraph_session_cookies(app_id = fgraph_config['app_id'], - app_secret = fgraph_config['app_secret']) - - return @fgraph_session_cookies if @fgraph_session_cookies - return if @fgraph_session_cookies == false - - # retrieve session from cookies - fbs_cookies = request.cookies["fbs_#{app_id}"] - if app_id.blank? or app_secret.blank? or fbs_cookies.blank? - return @fgraph_session_cookies = false - end + # Return Facebook session, default to retrieve session from cookies. + def fgraph_session(app_id = fgraph_config['app_id'], + app_secret = fgraph_config['app_secret']) + + return @fgraph_session if @fgraph_session + @fgraph_session = fgraph_session_cookies(app_id, app_secret) + end + + # Return Facebook session cookies. + def fgraph_session_cookies(app_id = fgraph_config['app_id'], + app_secret = fgraph_config['app_secret']) - # Parse facebook cookies - fbs_cookies = CGI.parse(fbs_cookies.gsub(/(^\"|\"$)/, '')) - session_cookies = {} - fbs_cookies.each do |key, value| - session_cookies[key] = value[0] - end - - # Validate session cookies - cookie_message = '' - session_cookies_list = session_cookies.sort - session_cookies_list.each do |cookie| - cookie_message += "#{cookie[0]}=#{cookie[1]}" if cookie[0] != 'sig' - end + return @fgraph_session_cookies if @fgraph_session_cookies + return if @fgraph_session_cookies == false - # Message digest does not match - if Digest::MD5.hexdigest(cookie_message + app_secret) != session_cookies['sig'] - @fgraph_session_cookies = false - end + fbsr_cookie = request.cookies["fbsr_#{app_id}"] + if app_id.blank? or app_secret.blank? or fbsr_cookie.blank? + return @fgraph_session_cookies = false + end - @fgraph_session_cookies = session_cookies - end - - def fgraph_access_token - return unless fgraph_session - fgraph_session['access_token'] - end - - def fgraph_logged_in? - return true if fgraph_session and fgraph_access_token - end - - # Currently logged in facebook user - def fgraph_current_user - return @fgraph_current_user if @fgraph_current_user - @fgraph_current_user = fgraph_client.me - end - - # Alias for fgraph_current_user - def fgraph_user - fgraph_current_user - end - - # Return FGraph::Client instance initialized with settings set in <tt>fgraph.yml</tt>. - # Initialized with <tt>:access_token</tt> as well if Facebook session exists. - def fgraph_client - return @fgraph_client if @fgraph_client - - @fgraph_client = FGraph::Client.new( - :client_id => fgraph_config['app_id'], - :client_secret => fgraph_config['app_secret'], - :access_token => fgraph_access_token - ) - end - - # Return Facebook object picture url: http://graph.facebook.com/[id]/picture + # Get authorization code and access token + signed_request = fgraph_parse_signed_request(fbsr_cookie, app_secret) + resp = FGraph.oauth_access_token(app_id, app_secret, :code => signed_request['code']) + + @fgraph_session_cookies = { + 'access_token' => resp['access_token'] + } + end + + def fgraph_base64_url_decode(str) + str += '=' * (4 - str.length.modulo(4)) + Base64.decode64(str.tr('-_', '+/')) + end + + # Parses a signed request string provided by Facebook to canvas apps or in a secure cookie. + # + # @param Input the signed request from Facebook + # @raise RuntimeError if the signature is incomplete, invalid, or using an unsupported algorithm + # @return A hash of the validated request information + def fgraph_parse_signed_request(input, app_secret) + encoded_sig, encoded_envelope = input.split('.', 2) + raise FGraph::OAuthError, 'SignedRequest: Invalid (incomplete) signature data' unless encoded_sig && encoded_envelope + + signature = fgraph_base64_url_decode(encoded_sig).unpack("H*").first + envelope = ActiveSupport::JSON.decode(fgraph_base64_url_decode(encoded_envelope)) + raise FGraph::OAuthError, "SignedRequest: Unsupported algorithm #{envelope['algorithm']}" if envelope['algorithm'] != 'HMAC-SHA256' + + hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, app_secret, encoded_envelope) + raise FGraph::OAuthError, 'SignedRequest: Invalid signature' if (signature != hmac) + + envelope + end + + def fgraph_access_token + return unless fgraph_session + fgraph_session['access_token'] + end + + def fgraph_logged_in? + return true if fgraph_session and fgraph_access_token + end + + # Currently logged in facebook user + def fgraph_current_user + return @fgraph_current_user if @fgraph_current_user + @fgraph_current_user = fgraph_client.me + end + + # Alias for fgraph_current_user + def fgraph_user + fgraph_current_user + end + + # Return FGraph::Client instance initialized with settings set in <tt>fgraph.yml</tt>. + # Initialized with <tt>:access_token</tt> as well if Facebook session exists. + def fgraph_client + return @fgraph_client if @fgraph_client + + @fgraph_client = FGraph::Client.new( + :client_id => fgraph_config['app_id'], + :client_secret => fgraph_config['app_secret'], + :access_token => fgraph_access_token + ) + end + + # Return Facebook object picture url: http://graph.facebook.com/[id]/picture # # ==== Type Options # * <tt>square</tt> - 50x50 (default) # * <tt>small</tt> - 50 pixels wide, variable height # * <tt>normal</tt> - 100 pixels wide, variable height \ No newline at end of file