thoughtbot-clearance 0.3.7 → 0.3.8

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 (32) hide show
  1. data/README.textile +147 -60
  2. data/Rakefile +29 -21
  3. data/TODO.textile +1 -15
  4. data/generators/clearance/clearance_generator.rb +31 -9
  5. data/generators/clearance/lib/insert_commands.rb +103 -0
  6. data/generators/clearance/lib/rake_commands.rb +22 -0
  7. data/generators/clearance/templates/README +37 -0
  8. data/generators/clearance/templates/app/views/clearance_mailer/change_password.html.erb +3 -1
  9. data/generators/clearance/templates/app/views/passwords/edit.html.erb +4 -4
  10. data/generators/clearance/templates/db/migrate/create_users_with_clearance_columns.rb +21 -0
  11. data/generators/clearance/templates/db/migrate/update_users_with_clearance_columns.rb +41 -0
  12. data/generators/clearance/templates/test/{factories.rb → factories/clearance_user.rb} +1 -1
  13. data/lib/clearance.rb +3 -4
  14. data/lib/clearance/app/controllers/application_controller.rb +47 -61
  15. data/lib/clearance/app/controllers/confirmations_controller.rb +25 -33
  16. data/lib/clearance/app/controllers/passwords_controller.rb +41 -46
  17. data/lib/clearance/app/controllers/sessions_controller.rb +49 -56
  18. data/lib/clearance/app/controllers/users_controller.rb +21 -29
  19. data/lib/clearance/app/models/clearance_mailer.rb +15 -19
  20. data/lib/clearance/app/models/user.rb +53 -56
  21. data/lib/clearance/test/functional/confirmations_controller_test.rb +4 -35
  22. data/lib/clearance/test/functional/passwords_controller_test.rb +9 -5
  23. data/lib/clearance/test/functional/sessions_controller_test.rb +67 -17
  24. data/lib/clearance/test/functional/users_controller_test.rb +15 -7
  25. data/lib/clearance/test/test_helper.rb +10 -81
  26. data/lib/clearance/test/unit/clearance_mailer_test.rb +5 -5
  27. data/lib/clearance/test/unit/user_test.rb +42 -59
  28. data/rails/init.rb +1 -0
  29. data/shoulda_macros/clearance.rb +45 -0
  30. metadata +14 -6
  31. data/generators/clearance/templates/app/views/confirmations/new.html.erb +0 -6
  32. data/lib/clearance/version.rb +0 -7
@@ -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,37 @@
1
+ *******************************************************************************
2
+ Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
3
+
4
+ 1. For any other file(s) that you already had and didn't want to overwrite, add
5
+ the corresponding Clearance module. They are namespaced exactly like the
6
+ directory structure of a Rails app, e.g:
7
+
8
+ if app/models/user.rb already exists, add:
9
+
10
+ class User < ActiveRecord::Base
11
+ include Clearance::App::Models::User
12
+ ...
13
+
14
+ 2. You need to define HOST constant in your environments files. In config/environments/test.rb and config/environments/development.rb it can be:
15
+
16
+ HOST = "localhost"
17
+
18
+ While in config/environments/production.rb it must be the actual host your application is deployed to because the constant is used by mailers to generate URLs in emails.
19
+
20
+ In config/environment.rb:
21
+
22
+ DO_NOT_REPLY = "donotreply@example.com"
23
+
24
+ 3. Clearance depends on root_url, so please make sure that it is defined in
25
+ your config/routes.rb:
26
+
27
+ map.root :controller => 'my_home_controller'
28
+
29
+ 4. To run tests you need to add the Clearance module to your
30
+ test/test_helper.rb:
31
+
32
+ class Test::Unit::TestCase
33
+ self.use_transactional_fixtures = true
34
+ self.use_instantiated_fixtures = false
35
+ include Clearance::Test::TestHelper
36
+ end
37
+ *******************************************************************************
@@ -1,6 +1,8 @@
1
1
  Someone, hopefully you, has requested that we send you a link to change your password.
2
2
 
3
3
  Here's the link:
4
- <%= edit_user_password_url @user, :email => @user.email, :password => @user.crypted_password %>
4
+ <%= edit_user_password_url(@user,
5
+ :email => @user.email,
6
+ :password => @user.crypted_password) %>
5
7
 
6
8
  If you didn't request this, no need to freak out, your password hasn't been changed. You can just ignore this email.
@@ -3,11 +3,11 @@
3
3
  </p>
4
4
 
5
5
  <%= error_messages_for :user %>
6
+
6
7
  <% form_for(:user,
7
- :url => user_password_path(
8
- @user,
9
- :email => @user.email,
10
- :password => @user.crypted_password),
8
+ :url => user_password_path(@user,
9
+ :email => @user.email,
10
+ :password => @user.crypted_password),
11
11
  :html => { :method => :put }) do |form| %>
12
12
  <div class="password_field">
13
13
  <%= form.label :password, 'Choose password' %>
@@ -0,0 +1,21 @@
1
+ class CreateOrUpdateUsersWithClearanceColumns < ActiveRecord::Migration
2
+ def self.up
3
+ create_table(:users) do |t|
4
+ t.string :email
5
+ t.string :crypted_password, :limit => 40
6
+ t.string :salt, :limit => 40
7
+ t.string :remember_token
8
+ t.datetime :remember_token_expires_at
9
+ t.boolean :confirmed, :default => false, :null => false
10
+ end
11
+
12
+ add_index :users, [:email, :crypted_password]
13
+ add_index :users, [:id, :salt]
14
+ add_index :users, :email
15
+ add_index :users, :remember_token
16
+ end
17
+
18
+ def self.down
19
+ drop_table :users
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ class CreateOrUpdateUsersWithClearanceColumns < ActiveRecord::Migration
2
+ def self.up
3
+ <%
4
+ existing_columns = ActiveRecord::Base.connection.columns(:users).map { |column| column.name }
5
+ columns = [
6
+ [:email, 't.string :email'],
7
+ [:crypted_password, 't.string :crypted_password, :limit => 40'],
8
+ [:salt, 't.string :salt, :limit => 40'],
9
+ [:remember_token, 't.string :remember_token'],
10
+ [:remember_token_expires_at, 't.datetime :remember_token_expires_at'],
11
+ [:confirmed, 't.boolean :confirmed, :default => false, :null => false']
12
+ ].delete_if {|c| existing_columns.include?(c.first.to_s)}
13
+ -%>
14
+ change_table(:users) do |t|
15
+ <% columns.each do |c| -%>
16
+ <%= c.last %>
17
+ <% end -%>
18
+ end
19
+
20
+ <%
21
+ existing_indexes = ActiveRecord::Base.connection.indexes(:users).map { |index| index.name }
22
+ indexes = [
23
+ [:index_users_on_email_and_crypted_password, 'add_index :users, [:email, :crypted_password]'],
24
+ [:index_users_on_id_and_salt, 'add_index :users, [:id, :salt]'],
25
+ [:index_users_on_email, 'add_index :users, :email'],
26
+ [:index_users_on_remember_token, 'add_index :users, :remember_token']
27
+ ].delete_if {|i| existing_indexes.include?(i.first.to_s)}
28
+ -%>
29
+ <% indexes.each do |i| -%>
30
+ <%= i.last %>
31
+ <% end -%>
32
+ end
33
+
34
+ def self.down
35
+ change_table(:users) do |t|
36
+ <% unless columns.empty? -%>
37
+ t.remove <%= columns.collect {|c| ":#{c.first}" }.join(',') %>
38
+ <% end -%>
39
+ end
40
+ end
41
+ end
@@ -2,7 +2,7 @@ Factory.sequence :email do |n|
2
2
  "user#{n}@example.com"
3
3
  end
4
4
 
5
- Factory.define :user do |user|
5
+ Factory.define :clearance_user, :class => 'user' do |user|
6
6
  user.email { Factory.next :email }
7
7
  user.password "password"
8
8
  user.password_confirmation "password"
@@ -3,13 +3,12 @@ require 'clearance/app/controllers/confirmations_controller'
3
3
  require 'clearance/app/controllers/passwords_controller'
4
4
  require 'clearance/app/controllers/sessions_controller'
5
5
  require 'clearance/app/controllers/users_controller'
6
- require 'clearance/app/models/user'
7
6
  require 'clearance/app/models/clearance_mailer'
7
+ require 'clearance/app/models/user'
8
8
  require 'clearance/test/functional/confirmations_controller_test'
9
+ require 'clearance/test/functional/passwords_controller_test'
9
10
  require 'clearance/test/functional/sessions_controller_test'
10
11
  require 'clearance/test/functional/users_controller_test'
11
- require 'clearance/test/functional/passwords_controller_test'
12
12
  require 'clearance/test/test_helper'
13
- require 'clearance/test/unit/user_test'
14
13
  require 'clearance/test/unit/clearance_mailer_test'
15
- require 'clearance/version'
14
+ require 'clearance/test/unit/user_test'
@@ -3,79 +3,65 @@ module Clearance
3
3
  module Controllers
4
4
  module ApplicationController
5
5
 
6
- def self.included(base)
7
- base.class_eval do
6
+ def self.included(controller)
7
+ controller.class_eval do
8
8
  helper_method :current_user
9
9
  helper_method :logged_in?
10
10
 
11
- include InstanceMethods
11
+ def current_user
12
+ user_from_session || user_from_cookie
13
+ end
12
14
 
13
- protected
14
- include ProtectedInstanceMethods
15
- end
16
- end
17
-
18
- module InstanceMethods
19
- def current_user
20
- @current_user ||= (user_from_session || user_from_cookie)
21
- end
22
-
23
- def logged_in?
24
- ! current_user.nil?
25
- end
26
- end
15
+ def logged_in?
16
+ ! current_user.nil?
17
+ end
18
+
19
+ protected
20
+
21
+ def authenticate
22
+ deny_access unless logged_in?
23
+ end
27
24
 
28
- module ProtectedInstanceMethods
29
- def authenticate
30
- deny_access unless logged_in?
31
- end
25
+ def user_from_session
26
+ User.find_by_id session[:user_id]
27
+ end
32
28
 
33
- def user_from_session
34
- user_model.find_by_id session[:user_id]
35
- end
29
+ def user_from_cookie
30
+ if cookies[:auth_token]
31
+ user = User.find_by_remember_token(cookies[:auth_token])
32
+ end
33
+ user && user.remember_token? ? user : nil
34
+ end
36
35
 
37
- def user_from_cookie
38
- user = user_model.find_by_remember_token(cookies[:auth_token]) if cookies[:auth_token]
39
- user && user.remember_token? ? user : nil
40
- end
36
+ # Level of indirection so you can easily overwrite this method
37
+ # but also call #login .
38
+ def log_user_in(user)
39
+ login(user)
40
+ end
41
41
 
42
- # Level of indirection so you can easily override this method
43
- # but also call #login .
44
- def log_user_in(user)
45
- login(user)
46
- end
47
-
48
- def login(user)
49
- session[:user_id] = user.id if user
50
- @current_user = user
51
- end
42
+ def login(user)
43
+ session[:user_id] = user.id if user
44
+ end
52
45
 
53
- def redirect_back_or(default)
54
- session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default)
55
- session[:return_to] = nil
56
- end
57
-
58
- def redirect_to_root
59
- redirect_to root_url
60
- end
46
+ def redirect_back_or(default)
47
+ session[:return_to] ||= params[:return_to]
48
+ session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default)
49
+ session[:return_to] = nil
50
+ end
61
51
 
62
- def store_location
63
- session[:return_to] = request.request_uri
64
- end
52
+ def redirect_to_root
53
+ redirect_to root_url
54
+ end
65
55
 
66
- def deny_access(flash_message = nil, opts = {})
67
- opts[:redirect] ||= new_session_path
68
- store_location
69
- flash[:error] = flash_message if flash_message
70
- redirect_to opts[:redirect]
71
- end
72
-
73
- def user_model
74
- User
75
- end
56
+ def store_location
57
+ session[:return_to] = request.request_uri
58
+ end
76
59
 
77
- def mailer_model
78
- ClearanceMailer
60
+ def deny_access(flash_message = nil, opts = {})
61
+ store_location
62
+ flash[:failure] = flash_message if flash_message
63
+ render :template => "/sessions/new",:status => :unauthorized
64
+ end
79
65
  end
80
66
  end
81
67
  end
@@ -3,44 +3,36 @@ module Clearance
3
3
  module Controllers
4
4
  module ConfirmationsController
5
5
 
6
- def self.included(base)
7
- base.class_eval do
8
- before_filter :existing_user?, :only => [:new, :create]
6
+ def self.included(controller)
7
+ controller.class_eval do
8
+ before_filter :existing_user?, :only => :new
9
9
 
10
- include InstanceMethods
10
+ def new
11
+ create
12
+ end
13
+
14
+ def create
15
+ @user.confirm!
16
+ session[:user_id] = @user.id
17
+ redirect_to url_after_create
18
+ end
11
19
 
12
- private
13
- include PrivateInstanceMethods
14
- end
15
- end
16
-
17
- module InstanceMethods
18
- def new
19
- @user = User.find_by_id_and_salt(params[:user_id], params[:salt])
20
- end
20
+ private
21
+
22
+ def existing_user?
23
+ @user = User.find_by_id_and_salt(params[:user_id], params[:salt])
24
+ if @user.nil?
25
+ render :nothing => true, :status => :not_found
26
+ end
27
+ end
21
28
 
22
- def create
23
- @user = User.find_by_id_and_salt(params[:user_id], params[:salt])
24
- @user.confirm!
25
- session[:user_id] = @user.id
26
- redirect_to url_after_create
27
- end
28
- end
29
-
30
- module PrivateInstanceMethods
31
- def existing_user?
32
- user = User.find_by_id_and_salt(params[:user_id], params[:salt])
33
- if user.nil?
34
- render :nothing => true, :status => :not_found
29
+ def url_after_create
30
+ root_url
35
31
  end
32
+
36
33
  end
37
-
38
- def url_after_create
39
- root_url
40
- end
41
- end
42
-
34
+ end
43
35
  end
44
36
  end
45
37
  end
46
- end
38
+ end
@@ -3,64 +3,59 @@ module Clearance
3
3
  module Controllers
4
4
  module PasswordsController
5
5
 
6
- def self.included(base)
7
- base.class_eval do
6
+ def self.included(controller)
7
+ controller.class_eval do
8
8
  before_filter :existing_user?, :only => [:edit, :update]
9
9
  filter_parameter_logging :password, :password_confirmation
10
10
 
11
- include InstanceMethods
12
-
13
- private
14
- include PrivateInstanceMethods
15
- end
16
- end
17
-
18
- module InstanceMethods
19
- def new
20
- end
11
+ def new
12
+ end
21
13
 
22
- def create
23
- user = User.find_by_email params[:password][:email]
24
- if user.nil?
25
- flash.now[:warning] = 'Unknown email'
26
- render :action => :new
27
- else
28
- ClearanceMailer.deliver_change_password user
29
- redirect_to url_after_create
14
+ def create
15
+ user = User.find_by_email(params[:password][:email])
16
+ if user.nil?
17
+ flash.now[:warning] = 'Unknown email'
18
+ render :action => :new
19
+ else
20
+ ClearanceMailer.deliver_change_password user
21
+ flash[:notice] = "Details for changing your password " <<
22
+ "have been sent to #{user.email}"
23
+ redirect_to url_after_create
24
+ end
30
25
  end
31
- end
32
26
 
33
- def edit
34
- @user = User.find_by_email_and_crypted_password(params[:email],
35
- params[:password])
36
- end
27
+ def edit
28
+ @user = User.find_by_email_and_crypted_password(params[:email],
29
+ params[:password])
30
+ end
37
31
 
38
- def update
39
- @user = User.find_by_email_and_crypted_password(params[:email],
40
- params[:password])
41
- if @user.update_attributes params[:user]
42
- session[:user_id] = @user.id
43
- redirect_to @user
44
- else
45
- render :action => :edit
32
+ def update
33
+ @user = User.find_by_email_and_crypted_password(params[:email],
34
+ params[:password])
35
+ if @user.update_attributes params[:user]
36
+ session[:user_id] = @user.id
37
+ redirect_to @user
38
+ else
39
+ render :action => :edit
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def existing_user?
46
+ user = User.find_by_email_and_crypted_password(params[:email],
47
+ params[:password])
48
+ if user.nil?
49
+ render :nothing => true, :status => :not_found
50
+ end
46
51
  end
47
- end
48
- end
49
52
 
50
- module PrivateInstanceMethods
51
- def existing_user?
52
- user = User.find_by_email_and_crypted_password(params[:email],
53
- params[:password])
54
- if user.nil?
55
- render :nothing => true, :status => :not_found
53
+ def url_after_create
54
+ new_session_url
56
55
  end
57
- end
58
-
59
- def url_after_create
60
- new_session_url
56
+
61
57
  end
62
58
  end
63
-
64
59
  end
65
60
  end
66
61
  end