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
@@ -3,42 +3,25 @@
3
3
 
4
4
  Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
5
5
 
6
- 1. For any other file(s) that you already had and didn't want to overwrite, add
7
- the corresponding Clearance module. They are namespaced exactly like the
8
- directory structure of a Rails app.
9
-
10
- Application controller example:
11
-
12
- class ApplicationController < ActionController::Base
13
- include Clearance::App::Controllers::ApplicationController
14
- end
15
-
16
- User model example:
6
+ 1. If you already had a User model, include the Clearance::User module now:
17
7
 
18
8
  class User < ActiveRecord::Base
19
- include Clearance::App::Models::User
20
- end
21
-
22
- User test example:
23
-
24
- class UserTest < ActiveSupport::TestCase
25
- include Clearance::Test::Unit::UserTest
9
+ include Clearance::User
26
10
  end
27
11
 
28
- 2. You need to define HOST constant in your environments files.
12
+ 2. Define a HOST constant in your environments files.
29
13
  In config/environments/test.rb and config/environments/development.rb it can be:
30
14
 
31
15
  HOST = "localhost"
32
16
 
33
- In production.rb it must be the actual host your application is deployed to.
17
+ In production.rb it must be the actual host your application is deployed to.
34
18
  The constant is used by mailers to generate URLs in emails.
35
19
 
36
- In config/environment.rb:
20
+ 3. In config/environment.rb:
37
21
 
38
22
  DO_NOT_REPLY = "donotreply@example.com"
39
23
 
40
- 3. Clearance depends on root_url, so please make sure that it is defined to
41
- *something* in your config/routes.rb:
24
+ 4. Define root_url to *something* in your config/routes.rb:
42
25
 
43
26
  map.root :controller => 'home'
44
27
 
@@ -8,9 +8,6 @@ Factory.define :user do |user|
8
8
  user.password_confirmation { "password" }
9
9
  end
10
10
 
11
- Factory.define :email_confirmed_user, :class => 'user' do |user|
12
- user.email { Factory.next :email }
13
- user.password { "password" }
14
- user.password_confirmation { "password" }
15
- user.email_confirmed { true }
11
+ Factory.define :email_confirmed_user, :parent => :user do |user|
12
+ user.email_confirmed { true }
16
13
  end
@@ -1,4 +1,4 @@
1
- class CreateOrUpdateUsersWithClearanceColumns < ActiveRecord::Migration
1
+ class ClearanceCreateUsers < ActiveRecord::Migration
2
2
  def self.up
3
3
  create_table(:users) do |t|
4
4
  t.string :email
@@ -1,14 +1,14 @@
1
- class CreateOrUpdateUsersWithClearanceColumns < ActiveRecord::Migration
1
+ class ClearanceUpdateUsers < ActiveRecord::Migration
2
2
  def self.up
3
3
  <%
4
4
  existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name }
5
5
  columns = [
6
- [:email, 't.string :email'],
7
- [:encrypted_password, 't.string :encrypted_password, :limit => 128'],
8
- [:salt, 't.string :salt, :limit => 128'],
9
- [:token, 't.string :token, :limit => 128'],
10
- [:token_expires_at, 't.datetime :token_expires_at'],
11
- [:email_confirmed, 't.boolean :email_confirmed, :default => false, :null => false']
6
+ [:email, 't.string :email'],
7
+ [:encrypted_password, 't.string :encrypted_password, :limit => 128'],
8
+ [:salt, 't.string :salt, :limit => 128'],
9
+ [:token, 't.string :token, :limit => 128'],
10
+ [:token_expires_at, 't.datetime :token_expires_at'],
11
+ [:email_confirmed, 't.boolean :email_confirmed, :default => false, :null => false']
12
12
  ].delete_if {|c| existing_columns.include?(c.first.to_s)}
13
13
  -%>
14
14
  change_table(:users) do |t|
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ include Clearance::User
3
+ end
@@ -1,7 +1,7 @@
1
1
  # General
2
2
 
3
3
  Then /^I should see error messages$/ do
4
- response.should contain(/error(s)? prohibited/)
4
+ assert_match /error(s)? prohibited/m, response.body
5
5
  end
6
6
 
7
7
  # Database
data/lib/clearance.rb CHANGED
@@ -1,15 +1,15 @@
1
- require 'clearance/lib/extensions/errors'
2
- require 'clearance/lib/extensions/rescue'
3
- require 'clearance/app/controllers/application_controller'
4
- require 'clearance/app/controllers/confirmations_controller'
5
- require 'clearance/app/controllers/passwords_controller'
6
- require 'clearance/app/controllers/sessions_controller'
7
- require 'clearance/app/controllers/users_controller'
8
- require 'clearance/app/models/clearance_mailer'
9
- require 'clearance/app/models/user'
10
- require 'clearance/test/functional/confirmations_controller_test'
11
- require 'clearance/test/functional/passwords_controller_test'
12
- require 'clearance/test/functional/sessions_controller_test'
13
- require 'clearance/test/functional/users_controller_test'
14
- require 'clearance/test/unit/clearance_mailer_test'
15
- require 'clearance/test/unit/user_test'
1
+ require 'clearance/extensions/errors'
2
+ require 'clearance/extensions/rescue'
3
+
4
+ require 'clearance/authentication'
5
+ require 'clearance/user'
6
+
7
+ class ActionController::Routing::RouteSet
8
+ def load_routes_with_clearance!
9
+ clearance_routes = File.join(File.dirname(__FILE__), *%w[.. config clearance_routes.rb])
10
+ add_configuration_file(clearance_routes) unless configuration_files.include? clearance_routes
11
+ load_routes_without_clearance!
12
+ end
13
+
14
+ alias_method_chain :load_routes!, :clearance
15
+ end
@@ -0,0 +1,80 @@
1
+ module Clearance
2
+ module Authentication
3
+
4
+ def self.included(controller)
5
+ controller.send(:include, InstanceMethods)
6
+
7
+ controller.class_eval do
8
+ helper_method :current_user
9
+ helper_method :signed_in?
10
+
11
+ hide_action :current_user, :signed_in?
12
+ end
13
+ end
14
+
15
+ module InstanceMethods
16
+ def current_user
17
+ @_current_user ||= (user_from_cookie || user_from_session)
18
+ end
19
+
20
+ def signed_in?
21
+ ! current_user.nil?
22
+ end
23
+
24
+ protected
25
+
26
+ def authenticate
27
+ deny_access unless signed_in?
28
+ end
29
+
30
+ def user_from_session
31
+ if session[:user_id]
32
+ return nil unless user = ::User.find_by_id(session[:user_id])
33
+ return user if user.email_confirmed?
34
+ end
35
+ end
36
+
37
+ def user_from_cookie
38
+ if token = cookies[:remember_token]
39
+ return nil unless user = ::User.find_by_token(token)
40
+ return user if user.remember?
41
+ end
42
+ end
43
+
44
+ def sign_user_in(user)
45
+ sign_in(user)
46
+ end
47
+
48
+ def sign_in(user)
49
+ if user
50
+ session[:user_id] = user.id
51
+ end
52
+ end
53
+
54
+ def redirect_back_or(default)
55
+ session[:return_to] ||= params[:return_to]
56
+ if session[:return_to]
57
+ redirect_to(session[:return_to])
58
+ else
59
+ redirect_to(default)
60
+ end
61
+ session[:return_to] = nil
62
+ end
63
+
64
+ def redirect_to_root
65
+ redirect_to root_url
66
+ end
67
+
68
+ def store_location
69
+ session[:return_to] = request.request_uri if request.get?
70
+ end
71
+
72
+ def deny_access(flash_message = nil, opts = {})
73
+ store_location
74
+ flash[:failure] = flash_message if flash_message
75
+ redirect_to new_session_url
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,114 @@
1
+ require 'digest/sha1'
2
+
3
+ module Clearance
4
+ module User
5
+
6
+ def self.included(model)
7
+ model.extend ClassMethods
8
+ model.send(:include, InstanceMethods)
9
+
10
+ model.class_eval do
11
+ attr_accessible :email, :password, :password_confirmation
12
+ attr_accessor :password, :password_confirmation
13
+
14
+ validates_presence_of :email
15
+ validates_presence_of :password, :if => :password_required?
16
+ validates_confirmation_of :password, :if => :password_required?
17
+ validates_uniqueness_of :email, :case_sensitive => false
18
+ validates_format_of :email, :with => %r{.+@.+\..+}
19
+
20
+ before_save :initialize_salt, :encrypt_password, :initialize_token
21
+ end
22
+ end
23
+
24
+ module InstanceMethods
25
+ def authenticated?(password)
26
+ encrypted_password == encrypt(password)
27
+ end
28
+
29
+ def encrypt(string)
30
+ generate_hash("--#{salt}--#{string}--")
31
+ end
32
+
33
+ def remember?
34
+ token_expires_at && Time.now.utc < token_expires_at
35
+ end
36
+
37
+ def remember_me!
38
+ remember_me_until! 2.weeks.from_now.utc
39
+ end
40
+
41
+ def forget_me!
42
+ clear_token
43
+ save(false)
44
+ end
45
+
46
+ def confirm_email!
47
+ self.email_confirmed = true
48
+ self.token = nil
49
+ save(false)
50
+ end
51
+
52
+ def forgot_password!
53
+ generate_token
54
+ save(false)
55
+ end
56
+
57
+ def update_password(new_password, new_password_confirmation)
58
+ self.password = new_password
59
+ self.password_confirmation = new_password_confirmation
60
+ clear_token if valid?
61
+ save
62
+ end
63
+
64
+ protected
65
+
66
+ def generate_hash(string)
67
+ Digest::SHA1.hexdigest(string)
68
+ end
69
+
70
+ def initialize_salt
71
+ if new_record?
72
+ self.salt = generate_hash("--#{Time.now.utc.to_s}--#{password}--")
73
+ end
74
+ end
75
+
76
+ def encrypt_password
77
+ return if password.blank?
78
+ self.encrypted_password = encrypt(password)
79
+ end
80
+
81
+ def generate_token
82
+ self.token = encrypt("--#{Time.now.utc.to_s}--#{password}--")
83
+ self.token_expires_at = nil
84
+ end
85
+
86
+ def clear_token
87
+ self.token = nil
88
+ self.token_expires_at = nil
89
+ end
90
+
91
+ def initialize_token
92
+ generate_token if new_record?
93
+ end
94
+
95
+ def password_required?
96
+ encrypted_password.blank? || !password.blank?
97
+ end
98
+
99
+ def remember_me_until!(time)
100
+ self.token_expires_at = time
101
+ self.token = encrypt("--#{token_expires_at}--#{password}--")
102
+ save(false)
103
+ end
104
+ end
105
+
106
+ module ClassMethods
107
+ def authenticate(email, password)
108
+ return nil unless user = find_by_email(email)
109
+ return user if user.authenticated?(password)
110
+ end
111
+ end
112
+
113
+ end
114
+ end
@@ -31,10 +31,17 @@ module Clearance
31
31
  end
32
32
  end
33
33
 
34
- def should_deny_access_on(command, opts = {})
35
- context "on #{command}" do
36
- setup { eval command }
37
- should_deny_access(opts)
34
+ # Examples:
35
+ # should_deny_access_on :get, :index, :flash => /not authorized/i
36
+ # should_deny_access_on :get, :show, :id => '1'
37
+ def should_deny_access_on(http_method, action, opts = {})
38
+ flash_message = opts.delete(:flash)
39
+ context "on #{http_method} to #{action}" do
40
+ setup do
41
+ send(http_method, action, opts)
42
+ end
43
+
44
+ should_deny_access(:flash => flash_message)
38
45
  end
39
46
  end
40
47
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thoughtbot-clearance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoughtbot, inc.
@@ -23,7 +23,7 @@ autorequire:
23
23
  bindir: bin
24
24
  cert_chain: []
25
25
 
26
- date: 2009-04-10 21:00:00 -07:00
26
+ date: 2009-04-20 21:00:00 -07:00
27
27
  default_executable:
28
28
  dependencies: []
29
29
 
@@ -40,51 +40,40 @@ files:
40
40
  - LICENSE
41
41
  - Rakefile
42
42
  - README.textile
43
+ - TODO.textile
44
+ - app/controllers
45
+ - app/controllers/clearance
46
+ - app/controllers/clearance/confirmations_controller.rb
47
+ - app/controllers/clearance/passwords_controller.rb
48
+ - app/controllers/clearance/sessions_controller.rb
49
+ - app/controllers/clearance/users_controller.rb
50
+ - app/models
51
+ - app/models/clearance_mailer.rb
52
+ - app/views
53
+ - app/views/clearance_mailer
54
+ - app/views/clearance_mailer/change_password.html.erb
55
+ - app/views/clearance_mailer/confirmation.html.erb
56
+ - app/views/passwords
57
+ - app/views/passwords/edit.html.erb
58
+ - app/views/passwords/new.html.erb
59
+ - app/views/sessions
60
+ - app/views/sessions/new.html.erb
61
+ - app/views/users
62
+ - app/views/users/_form.html.erb
63
+ - app/views/users/new.html.erb
64
+ - config/clearance_routes.rb
43
65
  - generators/clearance
44
66
  - generators/clearance/clearance_generator.rb
45
67
  - generators/clearance/lib
46
68
  - generators/clearance/lib/insert_commands.rb
47
69
  - generators/clearance/lib/rake_commands.rb
48
70
  - generators/clearance/templates
49
- - generators/clearance/templates/app
50
- - generators/clearance/templates/app/controllers
51
- - generators/clearance/templates/app/controllers/application.rb
52
- - generators/clearance/templates/app/controllers/confirmations_controller.rb
53
- - generators/clearance/templates/app/controllers/passwords_controller.rb
54
- - generators/clearance/templates/app/controllers/sessions_controller.rb
55
- - generators/clearance/templates/app/controllers/users_controller.rb
56
- - generators/clearance/templates/app/models
57
- - generators/clearance/templates/app/models/clearance_mailer.rb
58
- - generators/clearance/templates/app/models/user.rb
59
- - generators/clearance/templates/app/views
60
- - generators/clearance/templates/app/views/clearance_mailer
61
- - generators/clearance/templates/app/views/clearance_mailer/change_password.html.erb
62
- - generators/clearance/templates/app/views/clearance_mailer/confirmation.html.erb
63
- - generators/clearance/templates/app/views/passwords
64
- - generators/clearance/templates/app/views/passwords/edit.html.erb
65
- - generators/clearance/templates/app/views/passwords/new.html.erb
66
- - generators/clearance/templates/app/views/sessions
67
- - generators/clearance/templates/app/views/sessions/new.html.erb
68
- - generators/clearance/templates/app/views/users
69
- - generators/clearance/templates/app/views/users/_form.html.erb
70
- - generators/clearance/templates/app/views/users/edit.html.erb
71
- - generators/clearance/templates/app/views/users/new.html.erb
72
- - generators/clearance/templates/db
73
- - generators/clearance/templates/db/migrate
74
- - generators/clearance/templates/db/migrate/create_users_with_clearance_columns.rb
75
- - generators/clearance/templates/db/migrate/update_users_with_clearance_columns.rb
71
+ - generators/clearance/templates/factories.rb
72
+ - generators/clearance/templates/migrations
73
+ - generators/clearance/templates/migrations/create_users.rb
74
+ - generators/clearance/templates/migrations/update_users.rb
76
75
  - generators/clearance/templates/README
77
- - generators/clearance/templates/test
78
- - generators/clearance/templates/test/factories
79
- - generators/clearance/templates/test/factories/clearance.rb
80
- - generators/clearance/templates/test/functional
81
- - generators/clearance/templates/test/functional/confirmations_controller_test.rb
82
- - generators/clearance/templates/test/functional/passwords_controller_test.rb
83
- - generators/clearance/templates/test/functional/sessions_controller_test.rb
84
- - generators/clearance/templates/test/functional/users_controller_test.rb
85
- - generators/clearance/templates/test/unit
86
- - generators/clearance/templates/test/unit/clearance_mailer_test.rb
87
- - generators/clearance/templates/test/unit/user_test.rb
76
+ - generators/clearance/templates/user.rb
88
77
  - generators/clearance/USAGE
89
78
  - generators/clearance_features
90
79
  - generators/clearance_features/clearance_features_generator.rb
@@ -101,29 +90,11 @@ files:
101
90
  - generators/clearance_features/templates/features/support/paths.rb
102
91
  - generators/clearance_features/USAGE
103
92
  - lib/clearance
104
- - lib/clearance/app
105
- - lib/clearance/app/controllers
106
- - lib/clearance/app/controllers/application_controller.rb
107
- - lib/clearance/app/controllers/confirmations_controller.rb
108
- - lib/clearance/app/controllers/passwords_controller.rb
109
- - lib/clearance/app/controllers/sessions_controller.rb
110
- - lib/clearance/app/controllers/users_controller.rb
111
- - lib/clearance/app/models
112
- - lib/clearance/app/models/clearance_mailer.rb
113
- - lib/clearance/app/models/user.rb
114
- - lib/clearance/lib
115
- - lib/clearance/lib/extensions
116
- - lib/clearance/lib/extensions/errors.rb
117
- - lib/clearance/lib/extensions/rescue.rb
118
- - lib/clearance/test
119
- - lib/clearance/test/functional
120
- - lib/clearance/test/functional/confirmations_controller_test.rb
121
- - lib/clearance/test/functional/passwords_controller_test.rb
122
- - lib/clearance/test/functional/sessions_controller_test.rb
123
- - lib/clearance/test/functional/users_controller_test.rb
124
- - lib/clearance/test/unit
125
- - lib/clearance/test/unit/clearance_mailer_test.rb
126
- - lib/clearance/test/unit/user_test.rb
93
+ - lib/clearance/authentication.rb
94
+ - lib/clearance/extensions
95
+ - lib/clearance/extensions/errors.rb
96
+ - lib/clearance/extensions/rescue.rb
97
+ - lib/clearance/user.rb
127
98
  - lib/clearance.rb
128
99
  - shoulda_macros/clearance.rb
129
100
  - rails/init.rb