fbdoorman 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.
- data/CHANGELOG.md +3 -0
- data/LICENSE +21 -0
- data/README.md +142 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/app/controllers/clearance/confirmations_controller.rb +76 -0
- data/app/controllers/clearance/facebook_controller.rb +66 -0
- data/app/controllers/clearance/passwords_controller.rb +85 -0
- data/app/controllers/clearance/sessions_controller.rb +67 -0
- data/app/controllers/clearance/users_controller.rb +36 -0
- data/app/models/clearance_mailer.rb +21 -0
- data/app/views/clearance_mailer/change_password.html.erb +9 -0
- data/app/views/clearance_mailer/confirmation.html.erb +5 -0
- data/app/views/facebook/_fbjs.html.erb +14 -0
- data/app/views/facebook/closed.html.erb +1 -0
- data/app/views/passwords/edit.html.erb +23 -0
- data/app/views/passwords/new.html.erb +15 -0
- data/app/views/sessions/new.html.erb +25 -0
- data/app/views/users/_form.html.erb +13 -0
- data/app/views/users/new.html.erb +6 -0
- data/generators/fbdoorman/USAGE +1 -0
- data/generators/fbdoorman/fbdoorman_generator.rb +68 -0
- data/generators/fbdoorman/lib/insert_commands.rb +33 -0
- data/generators/fbdoorman/lib/rake_commands.rb +22 -0
- data/generators/fbdoorman/templates/README +43 -0
- data/generators/fbdoorman/templates/clearance.rb +3 -0
- data/generators/fbdoorman/templates/facebook.yml +7 -0
- data/generators/fbdoorman/templates/factories.rb +13 -0
- data/generators/fbdoorman/templates/migrations/create_users.rb +24 -0
- data/generators/fbdoorman/templates/migrations/update_users.rb +44 -0
- data/generators/fbdoorman/templates/user.rb +3 -0
- data/lib/clearance/authentication.rb +143 -0
- data/lib/clearance/configuration.rb +25 -0
- data/lib/clearance/extensions/errors.rb +6 -0
- data/lib/clearance/extensions/rescue.rb +5 -0
- data/lib/clearance/routes.rb +55 -0
- data/lib/clearance/user.rb +207 -0
- data/lib/facebook_helpers.rb +48 -0
- data/lib/fbdoorman.rb +27 -0
- data/lib/mini_fb.rb +673 -0
- data/rails/init.rb +1 -0
- metadata +110 -0
@@ -0,0 +1 @@
|
|
1
|
+
script/generate fbdoorman
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
|
3
|
+
|
4
|
+
class FbdoormanGenerator < Rails::Generator::Base
|
5
|
+
|
6
|
+
def manifest
|
7
|
+
record do |m|
|
8
|
+
m.directory File.join("config", "initializers")
|
9
|
+
m.file "clearance.rb", "config/initializers/clearance.rb"
|
10
|
+
|
11
|
+
m.insert_into "app/controllers/application_controller.rb",
|
12
|
+
"include Clearance::Authentication"
|
13
|
+
|
14
|
+
user_model = "app/models/user.rb"
|
15
|
+
if File.exists?(user_model)
|
16
|
+
m.insert_into user_model, "include Clearance::User"
|
17
|
+
else
|
18
|
+
m.directory File.join("app", "models")
|
19
|
+
m.file "user.rb", user_model
|
20
|
+
end
|
21
|
+
|
22
|
+
m.insert_into "config/routes.rb",
|
23
|
+
"Clearance::Routes.draw(map)"
|
24
|
+
|
25
|
+
m.directory File.join("test", "factories")
|
26
|
+
m.file "factories.rb", "test/factories/clearance.rb"
|
27
|
+
|
28
|
+
m.migration_template "migrations/#{migration_source_name}.rb",
|
29
|
+
'db/migrate',
|
30
|
+
:migration_file_name => "clearance_#{migration_target_name}"
|
31
|
+
|
32
|
+
m.readme "README"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def schema_version_constant
|
37
|
+
if upgrading_clearance_again?
|
38
|
+
"To#{schema_version.gsub('_', '')}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def migration_source_name
|
45
|
+
if ActiveRecord::Base.connection.table_exists?(:users)
|
46
|
+
'update_users'
|
47
|
+
else
|
48
|
+
'create_users'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def migration_target_name
|
53
|
+
if upgrading_clearance_again?
|
54
|
+
"update_users_to_#{schema_version}"
|
55
|
+
else
|
56
|
+
'create_users'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def schema_version
|
61
|
+
IO.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip.gsub(/[^\d]/, '_')
|
62
|
+
end
|
63
|
+
|
64
|
+
def upgrading_clearance_again?
|
65
|
+
ActiveRecord::Base.connection.table_exists?(:users)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
|
2
|
+
|
3
|
+
Rails::Generator::Commands::Base.class_eval do
|
4
|
+
def file_contains?(relative_destination, line)
|
5
|
+
File.read(destination_path(relative_destination)).include?(line)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Rails::Generator::Commands::Create.class_eval do
|
10
|
+
def insert_into(file, line)
|
11
|
+
logger.insert "#{line} into #{file}"
|
12
|
+
unless options[:pretend] || file_contains?(file, line)
|
13
|
+
gsub_file file, /^(class|module|.*Routes).*$/ do |match|
|
14
|
+
"#{match}\n #{line}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
21
|
+
def insert_into(file, line)
|
22
|
+
logger.remove "#{line} from #{file}"
|
23
|
+
unless options[:pretend]
|
24
|
+
gsub_file file, "\n #{line}", ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Rails::Generator::Commands::List.class_eval do
|
30
|
+
def insert_into(file, line)
|
31
|
+
logger.insert "#{line} into #{file}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Rails::Generator::Commands::Create.class_eval do
|
2
|
+
def rake_db_migrate
|
3
|
+
logger.rake "db:migrate"
|
4
|
+
unless system("rake db:migrate")
|
5
|
+
logger.rake "db:migrate failed. Rolling back"
|
6
|
+
command(:destroy).invoke!
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
12
|
+
def rake_db_migrate
|
13
|
+
logger.rake "db:rollback"
|
14
|
+
system "rake db:rollback"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Rails::Generator::Commands::List.class_eval do
|
19
|
+
def rake_db_migrate
|
20
|
+
logger.rake "db:migrate"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
*******************************************************************************
|
3
|
+
|
4
|
+
Next:
|
5
|
+
|
6
|
+
1. Configure default url options for the mailer to generate URLs in emails.
|
7
|
+
In production.rb it must be the actual host your application is deployed to.
|
8
|
+
In config/environments/test.rb and config/environments/development.rb:
|
9
|
+
|
10
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
11
|
+
|
12
|
+
2. Migrate:
|
13
|
+
|
14
|
+
rake db:migrate
|
15
|
+
|
16
|
+
4. Make sure you're displaying flashes somewhere. For instance, in a layout:
|
17
|
+
|
18
|
+
<div id="flash">
|
19
|
+
<% flash.each do |key, value| -%>
|
20
|
+
<div id="flash_<%= key %>"><%=h value %></div>
|
21
|
+
<% end -%>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
5. If you haven't, create your app in http://www.facebook.com/developers/createapp.php
|
25
|
+
|
26
|
+
6. Create config/facebook.yml and put in there you app's information. It should look something like this:
|
27
|
+
|
28
|
+
:app_id: #Get this from http://www.facebook.com/developers/createapp.php
|
29
|
+
:secret: #from FB
|
30
|
+
:api_key: #from FB
|
31
|
+
:base_url: http://localhost:3000 #This is the url where you app's in, this is where Fb should go after login
|
32
|
+
:after_login_path: /welcome/logged #Where to take your users when they login with FB
|
33
|
+
:after_register_path: /welcome/new #Where to go when a new user registers
|
34
|
+
:url_after_create: /welcome/logged #Where to go when a session is created
|
35
|
+
|
36
|
+
7. Insert the JS for the login button and FB single sign-on redirection to work in your layouts.
|
37
|
+
|
38
|
+
(...your layout code...)
|
39
|
+
<%= facebook_js %>
|
40
|
+
</body> (....)
|
41
|
+
|
42
|
+
|
43
|
+
*******************************************************************************
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Factory.sequence :email do |n|
|
2
|
+
"user#{n}@example.com"
|
3
|
+
end
|
4
|
+
|
5
|
+
Factory.define :user do |user|
|
6
|
+
user.email { Factory.next :email }
|
7
|
+
user.password { "password" }
|
8
|
+
user.password_confirmation { "password" }
|
9
|
+
end
|
10
|
+
|
11
|
+
Factory.define :email_confirmed_user, :parent => :user do |user|
|
12
|
+
user.email_confirmed { true }
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class ClearanceCreateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:users) do |t|
|
4
|
+
t.string :email
|
5
|
+
t.string :encrypted_password, :limit => 128
|
6
|
+
t.string :salt, :limit => 128
|
7
|
+
t.string :confirmation_token, :limit => 128
|
8
|
+
t.string :remember_token, :limit => 128
|
9
|
+
t.string :name, :limit => 128
|
10
|
+
t.integer :fbid
|
11
|
+
t.boolean :email_confirmed, :default => false, :null => false
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :users, [:id, :confirmation_token]
|
16
|
+
add_index :users, :email
|
17
|
+
add_index :users, :fbid
|
18
|
+
add_index :users, :remember_token
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.down
|
22
|
+
drop_table :users
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class ClearanceUpdateUsers<%= schema_version_constant %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<%
|
4
|
+
existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name }
|
5
|
+
columns = [
|
6
|
+
[:email, 't.string :email'],
|
7
|
+
[:encrypted_password, 't.string :encrypted_password, :limit => 128'],
|
8
|
+
[:salt, 't.string :salt, :limit => 128'],
|
9
|
+
[:confirmation_token, 't.string :confirmation_token, :limit => 128'],
|
10
|
+
[:remember_token, 't.string :remember_token, :limit => 128'],
|
11
|
+
[:name, 't.string :name, :limit => 128'],
|
12
|
+
[:fbid, 't.integer :fbid'],
|
13
|
+
[:email_confirmed, 't.boolean :email_confirmed, :default => false, :null => false']
|
14
|
+
].delete_if {|c| existing_columns.include?(c.first.to_s)}
|
15
|
+
-%>
|
16
|
+
change_table(:users) do |t|
|
17
|
+
<% columns.each do |c| -%>
|
18
|
+
<%= c.last %>
|
19
|
+
<% end -%>
|
20
|
+
end
|
21
|
+
|
22
|
+
<%
|
23
|
+
existing_indexes = ActiveRecord::Base.connection.indexes(:users)
|
24
|
+
index_names = existing_indexes.collect { |each| each.name }
|
25
|
+
new_indexes = [
|
26
|
+
[:index_users_on_id_and_confirmation_token, 'add_index :users, [:id, :confirmation_token]'],
|
27
|
+
[:index_users_on_email, 'add_index :users, :email'],
|
28
|
+
[:index_users_on_fbid, 'add_index :users, :fbid'],
|
29
|
+
[:index_users_on_remember_token, 'add_index :users, :remember_token']
|
30
|
+
].delete_if { |each| index_names.include?(each.first.to_s) }
|
31
|
+
-%>
|
32
|
+
<% new_indexes.each do |each| -%>
|
33
|
+
<%= each.last %>
|
34
|
+
<% end -%>
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.down
|
38
|
+
change_table(:users) do |t|
|
39
|
+
<% unless columns.empty? -%>
|
40
|
+
t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
|
41
|
+
<% end -%>
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Clearance
|
2
|
+
module Authentication
|
3
|
+
|
4
|
+
def self.included(controller) # :nodoc:
|
5
|
+
controller.send(:include, InstanceMethods)
|
6
|
+
controller.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def self.extended(controller)
|
11
|
+
controller.helper_method :current_user, :signed_in?, :signed_out?
|
12
|
+
controller.hide_action :current_user, :current_user=,
|
13
|
+
:signed_in?, :signed_out?,
|
14
|
+
:sign_in, :sign_out,
|
15
|
+
:authenticate, :deny_access
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module InstanceMethods
|
21
|
+
# User in the current cookie
|
22
|
+
#
|
23
|
+
# @return [User, nil]
|
24
|
+
def current_user
|
25
|
+
@_current_user ||= user_from_cookie
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set the current user
|
29
|
+
#
|
30
|
+
# @param [User]
|
31
|
+
def current_user=(user)
|
32
|
+
@_current_user = user
|
33
|
+
end
|
34
|
+
|
35
|
+
# Is the current user signed in?
|
36
|
+
#
|
37
|
+
# @return [true, false]
|
38
|
+
def signed_in?
|
39
|
+
! current_user.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
# Is the current user signed out?
|
43
|
+
#
|
44
|
+
# @return [true, false]
|
45
|
+
def signed_out?
|
46
|
+
current_user.nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
# Deny the user access if they are signed out.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# before_filter :authenticate
|
53
|
+
def authenticate
|
54
|
+
if user_from_fb? then #Manage different authentication if its a FB user
|
55
|
+
fb_deny_access unless authenticated_fbu? #Created a special deny access when a FB user loggout
|
56
|
+
else
|
57
|
+
deny_access unless signed_in?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sign user in to cookie.
|
62
|
+
#
|
63
|
+
# @param [User]
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# sign_in(@user)
|
67
|
+
def sign_in(user)
|
68
|
+
if user
|
69
|
+
cookies[:remember_token] = {
|
70
|
+
:value => user.remember_token,
|
71
|
+
:expires => 1.year.from_now.utc
|
72
|
+
}
|
73
|
+
self.current_user = user
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Sign user out of cookie.
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# sign_out
|
81
|
+
def sign_out
|
82
|
+
current_user.reset_remember_token! if current_user
|
83
|
+
cookies.delete(:remember_token)
|
84
|
+
#Remove FB cookie
|
85
|
+
delete_fb_cookie
|
86
|
+
self.current_user = nil
|
87
|
+
end
|
88
|
+
|
89
|
+
# Store the current location and redirect to sign in.
|
90
|
+
# Display a failure flash message if included.
|
91
|
+
#
|
92
|
+
# @param [String] optional flash message to display to denied user
|
93
|
+
def deny_access(flash_message = nil)
|
94
|
+
store_location
|
95
|
+
flash[:failure] = flash_message if flash_message
|
96
|
+
redirect_to(sign_in_url)
|
97
|
+
end
|
98
|
+
|
99
|
+
def fb_deny_access(flash_message = nil)
|
100
|
+
store_location
|
101
|
+
flash[:failure] = flash_message if flash_message
|
102
|
+
redirect_to FB_CLOSED_URL
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
def user_from_cookie
|
108
|
+
if token = cookies[:remember_token]
|
109
|
+
::User.find_by_remember_token(token)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def sign_user_in(user)
|
114
|
+
warn "[DEPRECATION] sign_user_in: unnecessary. use sign_in(user) instead."
|
115
|
+
sign_in(user)
|
116
|
+
end
|
117
|
+
|
118
|
+
def store_location
|
119
|
+
if request.get?
|
120
|
+
session[:return_to] = request.request_uri
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def redirect_back_or(default)
|
125
|
+
redirect_to(return_to || default)
|
126
|
+
clear_return_to
|
127
|
+
end
|
128
|
+
|
129
|
+
def return_to
|
130
|
+
session[:return_to] || params[:return_to]
|
131
|
+
end
|
132
|
+
|
133
|
+
def clear_return_to
|
134
|
+
session[:return_to] = nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def redirect_to_root
|
138
|
+
redirect_to('/')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Clearance
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :mailer_sender
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@mailer_sender = 'donotreply@example.com'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
# Configure Clearance someplace sensible,
|
15
|
+
# like config/initializers/clearance.rb
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# Clearance.configure do |config|
|
19
|
+
# config.mailer_sender = 'donotreply@example.com'
|
20
|
+
# end
|
21
|
+
def self.configure
|
22
|
+
self.configuration ||= Configuration.new
|
23
|
+
yield(configuration)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
if defined?(ActionDispatch::ShowExceptions) # Rails 3
|
2
|
+
ActionDispatch::ShowExceptions.rescue_responses.update('ActionController::Forbidden' => :forbidden)
|
3
|
+
elsif defined?(ActionController::Base)
|
4
|
+
ActionController::Base.rescue_responses.update('ActionController::Forbidden' => :forbidden)
|
5
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Clearance
|
2
|
+
class Routes
|
3
|
+
|
4
|
+
# In your application's config/routes.rb, draw Clearance's routes:
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# map.resources :posts
|
8
|
+
# Clearance::Routes.draw(map)
|
9
|
+
#
|
10
|
+
# If you need to override a Clearance route, invoke your app route
|
11
|
+
# earlier in the file so Rails' router short-circuits when it finds
|
12
|
+
# your route:
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# map.resources :users, :only => [:new, :create]
|
16
|
+
# Clearance::Routes.draw(map)
|
17
|
+
def self.draw(map)
|
18
|
+
map.resources :passwords,
|
19
|
+
:controller => 'clearance/passwords',
|
20
|
+
:only => [:new, :create]
|
21
|
+
|
22
|
+
map.resource :session,
|
23
|
+
:controller => 'clearance/sessions',
|
24
|
+
:only => [:new, :create, :destroy]
|
25
|
+
|
26
|
+
map.resources :users, :controller => 'clearance/users' do |users|
|
27
|
+
users.resource :password,
|
28
|
+
:controller => 'clearance/passwords',
|
29
|
+
:only => [:create, :edit, :update]
|
30
|
+
|
31
|
+
users.resource :confirmation,
|
32
|
+
:controller => 'clearance/confirmations',
|
33
|
+
:only => [:new, :create]
|
34
|
+
end
|
35
|
+
|
36
|
+
map.sign_up 'sign_up',
|
37
|
+
:controller => 'clearance/users',
|
38
|
+
:action => 'new'
|
39
|
+
map.sign_in 'sign_in',
|
40
|
+
:controller => 'clearance/sessions',
|
41
|
+
:action => 'new'
|
42
|
+
map.sign_out 'sign_out',
|
43
|
+
:controller => 'clearance/sessions',
|
44
|
+
:action => 'destroy',
|
45
|
+
:method => :delete
|
46
|
+
map.facebook 'facebook',
|
47
|
+
:controller => 'clearance/facebook',
|
48
|
+
:action => 'index'
|
49
|
+
map.fbclosed 'fbclosed',
|
50
|
+
:controller => 'clearance/facebook',
|
51
|
+
:action => 'closed'
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|