fbdoorman 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/CHANGELOG.md +3 -0
  2. data/LICENSE +21 -0
  3. data/README.md +142 -0
  4. data/Rakefile +27 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/clearance/confirmations_controller.rb +76 -0
  7. data/app/controllers/clearance/facebook_controller.rb +66 -0
  8. data/app/controllers/clearance/passwords_controller.rb +85 -0
  9. data/app/controllers/clearance/sessions_controller.rb +67 -0
  10. data/app/controllers/clearance/users_controller.rb +36 -0
  11. data/app/models/clearance_mailer.rb +21 -0
  12. data/app/views/clearance_mailer/change_password.html.erb +9 -0
  13. data/app/views/clearance_mailer/confirmation.html.erb +5 -0
  14. data/app/views/facebook/_fbjs.html.erb +14 -0
  15. data/app/views/facebook/closed.html.erb +1 -0
  16. data/app/views/passwords/edit.html.erb +23 -0
  17. data/app/views/passwords/new.html.erb +15 -0
  18. data/app/views/sessions/new.html.erb +25 -0
  19. data/app/views/users/_form.html.erb +13 -0
  20. data/app/views/users/new.html.erb +6 -0
  21. data/generators/fbdoorman/USAGE +1 -0
  22. data/generators/fbdoorman/fbdoorman_generator.rb +68 -0
  23. data/generators/fbdoorman/lib/insert_commands.rb +33 -0
  24. data/generators/fbdoorman/lib/rake_commands.rb +22 -0
  25. data/generators/fbdoorman/templates/README +43 -0
  26. data/generators/fbdoorman/templates/clearance.rb +3 -0
  27. data/generators/fbdoorman/templates/facebook.yml +7 -0
  28. data/generators/fbdoorman/templates/factories.rb +13 -0
  29. data/generators/fbdoorman/templates/migrations/create_users.rb +24 -0
  30. data/generators/fbdoorman/templates/migrations/update_users.rb +44 -0
  31. data/generators/fbdoorman/templates/user.rb +3 -0
  32. data/lib/clearance/authentication.rb +143 -0
  33. data/lib/clearance/configuration.rb +25 -0
  34. data/lib/clearance/extensions/errors.rb +6 -0
  35. data/lib/clearance/extensions/rescue.rb +5 -0
  36. data/lib/clearance/routes.rb +55 -0
  37. data/lib/clearance/user.rb +207 -0
  38. data/lib/facebook_helpers.rb +48 -0
  39. data/lib/fbdoorman.rb +27 -0
  40. data/lib/mini_fb.rb +673 -0
  41. data/rails/init.rb +1 -0
  42. 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,3 @@
1
+ Clearance.configure do |config|
2
+ config.mailer_sender = 'donotreply@example.com'
3
+ end
@@ -0,0 +1,7 @@
1
+ :app_id:
2
+ :secret:
3
+ :api_key:
4
+ :callback_url: http://localhost:3000/fbconnect/
5
+ :after_login_path:
6
+ :after_register_path:
7
+ :base_url: http://localhost:3000
@@ -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,3 @@
1
+ class User < ActiveRecord::Base
2
+ include Clearance::User
3
+ 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,6 @@
1
+ if defined?(ActionController)
2
+ module ActionController
3
+ class Forbidden < StandardError
4
+ end
5
+ end
6
+ 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