mrflip-frankie 0.3.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.
@@ -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