facebooker 1.0.18 → 1.0.29
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/{History.txt → CHANGELOG.rdoc} +0 -0
- data/{COPYING → COPYING.rdoc} +0 -0
- data/{README.txt → README.rdoc} +11 -4
- data/Rakefile +18 -15
- data/{TODO.txt → TODO.rdoc} +0 -0
- data/generators/facebook/templates/config/facebooker.yml +3 -0
- data/init.rb +12 -61
- data/lib/facebooker.rb +22 -15
- data/lib/facebooker/adapters/adapter_base.rb +3 -0
- data/lib/facebooker/logging.rb +1 -1
- data/lib/facebooker/model.rb +6 -4
- data/lib/facebooker/models/user.rb +39 -4
- data/lib/facebooker/parser.rb +14 -0
- data/lib/facebooker/rails/controller.rb +34 -10
- data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
- data/lib/facebooker/rails/extensions/rack_setup.rb +2 -0
- data/lib/facebooker/rails/extensions/routing.rb +15 -0
- data/lib/facebooker/rails/facebook_url_helper.rb +3 -3
- data/lib/facebooker/rails/facebook_url_rewriting.rb +18 -5
- data/lib/facebooker/rails/helpers.rb +19 -2
- data/lib/facebooker/rails/helpers/fb_connect.rb +20 -10
- data/lib/facebooker/rails/publisher.rb +9 -5
- data/lib/facebooker/service.rb +1 -2
- data/lib/facebooker/session.rb +13 -1
- data/lib/facebooker/version.rb +1 -1
- data/lib/rack/facebook.rb +77 -0
- data/lib/tasks/tunnel.rake +3 -3
- data/test/facebooker/logging_test.rb +2 -2
- data/test/facebooker/models/user_test.rb +39 -3
- data/test/facebooker/rails/publisher_test.rb +19 -3
- data/test/facebooker/rails_integration_test.rb +52 -6
- data/test/rack/facebook_test.rb +62 -0
- data/test/rails_test_helper.rb +2 -0
- metadata +21 -27
- data/CHANGELOG.txt +0 -0
- data/Manifest.txt +0 -127
- data/README +0 -46
- data/lib/facebooker/models/user.rb.orig +0 -396
- data/lib/facebooker/models/user.rb.rej +0 -17
- data/lib/facebooker/session.rb.orig +0 -564
- data/lib/facebooker/session.rb.rej +0 -29
@@ -0,0 +1,48 @@
|
|
1
|
+
module ::ActionController
|
2
|
+
class Base
|
3
|
+
def self.inherited_with_facebooker(subclass)
|
4
|
+
inherited_without_facebooker(subclass)
|
5
|
+
if subclass.to_s == "ApplicationController"
|
6
|
+
subclass.send(:include,Facebooker::Rails::Controller)
|
7
|
+
subclass.helper Facebooker::Rails::Helpers
|
8
|
+
end
|
9
|
+
end
|
10
|
+
class << self
|
11
|
+
alias_method_chain :inherited, :facebooker
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# When making get requests, Facebook sends fb_sig parameters both in the query string
|
18
|
+
# and also in the post body. We want to ignore the query string ones because they are one
|
19
|
+
# request out of date
|
20
|
+
# We only do thise when there are POST parameters so that IFrame linkage still works
|
21
|
+
if Rails.version < '2.3'
|
22
|
+
class ActionController::AbstractRequest
|
23
|
+
def query_parameters_with_facebooker
|
24
|
+
if request_parameters.blank?
|
25
|
+
query_parameters_without_facebooker
|
26
|
+
else
|
27
|
+
(query_parameters_without_facebooker||{}).reject {|key,value| key.to_s =~ /^fb_sig/}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method_chain :query_parameters, :facebooker
|
32
|
+
end
|
33
|
+
else
|
34
|
+
class ActionController::Request
|
35
|
+
def query_parameters_with_facebooker
|
36
|
+
if request_parameters.blank?
|
37
|
+
query_parameters_without_facebooker
|
38
|
+
else
|
39
|
+
(query_parameters_without_facebooker||{}).reject {|key,value| key.to_s =~ /^fb_sig/}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method_chain :query_parameters, :facebooker
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Mime::Type.register_alias "text/html", :fbml
|
48
|
+
Mime::Type.register_alias "text/javascript", :fbjs
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ActionController::Routing::Route
|
2
|
+
def recognition_conditions_with_facebooker
|
3
|
+
defaults = recognition_conditions_without_facebooker
|
4
|
+
defaults << " env[:canvas] == conditions[:canvas] " if conditions[:canvas]
|
5
|
+
defaults
|
6
|
+
end
|
7
|
+
alias_method_chain :recognition_conditions, :facebooker
|
8
|
+
end
|
9
|
+
|
10
|
+
# We turn off route optimization to make named routes use our code for figuring out if they should go to the session
|
11
|
+
ActionController::Base::optimise_named_routes = false
|
12
|
+
|
13
|
+
# pull :canvas=> into env in routing to allow for conditions
|
14
|
+
ActionController::Routing::RouteSet.send :include, Facebooker::Rails::Routing::RouteSetExtensions
|
15
|
+
ActionController::Routing::RouteSet::Mapper.send :include, Facebooker::Rails::Routing::MapperExtensions
|
@@ -50,7 +50,7 @@ module ActionView
|
|
50
50
|
module UrlHelper
|
51
51
|
# Alters one and only one line of the Rails button_to. See below.
|
52
52
|
def button_to_with_facebooker(name, options={}, html_options = {})
|
53
|
-
if !request_comes_from_facebook?
|
53
|
+
if !respond_to?(:request_comes_from_facebook?) || !request_comes_from_facebook?
|
54
54
|
button_to_without_facebooker(name,options,html_options)
|
55
55
|
else
|
56
56
|
html_options = html_options.stringify_keys
|
@@ -125,7 +125,7 @@ module ActionView
|
|
125
125
|
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?"})
|
126
126
|
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?", :color=>"pink"})
|
127
127
|
def confirm_javascript_function_with_facebooker(confirm, fun = nil)
|
128
|
-
if !request_comes_from_facebook?
|
128
|
+
if !respond_to?(:request_comes_from_facebook?) || !request_comes_from_facebook?
|
129
129
|
confirm_javascript_function_without_facebooker(confirm)
|
130
130
|
else
|
131
131
|
if(confirm.is_a?(Hash))
|
@@ -157,7 +157,7 @@ module ActionView
|
|
157
157
|
# Dynamically creates a form for link_to with method. Calls confirm_javascript_function if and
|
158
158
|
# only if (confirm && method) for link_to
|
159
159
|
def method_javascript_function_with_facebooker(method, url = '', href = nil, confirm = nil)
|
160
|
-
if !request_comes_from_facebook?
|
160
|
+
if !respond_to?(:request_comes_from_facebook?) || !request_comes_from_facebook?
|
161
161
|
method_javascript_function_without_facebooker(method,url,href)
|
162
162
|
else
|
163
163
|
action = (href && url.size > 0) ? "'#{url}'" : 'a.getHref()'
|
@@ -1,8 +1,16 @@
|
|
1
1
|
module ::ActionController
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
if Rails.version < '2.3'
|
3
|
+
class AbstractRequest
|
4
|
+
def relative_url_root
|
5
|
+
Facebooker.path_prefix
|
6
|
+
end
|
7
|
+
end
|
8
|
+
else
|
9
|
+
class Request
|
10
|
+
def relative_url_root
|
11
|
+
Facebooker.path_prefix
|
12
|
+
end
|
13
|
+
end
|
6
14
|
end
|
7
15
|
|
8
16
|
class Base
|
@@ -19,7 +27,12 @@ module ::ActionController
|
|
19
27
|
def link_to_canvas?(params, options)
|
20
28
|
option_override = options[:canvas]
|
21
29
|
return false if option_override == false # important to check for false. nil should use default behavior
|
22
|
-
option_override || @request.parameters["fb_sig_in_canvas"] == "1" || @request.parameters[:fb_sig_in_canvas] == "1"
|
30
|
+
option_override || (can_safely_access_request_parameters? && (@request.parameters["fb_sig_in_canvas"] == "1" || @request.parameters[:fb_sig_in_canvas] == "1" ))
|
31
|
+
end
|
32
|
+
|
33
|
+
#rails blindly tries to merge things that may be nil into the parameters. Make sure this won't break
|
34
|
+
def can_safely_access_request_parameters?
|
35
|
+
@request.request_parameters
|
23
36
|
end
|
24
37
|
|
25
38
|
def rewrite_url_with_facebooker(*args)
|
@@ -44,6 +44,13 @@ module Facebooker
|
|
44
44
|
|
45
45
|
FB_DIALOG_BUTTON_VALID_OPTION_KEYS = [:close_dialog, :href, :form_id, :clickrewriteurl, :clickrewriteid, :clickrewriteform]
|
46
46
|
|
47
|
+
def fb_show_feed_dialog(action, user_message = "", prompt = "", callback = nil)
|
48
|
+
update_page do |page|
|
49
|
+
page.call "Facebook.showFeedDialog",action.template_id,action.data,action.body_general,action.target_ids,callback,prompt,user_message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
47
54
|
# Create an fb:request-form without a selector
|
48
55
|
#
|
49
56
|
# The block passed to this tag is used as the content of the form
|
@@ -282,15 +289,25 @@ module Facebooker
|
|
282
289
|
|
283
290
|
# Render an <fb:profile-pic> for the specified user.
|
284
291
|
#
|
285
|
-
# You can optionally specify the size using the :size=> option.
|
292
|
+
# You can optionally specify the size using the :size=> option. Valid
|
293
|
+
# sizes are :thumb, :small, :normal and :square. Or, you can specify
|
294
|
+
# width and height settings instead, just like an img tag.
|
295
|
+
#
|
296
|
+
# You can optionally specify whether or not to include the facebook icon
|
297
|
+
# overlay using the :facebook_logo => true option. Default is false.
|
286
298
|
#
|
287
|
-
# Valid sizes are :thumb, :small, :normal and :square
|
288
299
|
def fb_profile_pic(user, options={})
|
289
300
|
options = options.dup
|
290
301
|
validate_fb_profile_pic_size(options)
|
302
|
+
options.transform_keys!(FB_PROFILE_PIC_OPTION_KEYS_TO_TRANSFORM)
|
303
|
+
options.assert_valid_keys(FB_PROFILE_PIC_VALID_OPTION_KEYS)
|
291
304
|
options.merge!(:uid => cast_to_facebook_id(user))
|
292
305
|
content_tag("fb:profile-pic", nil,stringify_vals(options))
|
293
306
|
end
|
307
|
+
|
308
|
+
FB_PROFILE_PIC_OPTION_KEYS_TO_TRANSFORM = {:facebook_logo => 'facebook-logo'}
|
309
|
+
FB_PROFILE_PIC_VALID_OPTION_KEYS = [:size, :linked, 'facebook-logo', :width, :height]
|
310
|
+
|
294
311
|
|
295
312
|
# Render an fb:photo tag.
|
296
313
|
# photo is either a Facebooker::Photo or an id of a Facebook photo or an object that responds to photo_id.
|
@@ -16,10 +16,19 @@ module Facebooker
|
|
16
16
|
if block_given?
|
17
17
|
additions = capture(&proc)
|
18
18
|
end
|
19
|
+
|
20
|
+
options = {:js => :prototype}
|
21
|
+
if required_features.last.is_a?(Hash)
|
22
|
+
options.merge!(required_features.pop.symbolize_keys)
|
23
|
+
end
|
24
|
+
|
19
25
|
init_string = "FB.Facebook.init('#{Facebooker.api_key}','/xd_receiver.html');"
|
20
26
|
unless required_features.blank?
|
21
27
|
init_string = <<-FBML
|
22
|
-
|
28
|
+
#{case options[:js]
|
29
|
+
when :jquery then "$(document).ready("
|
30
|
+
else "Element.observe(window,'load',"
|
31
|
+
end} function() {
|
23
32
|
FB_RequireFeatures(#{required_features.to_json}, function() {
|
24
33
|
#{init_string}
|
25
34
|
#{additions}
|
@@ -27,8 +36,8 @@ module Facebooker
|
|
27
36
|
});
|
28
37
|
FBML
|
29
38
|
end
|
30
|
-
if block_given?
|
31
|
-
concat
|
39
|
+
if block_given? && block_is_within_action_view?(proc)
|
40
|
+
concat(javascript_tag(init_string), proc.binding)
|
32
41
|
else
|
33
42
|
javascript_tag init_string
|
34
43
|
end
|
@@ -54,32 +63,33 @@ module Facebooker
|
|
54
63
|
def fb_login_button(*args)
|
55
64
|
|
56
65
|
callback = args.first
|
57
|
-
options = args
|
66
|
+
options = args[1] || {}
|
58
67
|
options.merge!(:onlogin=>callback)if callback
|
59
68
|
|
60
69
|
content_tag("fb:login-button",nil, options)
|
61
70
|
end
|
62
|
-
|
71
|
+
|
72
|
+
def fb_login_and_redirect(url, options = {})
|
63
73
|
js = update_page do |page|
|
64
74
|
page.redirect_to url
|
65
75
|
end
|
66
|
-
content_tag("fb:login-button",nil
|
76
|
+
content_tag("fb:login-button",nil,options.merge(:onlogin=>js))
|
67
77
|
end
|
68
78
|
|
69
79
|
def fb_unconnected_friends_count
|
70
80
|
content_tag "fb:unconnected-friends-count",nil
|
71
81
|
end
|
72
82
|
|
73
|
-
def fb_logout_link(text,url)
|
83
|
+
def fb_logout_link(text,url,*args)
|
74
84
|
js = update_page do |page|
|
75
85
|
page.call "FB.Connect.logoutAndRedirect",url
|
76
86
|
end
|
77
|
-
link_to_function text, js
|
87
|
+
link_to_function text, js, *args
|
78
88
|
end
|
79
89
|
|
80
|
-
def fb_user_action(action)
|
90
|
+
def fb_user_action(action, user_message = "", prompt = "", callback = nil)
|
81
91
|
update_page do |page|
|
82
|
-
page.call "FB.Connect.showFeedDialog",action.template_id,action.data,action.target_ids,action.body_general,nil,"FB.RequireConnect.promptConnect"
|
92
|
+
page.call "FB.Connect.showFeedDialog",action.template_id,action.data,action.target_ids,action.body_general,nil,page.literal("FB.RequireConnect.promptConnect"),callback,prompt,user_message
|
83
93
|
end
|
84
94
|
end
|
85
95
|
|
@@ -224,12 +224,12 @@ module Facebooker
|
|
224
224
|
attr_accessor :template_id
|
225
225
|
attr_accessor :template_name
|
226
226
|
attr_accessor :story_size
|
227
|
+
|
227
228
|
def target_ids=(val)
|
228
229
|
@target_ids = val.is_a?(Array) ? val.join(",") : val
|
229
230
|
end
|
230
231
|
def data_hash
|
231
|
-
|
232
|
-
default_data.merge(data||{})
|
232
|
+
data||{}
|
233
233
|
end
|
234
234
|
end
|
235
235
|
|
@@ -377,7 +377,7 @@ module Facebooker
|
|
377
377
|
when Ref
|
378
378
|
Facebooker::Session.create.server_cache.set_ref_handle(_body.handle,_body.fbml)
|
379
379
|
when UserAction
|
380
|
-
@from.session.publish_user_action(_body.template_id,_body.data_hash,_body.target_ids,_body.body_general)
|
380
|
+
@from.session.publish_user_action(_body.template_id,_body.data_hash,_body.target_ids,_body.body_general,_body.story_size)
|
381
381
|
else
|
382
382
|
raise UnspecifiedBodyType.new("You must specify a valid send_as")
|
383
383
|
end
|
@@ -404,7 +404,10 @@ module Facebooker
|
|
404
404
|
#only do this on Rails 2.1
|
405
405
|
if ActionController::Base.respond_to?(:append_view_path)
|
406
406
|
# only add the view path once
|
407
|
-
|
407
|
+
unless ActionController::Base.view_paths.include?(controller_root)
|
408
|
+
ActionController::Base.append_view_path(controller_root)
|
409
|
+
ActionController::Base.append_view_path(controller_root+"/..")
|
410
|
+
end
|
408
411
|
end
|
409
412
|
returning ActionView::Base.new([template_root,controller_root], assigns, self) do |template|
|
410
413
|
template.controller=self
|
@@ -427,6 +430,7 @@ module Facebooker
|
|
427
430
|
include ActionView::Helpers::FormHelper
|
428
431
|
include ActionView::Helpers::FormTagHelper
|
429
432
|
include ActionView::Helpers::AssetTagHelper
|
433
|
+
include ActionView::Helpers::NumberHelper
|
430
434
|
include Facebooker::Rails::Helpers
|
431
435
|
|
432
436
|
#define this for the publisher views
|
@@ -471,7 +475,7 @@ module Facebooker
|
|
471
475
|
case publisher._body
|
472
476
|
when UserAction
|
473
477
|
publisher._body.template_name = method
|
474
|
-
publisher._body.template_id
|
478
|
+
publisher._body.template_id ||= FacebookTemplate.bundle_id_for_class_and_method(self,method)
|
475
479
|
end
|
476
480
|
|
477
481
|
should_send ? publisher.send_message(method) : publisher._body
|
data/lib/facebooker/service.rb
CHANGED
data/lib/facebooker/session.rb
CHANGED
@@ -6,7 +6,15 @@ module Facebooker
|
|
6
6
|
# other than the logged in user (if that's unallowed)
|
7
7
|
class NonSessionUser < StandardError; end
|
8
8
|
class Session
|
9
|
+
|
10
|
+
#
|
11
|
+
# Raised when a facebook session has expired. This
|
12
|
+
# happens when the timeout is reached, or when the
|
13
|
+
# user logs out of facebook
|
14
|
+
# can be handled with:
|
15
|
+
# rescue_from Facebooker::Session::SessionExpired, :with => :some_method_name
|
9
16
|
class SessionExpired < StandardError; end
|
17
|
+
|
10
18
|
class UnknownError < StandardError; end
|
11
19
|
class ServiceUnavailable < StandardError; end
|
12
20
|
class MaxRequestsDepleted < StandardError; end
|
@@ -48,6 +56,9 @@ module Facebooker
|
|
48
56
|
class TooManyUnapprovedPhotosPending < StandardError; end
|
49
57
|
class ExtendedPermissionRequired < StandardError; end
|
50
58
|
class InvalidFriendList < StandardError; end
|
59
|
+
class UserUnRegistrationFailed < StandardError
|
60
|
+
attr_accessor :failed_users
|
61
|
+
end
|
51
62
|
class UserRegistrationFailed < StandardError
|
52
63
|
attr_accessor :failed_users
|
53
64
|
end
|
@@ -360,10 +371,11 @@ module Facebooker
|
|
360
371
|
# publish a previously rendered template bundle
|
361
372
|
# see http://wiki.developers.facebook.com/index.php/Feed.publishUserAction
|
362
373
|
#
|
363
|
-
def publish_user_action(bundle_id,data={},target_ids=nil,body_general=nil)
|
374
|
+
def publish_user_action(bundle_id,data={},target_ids=nil,body_general=nil,story_size=nil)
|
364
375
|
parameters={:template_bundle_id=>bundle_id,:template_data=>data.to_json}
|
365
376
|
parameters[:target_ids] = target_ids unless target_ids.blank?
|
366
377
|
parameters[:body_general] = body_general unless body_general.blank?
|
378
|
+
parameters[:story_size] = story_size unless story_size.nil?
|
367
379
|
post("facebook.feed.publishUserAction", parameters)
|
368
380
|
end
|
369
381
|
|
data/lib/facebooker/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Rack
|
2
|
+
# This Rack middleware checks the signature of Facebook params, and
|
3
|
+
# converts them to Ruby objects when appropiate. Also, it converts
|
4
|
+
# the request method from the Facebook POST to the original HTTP
|
5
|
+
# method used by the client.
|
6
|
+
#
|
7
|
+
# If the signature is wrong, it returns a "400 Invalid Facebook Signature".
|
8
|
+
#
|
9
|
+
# Optionally, it can take a block that receives the Rack environment
|
10
|
+
# and returns a value that evaluates to true when we want the middleware to
|
11
|
+
# be executed for the specific request.
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
#
|
15
|
+
# In your config.ru:
|
16
|
+
#
|
17
|
+
# require 'rack/facebook'
|
18
|
+
# use Rack::Facebook, "my_facebook_secret_key"
|
19
|
+
#
|
20
|
+
# Using a block condition:
|
21
|
+
#
|
22
|
+
# use Rack::Facebook, "my_facebook_secret_key" do |env|
|
23
|
+
# env['REQUEST_URI'] =~ /^\/facebook_only/
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
class Facebook
|
27
|
+
def initialize(app, secret_key, &condition)
|
28
|
+
@app = app
|
29
|
+
@secret_key = secret_key
|
30
|
+
@condition = condition
|
31
|
+
end
|
32
|
+
|
33
|
+
def call(env)
|
34
|
+
if @condition.nil? || @condition.call(env)
|
35
|
+
request = Rack::Request.new(env)
|
36
|
+
fb_params = extract_fb_sig_params(request.POST)
|
37
|
+
unless fb_params.empty?
|
38
|
+
unless signature_is_valid?(fb_params, request.POST['fb_sig'])
|
39
|
+
return Rack::Response.new(["Invalid Facebook signature"], 400).finish
|
40
|
+
end
|
41
|
+
env['REQUEST_METHOD'] = fb_params["request_method"] if fb_params["request_method"]
|
42
|
+
convert_parameters!(request.POST)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@app.call(env)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def extract_fb_sig_params(params)
|
51
|
+
params.inject({}) do |collection, (param, value)|
|
52
|
+
collection[param.sub(/^fb_sig_/, '')] = value if param[0,7] == 'fb_sig_'
|
53
|
+
collection
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def signature_is_valid?(fb_params, actual_sig)
|
58
|
+
raw_string = fb_params.map{ |*args| args.join('=') }.sort.join
|
59
|
+
expected_signature = Digest::MD5.hexdigest([raw_string, @secret_key].join)
|
60
|
+
actual_sig == expected_signature
|
61
|
+
end
|
62
|
+
|
63
|
+
def convert_parameters!(params)
|
64
|
+
|
65
|
+
params.each do |key, value|
|
66
|
+
case key
|
67
|
+
when 'fb_sig_added', 'fb_sig_in_canvas', 'fb_sig_in_new_facebook', 'fb_sig_position_fix', 'fb_sig_is_ajax'
|
68
|
+
params[key] = value == "1"
|
69
|
+
when 'fb_sig_expires', 'fb_sig_profile_update_time', 'fb_sig_time'
|
70
|
+
params[key] = value == "0" ? nil : Time.at(value.to_f)
|
71
|
+
when 'fb_sig_friends'
|
72
|
+
params[key] = value.split(',')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/tasks/tunnel.rake
CHANGED
@@ -19,8 +19,7 @@ namespace :facebooker do
|
|
19
19
|
# Adapted from Evan Weaver: http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally/
|
20
20
|
desc "Check if reverse tunnel is running"
|
21
21
|
task :status => [ :environment, :config ] do
|
22
|
-
if `ssh #{@public_host} -l #{@public_host_username} netstat -an |
|
23
|
-
egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
|
22
|
+
if `ssh #{@public_host} -l #{@public_host_username} netstat -an | egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
|
24
23
|
puts "Seems ok"
|
25
24
|
else
|
26
25
|
puts "Down"
|
@@ -35,10 +34,11 @@ namespace :facebooker do
|
|
35
34
|
@public_port = FACEBOOKER['tunnel']['public_port']
|
36
35
|
@local_port = FACEBOOKER['tunnel']['local_port']
|
37
36
|
@ssh_port = FACEBOOKER['tunnel']['ssh_port'] || 22
|
37
|
+
@server_alive_interval = FACEBOOKER['tunnel']['server_alive_interval'] || 0
|
38
38
|
@notification = "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
|
39
39
|
@notification << " using SSH port #{@ssh_port}" unless @ssh_port == 22
|
40
40
|
# "GatewayPorts yes" needs to be enabled in the remote's sshd config
|
41
|
-
@ssh_command =
|
41
|
+
@ssh_command = %Q[ssh -v -p #{@ssh_port} -nNT4 -o "ServerAliveInterval #{@server_alive_interval}" -R *:#{@public_port}:localhost:#{@local_port} #{@public_host_username}@#{@public_host}]
|
42
42
|
end
|
43
43
|
end
|
44
44
|
desc "Create a reverse ssh tunnel from a public server to a private development server."
|