mrflip-frankie 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ v0.3.0 Updated to work with Sinatra 0.9.x and facebooker 1.0.2, thanks to mjfreshyfresh
2
+
3
+ v0.2.5. Bugfix for fb_url_for helper method
4
+
5
+ v0.2.4. Add fb_url_for helper method to create link URL's that have proper Facebook application reference included
6
+
7
+ v0.2.3. Correct README and fix Sinatra version dependency in gem
8
+
9
+ v0.2.2. Updated to deal with session change in Sinatra, plus misc bug fixes with Facebooker integration
10
+
11
+ v0.2.0. Converted codebase to become Ruby Gem
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Ron Evans
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ bin/tunnel
2
+ CHANGELOG
3
+ lib/frankie.rb
4
+ LICENSE
5
+ Manifest
6
+ Rakefile
7
+ README.rdoc
8
+ test/frankie_test.rb
9
+ test/helper.rb
@@ -0,0 +1,79 @@
1
+ = Frankie
2
+
3
+ Frankie (http://facethesinatra.com) is a plugin for the Sinatra web framework (http://sinatrarb.com) that allows you to easily create a Facebook application by using the Facebooker gem.
4
+
5
+ Written by Ron Evans (http://www.deadprogrammersociety.com)
6
+
7
+ Based on merb_facebooker (http://github.com/vanpelt/merb_facebooker) by Chris Van Pelt, which was based on
8
+ the Rails classes in Facebooker (http://facebooker.rubyforge.org/) by Mike Mangino, Shane Vitarana, & Chad Fowler
9
+
10
+ 2/20/2009 - Now updated to Sinatra 0.9 and facebooker thanks to mjfreshyfresh.
11
+
12
+ Thanks, everyone!
13
+
14
+ = Here is a very simple example application:
15
+
16
+ require 'rubygems'
17
+ require 'frankie'
18
+
19
+ configure do
20
+ set_option :sessions, true
21
+ load_facebook_config "./config/facebooker.yml", Sinatra.env
22
+ end
23
+
24
+ ## facebooker helpers
25
+ before do
26
+ ensure_authenticated_to_facebook
27
+ ensure_application_is_installed_by_facebook_user
28
+ end
29
+
30
+ ## the site
31
+ get '/' do
32
+ body "<h1>Hello #{session[:facebook_session].user.name} and welcome to frankie!</h1>"
33
+ end
34
+
35
+
36
+ = How to use frankie
37
+ - Install the frankie gem (which will install both Sinatra and Facebooker if you do not already have them)
38
+ sudo gem install frankie
39
+
40
+ - Create the application directories for your new app
41
+ mkdir myapp
42
+ cd myapp
43
+ mkdir config
44
+
45
+ - Put your facebooker.yml file into the /myapp/config directory, and set the values to your information. Here is a simple example of the file:
46
+
47
+ development:
48
+ api_key: apikeyhere
49
+ secret_key: secretkeyhere
50
+ canvas_page_name: yourcanvashere
51
+ callback_url: http://localhost:4567
52
+ test:
53
+ api_key: apikeyhere
54
+ secret_key: secretkeyhere
55
+ canvas_page_name: yourcanvashere
56
+ callback_url: http://localhost:4567
57
+ production:
58
+ api_key: apikeyhere
59
+ secret_key: secretkeyhere
60
+ canvas_page_name: yourcanvashere
61
+ callback_url: http://yourrealserver.com
62
+
63
+
64
+ - Make sure you have setup your Facebook application on the facebook site. Google "setup new facebook application" if you are unsure how to do this. I recommend starting with an IFrame application. A more advanced and cooler approach uses a tunneling script, which is included with Frankie. You do need to have "autossh" installed in order to use it, as well as a publicly addressable server. From a command prompt type tunnel <host> <remote_port> <local_port> like this:
65
+
66
+ tunnel app.myhost.com 10000 4567
67
+
68
+ You will also need to make sure your server's /etc/ssh/sshd_config contains the following line:
69
+
70
+ GatewayPorts clientspecified
71
+
72
+ Thanks to the many people like Evan Weaver, Blake Mizerany, and whoever else that have provided the code used in this tunneling script.
73
+
74
+ - Create your application, based on the sample above, and then run it:
75
+ ruby sample.rb
76
+
77
+ - Test your app by going to http://apps.facebook.com/yourappname
78
+
79
+ Have fun!
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'echoe'
5
+
6
+ task :default => :test
7
+
8
+ Rake::RDocTask.new do |rd|
9
+ rd.main = "README.rdoc"
10
+ rd.rdoc_files += ["README.rdoc"]
11
+ rd.rdoc_files += Dir.glob("lib/**/*.rb")
12
+ rd.rdoc_dir = 'doc'
13
+ end
14
+
15
+ Rake::TestTask.new do |t|
16
+ ENV['SINATRA_ENV'] = 'test'
17
+ t.pattern = File.dirname(__FILE__) + "/test/*_test.rb"
18
+ end
19
+
20
+ Echoe.new("frankie") do |p|
21
+ p.author = "Ron Evans"
22
+ p.summary = "Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem."
23
+ p.url = "http://facethesinatra.com/"
24
+ p.dependencies = ["sinatra >=0.2.2", "facebooker >=0.9.5"]
25
+ p.install_message = "*** Frankie was installed ***"
26
+ p.include_rakefile = true
27
+ end
28
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ host, remote_port, local_port = ARGV
4
+ raise 'You must specify at least a hostname - i.e. tunnel myhost.com' unless host
5
+ remote_port ||= 10000
6
+ local_port ||= 4567
7
+ puts "Tunneling #{host}:#{remote_port} to 0.0.0.0:#{local_port}"
8
+ begin
9
+ exec "autossh -M 48484 -nNT -g -R *:#{remote_port}:0.0.0.0:#{local_port} #{host}"
10
+ rescue
11
+ raise "Tunnel failed to start. Do you have autossh installed?"
12
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{frankie}
5
+ s.version = "0.3.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Ron Evans"]
9
+ s.date = %q{2009-09-03}
10
+ s.default_executable = %q{tunnel}
11
+ s.description = %q{Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem.}
12
+ s.email = %q{}
13
+ s.executables = ["tunnel"]
14
+ s.extra_rdoc_files = ["bin/tunnel", "CHANGELOG", "lib/frankie.rb", "LICENSE", "README.rdoc"]
15
+ s.files = ["bin/tunnel", "CHANGELOG", "lib/frankie.rb", "LICENSE", "Manifest", "Rakefile", "README.rdoc", "test/frankie_test.rb", "test/helper.rb", "frankie.gemspec"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://facethesinatra.com/}
18
+ s.post_install_message = %q{*** Frankie was installed ***}
19
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Frankie", "--main", "README.rdoc"]
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{frankie}
22
+ s.rubygems_version = %q{1.3.1}
23
+ s.summary = %q{Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem.}
24
+ s.test_files = ["test/frankie_test.rb"]
25
+
26
+ if s.respond_to? :specification_version then
27
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
28
+ s.specification_version = 2
29
+
30
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
31
+ s.add_runtime_dependency(%q<sinatra>, [">= 0.2.2"])
32
+ s.add_runtime_dependency(%q<facebooker>, [">= 0.9.5"])
33
+ else
34
+ s.add_dependency(%q<sinatra>, [">= 0.2.2"])
35
+ s.add_dependency(%q<facebooker>, [">= 0.9.5"])
36
+ end
37
+ else
38
+ s.add_dependency(%q<sinatra>, [">= 0.2.2"])
39
+ s.add_dependency(%q<facebooker>, [">= 0.9.5"])
40
+ end
41
+ end
@@ -0,0 +1,195 @@
1
+ # frankie - a plugin for sinatra that integrates with the facebooker gem
2
+ #
3
+ # written by Ron Evans (http://www.deadprogrammersociety.com)
4
+ #
5
+ # based on merb_facebooker (http://github.com/vanpelt/merb_facebooker)
6
+ # and the Rails classes in Facebooker (http://facebooker.rubyforge.org/) from Mike Mangino, Shane Vitarana, & Chad Fowler
7
+ #
8
+
9
+ require 'sinatra'
10
+
11
+ module Frankie
12
+
13
+ module Loader
14
+
15
+ require 'yaml'
16
+ require 'uri'
17
+
18
+ def load_facebook_config(file, env=:development)
19
+ if File.exist?(file)
20
+ yaml = YAML.load_file(file)[env.to_s]
21
+ ENV['FACEBOOK_API_KEY'] = yaml['api_key']
22
+ ENV['FACEBOOK_SECRET_KEY'] = yaml['secret_key']
23
+ ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = yaml['canvas_page_name']
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ module EventContext
30
+
31
+ # pin it to newer version of Facebooker
32
+ # gem 'mmangino-facebooker', '>=1.0.2'
33
+ require 'facebooker'
34
+
35
+ def facebook_session
36
+ @facebook_session
37
+ end
38
+
39
+ def facebook_session_parameters
40
+ {:fb_sig_session_key=>params["fb_sig_session_key"]}
41
+ end
42
+
43
+ def set_facebook_session
44
+ session_set = session_already_secured? || secure_with_token! || secure_with_facebook_params!
45
+ if session_set
46
+ capture_facebook_friends_if_available!
47
+ Facebooker::Session.current = facebook_session
48
+ end
49
+ session_set
50
+ end
51
+
52
+ def facebook_params
53
+ @facebook_params ||= verified_facebook_params
54
+ end
55
+
56
+ private
57
+
58
+ def session_already_secured?
59
+ (@facebook_session = session[:facebook_session]) && session[:facebook_session].secured?
60
+ end
61
+
62
+ def secure_with_token!
63
+ if params['auth_token']
64
+ @facebook_session = new_facebook_session
65
+ @facebook_session.auth_token = params['auth_token']
66
+ @facebook_session.secure!
67
+ session[:facebook_session] = @facebook_session
68
+ end
69
+ end
70
+
71
+ def secure_with_facebook_params!
72
+ return unless request_is_for_a_facebook_canvas?
73
+ if ['user', 'session_key'].all? {|element| facebook_params[element]}
74
+ @facebook_session = new_facebook_session
75
+ @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'], facebook_params['ss'])
76
+ session[:facebook_session] = @facebook_session
77
+ end
78
+ end
79
+
80
+ def create_new_facebook_session_and_redirect!
81
+ session[:facebook_session] = new_facebook_session
82
+ throw :halt, do_redirect(session[:facebook_session].login_url) unless @installation_required
83
+ end
84
+
85
+ def new_facebook_session
86
+ Facebooker::Session.create(Facebooker::Session.api_key, Facebooker::Session.secret_key)
87
+ end
88
+
89
+ def capture_facebook_friends_if_available!
90
+ return unless request_is_for_a_facebook_canvas?
91
+ if friends = facebook_params['friends']
92
+ facebook_session.user.friends = friends.map do |friend_uid|
93
+ Facebooker::User.new(friend_uid, facebook_session)
94
+ end
95
+ end
96
+ end
97
+
98
+ def blank?(value)
99
+ (value == '0' || value.nil? || value == '')
100
+ end
101
+
102
+ def verified_facebook_params
103
+ facebook_sig_params = params.inject({}) do |collection, pair|
104
+ collection[pair.first.sub(/^fb_sig_/, '')] = pair.last if pair.first[0,7] == 'fb_sig_'
105
+ collection
106
+ end
107
+ verify_signature(facebook_sig_params, params['fb_sig'])
108
+ facebook_sig_params.inject(Hash.new) do |collection, pair|
109
+ collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
110
+ collection
111
+ end
112
+ end
113
+
114
+ # 48.hours.ago in sinatra
115
+ def earliest_valid_session
116
+ now = Time.now
117
+ now -= (60 * 60 * 48)
118
+ now
119
+ end
120
+
121
+ def verify_signature(facebook_sig_params,expected_signature)
122
+ return true if expected_signature.nil?
123
+ raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
124
+ actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
125
+ raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
126
+ raise Facebooker::Session::SignatureTooOld if Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
127
+ true
128
+ end
129
+
130
+ def facebook_parameter_conversions
131
+ @facebook_parameter_conversions ||= Hash.new do |hash, key|
132
+ lambda{|value| value}
133
+ end.merge(
134
+ 'time' => lambda{|value| Time.at(value.to_f)},
135
+ 'in_canvas' => lambda{|value| !blank?(value)},
136
+ 'added' => lambda{|value| !blank?(value)},
137
+ 'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
138
+ 'friends' => lambda{|value| value.split(/,/)}
139
+ )
140
+ end
141
+
142
+ def do_redirect(*args)
143
+ if request_is_for_a_facebook_canvas?
144
+ fbml_redirect_tag(args[0])
145
+ else
146
+ redirect args[0]
147
+ end
148
+ end
149
+
150
+ def fbml_redirect_tag(url)
151
+ "<fb:redirect url=\"#{url}\" />"
152
+ end
153
+
154
+ def request_is_for_a_facebook_canvas?
155
+ return false if (params["fb_sig_in_canvas"].nil? && params["fb_sig_in_iframe"].nil?)
156
+ (params["fb_sig_in_canvas"] == "1") || (params["fb_sig_in_iframe"] == '1')
157
+ end
158
+
159
+ def application_is_installed?
160
+ facebook_params['added']
161
+ end
162
+
163
+ def ensure_authenticated_to_facebook
164
+ set_facebook_session || create_new_facebook_session_and_redirect!
165
+ end
166
+
167
+ def ensure_application_is_installed_by_facebook_user
168
+ @installation_required = true
169
+ authenticated_and_installed = ensure_authenticated_to_facebook && application_is_installed?
170
+ application_is_not_installed_by_facebook_user unless authenticated_and_installed
171
+ authenticated_and_installed
172
+ end
173
+
174
+ def application_is_not_installed_by_facebook_user
175
+ throw :halt, do_redirect(session[:facebook_session].install_url)
176
+ end
177
+
178
+ def set_fbml_format
179
+ params['format']="fbml" if request_is_for_a_facebook_canvas?
180
+ end
181
+
182
+ def fb_url_for(url)
183
+ url = "" if url == "/"
184
+ url = URI.escape(url)
185
+ return url if !request_is_for_a_facebook_canvas?
186
+ "http://apps.facebook.com/#{ENV['FACEBOOKER_RELATIVE_URL_ROOT']}/#{url}"
187
+ end
188
+
189
+ end
190
+
191
+ end
192
+
193
+ # extend sinatra with frankie methods, changed to work with Sinatra 0.9.x
194
+ Sinatra::Default.send(:include, Frankie::EventContext)
195
+ include Frankie::Loader
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "frankie" do
4
+ it "should be a placeholder for a real test" do
5
+ end
6
+ end
7
+
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require File.dirname(__FILE__) + '/../lib/frankie'
4
+ require 'sinatra/test/spec'
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mrflip-frankie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Ron Evans
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-03 00:00:00 -07:00
13
+ default_executable: tunnel
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: facebooker
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.5
34
+ version:
35
+ description: Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem.
36
+ email: ""
37
+ executables:
38
+ - tunnel
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - bin/tunnel
43
+ - CHANGELOG
44
+ - lib/frankie.rb
45
+ - LICENSE
46
+ - README.rdoc
47
+ files:
48
+ - bin/tunnel
49
+ - CHANGELOG
50
+ - lib/frankie.rb
51
+ - LICENSE
52
+ - Manifest
53
+ - Rakefile
54
+ - README.rdoc
55
+ - test/frankie_test.rb
56
+ - test/helper.rb
57
+ - frankie.gemspec
58
+ has_rdoc: true
59
+ homepage: http://facethesinatra.com/
60
+ post_install_message: "*** Frankie was installed ***"
61
+ rdoc_options:
62
+ - --line-numbers
63
+ - --inline-source
64
+ - --title
65
+ - Frankie
66
+ - --main
67
+ - README.rdoc
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "1.2"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project: frankie
85
+ rubygems_version: 1.2.0
86
+ signing_key:
87
+ specification_version: 2
88
+ summary: Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem.
89
+ test_files:
90
+ - test/frankie_test.rb