thoughtbot-clearance 0.1.6 → 0.1.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.
- data/README.textile +36 -7
- data/clearance.gemspec +15 -13
- data/lib/clearance.rb +3 -0
- data/lib/clearance/app/controllers/application_controller.rb +7 -3
- data/lib/clearance/app/controllers/passwords_controller.rb +57 -0
- data/lib/clearance/app/controllers/sessions_controller.rb +2 -2
- data/lib/clearance/app/controllers/users_controller.rb +3 -2
- data/lib/clearance/test/functionals/passwords_controller_test.rb +188 -0
- data/lib/clearance/test/functionals/sessions_controller_test.rb +1 -1
- data/lib/clearance/test/functionals/users_controller_test.rb +1 -1
- data/lib/clearance/test/test_helper.rb +0 -12
- metadata +4 -2
data/README.textile
CHANGED
@@ -29,7 +29,7 @@ Then:
|
|
29
29
|
|
30
30
|
h2. Tests
|
31
31
|
|
32
|
-
The tests use "Shoulda":http://thoughtbot.com/projects/shoulda and "Factory Girl":http://thoughtbot.com/projects/factory_girl. You should create a User Factory:
|
32
|
+
The tests use "Shoulda":http://thoughtbot.com/projects/shoulda >= 2.0.4 and "Factory Girl":http://thoughtbot.com/projects/factory_girl. You should create a User Factory:
|
33
33
|
|
34
34
|
Factory.sequence :email do |n|
|
35
35
|
"user#{n}@example.com"
|
@@ -67,6 +67,12 @@ In test/functional/users_controller_test.rb:
|
|
67
67
|
include Clearance::UsersControllerTest
|
68
68
|
end
|
69
69
|
|
70
|
+
In test/functional/passwords_controller_test.rb:
|
71
|
+
|
72
|
+
class PasswordsControllerTest < ActionController::TestCase
|
73
|
+
include Clearance::PasswordsControllerTest
|
74
|
+
end
|
75
|
+
|
70
76
|
h2. Schema
|
71
77
|
|
72
78
|
Change your User model so it has these attributes:
|
@@ -90,6 +96,23 @@ In app/models/user.rb:
|
|
90
96
|
include Clearance::Model
|
91
97
|
end
|
92
98
|
|
99
|
+
h2. Mailer
|
100
|
+
|
101
|
+
In app/models/mailer.rb:
|
102
|
+
|
103
|
+
class Mailer < ActionMailer::Base
|
104
|
+
|
105
|
+
default_url_options[:host] = HOST
|
106
|
+
|
107
|
+
def change_password(user)
|
108
|
+
from "donotreply@example.com"
|
109
|
+
recipients user.email
|
110
|
+
subject "[YOUR APP] Request to change your password"
|
111
|
+
body :user => user
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
93
116
|
h2. Controllers
|
94
117
|
|
95
118
|
In app/controllers/application_controller.rb:
|
@@ -106,11 +129,11 @@ In app/controllers/sessions_controller.rb:
|
|
106
129
|
include Clearance::SessionsController
|
107
130
|
|
108
131
|
private
|
109
|
-
|
132
|
+
|
110
133
|
def url_after_create
|
111
134
|
root_url # the default
|
112
135
|
end
|
113
|
-
|
136
|
+
|
114
137
|
def url_after_destroy
|
115
138
|
login_url # the default
|
116
139
|
end
|
@@ -120,18 +143,24 @@ In app/controllers/users_controller.rb:
|
|
120
143
|
|
121
144
|
class UsersController < ApplicationController
|
122
145
|
include Clearance::UsersController
|
123
|
-
|
146
|
+
|
124
147
|
private
|
125
|
-
|
148
|
+
|
126
149
|
def url_after_create
|
127
150
|
root_url # the default
|
128
151
|
end
|
129
|
-
|
152
|
+
|
130
153
|
def url_after_update
|
131
154
|
root_url # the default
|
132
155
|
end
|
133
156
|
end
|
134
157
|
|
158
|
+
In app/controllers/passwords_controller.rb:
|
159
|
+
|
160
|
+
class PasswordsController < ApplicationController
|
161
|
+
include Clearance::PasswordsController
|
162
|
+
end
|
163
|
+
|
135
164
|
h2. Routes
|
136
165
|
|
137
166
|
map.with_options :controller => 'sessions' do |m|
|
@@ -139,7 +168,7 @@ h2. Routes
|
|
139
168
|
m.logout '/logout', :action => 'destroy'
|
140
169
|
end
|
141
170
|
map.resource :session
|
142
|
-
map.resources :users
|
171
|
+
map.resources :users, :has_one => :password
|
143
172
|
|
144
173
|
h2. Views
|
145
174
|
|
data/clearance.gemspec
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "clearance"
|
3
|
-
s.version = "0.1.
|
4
|
-
s.date = "2008-09
|
3
|
+
s.version = "0.1.8"
|
4
|
+
s.date = "2008-10-09"
|
5
5
|
s.summary = "Simple, complete Rails authentication."
|
6
6
|
s.email = "dcroak@thoughtbot.com"
|
7
7
|
s.homepage = "http://github.com/thoughtbot/clearance"
|
8
8
|
s.description = "Simple, complete Rails authentication scheme."
|
9
9
|
s.authors = ["thoughtbot, inc.", "Dan Croak", "Josh Nichols", "Mike Breen", "Mike Burns", "Jason Morrison"]
|
10
|
-
s.files = ["README.textile",
|
11
|
-
"clearance.gemspec",
|
12
|
-
"lib/clearance.rb",
|
13
|
-
"lib/clearance/app/controllers/application_controller.rb",
|
14
|
-
"lib/clearance/app/models/model.rb",
|
15
|
-
"lib/clearance/app/controllers/sessions_controller.rb",
|
16
|
-
"lib/clearance/test/functionals/sessions_controller_test.rb",
|
17
|
-
"lib/clearance/test/test_helper.rb",
|
18
|
-
"lib/clearance/test/units/user_test.rb",
|
19
|
-
"lib/clearance/app/controllers/users_controller.rb",
|
20
|
-
"lib/clearance/test/functionals/users_controller_test.rb"
|
10
|
+
s.files = ["README.textile",
|
11
|
+
"clearance.gemspec",
|
12
|
+
"lib/clearance.rb",
|
13
|
+
"lib/clearance/app/controllers/application_controller.rb",
|
14
|
+
"lib/clearance/app/models/model.rb",
|
15
|
+
"lib/clearance/app/controllers/sessions_controller.rb",
|
16
|
+
"lib/clearance/test/functionals/sessions_controller_test.rb",
|
17
|
+
"lib/clearance/test/test_helper.rb",
|
18
|
+
"lib/clearance/test/units/user_test.rb",
|
19
|
+
"lib/clearance/app/controllers/users_controller.rb",
|
20
|
+
"lib/clearance/test/functionals/users_controller_test.rb",
|
21
|
+
"lib/clearance/app/controllers/passwords_controller.rb",
|
22
|
+
"lib/clearance/test/functionals/passwords_controller_test.rb"]
|
21
23
|
end
|
data/lib/clearance.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'clearance/app/controllers/application_controller'
|
2
2
|
require 'clearance/app/controllers/sessions_controller'
|
3
3
|
require 'clearance/app/controllers/users_controller'
|
4
|
+
require 'clearance/app/controllers/passwords_controller'
|
4
5
|
require 'clearance/app/models/model'
|
5
6
|
require 'clearance/test/test_helper'
|
6
7
|
require 'clearance/test/functionals/sessions_controller_test'
|
7
8
|
require 'clearance/test/functionals/users_controller_test'
|
9
|
+
require 'clearance/test/functionals/passwords_controller_test'
|
8
10
|
require 'clearance/test/units/user_test'
|
11
|
+
require 'clearance/test/units/user_mailer_test'
|
@@ -29,16 +29,16 @@ module Clearance
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def user_from_session
|
32
|
-
|
32
|
+
user_model.find_by_id session[:user_id]
|
33
33
|
end
|
34
34
|
|
35
35
|
def user_from_cookie
|
36
|
-
user =
|
36
|
+
user = user_model.find_by_remember_token(cookies[:auth_token]) if cookies[:auth_token]
|
37
37
|
user && user.remember_token? ? user : nil
|
38
38
|
end
|
39
39
|
|
40
40
|
def login(user)
|
41
|
-
create_session_for
|
41
|
+
create_session_for(user)
|
42
42
|
@current_user = user
|
43
43
|
end
|
44
44
|
|
@@ -65,6 +65,10 @@ module Clearance
|
|
65
65
|
flash[:error] = flash_message if flash_message
|
66
66
|
redirect_to opts[:redirect]
|
67
67
|
end
|
68
|
+
|
69
|
+
def user_model
|
70
|
+
User
|
71
|
+
end
|
68
72
|
end
|
69
73
|
end
|
70
74
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Clearance
|
2
|
+
module PasswordsController
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
before_filter :existing_user?, :only => [:edit, :update]
|
7
|
+
filter_parameter_logging :password, :password_confirmation
|
8
|
+
include InstanceMethods
|
9
|
+
private
|
10
|
+
include PrivateInstanceMethods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module InstanceMethods
|
15
|
+
def new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
user = User.find_by_email params[:password][:email]
|
20
|
+
if user.nil?
|
21
|
+
flash.now[:warning] = 'Unknown email'
|
22
|
+
render :action => :new
|
23
|
+
else
|
24
|
+
UserMailer.deliver_change_password user
|
25
|
+
redirect_to login_path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit
|
30
|
+
@user = User.find_by_email_and_crypted_password(params[:email],
|
31
|
+
params[:password])
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
@user = User.find_by_email_and_crypted_password(params[:email],
|
36
|
+
params[:password])
|
37
|
+
if @user.update_attributes params[:user]
|
38
|
+
session[:user_id] = @user.id
|
39
|
+
redirect_to @user
|
40
|
+
else
|
41
|
+
render :action => :edit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module PrivateInstanceMethods
|
47
|
+
def existing_user?
|
48
|
+
user = User.find_by_email_and_crypted_password(params[:email],
|
49
|
+
params[:password])
|
50
|
+
if user.nil?
|
51
|
+
render :nothing => true, :status => :not_found
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -21,7 +21,7 @@ module Clearance
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def destroy
|
24
|
-
forget
|
24
|
+
forget(current_user)
|
25
25
|
reset_session
|
26
26
|
flash[:notice] = 'You have been logged out.'
|
27
27
|
redirect_to url_after_destroy
|
@@ -30,7 +30,7 @@ module Clearance
|
|
30
30
|
|
31
31
|
module ProtectedInstanceMethods
|
32
32
|
def login_via_password(email, password, remember_me)
|
33
|
-
user =
|
33
|
+
user = user_model.authenticate(email, password)
|
34
34
|
if login(user)
|
35
35
|
create_session_for(user)
|
36
36
|
remember(user) if remember_me == '1'
|
@@ -16,11 +16,11 @@ module Clearance
|
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
18
|
def new
|
19
|
-
@user =
|
19
|
+
@user = user_model.new(params[:user])
|
20
20
|
end
|
21
21
|
|
22
22
|
def create
|
23
|
-
@user =
|
23
|
+
@user = user_model.new params[:user]
|
24
24
|
if @user.save
|
25
25
|
current_user = @user
|
26
26
|
flash[:notice] = "User created and logged in."
|
@@ -32,6 +32,7 @@ module Clearance
|
|
32
32
|
end
|
33
33
|
|
34
34
|
module PrivateInstanceMethods
|
35
|
+
|
35
36
|
def url_after_create
|
36
37
|
root_url
|
37
38
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Clearance
|
2
|
+
module PasswordsControllerTest
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
|
7
|
+
should_route :get, '/users/1/password/edit', :action => 'edit', :user_id => '1'
|
8
|
+
|
9
|
+
context 'with a user' do
|
10
|
+
setup { @user = Factory :user }
|
11
|
+
|
12
|
+
context 'A GET to #new' do
|
13
|
+
setup { get :new, :user_id => @user_id }
|
14
|
+
|
15
|
+
should_respond_with :success
|
16
|
+
should_render_template 'new'
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'A POST to #create' do
|
20
|
+
context "with an existing user's email address" do
|
21
|
+
setup do
|
22
|
+
ActionMailer::Base.deliveries.clear
|
23
|
+
|
24
|
+
post :create, :password => { :email => @user.email }
|
25
|
+
@email = ActionMailer::Base.deliveries[0]
|
26
|
+
end
|
27
|
+
|
28
|
+
should 'send an email to the user to edit their password' do
|
29
|
+
assert @email.subject =~ /request to change your password/i
|
30
|
+
end
|
31
|
+
|
32
|
+
should_redirect_to "new_session_path"
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with a non-existing email address' do
|
36
|
+
setup do
|
37
|
+
email = 'user1@example.com'
|
38
|
+
assert ! User.exists?(['email = ?', email])
|
39
|
+
ActionMailer::Base.deliveries.clear
|
40
|
+
|
41
|
+
post :create, :password => { :email => email }
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'not send a password reminder email' do
|
45
|
+
assert ActionMailer::Base.deliveries.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'set a :warning flash' do
|
49
|
+
assert_not_nil flash.now[:warning]
|
50
|
+
end
|
51
|
+
|
52
|
+
should_render_template "new"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'A GET to #edit' do
|
57
|
+
context "with an existing user's id and password" do
|
58
|
+
setup do
|
59
|
+
get :edit,
|
60
|
+
:user_id => @user.id,
|
61
|
+
:password => @user.crypted_password,
|
62
|
+
:email => @user.email
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'find the user with the given id and password' do
|
66
|
+
assert_equal @user, assigns(:user)
|
67
|
+
end
|
68
|
+
|
69
|
+
should_respond_with :success
|
70
|
+
should_render_template "edit"
|
71
|
+
|
72
|
+
should "have a form for the user's email, password, and password confirm" do
|
73
|
+
update_path = ERB::Util.h(user_password_path(@user,
|
74
|
+
:password => @user.crypted_password,
|
75
|
+
:email => @user.email))
|
76
|
+
|
77
|
+
assert_select 'form[action=?]', update_path do
|
78
|
+
assert_select 'input[name=_method][value=?]', 'put'
|
79
|
+
assert_select 'input[name=?]', 'user[password]'
|
80
|
+
assert_select 'input[name=?]', 'user[password_confirmation]'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with an existing user's id but not password" do
|
86
|
+
setup do
|
87
|
+
get(:edit,
|
88
|
+
:user_id => @user.id,
|
89
|
+
:password => '')
|
90
|
+
end
|
91
|
+
|
92
|
+
should_respond_with :not_found
|
93
|
+
|
94
|
+
should 'render an empty response' do
|
95
|
+
assert @response.body.blank?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'A PUT to #update' do
|
101
|
+
context "with an existing user's id but not password" do
|
102
|
+
setup do
|
103
|
+
put(:update,
|
104
|
+
:user_id => @user.id,
|
105
|
+
:password => '')
|
106
|
+
end
|
107
|
+
|
108
|
+
should "not update the user's password" do
|
109
|
+
assert_not_equal @encrypted_new_password, @user.crypted_password
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'not log the user in' do
|
113
|
+
assert_nil session[:user_id]
|
114
|
+
end
|
115
|
+
|
116
|
+
should_respond_with :not_found
|
117
|
+
|
118
|
+
should 'render an empty response' do
|
119
|
+
assert @response.body.blank?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with a matching password and password confirmation' do
|
124
|
+
setup do
|
125
|
+
new_password = 'new_password'
|
126
|
+
encryption_format = "--#{@user.salt}--#{new_password}--"
|
127
|
+
@encrypted_new_password = Digest::SHA1.hexdigest encryption_format
|
128
|
+
assert_not_equal @encrypted_new_password, @user.crypted_password
|
129
|
+
|
130
|
+
put(:update,
|
131
|
+
:user_id => @user,
|
132
|
+
:email => @user.email,
|
133
|
+
:password => @user.crypted_password,
|
134
|
+
:user => {
|
135
|
+
:password => new_password,
|
136
|
+
:password_confirmation => new_password
|
137
|
+
})
|
138
|
+
@user.reload
|
139
|
+
end
|
140
|
+
|
141
|
+
should "update the user's password" do
|
142
|
+
assert_equal @encrypted_new_password, @user.crypted_password
|
143
|
+
end
|
144
|
+
|
145
|
+
should 'log the user in' do
|
146
|
+
assert_equal session[:user_id], @user.id
|
147
|
+
end
|
148
|
+
|
149
|
+
should_redirect_to "user_path(@user)"
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'with password but blank password confirmation' do
|
153
|
+
setup do
|
154
|
+
new_password = 'new_password'
|
155
|
+
encryption_format = "--#{@user.salt}--#{new_password}--"
|
156
|
+
@encrypted_new_password = Digest::SHA1.hexdigest encryption_format
|
157
|
+
|
158
|
+
put(:update,
|
159
|
+
:user_id => @user.id,
|
160
|
+
:password => @user.crypted_password,
|
161
|
+
:user => {
|
162
|
+
:password => new_password,
|
163
|
+
:password_confirmation => ''
|
164
|
+
})
|
165
|
+
@user.reload
|
166
|
+
end
|
167
|
+
|
168
|
+
should "not update the user's password" do
|
169
|
+
assert_not_equal @encrypted_new_password, @user.crypted_password
|
170
|
+
end
|
171
|
+
|
172
|
+
should 'not log the user in' do
|
173
|
+
assert_nil session[:user_id]
|
174
|
+
end
|
175
|
+
|
176
|
+
should_respond_with :not_found
|
177
|
+
|
178
|
+
should 'render an empty response' do
|
179
|
+
assert @response.body.blank?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
@@ -35,18 +35,6 @@ module Clearance
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def should_filter(*keys)
|
39
|
-
keys.each do |key|
|
40
|
-
should "filter #{key}" do
|
41
|
-
assert @controller.respond_to?(:filter_parameters),
|
42
|
-
"The key #{key} is not filtered"
|
43
|
-
filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s})
|
44
|
-
assert_equal '[FILTERED]', filtered[key.to_s],
|
45
|
-
"The key #{key} is not filtered"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
38
|
# should_have_form :action => 'admin_users_path',
|
51
39
|
# :method => :get,
|
52
40
|
# :fields => { 'email' => :text }
|
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.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thoughtbot, inc.
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2008-09
|
17
|
+
date: 2008-10-09 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -38,6 +38,8 @@ files:
|
|
38
38
|
- lib/clearance/test/units/user_test.rb
|
39
39
|
- lib/clearance/app/controllers/users_controller.rb
|
40
40
|
- lib/clearance/test/functionals/users_controller_test.rb
|
41
|
+
- lib/clearance/app/controllers/passwords_controller.rb
|
42
|
+
- lib/clearance/test/functionals/passwords_controller_test.rb
|
41
43
|
has_rdoc: false
|
42
44
|
homepage: http://github.com/thoughtbot/clearance
|
43
45
|
post_install_message:
|