Class: Knj::Facebook_connect

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Facebook_connect

Returns a new instance of Facebook_connect.



4
5
6
7
8
9
10
11
# File 'lib/knj/facebook_connect.rb', line 4

def initialize(args)
  require "http2"
  
  @args = args
  
  raise "No app-ID given." if !@args[:app_id]
  raise "No app-secret given." if !@args[:app_secret]
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



2
3
4
# File 'lib/knj/facebook_connect.rb', line 2

def args
  @args
end

Instance Method Details

#base64_urldecode(str) ⇒ Object



13
14
15
# File 'lib/knj/facebook_connect.rb', line 13

def base64_urldecode(str)
  return Base64.decode64("#{str.tr("-_", "+/")}=")
end

#get(http, url) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/knj/facebook_connect.rb', line 17

def get(http, url)
  resp = http.get(:url => url)
  
  if resp.body.length > 0
    begin
      jdata = JSON.parse(resp.body)
      
      error_type = RuntimeError
      if jdata["error"] and jdata["error"]["message"] == "Code was invalid or expired. The session is invalid because the user logged out."
        error_type = ArgumentError
      end
      
      raise error_type, "#{jdata["error"]["type"]}: #{jdata["error"]["message"]}" if jdata["error"]
    rescue JSON::ParserError
      #ignore
    end
  end
  
  return {:json => jdata, :resp => resp, :headers => resp.headers, :body => resp.body}
end

#login(args = {}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/knj/facebook_connect.rb', line 73

def (args = {})
  http = Http2.new(
    :host => "graph.facebook.com",
    :ssl => true
  )
  
  atoken = self.token_from_cookie(http, @args[:cookie])
  
  url = "me?access_token=#{Knj::Web.urlenc(atoken)}"
  resp = self.get(http, url)
  data = {"user" => resp[:json]}
  
  if args[:profile_picture]
    pic_data = self.get(http, "#{data["user"]["id"]}/picture?type=large")
    pic_obj = Magick::Image.from_blob(pic_data[:body].to_s)[0]
    data["pic"] = pic_obj
  end
  
  return data
end


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/knj/facebook_connect.rb', line 54

def token_from_cookie(http, cookie = nil)
  if @token
    return @token
  end
  
  raise "No token set and no cookie given." if !@args[:cookie]
  
  data = self.validate_cookie(@args[:cookie])
  resp = self.get(http, "oauth/access_token?client_id=#{Knj::Web.urlenc(@args[:app_id])}&client_secret=#{Knj::Web.urlenc(@args[:app_secret])}&redirect_uri=&code=#{Knj::Web.urlenc(data["code"])}")
  
  match = resp[:body].match(/access_token=(.+)&expires=(\d+)/)
  raise "No access token was given." if !match
  atoken = match[1]
  @token = atoken
  @expires = match[2]
  
  return atoken
end


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/knj/facebook_connect.rb', line 38

def validate_cookie(cookie)
  data = cookie.split(".", 2)
  enc_sig, payload = data[0], data[1]
  
  sig = self.base64_urldecode(enc_sig).unpack("H*").first
  data = self.base64_urldecode(payload)
  data = JSON.parse(data)
  
  raise "Unknown algorithm: '#{data["algorithm"]}'." if data["algorithm"] != "HMAC-SHA256"
  exp_sig = OpenSSL::HMAC.hexdigest("sha256", @args[:app_secret], payload)
  
  raise "Bad signed JSON signature." if sig != exp_sig
  
  return data
end

#wall_post(args) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/knj/facebook_connect.rb', line 94

def wall_post(args)
  http = Http2.new(
    :host => "graph.facebook.com",
    :ssl => true
  )
  
  atoken = self.token_from_cookie(http)
  post_data = {}
  
  args_keys = [:link, :object_attachment, :picture, :caption, :name, :description, :message, :media]
  args_keys.each do |key|
    if args.key?(key) and args[key]
      post_data[key] = args[key]
    end
  end
  
  res = http.post(:url => "/me/feed?access_token=#{atoken}", :post => post_data)
  raise res.body.to_s.strip if res.code.to_s != "200"
end