thoughtbot-clearance 0.2.5 → 0.2.6
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.
- data/README.textile +8 -16
- data/Rakefile +12 -10
- data/TODO.textile +7 -4
- data/generators/clearance/templates/app/controllers/application.rb +1 -1
- data/generators/clearance/templates/app/controllers/confirmations_controller.rb +1 -1
- data/generators/clearance/templates/app/controllers/passwords_controller.rb +1 -1
- data/generators/clearance/templates/app/controllers/sessions_controller.rb +1 -1
- data/generators/clearance/templates/app/controllers/users_controller.rb +1 -1
- data/generators/clearance/templates/app/models/user.rb +1 -1
- data/generators/clearance/templates/app/models/user_mailer.rb +1 -1
- data/generators/clearance/templates/test/functional/confirmations_controller_test.rb +1 -1
- data/generators/clearance/templates/test/functional/passwords_controller_test.rb +1 -1
- data/generators/clearance/templates/test/functional/sessions_controller_test.rb +1 -1
- data/generators/clearance/templates/test/functional/users_controller_test.rb +1 -1
- data/generators/clearance/templates/test/unit/user_mailer_test.rb +1 -1
- data/generators/clearance/templates/test/unit/user_test.rb +1 -1
- data/lib/clearance.rb +6 -6
- data/lib/clearance/app/controllers/application_controller.rb +58 -54
- data/lib/clearance/app/controllers/confirmations_controller.rb +30 -26
- data/lib/clearance/app/controllers/passwords_controller.rb +48 -44
- data/lib/clearance/app/controllers/sessions_controller.rb +61 -56
- data/lib/clearance/app/controllers/users_controller.rb +32 -28
- data/lib/clearance/app/models/user.rb +58 -56
- data/lib/clearance/app/models/user_mailer.rb +21 -18
- data/lib/clearance/test/test_helper.rb +66 -64
- data/lib/clearance/version.rb +2 -2
- data/test/rails_root/app/controllers/application.rb +1 -1
- data/test/rails_root/app/controllers/confirmations_controller.rb +1 -1
- data/test/rails_root/app/controllers/passwords_controller.rb +1 -1
- data/test/rails_root/app/controllers/sessions_controller.rb +1 -1
- data/test/rails_root/app/controllers/users_controller.rb +1 -1
- data/test/rails_root/app/models/user.rb +1 -1
- data/test/rails_root/app/models/user_mailer.rb +1 -1
- data/test/rails_root/test/functional/confirmations_controller_test.rb +1 -1
- data/test/rails_root/test/functional/passwords_controller_test.rb +1 -1
- data/test/rails_root/test/functional/sessions_controller_test.rb +1 -1
- data/test/rails_root/test/functional/users_controller_test.rb +1 -1
- data/test/rails_root/test/test_helper.rb +1 -1
- data/test/rails_root/test/unit/user_mailer_test.rb +1 -1
- data/test/rails_root/test/unit/user_test.rb +1 -1
- metadata +34 -10
- data/lib/clearance/test/functionals/confirmations_controller_test.rb +0 -81
- data/lib/clearance/test/functionals/passwords_controller_test.rb +0 -188
- data/lib/clearance/test/functionals/sessions_controller_test.rb +0 -91
- data/lib/clearance/test/functionals/users_controller_test.rb +0 -60
- data/lib/clearance/test/units/user_mailer_test.rb +0 -34
- data/lib/clearance/test/units/user_test.rb +0 -203
@@ -1,72 +1,77 @@
|
|
1
1
|
module Clearance
|
2
|
-
module
|
2
|
+
module App
|
3
|
+
module Controllers
|
4
|
+
module SessionsController
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
skip_before_filter :authenticate
|
9
|
+
protect_from_forgery :except => :create
|
10
|
+
filter_parameter_logging :password
|
9
11
|
|
10
|
-
|
12
|
+
include InstanceMethods
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
protected
|
15
|
+
include ProtectedInstanceMethods
|
16
|
+
end
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
module InstanceMethods
|
20
|
+
def create
|
21
|
+
remember_me = params[:session][:remember_me] if params[:session]
|
22
|
+
login_via_password(params[:session][:email], params[:session][:password], remember_me)
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
module ProtectedInstanceMethods
|
32
|
-
def login_via_password(email, password, remember_me)
|
33
|
-
user = user_model.authenticate(email, password)
|
34
|
-
if login(user)
|
35
|
-
create_session_for(user)
|
36
|
-
remember(user) if remember_me == '1'
|
37
|
-
login_successful
|
38
|
-
else
|
39
|
-
login_failure
|
25
|
+
def destroy
|
26
|
+
forget(current_user)
|
27
|
+
reset_session
|
28
|
+
flash[:notice] = 'You have been logged out.'
|
29
|
+
redirect_to url_after_destroy
|
30
|
+
end
|
40
31
|
end
|
41
|
-
|
32
|
+
|
33
|
+
module ProtectedInstanceMethods
|
34
|
+
def login_via_password(email, password, remember_me)
|
35
|
+
user = user_model.authenticate(email, password)
|
36
|
+
if login(user)
|
37
|
+
create_session_for(user)
|
38
|
+
remember(user) if remember_me == '1'
|
39
|
+
login_successful
|
40
|
+
else
|
41
|
+
login_failure
|
42
|
+
end
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def login_successful
|
46
|
+
flash[:notice] = 'Logged in successfully'
|
47
|
+
redirect_back_or url_after_create
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
def login_failure(message = "Bad email or password.")
|
51
|
+
flash.now[:notice] = message
|
52
|
+
render :action => :new
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
def remember(user)
|
56
|
+
user.remember_me!
|
57
|
+
cookies[:auth_token] = { :value => user.remember_token,
|
58
|
+
:expires => user.remember_token_expires_at }
|
59
|
+
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
def forget(user)
|
62
|
+
user.forget_me! if user
|
63
|
+
cookies.delete :auth_token
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
66
|
+
def url_after_create
|
67
|
+
root_url
|
68
|
+
end
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
+
def url_after_destroy
|
71
|
+
new_session_url
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
70
75
|
end
|
71
76
|
end
|
72
77
|
end
|
@@ -1,42 +1,46 @@
|
|
1
1
|
module Clearance
|
2
|
-
module
|
2
|
+
module App
|
3
|
+
module Controllers
|
4
|
+
module UsersController
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
before_filter :redirect_to_root, :only => [:new, :create], :if => :logged_in?
|
7
9
|
|
8
|
-
|
10
|
+
filter_parameter_logging :password
|
9
11
|
|
10
|
-
|
12
|
+
include InstanceMethods
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
private
|
15
|
+
include PrivateInstanceMethods
|
16
|
+
end
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
module InstanceMethods
|
20
|
+
def new
|
21
|
+
@user = user_model.new(params[:user])
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
def create
|
25
|
+
@user = user_model.new params[:user]
|
26
|
+
if @user.save
|
27
|
+
UserMailer.deliver_confirmation @user
|
28
|
+
flash[:notice] = "You will receive an email within the next few minutes. It contains instructions for you to confirm your account."
|
29
|
+
redirect_to new_session_url
|
30
|
+
else
|
31
|
+
render :action => "new"
|
32
|
+
end
|
33
|
+
end
|
30
34
|
end
|
31
|
-
end
|
32
|
-
end
|
33
35
|
|
34
|
-
|
36
|
+
module PrivateInstanceMethods
|
37
|
+
|
38
|
+
def url_after_create
|
39
|
+
new_session_url
|
40
|
+
end
|
41
|
+
end
|
35
42
|
|
36
|
-
def url_after_create
|
37
|
-
new_session_url
|
38
43
|
end
|
39
44
|
end
|
40
|
-
|
41
45
|
end
|
42
46
|
end
|
@@ -1,84 +1,86 @@
|
|
1
1
|
module Clearance
|
2
|
-
module
|
3
|
-
module
|
2
|
+
module App
|
3
|
+
module Models
|
4
|
+
module User
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
attr_accessible :email, :password, :password_confirmation
|
10
|
+
attr_accessor :password, :password_confirmation
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
validates_presence_of :email
|
13
|
+
validates_presence_of :password, :if => :password_required?
|
14
|
+
validates_confirmation_of :password, :if => :password_required?
|
15
|
+
validates_uniqueness_of :email
|
15
16
|
|
16
|
-
|
17
|
+
before_save :initialize_salt, :encrypt_password
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
extend ClassMethods
|
20
|
+
include InstanceMethods
|
20
21
|
|
21
|
-
|
22
|
+
protected
|
22
23
|
|
23
|
-
|
24
|
+
include ProtectedInstanceMethods
|
24
25
|
|
26
|
+
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
module ClassMethods
|
30
|
+
def authenticate(email, password)
|
31
|
+
user = find_by_email email
|
32
|
+
user && user.authenticated?(password) ? user : nil
|
33
|
+
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
module InstanceMethods
|
37
|
+
def authenticated?(password)
|
38
|
+
crypted_password == encrypt(password)
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
def encrypt(password)
|
42
|
+
Digest::SHA1.hexdigest "--#{salt}--#{password}--"
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def remember_token?
|
46
|
+
remember_token_expires_at && Time.now.utc < remember_token_expires_at
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def remember_me!
|
50
|
+
remember_me_until 2.weeks.from_now.utc
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
def remember_me_until(time)
|
54
|
+
self.update_attribute :remember_token_expires_at, time
|
55
|
+
self.update_attribute :remember_token, encrypt("#{email}--#{remember_token_expires_at}")
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
def forget_me!
|
59
|
+
self.update_attribute :remember_token_expires_at, nil
|
60
|
+
self.update_attribute :remember_token, nil
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
def confirm!
|
64
|
+
self.update_attribute :confirmed, true
|
65
|
+
end
|
64
66
|
end
|
65
|
-
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
module ProtectedInstanceMethods
|
69
|
+
def initialize_salt
|
70
|
+
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{email}--") if new_record?
|
71
|
+
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
def encrypt_password
|
74
|
+
return if password.blank?
|
75
|
+
self.crypted_password = encrypt(password)
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
78
|
+
def password_required?
|
79
|
+
crypted_password.blank? || !password.blank?
|
80
|
+
end
|
79
81
|
end
|
80
|
-
end
|
81
82
|
|
83
|
+
end
|
82
84
|
end
|
83
85
|
end
|
84
86
|
end
|
@@ -1,29 +1,32 @@
|
|
1
1
|
module Clearance
|
2
|
-
module
|
3
|
-
module
|
2
|
+
module App
|
3
|
+
module Models
|
4
|
+
module UserMailer
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
7
8
|
|
8
|
-
|
9
|
+
include InstanceMethods
|
9
10
|
|
11
|
+
end
|
10
12
|
end
|
11
|
-
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
module InstanceMethods
|
15
|
+
def change_password(user)
|
16
|
+
from "donotreply@example.com"
|
17
|
+
recipients user.email
|
18
|
+
subject "[YOUR APP] Request to change your password"
|
19
|
+
body :user => user
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def confirmation(user)
|
23
|
+
recipients user.email
|
24
|
+
from "donotreply@example.com"
|
25
|
+
subject 'Account Confirmation'
|
26
|
+
body :user => user
|
27
|
+
end
|
26
28
|
end
|
29
|
+
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
@@ -1,88 +1,90 @@
|
|
1
1
|
module Clearance
|
2
|
-
module
|
2
|
+
module Test
|
3
|
+
module TestHelper
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
include InstanceMethods
|
8
|
+
extend ClassMethods
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
module InstanceMethods
|
13
|
+
def login_as(user = nil)
|
14
|
+
user ||= Factory(:user)
|
15
|
+
@request.session[:user_id] = user.id
|
16
|
+
return user
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
def logout
|
20
|
+
@request.session[:user_id] = nil
|
21
|
+
end
|
20
22
|
end
|
21
|
-
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
module ClassMethods
|
25
|
+
def should_deny_access_on(command, opts = {})
|
26
|
+
opts[:redirect] ||= "root_url"
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
context "on #{command}" do
|
29
|
+
setup { eval command }
|
30
|
+
should_redirect_to opts[:redirect]
|
31
|
+
if opts[:flash]
|
32
|
+
should_set_the_flash_to opts[:flash]
|
33
|
+
else
|
34
|
+
should_not_set_the_flash
|
35
|
+
end
|
34
36
|
end
|
35
37
|
end
|
36
|
-
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
# should_have_form :action => 'admin_users_path',
|
40
|
+
# :method => :get,
|
41
|
+
# :fields => { 'email' => :text }
|
42
|
+
# TODO: http_method should be pulled out
|
43
|
+
def should_have_form(opts)
|
44
|
+
model = self.name.gsub(/ControllerTest$/, '').singularize.downcase
|
45
|
+
model = model[model.rindex('::')+2..model.size] if model.include?('::')
|
46
|
+
http_method, hidden_http_method = form_http_method opts[:method]
|
47
|
+
should "have a #{model} form" do
|
48
|
+
assert_select "form[action=?][method=#{http_method}]", eval(opts[:action]) do
|
49
|
+
if hidden_http_method
|
50
|
+
assert_select "input[type=hidden][name=_method][value=#{hidden_http_method}]"
|
51
|
+
end
|
52
|
+
opts[:fields].each do |attribute, type|
|
53
|
+
attribute = attribute.is_a?(Symbol) ? "#{model}[#{attribute.to_s}]" : attribute
|
54
|
+
assert_select "input[type=#{type.to_s}][name=?]", attribute
|
55
|
+
end
|
56
|
+
assert_select "input[type=submit]"
|
54
57
|
end
|
55
|
-
assert_select "input[type=submit]"
|
56
58
|
end
|
57
59
|
end
|
58
|
-
end
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
def form_http_method(http_method)
|
62
|
+
http_method = http_method.nil? ? 'post' : http_method.to_s
|
63
|
+
if http_method == "post" || http_method == "get"
|
64
|
+
return http_method, nil
|
65
|
+
else
|
66
|
+
return "post", http_method
|
67
|
+
end
|
66
68
|
end
|
67
|
-
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
def logged_in_user_context(&blk)
|
71
|
+
context "A logged in user" do
|
72
|
+
setup do
|
73
|
+
@user = Factory :user
|
74
|
+
login_as @user
|
75
|
+
end
|
76
|
+
merge_block(&blk)
|
74
77
|
end
|
75
|
-
merge_block(&blk)
|
76
78
|
end
|
77
|
-
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
def public_context(&blk)
|
81
|
+
context "The public" do
|
82
|
+
setup { logout }
|
83
|
+
merge_block(&blk)
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
85
|
-
|
86
|
-
|
87
|
+
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|