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.
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