rfacebook 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +76 -0
- data/lib/facebook_desktop_session.rb +152 -0
- data/lib/facebook_session.rb +245 -0
- data/lib/facebook_web_session.rb +114 -0
- metadata +57 -0
data/README
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
============================== IMPORTANT NOTES ==============================
|
2
|
+
|
3
|
+
|
4
|
+
** THIS IS ESPECIALLY IMPORTANT FOR PEOPLE WHO USED THE OLD CLIENT WHEN IT WAS CALLED "RBook" **
|
5
|
+
|
6
|
+
[1] The RBook name was already taken, so now you need to change any "RBook" references to "RFacebook"
|
7
|
+
|
8
|
+
[2] The desktop app login process is much simpler now:
|
9
|
+
|
10
|
+
fbsession = RFacebook::FacebookDesktopSession.new(APIKEY, APISECRET)
|
11
|
+
puts fbsession.get_login_url # tell the user to login at this url
|
12
|
+
# ...after the user logs in...
|
13
|
+
fbsession.activate
|
14
|
+
|
15
|
+
[3] The "init_with_token" method is now "activate_with_token" (it is a little less confusing with this naming)
|
16
|
+
|
17
|
+
[4] A helpful "NotActivatedException" will be raised if you forget to activate your session in one of the following ways:
|
18
|
+
|
19
|
+
Web: you must call either "activate_with_token" or "activate_with_previous_session"
|
20
|
+
Desktop: you must call either "activate" or "activate_with_previous_session"
|
21
|
+
|
22
|
+
[5] Infinite sessions are now supported (web and desktop)...
|
23
|
+
|
24
|
+
Web:
|
25
|
+
|
26
|
+
(a) Save the session key to a file or something
|
27
|
+
(i.e. "keyToSave = fbsession.session_key")
|
28
|
+
|
29
|
+
(b) Normally, you would redirect the user to "get_login_url" and then call "activate_with_token" after the callback.
|
30
|
+
With an infinite session, skip these two steps and call "fbsession.activate_with_previous_session(keyToSave)" instead.
|
31
|
+
|
32
|
+
Desktop:
|
33
|
+
|
34
|
+
(a) Save the session key and session secret to a file or something
|
35
|
+
(i.e. "keyToSave = fbsession.session_key" and "secretToSave = fbsession.session_secret")
|
36
|
+
|
37
|
+
(b) Normally, you would redirect the user to "get_login_url" and then call "activate".
|
38
|
+
With an infinite session, skip these two steps and call "fbsession.activate_with_previous_session(keyToSave, secretToSave)" instead.
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
============================== LICENSE ==============================
|
43
|
+
|
44
|
+
Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
45
|
+
All rights reserved.
|
46
|
+
|
47
|
+
Redistribution and use in source and binary forms, with or without modification,
|
48
|
+
are permitted provided that the following conditions are met:
|
49
|
+
|
50
|
+
Redistributions of source code must retain the above copyright notice,
|
51
|
+
this list of conditions and the following disclaimer.
|
52
|
+
|
53
|
+
Redistributions in binary form must reproduce the above copyright notice,
|
54
|
+
this list of conditions and the following disclaimer in the documentation
|
55
|
+
and/or other materials provided with the distribution.
|
56
|
+
|
57
|
+
Neither the name of the original author nor the names of contributors
|
58
|
+
may be used to endorse or promote products derived from this software
|
59
|
+
without specific prior written permission.
|
60
|
+
|
61
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
62
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
63
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
64
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
65
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
66
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
67
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
68
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
69
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
70
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
Some code was inspired by techniques used in Alpha Chen's old client.
|
75
|
+
Some code was ported from the official PHP5 client.
|
76
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# Neither the name of the original author nor the names of contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#
|
29
|
+
|
30
|
+
#
|
31
|
+
# Some code was inspired by techniques used in Alpha Chen's old client.
|
32
|
+
# Some code was ported from the official PHP5 client.
|
33
|
+
#
|
34
|
+
|
35
|
+
require "facebook_session"
|
36
|
+
|
37
|
+
module RFacebook
|
38
|
+
|
39
|
+
class FacebookDesktopSession < FacebookSession
|
40
|
+
|
41
|
+
# you'll need to access session_secret (in addition to the session_key) to be able to
|
42
|
+
# call "activate_with_previous_session" when using infinite sessions
|
43
|
+
attr_reader :session_secret
|
44
|
+
|
45
|
+
# Function: get_login_url
|
46
|
+
# Gets the authentication URL
|
47
|
+
#
|
48
|
+
# Parameters:
|
49
|
+
# options.next - the page to redirect to after login
|
50
|
+
# options.popup - boolean, whether or not to use the popup style (defaults to true)
|
51
|
+
# options.skipcookie - boolean, whether to force new Facebook login (defaults to false)
|
52
|
+
# options.hidecheckbox - boolean, whether to show the "infinite session" option checkbox
|
53
|
+
def get_login_url(options={})
|
54
|
+
# options
|
55
|
+
path_next = options[:next] ||= nil
|
56
|
+
popup = (options[:popup] == nil) ? true : false
|
57
|
+
skipcookie = (options[:skipcookie] == nil) ? false : true
|
58
|
+
|
59
|
+
# get some extra portions of the URL
|
60
|
+
optionalNext = (path_next == nil) ? "" : "&next=#{CGI.escape(path_next.to_s)}"
|
61
|
+
optionalPopup = (popup == true) ? "&popup=true" : ""
|
62
|
+
optionalSkipCookie = (skipcookie == true) ? "&skipcookie=true" : ""
|
63
|
+
optionalHideCheckbox = (hidecheckbox == true) ? "&hide_checkbox=true" : ""
|
64
|
+
|
65
|
+
# build and return URL
|
66
|
+
return "http://#{LOGIN_SERVER_BASE_URL}#{LOGIN_SERVER_PATH}?v=1.0&api_key=#{@api_key}&auth_token=#{@desktop_auth_token}#{optionalPopup}#{optionalNext}#{optionalSkipCookie}#{optionalHideCheckbox}"
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Function: initialize
|
71
|
+
# Constructs a FacebookSession
|
72
|
+
#
|
73
|
+
# Parameters:
|
74
|
+
# api_key - your API key
|
75
|
+
# api_secret - your API secret
|
76
|
+
# desktop - boolean, whether this is a desktop client or not (defaults to false)
|
77
|
+
# options.suppress_exceptions - boolean, set to true if you don't want exceptions to be thrown (defaults to false)
|
78
|
+
def initialize(api_key, api_secret, suppress_exceptions = false)
|
79
|
+
super(api_key, api_secret, suppress_exceptions)
|
80
|
+
@desktop_auth_token = get_auth_token
|
81
|
+
end
|
82
|
+
|
83
|
+
def activate
|
84
|
+
activate_with_token(@desktop_auth_token)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Function: activate_with_previous_session
|
88
|
+
# Sets the session key and secret directly (for example, if you have an infinite session key)
|
89
|
+
#
|
90
|
+
# Parameters:
|
91
|
+
# key - the session key to use
|
92
|
+
def activate_with_previous_session(key, secret)
|
93
|
+
# set the session key and secret
|
94
|
+
@session_key = key
|
95
|
+
@session_secret = secret
|
96
|
+
|
97
|
+
# determine the current user's id
|
98
|
+
result = call_method("users.getLoggedInUser")
|
99
|
+
@session_uid = result.at("users_getLoggedInUser_response").inner_html
|
100
|
+
end
|
101
|
+
|
102
|
+
def is_valid?
|
103
|
+
return (is_activated? and !session_expired?)
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def is_activated?
|
109
|
+
return (@session_key != nil and @session_secret != nil)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Function: activate_with_token
|
113
|
+
# Gets the session information available after current user logs in.
|
114
|
+
#
|
115
|
+
# Parameters:
|
116
|
+
# auth_token - string token returned by auth.createToken (see: <get_auth_token>)
|
117
|
+
def activate_with_token(auth_token)
|
118
|
+
result = call_method("auth.getSession", {:auth_token => auth_token}, true)
|
119
|
+
if result != nil
|
120
|
+
@session_uid = result.at("uid").inner_html
|
121
|
+
@session_key = result.at("session_key").inner_html
|
122
|
+
@session_secret = result.at("secret").inner_html
|
123
|
+
end
|
124
|
+
return result
|
125
|
+
end
|
126
|
+
|
127
|
+
# Function: auth_createToken
|
128
|
+
# Returns a string auth_token
|
129
|
+
def get_auth_token
|
130
|
+
result = call_method("auth.createToken", {})
|
131
|
+
result = result.at("auth_createtoken_response").inner_html.to_s ||= result.at("auth_createToken_response").inner_html.to_s
|
132
|
+
return result
|
133
|
+
end
|
134
|
+
|
135
|
+
# Function: get_secret
|
136
|
+
# Template method, used by super::signature to generate a signature
|
137
|
+
def get_secret(params)
|
138
|
+
|
139
|
+
if ( params[:method] != "facebook.auth.getSession" and params[:method] != "facebook.auth.createToken")
|
140
|
+
return @session_secret
|
141
|
+
else
|
142
|
+
return @api_secret
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# Neither the name of the original author nor the names of contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#
|
29
|
+
|
30
|
+
#
|
31
|
+
# Some code was inspired by techniques used in Alpha Chen's old client.
|
32
|
+
# Some code was ported from the official PHP5 client.
|
33
|
+
#
|
34
|
+
|
35
|
+
require "digest/md5"
|
36
|
+
require "net/https"
|
37
|
+
require "cgi"
|
38
|
+
require "hpricot"
|
39
|
+
|
40
|
+
module RFacebook
|
41
|
+
|
42
|
+
API_SERVER_BASE_URL = "api.facebook.com"
|
43
|
+
LOGIN_SERVER_BASE_URL = "www.facebook.com"
|
44
|
+
API_SERVER_PATH = "/restserver.php"
|
45
|
+
LOGIN_SERVER_PATH = "/login.php"
|
46
|
+
|
47
|
+
class FacebookSession
|
48
|
+
|
49
|
+
attr_reader :session_uid, :session_key
|
50
|
+
attr_reader :last_call_was_successful, :last_error
|
51
|
+
attr_writer :suppress_exceptions
|
52
|
+
|
53
|
+
# SECTION: Exceptions
|
54
|
+
|
55
|
+
class RemoteException < Exception; end
|
56
|
+
class ExpiredSessionException < Exception; end
|
57
|
+
class NotActivatedException < Exception; end
|
58
|
+
|
59
|
+
# SECTION: Public Methods
|
60
|
+
|
61
|
+
# Function: initialize
|
62
|
+
# Constructs a FacebookSession
|
63
|
+
#
|
64
|
+
# Parameters:
|
65
|
+
# api_key - your API key
|
66
|
+
# api_secret - your API secret
|
67
|
+
# suppress_exceptions - boolean, set to true if you don't want exceptions to be thrown (defaults to false)
|
68
|
+
def initialize(api_key, api_secret, suppress_exceptions = false)
|
69
|
+
|
70
|
+
# required parameters
|
71
|
+
@api_key = api_key
|
72
|
+
@api_secret = api_secret
|
73
|
+
|
74
|
+
# calculated parameters
|
75
|
+
@api_server_base_url = API_SERVER_BASE_URL
|
76
|
+
@api_server_path = API_SERVER_PATH
|
77
|
+
|
78
|
+
# optional parameters
|
79
|
+
@suppress_exceptions = suppress_exceptions
|
80
|
+
|
81
|
+
# initialize internal state
|
82
|
+
@last_call_was_successful = true
|
83
|
+
@last_error = nil
|
84
|
+
@session_expired = false
|
85
|
+
|
86
|
+
# virtual members (subclasses will set these)
|
87
|
+
@session_uid = nil
|
88
|
+
@session_key = nil
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
def session_expired?
|
93
|
+
return (@session_expired == true)
|
94
|
+
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
|
98
|
+
# SECTION: Protected Abstract Interface
|
99
|
+
|
100
|
+
def get_secret(params)
|
101
|
+
raise Exception
|
102
|
+
end
|
103
|
+
|
104
|
+
def init_with_token(auth_token)
|
105
|
+
raise Exception
|
106
|
+
end
|
107
|
+
|
108
|
+
def session_key=(key)
|
109
|
+
raise Exception
|
110
|
+
end
|
111
|
+
|
112
|
+
def is_activated?
|
113
|
+
raise Exception
|
114
|
+
end
|
115
|
+
|
116
|
+
def is_valid?
|
117
|
+
raise Exception
|
118
|
+
end
|
119
|
+
|
120
|
+
# SECTION: Protected Concrete Interface
|
121
|
+
|
122
|
+
# Function: method_missing
|
123
|
+
# This allows *any* Facebook method to be called, using the Ruby
|
124
|
+
# mechanism for responding to unimplemented methods. Basically,
|
125
|
+
# this converts a call to "auth_getSession" to "auth.getSession"
|
126
|
+
# and does the proper API call using the parameter hash given.
|
127
|
+
def method_missing(methodSymbol, *params)
|
128
|
+
methodString = methodSymbol.to_s.gsub!("_", ".")
|
129
|
+
# TODO: check here for valid method names
|
130
|
+
call_method(methodString, params.first)
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Function: call_method
|
135
|
+
# Sets up the necessary parameters to make the POST request to the server
|
136
|
+
#
|
137
|
+
# Parameters:
|
138
|
+
# method - i.e. "users.getInfo"
|
139
|
+
# params - hash of key,value pairs for the parameters to this method
|
140
|
+
# use_ssl - set to true if the call will be made over SSL
|
141
|
+
def call_method(method, params={}, use_ssl=false)
|
142
|
+
|
143
|
+
# ensure that this object has been activated somehow
|
144
|
+
if (!method.include?("auth") and !is_activated?)
|
145
|
+
raise NotActivatedException, "You must activate the session before using it."
|
146
|
+
end
|
147
|
+
|
148
|
+
# set up params hash
|
149
|
+
params = params ||= {}
|
150
|
+
params[:method] = "facebook.#{method}"
|
151
|
+
params[:api_key] = @api_key
|
152
|
+
params[:v] = "1.0"
|
153
|
+
|
154
|
+
if (method != "auth.getSession" and method != "auth.createToken")
|
155
|
+
params[:session_key] = @session_key
|
156
|
+
params[:call_id] = Time.now.to_f.to_s
|
157
|
+
end
|
158
|
+
|
159
|
+
# convert arrays to comma-separated lists
|
160
|
+
params.each{|k,v| params[k] = v.join(",") if v.is_a?(Array)}
|
161
|
+
|
162
|
+
# set up the param_signature value in the params
|
163
|
+
params[:sig] = param_signature(params)
|
164
|
+
|
165
|
+
# prepare internal state
|
166
|
+
@last_call_was_successful = true
|
167
|
+
#@last_error = nil
|
168
|
+
|
169
|
+
# do the request
|
170
|
+
xmlstring = post_request(@api_server_base_url, @api_server_path, method, params, use_ssl)
|
171
|
+
xml = Hpricot(xmlstring)
|
172
|
+
|
173
|
+
# error checking
|
174
|
+
if xml.at("error_response")
|
175
|
+
@last_call_was_successful = false
|
176
|
+
code = xml.at("error_code").inner_html
|
177
|
+
msg = xml.at("error_msg").inner_html
|
178
|
+
@last_error = "ERROR #{code}: #{msg} (#{method}, #{params})"
|
179
|
+
@last_error_code = code
|
180
|
+
|
181
|
+
# check to see if this error was an expired session error
|
182
|
+
if code.to_i == 102
|
183
|
+
@session_expired = true
|
184
|
+
raise ExpiredSessionException, @last_error unless @suppress_exceptions == true
|
185
|
+
end
|
186
|
+
|
187
|
+
# otherwise, just throw a generic expired session
|
188
|
+
raise RemoteException, @last_error unless @suppress_exceptions == true
|
189
|
+
|
190
|
+
return nil
|
191
|
+
end
|
192
|
+
|
193
|
+
return xml
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
# SECTION: Private Concrete Interface
|
200
|
+
|
201
|
+
# Function: post_request
|
202
|
+
# Does a post to the given server/path, using the params as formdata
|
203
|
+
#
|
204
|
+
# Parameters:
|
205
|
+
# api_server_base_url - i.e. "api.facebook.com"
|
206
|
+
# api_server_path - i.e. "/restserver.php"
|
207
|
+
# method - i.e. "facebook.users.getInfo"
|
208
|
+
# params - hash of key/value pairs that get sent as form data to the server
|
209
|
+
# use_ssl - set to true if you want to use SSL for this request
|
210
|
+
def post_request(api_server_base_url, api_server_path, method, params, use_ssl)
|
211
|
+
|
212
|
+
# get a server handle
|
213
|
+
port = (use_ssl == true) ? 443 : 80
|
214
|
+
http_server = Net::HTTP.new(@api_server_base_url, port)
|
215
|
+
http_server.use_ssl = use_ssl
|
216
|
+
|
217
|
+
# build a request
|
218
|
+
http_request = Net::HTTP::Post.new(@api_server_path)
|
219
|
+
http_request.form_data = params
|
220
|
+
response = http_server.start{|http| http.request(http_request)}.body
|
221
|
+
|
222
|
+
# return the text of the body
|
223
|
+
return response
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
# Function: param_signature
|
228
|
+
# Generates a param_signature for a call to the API, per the spec on Facebook
|
229
|
+
# see: <http://developers.facebook.com/documentation.php?v=1.0&doc=auth>
|
230
|
+
def param_signature(params)
|
231
|
+
|
232
|
+
args = []
|
233
|
+
params.each do |k,v|
|
234
|
+
args << "#{k}=#{v}"
|
235
|
+
end
|
236
|
+
sorted_array = args.sort
|
237
|
+
request_str = sorted_array.join("")
|
238
|
+
param_signature = Digest::MD5.hexdigest("#{request_str}#{get_secret(params)}") # uses Template method get_secret
|
239
|
+
return param_signature
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# Neither the name of the original author nor the names of contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#
|
29
|
+
|
30
|
+
#
|
31
|
+
# Some code was inspired by techniques used in Alpha Chen's old client.
|
32
|
+
# Some code was ported from the official PHP5 client.
|
33
|
+
#
|
34
|
+
|
35
|
+
require "facebook_session"
|
36
|
+
|
37
|
+
module RFacebook
|
38
|
+
|
39
|
+
class FacebookWebSession < FacebookSession
|
40
|
+
|
41
|
+
# Function: get_login_url
|
42
|
+
# Gets the authentication URL
|
43
|
+
#
|
44
|
+
# Parameters:
|
45
|
+
# options.next - the page to redirect to after login
|
46
|
+
# options.popup - boolean, whether or not to use the popup style (defaults to true)
|
47
|
+
# options.skipcookie - boolean, whether to force new Facebook login (defaults to false)
|
48
|
+
# options.hidecheckbox - boolean, whether to show the "infinite session" option checkbox
|
49
|
+
def get_login_url(options={})
|
50
|
+
# options
|
51
|
+
path_next = options[:next] ||= nil
|
52
|
+
popup = (options[:popup] == nil) ? true : false
|
53
|
+
skipcookie = (options[:skipcookie] == nil) ? false : true
|
54
|
+
|
55
|
+
# get some extra portions of the URL
|
56
|
+
optionalNext = (path_next == nil) ? "" : "&next=#{CGI.escape(path_next.to_s)}"
|
57
|
+
optionalPopup = (popup == true) ? "&popup=true" : ""
|
58
|
+
optionalSkipCookie = (skipcookie == true) ? "&skipcookie=true" : ""
|
59
|
+
optionalHideCheckbox = (hidecheckbox == true) ? "&hide_checkbox=true" : ""
|
60
|
+
|
61
|
+
# build and return URL
|
62
|
+
return "http://#{LOGIN_SERVER_BASE_URL}#{LOGIN_SERVER_PATH}?v=1.0&api_key=#{@api_key}#{optionalPopup}#{optionalNext}#{optionalSkipCookie}#{optionalHideCheckbox}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Function: activate_with_token
|
66
|
+
# Gets the session information available after current user logs in.
|
67
|
+
#
|
68
|
+
# Parameters:
|
69
|
+
# auth_token - string token passed back by the callback URL
|
70
|
+
def activate_with_token(auth_token)
|
71
|
+
result = call_method("auth.getSession", {:auth_token => auth_token})
|
72
|
+
if result != nil
|
73
|
+
@session_uid = result.at("uid").inner_html
|
74
|
+
@session_key = result.at("session_key").inner_html
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Function: activate_with_previous_session
|
79
|
+
# Sets the session key directly (for example, if you have an infinite session key)
|
80
|
+
#
|
81
|
+
# Parameters:
|
82
|
+
# key - the session key to use
|
83
|
+
def activate_with_previous_session(key)
|
84
|
+
# set the session key
|
85
|
+
@session_key = key
|
86
|
+
|
87
|
+
# determine the current user's id
|
88
|
+
result = call_method("users.getLoggedInUser")
|
89
|
+
@session_uid = result.at("users_getLoggedInUser_response").inner_html
|
90
|
+
end
|
91
|
+
|
92
|
+
def is_valid?
|
93
|
+
return (is_activated? and !session_expired?)
|
94
|
+
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
|
98
|
+
def is_activated?
|
99
|
+
return (@session_key != nil)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Function: get_secret
|
103
|
+
# Template method, used by super::signature to generate a signature
|
104
|
+
def get_secret(params)
|
105
|
+
|
106
|
+
return @api_secret
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: rfacebook
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.5.0
|
7
|
+
date: 2007-05-08 00:00:00 -04:00
|
8
|
+
summary: A Ruby interface to the Facebook API v1.0+
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: matt@livelearncode.com
|
12
|
+
homepage: http://livelearncode.com/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: rfacebook
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Matt Pizzimenti
|
31
|
+
files:
|
32
|
+
- lib/facebook_desktop_session.rb
|
33
|
+
- lib/facebook_session.rb
|
34
|
+
- lib/facebook_web_session.rb
|
35
|
+
- README
|
36
|
+
test_files: []
|
37
|
+
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- README
|
42
|
+
executables: []
|
43
|
+
|
44
|
+
extensions: []
|
45
|
+
|
46
|
+
requirements: []
|
47
|
+
|
48
|
+
dependencies:
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: hpricot
|
51
|
+
version_requirement:
|
52
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.4.0
|
57
|
+
version:
|