facepalm2 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +72 -0
- data/LICENSE +23 -0
- data/README.md +105 -0
- data/Rakefile +33 -0
- data/VERSION +1 -0
- data/app/.gitkeep +1 -0
- data/app/controllers/facepalm/endpoint_controller.rb +30 -0
- data/config/routes.rb +16 -0
- data/facepalm.gemspec +65 -0
- data/init.rb +1 -0
- data/install +7 -0
- data/lib/facepalm/config.rb +66 -0
- data/lib/facepalm/engine.rb +28 -0
- data/lib/facepalm/rack/post_canvas_middleware.rb +28 -0
- data/lib/facepalm/rails/controller/oauth_access.rb +108 -0
- data/lib/facepalm/rails/controller/redirects.rb +74 -0
- data/lib/facepalm/rails/controller/url_rewriting.rb +35 -0
- data/lib/facepalm/rails/controller.rb +67 -0
- data/lib/facepalm/rails/helpers/javascript_helper.rb +107 -0
- data/lib/facepalm/rails/helpers/url_helper.rb +27 -0
- data/lib/facepalm/rails/helpers.rb +12 -0
- data/lib/facepalm/user.rb +78 -0
- data/lib/facepalm.rb +17 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: df7444ea0447bf5fa7110a3c899a5ce233cf629e
|
4
|
+
data.tar.gz: fae1374d10c29e9d34a77e6a1af909e688b9b54e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3a57d325e731bdb1bd6c2ac64675640971d127c880cf34e0846fec704bdc078e336f8cc3e513bde1e884a39bfaefff21e96ca433689053ecc2ab7e79de8a58f
|
7
|
+
data.tar.gz: 7d995775af09763d5cf6aa9ca55c4f1c47b9843233c49733d653bbe35406a5046d2f980cdbd284354e3c3081e7135c58b99d12f534a37679f64f20c05e9c3732
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (2.3.11)
|
5
|
+
actionpack (= 2.3.11)
|
6
|
+
actionpack (2.3.11)
|
7
|
+
activesupport (= 2.3.11)
|
8
|
+
rack (~> 1.1.0)
|
9
|
+
activerecord (2.3.11)
|
10
|
+
activesupport (= 2.3.11)
|
11
|
+
activeresource (2.3.11)
|
12
|
+
activesupport (= 2.3.11)
|
13
|
+
activesupport (2.3.11)
|
14
|
+
addressable (2.3.8)
|
15
|
+
builder (3.2.2)
|
16
|
+
descendants_tracker (0.0.4)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
18
|
+
faraday (0.9.1)
|
19
|
+
multipart-post (>= 1.2, < 3)
|
20
|
+
git (1.2.9.1)
|
21
|
+
github_api (0.12.3)
|
22
|
+
addressable (~> 2.3)
|
23
|
+
descendants_tracker (~> 0.0.4)
|
24
|
+
faraday (~> 0.8, < 0.10)
|
25
|
+
hashie (>= 3.3)
|
26
|
+
multi_json (>= 1.7.5, < 2.0)
|
27
|
+
nokogiri (~> 1.6.3)
|
28
|
+
oauth2
|
29
|
+
hashie (3.4.1)
|
30
|
+
highline (1.7.1)
|
31
|
+
httpauth (0.2.1)
|
32
|
+
jeweler (2.0.1)
|
33
|
+
builder
|
34
|
+
bundler (>= 1.0)
|
35
|
+
git (>= 1.2.5)
|
36
|
+
github_api
|
37
|
+
highline (>= 1.6.15)
|
38
|
+
nokogiri (>= 1.5.10)
|
39
|
+
rake
|
40
|
+
rdoc
|
41
|
+
json (1.8.2)
|
42
|
+
mini_portile (0.6.2)
|
43
|
+
multi_json (1.11.0)
|
44
|
+
multipart-post (2.0.0)
|
45
|
+
nokogiri (1.6.6.2)
|
46
|
+
mini_portile (~> 0.6.0)
|
47
|
+
oauth2 (0.6.1)
|
48
|
+
faraday (~> 0.7)
|
49
|
+
httpauth (~> 0.1)
|
50
|
+
multi_json (~> 1.3)
|
51
|
+
rack (1.1.6)
|
52
|
+
rails (2.3.11)
|
53
|
+
actionmailer (= 2.3.11)
|
54
|
+
actionpack (= 2.3.11)
|
55
|
+
activerecord (= 2.3.11)
|
56
|
+
activeresource (= 2.3.11)
|
57
|
+
activesupport (= 2.3.11)
|
58
|
+
rake (>= 0.8.3)
|
59
|
+
rake (10.4.2)
|
60
|
+
rdoc (4.2.0)
|
61
|
+
json (~> 1.4)
|
62
|
+
redgreen (1.2.2)
|
63
|
+
thread_safe (0.3.5)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
jeweler
|
70
|
+
rails (= 2.3.11)
|
71
|
+
rake
|
72
|
+
redgreen
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
LICENSE
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 2008 Jon Yurek and thoughtbot, inc.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
9
|
+
in the Software without restriction, including without limitation the rights
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
Facepalm
|
2
|
+
===========
|
3
|
+
|
4
|
+
Provides a set of classes, methods, and helpers to ease development of Facebook applications with Rails.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
In order to install Facepalm you should add it to your Gemfile:
|
10
|
+
|
11
|
+
gem 'facepalm'
|
12
|
+
|
13
|
+
Usage
|
14
|
+
-----
|
15
|
+
|
16
|
+
**Requesting Permissions**
|
17
|
+
|
18
|
+
Facepalm makes it simple to require Facebook authentication to access certain controller actions. You can require user to provide certain permissions to your application:
|
19
|
+
|
20
|
+
class PostsController < ApplicationController
|
21
|
+
facepalm_authentication :email, :publish_actions, :only => :index
|
22
|
+
|
23
|
+
def index
|
24
|
+
...
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
This code will redirect user to Facebook permission request page if user wasn't authenticated yet.
|
29
|
+
|
30
|
+
You can also check user authentication right in your action code and request certain permission if necessary:
|
31
|
+
|
32
|
+
class PostsController < ApplicationController
|
33
|
+
facepalm_authentication :email, :publish_actions, :only => :index
|
34
|
+
|
35
|
+
def edit
|
36
|
+
if facepalm_require_authentication(:email)
|
37
|
+
...
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
**Accessing Current User**
|
43
|
+
|
44
|
+
Current Facebook user data can be accessed using the ```current_facebook_user``` method:
|
45
|
+
|
46
|
+
class UsersController < ApplicationController
|
47
|
+
def profile
|
48
|
+
@user = User.find_by_facebook_id(current_facebook_user.uid)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
This method is also accessible as a view helper.
|
53
|
+
|
54
|
+
**Application Configuration**
|
55
|
+
|
56
|
+
In order to use Facepalm you should set a default configuration for your Facebook application. The config file should be placed at RAILS_ROOT/config/facebook.yml
|
57
|
+
|
58
|
+
Sample config file:
|
59
|
+
|
60
|
+
development:
|
61
|
+
app_id: ...
|
62
|
+
secret: ...
|
63
|
+
namespace: your-app-namespace
|
64
|
+
callback_domain: yourdomain.com
|
65
|
+
|
66
|
+
test:
|
67
|
+
app_id: ...
|
68
|
+
secret: ...
|
69
|
+
namespace: test
|
70
|
+
callback_domain: callback.url
|
71
|
+
|
72
|
+
All these attributes attributes can be obtained or defined in your application settings at the [Facebook developer page](https://developers.facebook.com/apps).
|
73
|
+
|
74
|
+
Default configuration will be automatically loaded at the first request and won't reload. If you want to change application settings you should restart your application server instance.
|
75
|
+
|
76
|
+
Default configuration can be accessed from any parts of your code:
|
77
|
+
|
78
|
+
Facepalm::Config.default # => #<Facepalm::Config:0x108c03f38 @config={:secret=>"...", :namespace=>"...", :callback_domain=>"...", :app_id=>...}>
|
79
|
+
|
80
|
+
Current configuration is also accessible as a ```facepalm``` method in your controller. You can override this method to provide application configuration on a per-request basis:
|
81
|
+
|
82
|
+
class PostsController < ApplicationController
|
83
|
+
def current_fb_app
|
84
|
+
FbApp.find_by_app_id(params[:app_id])
|
85
|
+
end
|
86
|
+
|
87
|
+
def facepalm
|
88
|
+
if current_fb_app
|
89
|
+
Facepalm::Config.new(current_fb_app.attributes)
|
90
|
+
else
|
91
|
+
Facepalm::Config.default
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
Credits
|
97
|
+
-------
|
98
|
+
|
99
|
+
Big thanks to authors of the Facebooker2 plugin for inspiring me to develop this piece of software. I also copied some code snippets from this project so big thanks to everyone who put their effort to develop Facebooker2.
|
100
|
+
|
101
|
+
|
102
|
+
Copyright & License
|
103
|
+
-------------------
|
104
|
+
|
105
|
+
Copyright (c) 2011-2012 Aleksey V. Dmitriev.It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
Rake::TestTask.new(:test) do |test|
|
4
|
+
test.libs << 'lib'
|
5
|
+
test.pattern = 'test/**/*_test.rb'
|
6
|
+
test.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default do
|
10
|
+
sh "RAILS=2.3.12 && (bundle || bundle install) && bundle exec rake test"
|
11
|
+
sh "RAILS=3.0.10 && (bundle || bundle install) && exec rake test"
|
12
|
+
sh "RAILS=3.1.2 && (bundle || bundle install) && exec rake test"
|
13
|
+
sh "git checkout Gemfile.lock"
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'jeweler'
|
18
|
+
|
19
|
+
Jeweler::Tasks.new do |gem|
|
20
|
+
gem.name = 'facepalm2'
|
21
|
+
gem.summary = "Facebook v2 integration for Rack & Rails application"
|
22
|
+
gem.email = "vk.stelmakh@gmail.com"
|
23
|
+
gem.homepage = "http://github.com/stelmakh/facepalm"
|
24
|
+
gem.authors = ["Aleksey V. Dmitriev", "Volodymyr Stelmakh"]
|
25
|
+
|
26
|
+
gem.add_dependency "ie_iframe_cookies", '~> 0.1.2'
|
27
|
+
gem.add_dependency "koala", '~> 2.0'
|
28
|
+
end
|
29
|
+
|
30
|
+
Jeweler::GemcutterTasks.new
|
31
|
+
rescue LoadError
|
32
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
|
33
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/app/.gitkeep
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This folder is necessary to correctly include routes in Rails 2.3. Without this folder routes won't be loaded correctly.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Facepalm
|
2
|
+
class EndpointController < ActionController::Base
|
3
|
+
# OAuth 2.0 endpoint action added to ApplicationController and mounted to /facebook_oauth
|
4
|
+
def show
|
5
|
+
if params[:error]
|
6
|
+
raise Facepalm::OAuthException.new(params[:error_description])
|
7
|
+
else
|
8
|
+
# this is where you get a code for requesting an access_token to do additional OAuth requests
|
9
|
+
# outside of using the FB JavaScript library (see Authenticating Users in a Web Application
|
10
|
+
# under the Authentication docs at http://developers.facebook.com/docs/authentication/)
|
11
|
+
if params[:code]
|
12
|
+
begin
|
13
|
+
# Decrypting return URL and redirecting to it
|
14
|
+
return_url = URI.unescape(params[:fb_return_to].to_s)
|
15
|
+
::Rails.logger.fatal("Return URL: #{return_url}")
|
16
|
+
redirect_to(facebook_canvas_page_url + facepalm_url_encryptor.decrypt(return_url))
|
17
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage
|
18
|
+
::Rails.logger.fatal "ERROR: Failed to decrypt return URL: #{ params[:fb_return_to] }"
|
19
|
+
|
20
|
+
redirect_to facebook_canvas_page_url
|
21
|
+
end
|
22
|
+
|
23
|
+
false
|
24
|
+
else
|
25
|
+
raise Facepalm::OAuthException.new('No code returned.')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
if Rails::VERSION::MAJOR < 3
|
2
|
+
|
3
|
+
ActionController::Routing::Routes.draw do |map|
|
4
|
+
# OAuth 2.0 endpoint for facebook authentication
|
5
|
+
map.facepalm_endpoint '/facepalm/endpoint',
|
6
|
+
:controller => "facepalm/endpoint",
|
7
|
+
:action => "show"
|
8
|
+
end
|
9
|
+
|
10
|
+
else
|
11
|
+
|
12
|
+
Rails.application.routes.draw do
|
13
|
+
match '/facepalm/endpoint' => 'facepalm/endpoint#show', :as => :facepalm_endpoint
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/facepalm.gemspec
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: facepalm 0.2.6.b3 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "facepalm"
|
9
|
+
s.version = "0.2.6.b3"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Aleksey V. Dmitriev", "Volodymyr Stelmakh"]
|
14
|
+
s.date = "2015-04-09"
|
15
|
+
s.email = "vk.stelmakh@gmail.com"
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"README.md"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"app/.gitkeep",
|
28
|
+
"app/controllers/facepalm/endpoint_controller.rb",
|
29
|
+
"config/routes.rb",
|
30
|
+
"facepalm.gemspec",
|
31
|
+
"init.rb",
|
32
|
+
"install",
|
33
|
+
"lib/facepalm.rb",
|
34
|
+
"lib/facepalm/config.rb",
|
35
|
+
"lib/facepalm/engine.rb",
|
36
|
+
"lib/facepalm/rack/post_canvas_middleware.rb",
|
37
|
+
"lib/facepalm/rails/controller.rb",
|
38
|
+
"lib/facepalm/rails/controller/oauth_access.rb",
|
39
|
+
"lib/facepalm/rails/controller/redirects.rb",
|
40
|
+
"lib/facepalm/rails/controller/url_rewriting.rb",
|
41
|
+
"lib/facepalm/rails/helpers.rb",
|
42
|
+
"lib/facepalm/rails/helpers/javascript_helper.rb",
|
43
|
+
"lib/facepalm/rails/helpers/url_helper.rb",
|
44
|
+
"lib/facepalm/user.rb"
|
45
|
+
]
|
46
|
+
s.homepage = "http://github.com/stelmakh/facepalm"
|
47
|
+
s.rubygems_version = "2.2.2"
|
48
|
+
s.summary = "Facebook integration for Rack & Rails application"
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
s.specification_version = 4
|
52
|
+
|
53
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_runtime_dependency(%q<ie_iframe_cookies>, ["~> 0.1.2"])
|
55
|
+
s.add_runtime_dependency(%q<koala>, ["~> 2.0"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<ie_iframe_cookies>, ["~> 0.1.2"])
|
58
|
+
s.add_dependency(%q<koala>, ["~> 2.0"])
|
59
|
+
end
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<ie_iframe_cookies>, ["~> 0.1.2"])
|
62
|
+
s.add_dependency(%q<koala>, ["~> 2.0"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "facepalm")
|
data/install
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Facepalm
|
2
|
+
# Facebook application configuration class
|
3
|
+
class Config
|
4
|
+
attr_accessor :config
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# A shortcut to access default configuration stored in RAILS_ROOT/config/facebook.yml
|
8
|
+
def default
|
9
|
+
@@default ||= self.new(load_default_config_from_file)
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_default_config_from_file
|
13
|
+
config_data = YAML.load(
|
14
|
+
ERB.new(
|
15
|
+
File.read(::Rails.root.join("config", "facebook.yml"))
|
16
|
+
).result
|
17
|
+
)[::Rails.env]
|
18
|
+
|
19
|
+
raise NotConfigured.new("Unable to load configuration for #{ ::Rails.env } from config/facebook.yml") unless config_data
|
20
|
+
|
21
|
+
config_data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
self.config = options.to_options
|
27
|
+
end
|
28
|
+
|
29
|
+
# Defining methods for quick access to config values
|
30
|
+
%w{app_id secret namespace callback_domain}.each do |attribute|
|
31
|
+
class_eval %{
|
32
|
+
def #{ attribute }
|
33
|
+
config[:#{ attribute }]
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def oauth_client
|
39
|
+
@oauth_client ||= Koala::Facebook::OAuth.new(app_id, secret)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Koala Facebook API client instantiated with application access token
|
43
|
+
def api_client
|
44
|
+
@api_client ||= Koala::Facebook::API.new(app_access_token)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Fetches application access token
|
48
|
+
def app_access_token
|
49
|
+
@app_access_token ||= oauth_client.get_app_access_token
|
50
|
+
end
|
51
|
+
|
52
|
+
def subscription_token
|
53
|
+
Digest::MD5.hexdigest(secret)
|
54
|
+
end
|
55
|
+
|
56
|
+
# URL of the application canvas page
|
57
|
+
def canvas_page_url(protocol)
|
58
|
+
"#{ protocol }apps.facebook.com/#{ namespace }"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Application callback URL
|
62
|
+
def callback_url(protocol)
|
63
|
+
protocol + callback_domain
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
if Rails::VERSION::MAJOR > 2
|
2
|
+
|
3
|
+
module Facepalm
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
initializer "facepalm.middleware" do |app|
|
6
|
+
app.middleware.insert_after(ActionDispatch::ParamsParser, Facepalm::Rack::PostCanvasMiddleware)
|
7
|
+
end
|
8
|
+
|
9
|
+
initializer "facepalm.controller_extension" do
|
10
|
+
ActiveSupport.on_load :action_controller do
|
11
|
+
ActionController::Base.send(:include, Facepalm::Rails::Controller)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
else
|
18
|
+
ActionController::Routing::Routes.add_configuration_file(File.expand_path('../../../config/routes.rb', __FILE__))
|
19
|
+
|
20
|
+
ActionController::Dispatcher.middleware.insert_after(ActionController::ParamsParser, Facepalm::Rack::PostCanvasMiddleware)
|
21
|
+
|
22
|
+
ActionController::Base.send(:include, Facepalm::Rails::Controller)
|
23
|
+
|
24
|
+
# Loading plugin controllers manually because the're not loaded automatically from gems
|
25
|
+
Dir[File.expand_path('../../../app/controllers/**/*.rb', __FILE__)].each do |file|
|
26
|
+
require file
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Facepalm
|
2
|
+
module Rack
|
3
|
+
|
4
|
+
# This rack middleware converts POST requests from Facebook to GET requests.
|
5
|
+
# It's necessary to make RESTful routes work as expected without any changes
|
6
|
+
# in the application.
|
7
|
+
class PostCanvasMiddleware
|
8
|
+
def initialize(app, options = {})
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
request = ::Rack::Request.new(env)
|
14
|
+
|
15
|
+
if request.POST['signed_request'] && request.post? && request.params['_method'].blank?
|
16
|
+
env['REQUEST_METHOD'] = 'GET'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Put signed_request parameter to the same place where HTTP header X-Signed-Request come.
|
20
|
+
# This let us work both with params and HTTP headers in the same way. Very useful for AJAX.
|
21
|
+
env['HTTP_SIGNED_REQUEST'] ||= request.POST['signed_request']
|
22
|
+
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Facepalm
|
2
|
+
class OAuthException < StandardError; end
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
module Controller
|
6
|
+
|
7
|
+
# OAuth 2.0 authentication module
|
8
|
+
module OauthAccess
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
# A filter class for Rails
|
14
|
+
class AccessFilter
|
15
|
+
def initialize(*permissions)
|
16
|
+
@permissions = permissions
|
17
|
+
end
|
18
|
+
|
19
|
+
def filter(controller)
|
20
|
+
controller.send(:facepalm_require_authentication, *@permissions)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
# Requires Facebook authentication for the whole set of controller actions.
|
26
|
+
# Use it to setup a given set of permissions for the whole controller
|
27
|
+
#
|
28
|
+
# @param permissions An array of permissions to require
|
29
|
+
# @param options A hash of options to control filter application, similar to
|
30
|
+
# options hash for before_filter
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# class MyController < ApplicationController
|
34
|
+
# facepalm_authentication :email, :publish_actions, :only => :index
|
35
|
+
# end
|
36
|
+
def facepalm_authentication(*permissions)
|
37
|
+
options = permissions.extract_options!
|
38
|
+
|
39
|
+
cattr_accessor :facepalm_authentication_filter
|
40
|
+
self.facepalm_authentication_filter = AccessFilter.new(*permissions)
|
41
|
+
|
42
|
+
before_filter(facepalm_authentication_filter, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
# Requires a given set of permissions in context of the current action.
|
49
|
+
# Use it to require permissions in a single action or custom filter.
|
50
|
+
#
|
51
|
+
# NOTE: Facepalm doesn't check if user provided all required permissions.
|
52
|
+
# It only checks if user was authenticated and redirects to permission
|
53
|
+
# request page with a given set of permissions.
|
54
|
+
#
|
55
|
+
# @param permissions An array of permissions to require
|
56
|
+
#
|
57
|
+
# @return true if user authorized the application, false otehrwise
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
# class MyController < ApplicationController
|
61
|
+
# before_filter :my_custom_filter, :only => :show
|
62
|
+
#
|
63
|
+
# def my_custom_filter
|
64
|
+
# my_custom_condition? and facepalm_require_authentication(:publish_actions)
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def index
|
68
|
+
# if facepalm_require_authentication(:email)
|
69
|
+
# ... do what you need ...
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
def facepalm_require_authentication(*permissions)
|
74
|
+
if current_facebook_user.try(:authenticated?)
|
75
|
+
true
|
76
|
+
else
|
77
|
+
redirect_to = facepalm.oauth_client.url_for_oauth_code(
|
78
|
+
:permissions => permissions,
|
79
|
+
:callback => facepalm_endpoint_url(
|
80
|
+
:fb_return_to => facepalm_auth_return_code
|
81
|
+
)
|
82
|
+
)
|
83
|
+
::Rails.logger.fatal("User #{current_facebook_user} is not authenticated\nRedirecting to #{redirect_to}")
|
84
|
+
redirect_from_iframe(redirect_to)
|
85
|
+
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Encrypting return URL to pass it to Facebook
|
91
|
+
def facepalm_auth_return_code
|
92
|
+
facepalm_url_encryptor.encrypt(
|
93
|
+
url_for(params_without_facebook_data.merge(:canvas => false, :only_path => true))
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Internally used to encrypt return URL for authentication endpoint
|
98
|
+
#
|
99
|
+
# @return ActiveSupport::MessageEncryptor
|
100
|
+
#
|
101
|
+
# @private
|
102
|
+
def facepalm_url_encryptor
|
103
|
+
@facebook_url_encryptor ||= ActiveSupport::MessageEncryptor.new(facepalm.secret)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Facepalm
|
2
|
+
module Rails
|
3
|
+
module Controller
|
4
|
+
module Redirects
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
alias_method_chain :redirect_to, :signed_request
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
# Overrides ActionController::Base#redirect_to to pass signed_request in flash[]
|
14
|
+
def redirect_to_with_signed_request(*args)
|
15
|
+
flash[:signed_request] = fb_signed_request if fb_canvas?
|
16
|
+
|
17
|
+
redirect_to_without_signed_request(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Redirects user to a definite URL with JavaScript code that overwrites
|
21
|
+
# top frame location. Use it to redirect user from within an iframe.
|
22
|
+
def redirect_from_iframe(url_options)
|
23
|
+
redirect_url = url_options.is_a?(String) ? url_options : url_for(url_options)
|
24
|
+
|
25
|
+
logger.info "Redirecting from IFRAME to #{ redirect_url }"
|
26
|
+
|
27
|
+
respond_to do |format|
|
28
|
+
format.html do
|
29
|
+
render(
|
30
|
+
:text => iframe_redirect_html_code(redirect_url),
|
31
|
+
:layout => false
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
format.js do
|
36
|
+
render(
|
37
|
+
:text => iframe_redirect_js_code(redirect_url),
|
38
|
+
:layout => false
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generates HTML and JavaScript code to redirect user with top frame location
|
45
|
+
# overwrite
|
46
|
+
#
|
47
|
+
# @param target_url An URL to redirect the user to
|
48
|
+
# @param custom_code A custom HTML code to insert into the result document.
|
49
|
+
# Can be used to add OpenGraph tags to redirect page code.
|
50
|
+
def iframe_redirect_html_code(target_url, custom_code = nil)
|
51
|
+
%{
|
52
|
+
<html><head>
|
53
|
+
<script type="text/javascript">
|
54
|
+
window.top.location.href = #{ target_url.to_json };
|
55
|
+
</script>
|
56
|
+
<noscript>
|
57
|
+
<meta http-equiv="refresh" content="0;url=#{ target_url }" />
|
58
|
+
<meta http-equiv="window-target" content="_top" />
|
59
|
+
</noscript>
|
60
|
+
#{ custom_code }
|
61
|
+
</head></html>
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
# Generates JavaScript code to redirect user
|
66
|
+
#
|
67
|
+
# @param target_url An URL to redirect the user to
|
68
|
+
def iframe_redirect_js_code(target_url)
|
69
|
+
"window.top.location.href = #{ target_url.to_json };"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'facepalm/rails/helpers/url_helper'
|
2
|
+
|
3
|
+
module Facepalm
|
4
|
+
module Rails
|
5
|
+
module Controller
|
6
|
+
module UrlRewriting
|
7
|
+
include Facepalm::Rails::Helpers::UrlHelper
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
helper_method(:facebook_canvas_page_url, :facebook_callback_url)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
# A helper to generate an URL of the application canvas page URL
|
18
|
+
#
|
19
|
+
# @param protocol A request protocol, should be either 'http://' or 'https://'.
|
20
|
+
# Defaults to current protocol.
|
21
|
+
def facebook_canvas_page_url(protocol = nil)
|
22
|
+
facepalm.canvas_page_url(protocol || request.protocol)
|
23
|
+
end
|
24
|
+
|
25
|
+
# A helper to generate an application callback URL
|
26
|
+
#
|
27
|
+
# @param protocol A request protocol, should be either 'http://' or 'https://'.
|
28
|
+
# Defaults to current protocol.
|
29
|
+
def facebook_callback_url(protocol = nil)
|
30
|
+
facepalm.callback_url(protocol || request.protocol)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'facepalm/rails/controller/oauth_access'
|
2
|
+
require 'facepalm/rails/controller/url_rewriting'
|
3
|
+
require 'facepalm/rails/controller/redirects'
|
4
|
+
|
5
|
+
module Facepalm
|
6
|
+
module Rails
|
7
|
+
|
8
|
+
# Rails application controller extension
|
9
|
+
module Controller
|
10
|
+
def self.included(base)
|
11
|
+
base.class_eval do
|
12
|
+
include Facepalm::Rails::Controller::OauthAccess
|
13
|
+
include Facepalm::Rails::Controller::UrlRewriting
|
14
|
+
include Facepalm::Rails::Controller::Redirects
|
15
|
+
|
16
|
+
# Fix cookie permission issue in IE
|
17
|
+
before_filter :normal_cookies_for_ie_in_iframes!
|
18
|
+
|
19
|
+
helper_method(:facepalm, :fb_signed_request, :current_facebook_user, :params_without_facebook_data, :fb_canvas?)
|
20
|
+
|
21
|
+
helper Facepalm::Rails::Helpers
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
# Accessor to current application config. Override it in your controller
|
28
|
+
# if you need multi-application support or per-request configuration selection.
|
29
|
+
def facepalm
|
30
|
+
Facepalm::Config.default
|
31
|
+
end
|
32
|
+
|
33
|
+
# Accessor to current facebook user. Returns instance of Facepalm::User
|
34
|
+
def current_facebook_user
|
35
|
+
@current_facebook_user ||= fetch_current_facebook_user
|
36
|
+
end
|
37
|
+
|
38
|
+
# Accessor to secure cookie set by Facebook
|
39
|
+
def fb_cookie
|
40
|
+
cookies["fbsr_#{ facepalm.app_id }"]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Accessor to signed request passed either in params or in flash
|
44
|
+
def fb_signed_request
|
45
|
+
request.env['HTTP_SIGNED_REQUEST'] || flash[:signed_request]
|
46
|
+
end
|
47
|
+
|
48
|
+
# A hash of params passed to this action, excluding secure information
|
49
|
+
# passed by Facebook
|
50
|
+
def params_without_facebook_data
|
51
|
+
params.except(:signed_request)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Did the request come from canvas app
|
55
|
+
def fb_canvas?
|
56
|
+
request.env['HTTP_SIGNED_REQUEST'].present? || flash[:signed_request].present?
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def fetch_current_facebook_user
|
62
|
+
Facepalm::User.from_signed_request(facepalm, fb_signed_request || fb_cookie)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Facepalm
|
2
|
+
module Rails
|
3
|
+
module Helpers
|
4
|
+
module JavascriptHelper
|
5
|
+
|
6
|
+
# A helper to integrate Facebook Connect to the current page. Generates a
|
7
|
+
# JavaScript code that initializes Facebook Javascript client for the
|
8
|
+
# current application.
|
9
|
+
#
|
10
|
+
# @param app_id Facebook App ID of the application. Defaults to value provided by the current config.
|
11
|
+
# @param options A hash of options for JavaScript generation. Available options are:
|
12
|
+
# :cookie - Enable cookie generation for the application. Default to true.
|
13
|
+
# :status - Enable login status check. Defaults to true.
|
14
|
+
# :xfbml - Enable XFBML tag parsing. Default to true.
|
15
|
+
# :frictionless - Enable frictionless app request delivery. Defaults to true
|
16
|
+
# :locale - Locale to use for JavaScript client. Defaults to 'en_US'.
|
17
|
+
# :weak_cache - Enable FB JS client cache expiration every minute. Defaults to false.
|
18
|
+
# :async - Enable asynchronous FB JS client code load and initialization. Defaults to false.
|
19
|
+
# :cache_url - An URL to load custom or cached version of the FB JS client code. Not used by default.
|
20
|
+
# @param &block A block of JS code to be inserted in addition to FB client initialization code.
|
21
|
+
def fb_connect_js(*args, &block)
|
22
|
+
options = args.extract_options!
|
23
|
+
|
24
|
+
app_id = args.shift || facepalm.app_id
|
25
|
+
|
26
|
+
options.reverse_merge!(
|
27
|
+
:cookie => true,
|
28
|
+
:status => true,
|
29
|
+
:xfbml => true,
|
30
|
+
:frictionless => true,
|
31
|
+
:locale => "en_US"
|
32
|
+
)
|
33
|
+
|
34
|
+
extra_js = capture(&block) if block_given?
|
35
|
+
|
36
|
+
init_js = <<-JAVASCRIPT
|
37
|
+
FB.init({
|
38
|
+
appId : '#{ app_id }',
|
39
|
+
version : 'v2.0',
|
40
|
+
status : #{ options[:status] },
|
41
|
+
cookie : #{ options[:cookie] },
|
42
|
+
xfbml : #{ options[:xfbml] },
|
43
|
+
frictionlessRequests : #{ options[:frictionless] },
|
44
|
+
channelUrl : '#{ options[:channel_url] || 'null' }'
|
45
|
+
});
|
46
|
+
JAVASCRIPT
|
47
|
+
|
48
|
+
init_js = "FB._https = true; #{ init_js }" if request.ssl?
|
49
|
+
|
50
|
+
js_url = "connect.facebook.net/#{options[:locale]}/sdk.js"
|
51
|
+
js_url << "?#{Time.now.change(:min => 0, :sec => 0, :usec => 0).to_i}" if options[:weak_cache]
|
52
|
+
|
53
|
+
if options[:async]
|
54
|
+
js = <<-JAVASCRIPT
|
55
|
+
window.fbAsyncInit = function() {
|
56
|
+
#{init_js}
|
57
|
+
#{extra_js}
|
58
|
+
};
|
59
|
+
|
60
|
+
(function() {
|
61
|
+
var e = document.createElement('script');
|
62
|
+
e.src = document.location.protocol + '//#{ js_url }';
|
63
|
+
e.async = true;
|
64
|
+
document.getElementById('fb-root').appendChild(e);
|
65
|
+
}());
|
66
|
+
JAVASCRIPT
|
67
|
+
|
68
|
+
js = <<-CODE
|
69
|
+
<div id="fb-root"></div>
|
70
|
+
<script type="text/javascript">#{ js }</script>
|
71
|
+
CODE
|
72
|
+
else
|
73
|
+
js = <<-CODE
|
74
|
+
<div id="fb-root"></div>
|
75
|
+
<script src="#{ request.protocol }#{ js_url }" type="text/javascript"></script>
|
76
|
+
CODE
|
77
|
+
|
78
|
+
if options[:cache_url]
|
79
|
+
js << <<-CODE
|
80
|
+
<script type="text/javascript">
|
81
|
+
window.FB || document.write(unescape(\"%3Cscript src='#{ options[:cache_url] }' type='text/javascript'%3E%3C/script%3E\"));
|
82
|
+
</script>
|
83
|
+
CODE
|
84
|
+
end
|
85
|
+
|
86
|
+
js << <<-CODE
|
87
|
+
<script type="text/javascript">
|
88
|
+
if(typeof FB !== 'undefined'){
|
89
|
+
#{init_js}
|
90
|
+
#{extra_js}
|
91
|
+
}
|
92
|
+
</script>
|
93
|
+
CODE
|
94
|
+
end
|
95
|
+
|
96
|
+
js = js.html_safe
|
97
|
+
|
98
|
+
if block_given? && ::Rails::VERSION::STRING.to_i < 3
|
99
|
+
concat(js)
|
100
|
+
else
|
101
|
+
js
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Facepalm
|
2
|
+
module Rails
|
3
|
+
module Helpers
|
4
|
+
module UrlHelper
|
5
|
+
# Overrides UrlHelper#url_for to filter out secure Facebook params
|
6
|
+
# and add Facebook Canvas URL if necessary
|
7
|
+
def url_for(options = {})
|
8
|
+
if options.is_a?(Hash)
|
9
|
+
if options.delete(:canvas) && !options[:host]
|
10
|
+
options[:only_path] = true
|
11
|
+
|
12
|
+
canvas = true
|
13
|
+
else
|
14
|
+
canvas = false
|
15
|
+
end
|
16
|
+
|
17
|
+
url = super(options.except(:signed_request))
|
18
|
+
|
19
|
+
canvas ? facebook_canvas_page_url + url : url
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Facepalm
|
2
|
+
|
3
|
+
# A class for Facebook user
|
4
|
+
class User
|
5
|
+
class UnsupportedAlgorithm < StandardError; end
|
6
|
+
class InvalidSignature < StandardError; end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# Creates an instance of Facepalm::User using application config and signed_request
|
10
|
+
def from_signed_request(config, input)
|
11
|
+
return if input.blank?
|
12
|
+
|
13
|
+
new(parse_signed_request(config, input))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Originally provided directly by Facebook, however this has changed
|
17
|
+
# as their concept of crypto changed. For historic purposes, this is their proposal:
|
18
|
+
# https://developers.facebook.com/docs/authentication/canvas/encryption_proposal/
|
19
|
+
# Currently see https://github.com/facebook/php-sdk/blob/master/src/facebook.php#L758
|
20
|
+
# for a more accurate reference implementation strategy.
|
21
|
+
def parse_signed_request(config, input)
|
22
|
+
encoded_sig, encoded_envelope = input.split('.', 2)
|
23
|
+
signature = base64_url_decode(encoded_sig).unpack("H*").first
|
24
|
+
|
25
|
+
MultiJson.decode(base64_url_decode(encoded_envelope)).tap do |envelope|
|
26
|
+
raise UnsupportedAlgorithm.new("Unsupported encryption algorithm: #{ envelope['algorithm'] }") unless envelope['algorithm'] == 'HMAC-SHA256'
|
27
|
+
|
28
|
+
# now see if the signature is valid (digest, key, data)
|
29
|
+
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, config.secret, encoded_envelope)
|
30
|
+
|
31
|
+
raise InvalidSignature.new('Invalid request signature') if (signature != hmac)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def base64_url_decode(str)
|
36
|
+
str += '=' * (4 - str.length.modulo(4))
|
37
|
+
|
38
|
+
Base64.decode64(str.tr('-_', '+/'))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def initialize(options = {})
|
44
|
+
@options = options
|
45
|
+
end
|
46
|
+
|
47
|
+
# Checks if user is authenticated in the application
|
48
|
+
def authenticated?
|
49
|
+
access_token && !access_token.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Facebook UID
|
53
|
+
def uid
|
54
|
+
@options['user_id']
|
55
|
+
end
|
56
|
+
|
57
|
+
# The code used for OAuth 2.0
|
58
|
+
def oauth_code
|
59
|
+
@options['code']
|
60
|
+
end
|
61
|
+
|
62
|
+
# OAuth 2.0 access token generated for this user
|
63
|
+
def access_token
|
64
|
+
@options['access_token'] || @options['oauth_token']
|
65
|
+
end
|
66
|
+
|
67
|
+
# Token expiration time
|
68
|
+
def access_token_expires_at
|
69
|
+
Time.at(@options['expires'])
|
70
|
+
end
|
71
|
+
|
72
|
+
# Koala Facebook API client instantiated with user's access token
|
73
|
+
def api_client
|
74
|
+
@api_client ||= Koala::Facebook::API.new(access_token)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/lib/facepalm.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Facepalm
|
2
|
+
end
|
3
|
+
|
4
|
+
# Dependencies
|
5
|
+
require 'ie_iframe_cookies'
|
6
|
+
require 'koala'
|
7
|
+
|
8
|
+
require 'facepalm/config'
|
9
|
+
require 'facepalm/user'
|
10
|
+
|
11
|
+
require 'facepalm/rack/post_canvas_middleware'
|
12
|
+
|
13
|
+
# Rails integration
|
14
|
+
require 'facepalm/rails/controller'
|
15
|
+
require 'facepalm/rails/helpers'
|
16
|
+
|
17
|
+
require 'facepalm/engine'
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: facepalm2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aleksey V. Dmitriev
|
8
|
+
- Volodymyr Stelmakh
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-04-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ie_iframe_cookies
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.1.2
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.1.2
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: koala
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.0'
|
42
|
+
description:
|
43
|
+
email: vk.stelmakh@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files:
|
47
|
+
- LICENSE
|
48
|
+
- README.md
|
49
|
+
files:
|
50
|
+
- Gemfile
|
51
|
+
- Gemfile.lock
|
52
|
+
- LICENSE
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- VERSION
|
56
|
+
- app/.gitkeep
|
57
|
+
- app/controllers/facepalm/endpoint_controller.rb
|
58
|
+
- config/routes.rb
|
59
|
+
- facepalm.gemspec
|
60
|
+
- init.rb
|
61
|
+
- install
|
62
|
+
- lib/facepalm.rb
|
63
|
+
- lib/facepalm/config.rb
|
64
|
+
- lib/facepalm/engine.rb
|
65
|
+
- lib/facepalm/rack/post_canvas_middleware.rb
|
66
|
+
- lib/facepalm/rails/controller.rb
|
67
|
+
- lib/facepalm/rails/controller/oauth_access.rb
|
68
|
+
- lib/facepalm/rails/controller/redirects.rb
|
69
|
+
- lib/facepalm/rails/controller/url_rewriting.rb
|
70
|
+
- lib/facepalm/rails/helpers.rb
|
71
|
+
- lib/facepalm/rails/helpers/javascript_helper.rb
|
72
|
+
- lib/facepalm/rails/helpers/url_helper.rb
|
73
|
+
- lib/facepalm/user.rb
|
74
|
+
homepage: http://github.com/stelmakh/facepalm
|
75
|
+
licenses: []
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.2.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Facebook v2 integration for Rack & Rails application
|
97
|
+
test_files: []
|