facepalm2 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|