rfacebook 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|