faceb 0.1.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/.document +5 -0
- data/.gitignore +24 -0
- data/Gemfile +13 -0
- data/LICENSE +20 -0
- data/README.md +70 -0
- data/Rakefile +76 -0
- data/VERSION +1 -0
- data/bin/console +3 -0
- data/faceb.gemspec +164 -0
- data/features/faceb-session.feature +7 -0
- data/features/step_definitions/facebook-session_steps.rb +14 -0
- data/features/support/env.rb +4 -0
- data/lib/faceb.rb +7 -0
- data/lib/faceb/api.rb +69 -0
- data/lib/faceb/base.rb +51 -0
- data/lib/faceb/rails.rb +12 -0
- data/lib/faceb/rails/api.rb +21 -0
- data/lib/faceb/rails/base.rb +30 -0
- data/lib/faceb/rails/configuration.rb +31 -0
- data/lib/faceb/rails/controller.rb +49 -0
- data/lib/faceb/rails/generators.rb +3 -0
- data/lib/faceb/rails/generators/config/USAGE +8 -0
- data/lib/faceb/rails/generators/config/config_generator.rb +16 -0
- data/lib/faceb/rails/generators/config/templates/faceb.yml +6 -0
- data/lib/faceb/rails/generators/fb_connect/USAGE +7 -0
- data/lib/faceb/rails/generators/fb_connect/fb_connect_generator.rb +16 -0
- data/lib/faceb/rails/generators/fb_connect/templates/xd_receiver.html +10 -0
- data/lib/faceb/rails/generators/fb_connect/templates/xd_receiver_ssl.html +10 -0
- data/lib/faceb/rails/rails_23_init.rb +21 -0
- data/lib/faceb/rails/railtie.rb +39 -0
- data/lib/faceb/rails/tasks.rb +2 -0
- data/lib/faceb/rails/tasks/faceb.tasks +6 -0
- data/lib/faceb/rails/tasks/tunnel.tasks +46 -0
- data/lib/faceb/session.rb +38 -0
- data/spec/faceb_api_spec.rb +107 -0
- data/spec/faceb_base_spec.rb +48 -0
- data/spec/faceb_session_spec.rb +64 -0
- data/spec/rails/config_generator_spec.rb +39 -0
- data/spec/rails/configuration_sepc.rb +11 -0
- data/spec/rails/controller_spec.rb +39 -0
- data/spec/rails/fb_connect_generator_spec.rb +28 -0
- data/spec/rails/railtie_spec.rb +23 -0
- data/spec/rails_app/app/controllers/application_controller.rb +3 -0
- data/spec/rails_app/app/controllers/posts_controller.rb +7 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +46 -0
- data/spec/rails_app/config/boot.rb +9 -0
- data/spec/rails_app/config/database.yml +22 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/development.rb +19 -0
- data/spec/rails_app/config/environments/production.rb +33 -0
- data/spec/rails_app/config/environments/test.rb +32 -0
- data/spec/rails_app/config/faceb.yml +3 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/cookie_verification_secret.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/initializers/session_store.rb +10 -0
- data/spec/rails_app/config/locales/en.yml +5 -0
- data/spec/rails_app/config/routes.rb +58 -0
- data/spec/rails_app/log/development.log +0 -0
- data/spec/rails_app/log/production.log +0 -0
- data/spec/rails_app/log/server.log +0 -0
- data/spec/rails_app/log/test.log +0 -0
- data/spec/rails_app/public/404.html +26 -0
- data/spec/rails_app/public/422.html +26 -0
- data/spec/rails_app/public/500.html +26 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/javascripts/application.js +2 -0
- data/spec/rails_app/public/javascripts/controls.js +965 -0
- data/spec/rails_app/public/javascripts/dragdrop.js +974 -0
- data/spec/rails_app/public/javascripts/effects.js +1123 -0
- data/spec/rails_app/public/javascripts/prototype.js +4874 -0
- data/spec/rails_app/public/javascripts/rails.js +110 -0
- data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
- data/spec/rails_app/script/rails +9 -0
- data/spec/rails_spec_helper.rb +6 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +27 -0
- metadata +247 -0
data/lib/faceb/base.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module FaceB
|
2
|
+
class << self
|
3
|
+
##
|
4
|
+
# Return the current Facebook session
|
5
|
+
#
|
6
|
+
# @return [FaceB::Session] The current facebook session
|
7
|
+
def current_session
|
8
|
+
Session.current
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Create a new Facebook session
|
13
|
+
#
|
14
|
+
# @param [String] api_key The Facebook application api key
|
15
|
+
# @param [String] secret_key The Facebook application secret key
|
16
|
+
# @param [String] session_key The session key of a Facebook user
|
17
|
+
#
|
18
|
+
# @return [FaceB::Session] The new current facebook session
|
19
|
+
#
|
20
|
+
# @example Create a new session
|
21
|
+
# FaceB.new('api-key', 'secret-key')
|
22
|
+
# @example Create a new session with a specific session key
|
23
|
+
# FaceB.new('api-key', 'secret-key', 'session-key')
|
24
|
+
#
|
25
|
+
# @see FaceB::Session.create
|
26
|
+
def new(api_key = nil, secret_key = nil, session_key = nil)
|
27
|
+
Session.create(api_key, secret_key, session_key)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Call a Facebook API method
|
32
|
+
#
|
33
|
+
# @param [String] api_key The Facebook application api key
|
34
|
+
# @param [String] secret_key The Facebook application secret key
|
35
|
+
# @param [String] method The API method to call
|
36
|
+
# @param [Hash] params Params to pass to API method call (see FaceB::Api#call)
|
37
|
+
#
|
38
|
+
# @return [FaceB::Api::Response] The API method response
|
39
|
+
#
|
40
|
+
# @example Call a method
|
41
|
+
# FaceB.call('api-key', 'secret-key', 'method.name', :key1 => 'value1')
|
42
|
+
# @example Call a method with a specific
|
43
|
+
# FaceB.call('api-key', 'secret-key', 'method.name', :key1 => 'value1', :secret_key => 'session-key')
|
44
|
+
#
|
45
|
+
# @see FaceB::Api#call
|
46
|
+
# @see FaceB::Session#call
|
47
|
+
def call(api_key, secret_key, method, params = {})
|
48
|
+
Session.new(api_key, secret_key).call(method, params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/faceb/rails.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
if Rails.version >= "3.0"
|
2
|
+
require 'faceb/rails/railtie'
|
3
|
+
require 'faceb/rails/generators'
|
4
|
+
elsif Rails.version >= "2.3"
|
5
|
+
require 'faceb/rails/rails_23_init'
|
6
|
+
else
|
7
|
+
raise "Sorry, but FaceB needs Rails 2.3 or later"
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'faceb/rails/base'
|
11
|
+
require 'faceb/rails/api'
|
12
|
+
require 'faceb/rails/controller'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FaceB
|
2
|
+
Api.class_eval do
|
3
|
+
def call_with_rails(method, params = {})
|
4
|
+
ActiveSupport::Notifications.instrument("faceb.api", :method => method, :params => params) do
|
5
|
+
call_without_rails(method, params)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method :call_without_rails, :call
|
10
|
+
alias_method :call, :call_with_rails
|
11
|
+
end
|
12
|
+
|
13
|
+
class LogSubscriber < Rails::LogSubscriber
|
14
|
+
def api(event)
|
15
|
+
debug color("FaceB call method '#{event.payload[:method]}' with #{event.payload[:params].inspect} in (#{event.duration})", :blue, true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add log for API method call
|
21
|
+
Rails::LogSubscriber.add :faceb, FaceB::LogSubscriber.new
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'faceb/rails/configuration'
|
2
|
+
|
3
|
+
module FaceB
|
4
|
+
class << self
|
5
|
+
|
6
|
+
##
|
7
|
+
# Return FaceB config file path
|
8
|
+
#
|
9
|
+
# @return [String] config file path
|
10
|
+
def config_file_path
|
11
|
+
File.join(::Rails.root, 'config', 'faceb.yml')
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Return the current Facebook Rails configuration
|
16
|
+
#
|
17
|
+
# @return [FaceB::Configuration] the current Facebook Rails configuration
|
18
|
+
def config
|
19
|
+
FaceB::Configuration.config
|
20
|
+
end
|
21
|
+
|
22
|
+
# Change method signature with default api_key and secret_key
|
23
|
+
def new_with_rails(api_key = FaceB.config.api_key, secret_key = FaceB.config.secret_key, session_key = nil)
|
24
|
+
new_without_rails(api_key, secret_key, session_key)
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :new_without_rails, :new
|
28
|
+
alias_method :new, :new_with_rails
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module FaceB
|
4
|
+
class Configuration
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args)
|
10
|
+
@config[name.to_s]
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
# Load a config file to create a new instance of Configuration
|
16
|
+
#
|
17
|
+
# @param [String] file File path
|
18
|
+
# @param [String] environment The Rails environment
|
19
|
+
def self.load_config_file(file, environment)
|
20
|
+
@config = self.new(YAML.load_file(file)[environment])
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Return the current configuration instance
|
25
|
+
#
|
26
|
+
# @return [FaceB::Configuration] The current configuration instance
|
27
|
+
def self.config
|
28
|
+
@config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module FaceB
|
2
|
+
module Rails
|
3
|
+
module Controller
|
4
|
+
|
5
|
+
def self.included(controller)
|
6
|
+
controller.extend(ClassMethods)
|
7
|
+
controller.before_filter :set_facebook_request_format
|
8
|
+
controller.helper_method :facebook_session
|
9
|
+
end
|
10
|
+
|
11
|
+
def facebook_session
|
12
|
+
FaceB::Session.current
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_facebook_session
|
16
|
+
FaceB::Session.create(FaceB.config.api_key, FaceB.config.secret_key, env['facebook.session_key'])
|
17
|
+
end
|
18
|
+
|
19
|
+
def ensure_authenticated_to_facebook
|
20
|
+
create_facebook_session
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return true if request comes from a Facebook canvas
|
24
|
+
def in_canvas?
|
25
|
+
!!env['facebook.in_canvas']
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return true if request comes from a Facebook iframe
|
29
|
+
def in_iframe?
|
30
|
+
!!env["facebook.in_iframe"]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set the request format
|
34
|
+
def set_facebook_request_format
|
35
|
+
if in_canvas? && !in_iframe?
|
36
|
+
request.format = :fbml
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Class methods
|
41
|
+
module ClassMethods
|
42
|
+
def ensure_authenticated_to_facebook(options = {})
|
43
|
+
before_filter :ensure_authenticated_to_facebook, options
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module FaceB
|
4
|
+
class ConfigGenerator < Rails::Generators::Base
|
5
|
+
class_option :api_key, :type => :string, :aliases => '-a', :desc => "Facebook API key"
|
6
|
+
class_option :secret_key, :type => :string, :aliases => '-s', :desc => "Facebook secret key"
|
7
|
+
|
8
|
+
def create_config_file
|
9
|
+
template "faceb.yml", "config/faceb.yml"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.join(File.dirname(__FILE__), 'templates')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module FaceB
|
4
|
+
class FbConnectGenerator < Rails::Generators::Base
|
5
|
+
class_option :ssl, :type => :boolean, :desc => "SSL support"
|
6
|
+
|
7
|
+
def create_xd_receiver_file
|
8
|
+
file = options.ssl ? 'xd_receiver_ssl.html' : 'xd_receiver.html'
|
9
|
+
template file, "public/#{file}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.join(File.dirname(__FILE__), 'templates')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" >
|
4
|
+
<head>
|
5
|
+
<title>Cross-Domain Receiver Page</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" >
|
4
|
+
<head>
|
5
|
+
<title>Cross-Domain Receiver Page</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<script src="https://ssl.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Rails.configuration.after_initialize do
|
2
|
+
require 'rack/facebook'
|
3
|
+
|
4
|
+
# Load the FaceB config file
|
5
|
+
begin
|
6
|
+
@facebook_config = FaceB::Configuration.load_config_file(FaceB.config_file_path, ::Rails.env)
|
7
|
+
rescue Errno::ENOENT
|
8
|
+
puts "Warning : config/faceb.yml is not present. Maybe you should called rake faceb:init"
|
9
|
+
rescue
|
10
|
+
puts "Error during load FaceB config file."
|
11
|
+
end
|
12
|
+
|
13
|
+
# Load Rack-Facebook as a middleware
|
14
|
+
Rails.configuration.middleware.use Rack::Facebook, {
|
15
|
+
:application_secret => @facebook_config.secret_key,
|
16
|
+
:api_key => @facebook_config.api_key
|
17
|
+
}
|
18
|
+
|
19
|
+
# Registered FBML request type
|
20
|
+
Mime::Type.register "text/html", :fbml
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'faceb'
|
3
|
+
require 'rack/facebook'
|
4
|
+
|
5
|
+
module FaceB
|
6
|
+
class Railtie < ::Rails::Railtie
|
7
|
+
railtie_name :facebook
|
8
|
+
|
9
|
+
# Load the FaceB config file
|
10
|
+
initializer "faceb.load_config_file" do |app|
|
11
|
+
begin
|
12
|
+
@facebook_config = FaceB::Configuration.load_config_file(FaceB.config_file_path, ::Rails.env)
|
13
|
+
rescue Errno::ENOENT
|
14
|
+
puts "Warning : config/faceb.yml is not present. Maybe you should called ./script/rails generate face_b"
|
15
|
+
rescue
|
16
|
+
puts "Error during load FaceB config file."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Load Rack-Facebook as a middleware
|
21
|
+
initializer "faceb.add_middleware" do |app|
|
22
|
+
app.config.middleware.use Rack::Facebook, {
|
23
|
+
:application_secret => @facebook_config.secret_key,
|
24
|
+
:api_key => @facebook_config.api_key
|
25
|
+
} if @facebook_config
|
26
|
+
end
|
27
|
+
|
28
|
+
# Registered FBML request type
|
29
|
+
initializer "faceb.add_fbml_request_type" do |app|
|
30
|
+
Mime::Type.register "text/html", :fbml
|
31
|
+
end
|
32
|
+
|
33
|
+
# load Facebook Specific tasks
|
34
|
+
rake_tasks do
|
35
|
+
load "faceb/rails/tasks/faceb.tasks"
|
36
|
+
load "faceb/rails/tasks/tunnel.tasks"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
namespace :faceb do
|
2
|
+
|
3
|
+
tunnel_ns = namespace :tunnel do
|
4
|
+
# Courtesy of Christopher Haupt
|
5
|
+
# http://www.BuildingWebApps.com
|
6
|
+
# http://www.LearningRails.com
|
7
|
+
desc "Create a reverse ssh tunnel from a public server to a private development server."
|
8
|
+
task :start => [ :environment, :config ] do
|
9
|
+
puts @notification
|
10
|
+
system @ssh_command
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Create a reverse ssh tunnel in the background. Requires ssh keys to be setup."
|
14
|
+
task :background_start => [ :environment, :config ] do
|
15
|
+
puts @notification
|
16
|
+
system "#{@ssh_command} > /dev/null 2>&1 &"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adapted from Evan Weaver: http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally/
|
20
|
+
desc "Check if reverse tunnel is running"
|
21
|
+
task :status => [ :environment, :config ] do
|
22
|
+
if `ssh #{@public_host} -l #{@public_host_username} netstat -an | egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
|
23
|
+
puts "Seems ok"
|
24
|
+
else
|
25
|
+
puts "Down"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
task :config => :environment do
|
30
|
+
facebook_config = File.join(Rails.root, 'config', 'faceb.yml')
|
31
|
+
FACEBOOKER = YAML.load(ERB.new(File.read(facebook_config)).result)[Rails.env]
|
32
|
+
@public_host_username = FACEBOOKER['tunnel']['public_host_username']
|
33
|
+
@public_host = FACEBOOKER['tunnel']['public_host']
|
34
|
+
@public_port = FACEBOOKER['tunnel']['public_port']
|
35
|
+
@local_port = FACEBOOKER['tunnel']['local_port']
|
36
|
+
@ssh_port = FACEBOOKER['tunnel']['ssh_port'] || 22
|
37
|
+
@server_alive_interval = FACEBOOKER['tunnel']['server_alive_interval'] || 0
|
38
|
+
@notification = "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
|
39
|
+
@notification << " using SSH port #{@ssh_port}" unless @ssh_port == 22
|
40
|
+
# "GatewayPorts yes" needs to be enabled in the remote's sshd config
|
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
|
+
end
|
43
|
+
end
|
44
|
+
desc "Create a reverse ssh tunnel from a public server to a private development server."
|
45
|
+
task :tunnel => tunnel_ns[:start]
|
46
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module FaceB
|
2
|
+
class Session
|
3
|
+
attr_reader :api_key, :secret_key, :session_key, :user_facebook_uid
|
4
|
+
|
5
|
+
def self.create(api_key, secret_key, session_key = nil)
|
6
|
+
@current_session = self.new(api_key, secret_key, session_key) unless defined?(@current_session) && !!@current_session
|
7
|
+
@current_session
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.current
|
11
|
+
@current_session
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset!
|
15
|
+
@current_session = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(api_key, secret_key, session_key = nil)
|
19
|
+
@api_key = api_key
|
20
|
+
@secret_key = secret_key
|
21
|
+
@session_key = session_key
|
22
|
+
secure_with_session_key!(session_key) unless !session_key
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(method, params ={})
|
26
|
+
Api.new(self).call(method, params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def secure_with_session_key!(session_key)
|
30
|
+
@session_key = session_key
|
31
|
+
@user_facebook_uid = self.call('users.getLoggedInUser', :session_key => session_key).data
|
32
|
+
end
|
33
|
+
|
34
|
+
def secured?
|
35
|
+
!!@user_facebook_uid
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|