thoughtbot-clearance 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG.textile +25 -1
  2. data/README.textile +18 -5
  3. data/Rakefile +9 -10
  4. data/TODO.textile +6 -0
  5. data/app/controllers/clearance/confirmations_controller.rb +47 -0
  6. data/app/controllers/clearance/passwords_controller.rb +65 -0
  7. data/app/controllers/clearance/sessions_controller.rb +62 -0
  8. data/app/controllers/clearance/users_controller.rb +30 -0
  9. data/app/models/clearance_mailer.rb +19 -0
  10. data/{generators/clearance/templates/app → app}/views/clearance_mailer/change_password.html.erb +0 -0
  11. data/{generators/clearance/templates/app → app}/views/clearance_mailer/confirmation.html.erb +0 -0
  12. data/{generators/clearance/templates/app → app}/views/passwords/edit.html.erb +0 -0
  13. data/{generators/clearance/templates/app → app}/views/passwords/new.html.erb +0 -0
  14. data/{generators/clearance/templates/app → app}/views/sessions/new.html.erb +0 -0
  15. data/{generators/clearance/templates/app → app}/views/users/_form.html.erb +0 -0
  16. data/{generators/clearance/templates/app → app}/views/users/new.html.erb +0 -0
  17. data/config/clearance_routes.rb +19 -0
  18. data/generators/clearance/clearance_generator.rb +16 -76
  19. data/generators/clearance/templates/README +6 -23
  20. data/generators/clearance/templates/{test/factories/clearance.rb → factories.rb} +2 -5
  21. data/generators/clearance/templates/{db/migrate/create_users_with_clearance_columns.rb → migrations/create_users.rb} +1 -1
  22. data/generators/clearance/templates/{db/migrate/update_users_with_clearance_columns.rb → migrations/update_users.rb} +7 -7
  23. data/generators/clearance/templates/user.rb +3 -0
  24. data/generators/clearance_features/templates/features/step_definitions/clearance_steps.rb +1 -1
  25. data/lib/clearance.rb +15 -15
  26. data/lib/clearance/authentication.rb +80 -0
  27. data/lib/clearance/{lib/extensions → extensions}/errors.rb +0 -0
  28. data/lib/clearance/{lib/extensions → extensions}/rescue.rb +0 -0
  29. data/lib/clearance/user.rb +114 -0
  30. data/shoulda_macros/clearance.rb +11 -4
  31. metadata +34 -63
  32. data/generators/clearance/templates/app/controllers/application.rb +0 -5
  33. data/generators/clearance/templates/app/controllers/confirmations_controller.rb +0 -3
  34. data/generators/clearance/templates/app/controllers/passwords_controller.rb +0 -3
  35. data/generators/clearance/templates/app/controllers/sessions_controller.rb +0 -3
  36. data/generators/clearance/templates/app/controllers/users_controller.rb +0 -3
  37. data/generators/clearance/templates/app/models/clearance_mailer.rb +0 -5
  38. data/generators/clearance/templates/app/models/user.rb +0 -3
  39. data/generators/clearance/templates/app/views/users/edit.html.erb +0 -6
  40. data/generators/clearance/templates/test/functional/confirmations_controller_test.rb +0 -5
  41. data/generators/clearance/templates/test/functional/passwords_controller_test.rb +0 -5
  42. data/generators/clearance/templates/test/functional/sessions_controller_test.rb +0 -5
  43. data/generators/clearance/templates/test/functional/users_controller_test.rb +0 -5
  44. data/generators/clearance/templates/test/unit/clearance_mailer_test.rb +0 -6
  45. data/generators/clearance/templates/test/unit/user_test.rb +0 -5
  46. data/lib/clearance/app/controllers/application_controller.rb +0 -84
  47. data/lib/clearance/app/controllers/confirmations_controller.rb +0 -63
  48. data/lib/clearance/app/controllers/passwords_controller.rb +0 -79
  49. data/lib/clearance/app/controllers/sessions_controller.rb +0 -74
  50. data/lib/clearance/app/controllers/users_controller.rb +0 -45
  51. data/lib/clearance/app/models/clearance_mailer.rb +0 -23
  52. data/lib/clearance/app/models/user.rb +0 -118
  53. data/lib/clearance/test/functional/confirmations_controller_test.rb +0 -72
  54. data/lib/clearance/test/functional/passwords_controller_test.rb +0 -180
  55. data/lib/clearance/test/functional/sessions_controller_test.rb +0 -187
  56. data/lib/clearance/test/functional/users_controller_test.rb +0 -60
  57. data/lib/clearance/test/unit/clearance_mailer_test.rb +0 -65
  58. data/lib/clearance/test/unit/user_test.rb +0 -236
data/CHANGELOG.textile CHANGED
@@ -1,9 +1,33 @@
1
+ h1. 0.6.0 (04/21/2009)
2
+
3
+ * Converted Clearance to a Rails engine. (Dan Croak & Joe Ferris)
4
+ * Include Clearance::User in User model in app. (Dan Croak & Joe Ferris)
5
+ * Include Clearance::Authentication in ApplicationController. (Dan Croak & Joe Ferris)
6
+ * Namespace controllers under Clearance. (Dan Croak & Joe Ferris)
7
+ * Routes move to engine, use namespaced controllers but publicly the same. (Dan Croak & Joe Ferris)
8
+ * If you want to override a controller, subclass it like SessionsController <
9
+ Clearance::SessionsController. This gives you access to usual hooks such as
10
+ url_after_create. (Dan Croak & Joe Ferris)
11
+ * Controllers, mailer, model, routes all unit tested inside engine. Use
12
+ script/generate clearance_features to test integration of Clearance with your
13
+ Rails app. No longer including modules in your app's test files. (Dan Croak & Joe Ferris)
14
+ * Moved views to engine. (Joe Ferris)
15
+ * Converted generated test/factories/clearance.rb to use inheritence for
16
+ email_confirmed_user. (Dan Croak)
17
+ * Corrected some spelling errors with methods (Nick Quaranto)
18
+ * Converted "I should see error messages" to use a regex in the features (Nick
19
+ Quaranto)
20
+ * Loading clearance routes after rails routes via some monkeypatching (Nick
21
+ Quaranto)
22
+ * Made the clearance controllers unloadable to stop constant loading errors in
23
+ development mode (Nick Quaranto)
24
+
1
25
  h2. 0.5.6 (4/11/2009)
2
26
 
3
27
  * [#57] Step definition changed for "User should see error messages" so
4
28
  features won't fail for certain validations. (Nick Quaranto)
5
29
 
6
- h2. 0.5.5 (3/23/2009)
30
+ h1. 0.5.5 (3/23/2009)
7
31
 
8
32
  * Removing duplicate test to get rid of warning. (Nick Quaranto)
9
33
 
data/README.textile CHANGED
@@ -4,6 +4,10 @@ Rails authentication with email & password.
4
4
 
5
5
  "We have clearance, Clarence.":http://www.youtube.com/v/mNRXJEE3Nz8
6
6
 
7
+ h2. Engine
8
+
9
+ Clearance is a Rails engine. It works with versions of Rails greater than 2.3.
10
+
7
11
  h2. Wiki
8
12
 
9
13
  Most information regarding Clearance is on the "Github Wiki":http://wiki.github.com/thoughtbot/clearance.
@@ -12,30 +16,30 @@ h2. Integration with Suspenders
12
16
 
13
17
  Clearance is based on the same conventions and tools as "Suspenders":http://github.com/thoughtbot/suspenders If you use it, you already have some configuration mentioned below.
14
18
 
15
- h2. Gem installation (Rails 2.1+)
19
+ h2. Gem installation
16
20
 
17
21
  In config/environment.rb:
18
22
 
19
23
  config.gem "thoughtbot-clearance",
20
24
  :lib => 'clearance',
21
25
  :source => 'http://gems.github.com',
22
- :version => '0.5.5'
26
+ :version => '0.6.0'
23
27
 
24
28
  In config/environments/test.rb:
25
29
 
26
30
  config.gem 'thoughtbot-shoulda',
27
31
  :lib => 'shoulda',
28
32
  :source => "http://gems.github.com",
29
- :version => '2.10.0'
33
+ :version => '2.10.1'
30
34
  config.gem 'thoughtbot-factory_girl',
31
35
  :lib => 'factory_girl',
32
36
  :source => "http://gems.github.com",
33
- :version => '1.2.0'
37
+ :version => '1.2.1'
34
38
 
35
39
  Then:
36
40
 
37
41
  rake gems:install
38
- rake gems:unpack
42
+ rake gems:unpack
39
43
  rake gems:install RAILS_ENV=test
40
44
  rake gems:unpack RAILS_ENV=test
41
45
 
@@ -74,3 +78,12 @@ h2. Authors
74
78
  Clearance was extracted out of "Hoptoad":http://hoptoadapp.com. We merged the authentication code from two of thoughtbot's client's Rails apps. The following people have made significant contributions, suggestions, and generally improved the library. Thank you!
75
79
 
76
80
  Dan Croak, Mike Burns, Jason Morrison, Joe Ferris, Eugene Bolshakov, Josh Nichols, Mike Breen, Marcel Görner, Bence Nagy, Ben Mabey, Eloy Duran, Tim Pope, Mihai Anca, & Mark Cornick.
81
+
82
+ h2. Questions?
83
+
84
+ * Ask the "mailing list":http://groups.google.com/group/thoughtbot-clearance
85
+
86
+ h2. Bugs?
87
+
88
+ * Open up a "Lighthouse ticket":https://thoughtbot.lighthouseapp.com/projects/18503-clearance
89
+
data/Rakefile CHANGED
@@ -2,19 +2,17 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'cucumber/rake/task'
4
4
 
5
- test_files_pattern = 'test/rails_root/test/{unit,functional,other}/**/*_test.rb'
6
-
7
5
  namespace :test do
8
6
  Rake::TestTask.new(:all => ['generator:cleanup',
9
7
  'generator:generate']) do |task|
10
8
  task.libs << 'lib'
11
- task.libs << File.join(File.dirname(__FILE__), "test/rails_root/test")
12
- task.pattern = test_files_pattern
9
+ task.libs << "test"
10
+ task.pattern = 'test/**/*_test.rb'
13
11
  task.verbose = false
14
12
  end
15
13
 
16
14
  Cucumber::Rake::Task.new(:features) do |t|
17
- t.cucumber_opts = "--format pretty"
15
+ t.cucumber_opts = "--format progress"
18
16
  t.feature_pattern = 'test/rails_root/features/*.feature'
19
17
  end
20
18
  end
@@ -35,14 +33,15 @@ namespace :generator do
35
33
  FileUtils.rm_rf(each)
36
34
  end
37
35
  FileUtils.rm_rf("test/rails_root/vendor/plugins/clearance")
38
- system "mkdir -p test/rails_root/vendor/plugins/clearance"
39
- system "cp -R generators test/rails_root/vendor/plugins/clearance"
36
+ FileUtils.mkdir_p("test/rails_root/vendor/plugins")
37
+ clearance_root = File.expand_path(File.dirname(__FILE__))
38
+ system("ln -s #{clearance_root} test/rails_root/vendor/plugins/clearance")
40
39
  end
41
40
 
42
41
  desc "Run the generator on the tests"
43
42
  task :generate do
44
43
  generators.each do |generator|
45
- system "cd test/rails_root && ./script/generate #{generator}"
44
+ system "cd test/rails_root && ./script/generate #{generator} && rake db:migrate db:test:prepare"
46
45
  end
47
46
  end
48
47
  end
@@ -52,7 +51,7 @@ task :default => ['test:all', 'test:features']
52
51
 
53
52
  gem_spec = Gem::Specification.new do |gem_spec|
54
53
  gem_spec.name = "clearance"
55
- gem_spec.version = "0.5.6"
54
+ gem_spec.version = "0.6.0"
56
55
  gem_spec.summary = "Rails authentication for developers who write tests."
57
56
  gem_spec.email = "support@thoughtbot.com"
58
57
  gem_spec.homepage = "http://github.com/thoughtbot/clearance"
@@ -62,7 +61,7 @@ gem_spec = Gem::Specification.new do |gem_spec|
62
61
  "Mike Breen", "Joe Ferris", "Bence Nagy",
63
62
  "Marcel Görner", "Ben Mabey", "Tim Pope",
64
63
  "Eloy Duran", "Mihai Anca", "Mark Cornick"]
65
- gem_spec.files = FileList["[A-Z]*", "{generators,lib,shoulda_macros,rails}/**/*"]
64
+ gem_spec.files = FileList["[A-Z]*", "{app,config,generators,lib,shoulda_macros,rails}/**/*"]
66
65
  end
67
66
 
68
67
  desc "Generate a gemspec file"
data/TODO.textile ADDED
@@ -0,0 +1,6 @@
1
+ h1. To-do
2
+
3
+ * Make insertion of Clearance::User into User model automatic from the generator.
4
+ * Change generated README to include instruction about running the migration.
5
+ * DO_NOT_REPLY, HOST refactoring.
6
+
@@ -0,0 +1,47 @@
1
+ class Clearance::ConfirmationsController < ApplicationController
2
+ unloadable
3
+
4
+ before_filter :forbid_confirmed_user, :only => :new
5
+ before_filter :forbid_missing_token, :only => :new
6
+ before_filter :forbid_non_existent_user, :only => :new
7
+ filter_parameter_logging :token
8
+
9
+ def new
10
+ create
11
+ end
12
+
13
+ def create
14
+ @user = User.find_by_id_and_token(params[:user_id], params[:token])
15
+ @user.confirm_email!
16
+
17
+ sign_user_in(@user)
18
+ flash[:success] = "Confirmed email and signed in."
19
+ redirect_to url_after_create
20
+ end
21
+
22
+ private
23
+
24
+ def forbid_confirmed_user
25
+ user = User.find_by_id(params[:user_id])
26
+ if user && user.email_confirmed?
27
+ raise ActionController::Forbidden, "confirmed user"
28
+ end
29
+ end
30
+
31
+ def forbid_missing_token
32
+ if params[:token].blank?
33
+ raise ActionController::Forbidden, "missing token"
34
+ end
35
+ end
36
+
37
+ def forbid_non_existent_user
38
+ unless User.find_by_id_and_token(params[:user_id], params[:token])
39
+ raise ActionController::Forbidden, "non-existent user"
40
+ end
41
+ end
42
+
43
+ def url_after_create
44
+ root_url
45
+ end
46
+
47
+ end
@@ -0,0 +1,65 @@
1
+ class Clearance::PasswordsController < ApplicationController
2
+ unloadable
3
+
4
+ before_filter :forbid_missing_token, :only => [:edit, :update]
5
+ before_filter :forbid_non_existent_user, :only => [:edit, :update]
6
+ filter_parameter_logging :password, :password_confirmation
7
+
8
+ def new
9
+ render :template => 'passwords/new'
10
+ end
11
+
12
+ def create
13
+ if user = User.find_by_email(params[:password][:email])
14
+ user.forgot_password!
15
+ ClearanceMailer.deliver_change_password user
16
+ flash[:notice] = "You will receive an email within the next few minutes. " <<
17
+ "It contains instructions for changing your password."
18
+ redirect_to url_after_create
19
+ else
20
+ flash.now[:notice] = "Unknown email"
21
+ render :template => 'passwords/new'
22
+ end
23
+ end
24
+
25
+ def edit
26
+ @user = User.find_by_id_and_token(params[:user_id], params[:token])
27
+ render :template => 'passwords/edit'
28
+ end
29
+
30
+ def update
31
+ @user = User.find_by_id_and_token(params[:user_id], params[:token])
32
+
33
+ if @user.update_password(params[:user][:password],
34
+ params[:user][:password_confirmation])
35
+ @user.confirm_email! unless @user.email_confirmed?
36
+ sign_user_in(@user)
37
+ redirect_to url_after_update
38
+ else
39
+ render :template => 'passwords/edit'
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def forbid_missing_token
46
+ if params[:token].blank?
47
+ raise ActionController::Forbidden, "missing token"
48
+ end
49
+ end
50
+
51
+ def forbid_non_existent_user
52
+ unless User.find_by_id_and_token(params[:user_id], params[:token])
53
+ raise ActionController::Forbidden, "non-existent user"
54
+ end
55
+ end
56
+
57
+ def url_after_create
58
+ new_session_url
59
+ end
60
+
61
+ def url_after_update
62
+ root_url
63
+ end
64
+
65
+ end
@@ -0,0 +1,62 @@
1
+ class Clearance::SessionsController < ApplicationController
2
+ unloadable
3
+
4
+ protect_from_forgery :except => :create
5
+ filter_parameter_logging :password
6
+
7
+ def new
8
+ render :template => 'sessions/new'
9
+ end
10
+
11
+ def create
12
+ @user = User.authenticate(params[:session][:email],
13
+ params[:session][:password])
14
+ if @user.nil?
15
+ flash.now[:notice] = "Bad email or password."
16
+ render :template => 'sessions/new', :status => :unauthorized
17
+ else
18
+ if @user.email_confirmed?
19
+ remember(@user) if remember?
20
+ sign_user_in(@user)
21
+ flash[:notice] = "Signed in successfully."
22
+ redirect_back_or url_after_create
23
+ else
24
+ ClearanceMailer.deliver_confirmation(@user)
25
+ deny_access("User has not confirmed email. Confirmation email will be resent.")
26
+ end
27
+ end
28
+ end
29
+
30
+ def destroy
31
+ forget(current_user)
32
+ reset_session
33
+ flash[:notice] = "You have been signed out."
34
+ redirect_to url_after_destroy
35
+ end
36
+
37
+ private
38
+
39
+ def remember?
40
+ params[:session] && params[:session][:remember_me] == "1"
41
+ end
42
+
43
+ def remember(user)
44
+ user.remember_me!
45
+ cookies[:remember_token] = { :value => user.token,
46
+ :expires => user.token_expires_at }
47
+ end
48
+
49
+ def forget(user)
50
+ user.forget_me! if user
51
+ cookies.delete :remember_token
52
+ end
53
+
54
+ def url_after_create
55
+ root_url
56
+ end
57
+
58
+ def url_after_destroy
59
+ new_session_url
60
+ end
61
+
62
+ end
@@ -0,0 +1,30 @@
1
+ class Clearance::UsersController < ApplicationController
2
+ unloadable
3
+
4
+ before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in?
5
+ filter_parameter_logging :password
6
+
7
+ def new
8
+ @user = User.new(params[:user])
9
+ render :template => 'users/new'
10
+ end
11
+
12
+ def create
13
+ @user = User.new params[:user]
14
+ if @user.save
15
+ ClearanceMailer.deliver_confirmation @user
16
+ flash[:notice] = "You will receive an email within the next few minutes. " <<
17
+ "It contains instructions for confirming your account."
18
+ redirect_to url_after_create
19
+ else
20
+ render :template => 'users/new'
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def url_after_create
27
+ new_session_url
28
+ end
29
+
30
+ end
@@ -0,0 +1,19 @@
1
+ class ClearanceMailer < ActionMailer::Base
2
+
3
+ default_url_options[:host] = HOST
4
+
5
+ def change_password(user)
6
+ from DO_NOT_REPLY
7
+ recipients user.email
8
+ subject "Change your password"
9
+ body :user => user
10
+ end
11
+
12
+ def confirmation(user)
13
+ from DO_NOT_REPLY
14
+ recipients user.email
15
+ subject "Account confirmation"
16
+ body :user => user
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resources :passwords,
3
+ :controller => 'clearance/passwords',
4
+ :only => [:new, :create]
5
+
6
+ map.resource :session,
7
+ :controller => 'clearance/sessions',
8
+ :only => [:new, :create, :destroy]
9
+
10
+ map.resources :users, :controller => 'clearance/users' do |users|
11
+ users.resource :password,
12
+ :controller => 'clearance/passwords',
13
+ :only => [:create, :edit, :update]
14
+
15
+ users.resource :confirmation,
16
+ :controller => 'clearance/confirmations',
17
+ :only => [:new, :create]
18
+ end
19
+ end
@@ -6,90 +6,30 @@ class ClearanceGenerator < Rails::Generator::Base
6
6
 
7
7
  def manifest
8
8
  record do |m|
9
- m.directory File.join("app", "controllers")
10
- if Rails.version >= "2.3.0"
11
- file = "app/controllers/application_controller.rb"
12
- else
13
- file = "app/controllers/application.rb"
14
- end
15
- if File.exists?(file)
16
- m.insert_into file, "include Clearance::App::Controllers::ApplicationController"
17
- else
18
- m.file file, file
19
- end
20
-
21
- ["app/controllers/confirmations_controller.rb",
22
- "app/controllers/passwords_controller.rb",
23
- "app/controllers/sessions_controller.rb",
24
- "app/controllers/users_controller.rb"].each do |file|
25
- m.file file, file
26
- end
9
+ m.insert_into "app/controllers/application_controller.rb",
10
+ "include Clearance::Authentication"
27
11
 
28
12
  m.directory File.join("app", "models")
29
- ["app/models/user.rb", "app/models/clearance_mailer.rb"].each do |file|
30
- m.file file, file
31
- end
32
-
33
- m.directory File.join("app", "views")
34
-
35
- m.directory File.join("app", "views", "passwords")
36
- ["app/views/passwords/new.html.erb",
37
- "app/views/passwords/edit.html.erb"].each do |file|
38
- m.file file, file
39
- end
40
-
41
- m.directory File.join("app", "views", "sessions")
42
- ["app/views/sessions/new.html.erb"].each do |file|
43
- m.file file, file
44
- end
45
-
46
- m.directory File.join("app", "views", "clearance_mailer")
47
- ["app/views/clearance_mailer/change_password.html.erb",
48
- "app/views/clearance_mailer/confirmation.html.erb"].each do |file|
49
- m.file file, file
50
- end
51
-
52
- m.directory File.join("app", "views", "users")
53
- ["app/views/users/_form.html.erb",
54
- "app/views/users/edit.html.erb",
55
- "app/views/users/new.html.erb"].each do |file|
56
- m.file file, file
57
- end
58
-
59
- m.directory File.join("test", "functional")
60
- ["test/functional/confirmations_controller_test.rb",
61
- "test/functional/passwords_controller_test.rb",
62
- "test/functional/sessions_controller_test.rb",
63
- "test/functional/users_controller_test.rb"].each do |file|
64
- m.file file, file
65
- end
66
-
67
- m.directory File.join("test", "unit")
68
- ["test/unit/clearance_mailer_test.rb",
69
- "test/unit/user_test.rb"].each do |file|
70
- m.file file, file
71
- end
13
+ m.file "user.rb", "app/models/user.rb"
72
14
 
73
15
  m.directory File.join("test", "factories")
74
- ["test/factories/clearance.rb"].each do |file|
75
- m.file file, file
76
- end
16
+ m.file "factories.rb", "test/factories/clearance.rb"
77
17
 
78
- m.route_resources ':passwords'
79
- m.route_resource ':session'
80
- m.route_resources ':users, :has_one => [:password, :confirmation]'
18
+ m.migration_template "migrations/#{migration_name}.rb",
19
+ 'db/migrate',
20
+ :migration_file_name => "clearance_#{migration_name}"
81
21
 
82
- if ActiveRecord::Base.connection.table_exists?(:users)
83
- m.migration_template 'db/migrate/update_users_with_clearance_columns.rb',
84
- 'db/migrate', :migration_file_name => 'create_or_update_users_with_clearance_columns'
85
- else
86
- m.migration_template 'db/migrate/create_users_with_clearance_columns.rb',
87
- 'db/migrate', :migration_file_name => 'create_or_update_users_with_clearance_columns'
88
- end
22
+ m.readme "README"
23
+ end
24
+ end
89
25
 
90
- m.rake_db_migrate
26
+ private
91
27
 
92
- m.readme "README"
28
+ def migration_name
29
+ if ActiveRecord::Base.connection.table_exists?(:users)
30
+ 'update_users'
31
+ else
32
+ 'create_users'
93
33
  end
94
34
  end
95
35