thoughtbot-clearance 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.textile CHANGED
@@ -1,3 +1,14 @@
1
+ h2. 0.4.5 (unreleased)
2
+
3
+ * [#43] Removed email downcasing. (local-part is case sensitive per RFC5321)
4
+ * [#42] Removed dependency on Mocha.
5
+ * Required Shoulda >= 2.9.1.
6
+ * Added password reset feature to clearance_features generator.
7
+ * Removed unnecessary session[:salt].
8
+ * [#41] Only store location for session[:return_to] for GET requests.
9
+ * Audited "sign up" naming convention. "Register" had slipped in a few places.
10
+ * Switched to SHA1 encryption. Cypher doesn't matter much for email confirmation, password reset. Better to have shorter hashes in the emails for clients who line break on 72 chars.
11
+
1
12
  h2. 0.4.4 (2/2/2009)
2
13
 
3
14
  * Added a generator for Cucumber features
data/README.textile CHANGED
@@ -12,24 +12,28 @@ h2. Gem installation (Rails 2.1+)
12
12
 
13
13
  In config/environment.rb:
14
14
 
15
- config.gem 'mocha'
15
+ config.gem "thoughtbot-clearance",
16
+ :lib => 'clearance',
17
+ :source => 'http://gems.github.com',
18
+ :version => '>= 0.4.3'
19
+
20
+ In config/environments/test.rb:
21
+
16
22
  config.gem 'thoughtbot-shoulda',
17
23
  :lib => 'shoulda',
18
24
  :source => "http://gems.github.com",
19
- :version => '>= 2.0.6'
25
+ :version => '>= 2.9.1'
20
26
  config.gem 'thoughtbot-factory_girl',
21
27
  :lib => 'factory_girl',
22
28
  :source => "http://gems.github.com",
23
29
  :version => '>= 1.1.5'
24
- config.gem "thoughtbot-clearance",
25
- :lib => 'clearance',
26
- :source => 'http://gems.github.com',
27
- :version => '>= 0.3.9'
28
30
 
29
31
  Then:
30
32
 
31
33
  rake gems:install
32
- rake gems:unpack
34
+ rake gems:unpack
35
+ rake gems:install RAILS_ENV=test
36
+ rake gems:unpack RAILS_ENV=test
33
37
 
34
38
  h2. The generator
35
39
 
@@ -93,7 +97,7 @@ In config/environment.rb:
93
97
 
94
98
  h2. Tests
95
99
 
96
- The tests use "Shoulda":http://thoughtbot.com/projects/shoulda >= 2.0.6 and "Factory Girl":http://thoughtbot.com/projects/factory_girl >= 1.1.5. There needs to be a Clearance module in your test/test_helper.rb:
100
+ The tests use "Shoulda":http://thoughtbot.com/projects/shoulda >= 2.9.1 and "Factory Girl":http://thoughtbot.com/projects/factory_girl >= 1.1.5. There needs to be a Clearance module in your test/test_helper.rb:
97
101
 
98
102
  class Test::Unit::TestCase
99
103
  self.use_transactional_fixtures = true
@@ -108,7 +112,7 @@ h2. Usage: basic workflow
108
112
 
109
113
  Rails authentication with Clearance uses the standard approach thoughtbot and our clients have agreed upon.
110
114
 
111
- Users register (UsersController) using an email address and a password (User model). They get an email (ClearanceMailer) with a confirmation link to confirm their registration (ConfirmationController).
115
+ Users sign up (UsersController) using an email address and a password (User model). They get an email (ClearanceMailer) with a confirmation link to confirm their registration (ConfirmationController).
112
116
 
113
117
  Registered users can sign in and out (SessionsController). If they forget their password, they request an email (ClearanceMailer) containing a link to change it (PasswordsController).
114
118
 
@@ -169,7 +173,7 @@ Actions that redirect (create, update, and destroy) in Clearance controllers are
169
173
 
170
174
  There are similar methods in other controllers as well:
171
175
 
172
- UsersController#url_after_create (register)
176
+ UsersController#url_after_create (sign up)
173
177
  SessionsController#url_after_create (sign in)
174
178
  SessionsController#url_after_destroy (sign out)
175
179
  PasswordsController#url_after_create (password request)
data/Rakefile CHANGED
@@ -50,7 +50,7 @@ task :default => ['test:all', 'test:features']
50
50
 
51
51
  gem_spec = Gem::Specification.new do |gem_spec|
52
52
  gem_spec.name = "clearance"
53
- gem_spec.version = "0.4.4"
53
+ gem_spec.version = "0.4.5"
54
54
  gem_spec.summary = "Rails authentication for developers who write tests."
55
55
  gem_spec.email = "support@thoughtbot.com"
56
56
  gem_spec.homepage = "http://github.com/thoughtbot/clearance"
@@ -7,7 +7,8 @@ class ClearanceFeaturesGenerator < Rails::Generator::Base
7
7
  ["features/step_definitions/clearance_steps.rb",
8
8
  "features/sign_in.feature",
9
9
  "features/sign_out.feature",
10
- "features/sign_up.feature"].each do |file|
10
+ "features/sign_up.feature",
11
+ "features/password_reset.feature"].each do |file|
11
12
  m.file file, file
12
13
  end
13
14
  end
@@ -3,7 +3,7 @@ Fature: Password Reset
3
3
  A user
4
4
  Should be able to reset it
5
5
 
6
- Scenario: User is not registered
6
+ Scenario: User is not signed up
7
7
  Given there is no user with "email@person.com"
8
8
  When I request password reset link to be sent to "email@person.com"
9
9
  Then I should see "Unknown email"
@@ -1,9 +1,9 @@
1
1
  Feature: Sign in
2
2
  In order to get access to protected sections of the site
3
- A registered user
3
+ A user
4
4
  Should be able to sign in
5
5
 
6
- Scenario User is not registered
6
+ Scenario User is not signed up
7
7
  Given there is no user with "email@person.com"
8
8
  When I go to the sign in page
9
9
  And I sign in as "email@person.com/password"
@@ -28,17 +28,14 @@ end
28
28
 
29
29
  Then /^I should be signed in$/ do
30
30
  assert_not_nil request.session[:user_id]
31
- assert_not_nil request.session[:salt]
32
31
  end
33
32
 
34
33
  Then /^I should not be signed in$/ do
35
34
  assert_nil request.session[:user_id]
36
- assert_nil request.session[:salt]
37
35
  end
38
36
 
39
37
  When /^session is cleared$/ do
40
38
  request.session[:user_id] = nil
41
- request.session[:salt] = nil
42
39
  end
43
40
 
44
41
  # Emails
@@ -26,8 +26,8 @@ module Clearance
26
26
  end
27
27
 
28
28
  def user_from_session
29
- if session[:user_id] && session[:salt]
30
- user = User.find_by_id_and_salt(session[:user_id], session[:salt])
29
+ if session[:user_id]
30
+ user = User.find_by_id(session[:user_id])
31
31
  user && user.email_confirmed? ? user : nil
32
32
  end
33
33
  end
@@ -47,7 +47,6 @@ module Clearance
47
47
  def sign_in(user)
48
48
  if user
49
49
  session[:user_id] = user.id
50
- session[:salt] = user.salt
51
50
  end
52
51
  end
53
52
 
@@ -66,7 +65,7 @@ module Clearance
66
65
  end
67
66
 
68
67
  def store_location
69
- session[:return_to] = request.request_uri
68
+ session[:return_to] = request.request_uri if request.get?
70
69
  end
71
70
 
72
71
  def deny_access(flash_message = nil, opts = {})
@@ -1,4 +1,4 @@
1
- require 'digest/sha2'
1
+ require 'digest/sha1'
2
2
 
3
3
  module Clearance
4
4
  module App
@@ -17,10 +17,10 @@ module Clearance
17
17
  validates_uniqueness_of :email, :case_sensitive => false
18
18
  validates_format_of :email, :with => %r{.+@.+\..+}
19
19
 
20
- before_save :initialize_salt, :encrypt_password, :initialize_token, :downcase_email
20
+ before_save :initialize_salt, :encrypt_password, :initialize_token
21
21
 
22
22
  def self.authenticate(email, password)
23
- user = find(:first, :conditions => ['LOWER(email) = ?', email.to_s.downcase])
23
+ user = find(:first, :conditions => ['email = ?', email.to_s])
24
24
  user && user.authenticated?(password) ? user : nil
25
25
  end
26
26
 
@@ -72,7 +72,7 @@ module Clearance
72
72
  protected
73
73
 
74
74
  def generate_hash(string)
75
- Digest::SHA512.hexdigest(string)
75
+ Digest::SHA1.hexdigest(string)
76
76
  end
77
77
 
78
78
  def initialize_salt
@@ -104,10 +104,6 @@ module Clearance
104
104
  encrypted_password.blank? || !password.blank?
105
105
  end
106
106
 
107
- def downcase_email
108
- self.email = email.to_s.downcase
109
- end
110
-
111
107
  end
112
108
  end
113
109
 
@@ -11,13 +11,11 @@ module Clearance
11
11
  user.confirm_email!
12
12
  end
13
13
  @request.session[:user_id] = user.id
14
- @request.session[:salt] = user.salt
15
14
  return user
16
15
  end
17
16
 
18
17
  def sign_out
19
18
  @request.session[:user_id] = nil
20
- @request.session[:salt] = nil
21
19
  end
22
20
 
23
21
  end
@@ -6,14 +6,14 @@ module Clearance
6
6
  def self.included(unit_test)
7
7
  unit_test.class_eval do
8
8
 
9
- should_protect_attributes :email_confirmed,
9
+ should_not_allow_mass_assignment_of :email_confirmed,
10
10
  :salt, :encrypted_password,
11
11
  :token, :token_expires_at
12
12
 
13
13
  # signing up
14
14
 
15
15
  context "When signing up" do
16
- should_require_attributes :email, :password
16
+ should_validate_presence_of :email, :password
17
17
  should_allow_values_for :email, "foo@example.com"
18
18
  should_not_allow_values_for :email, "foo"
19
19
  should_not_allow_values_for :email, "example.com"
@@ -33,13 +33,13 @@ module Clearance
33
33
  context "encrypt password" do
34
34
  setup do
35
35
  @salt = "salt"
36
- User.any_instance.stubs(:initialize_salt)
37
-
38
- @user = Factory(:user, :salt => @salt)
36
+ @user = Factory.build(:user, :salt => @salt)
37
+ def @user.initialize_salt; end
38
+ @user.save!
39
39
  @password = @user.password
40
40
 
41
41
  @user.encrypt(@password)
42
- @expected = Digest::SHA512.hexdigest("--#{@salt}--#{@password}--")
42
+ @expected = Digest::SHA1.hexdigest("--#{@salt}--#{@password}--")
43
43
  end
44
44
 
45
45
  should "create an encrypted password using SHA512 encryption" do
@@ -48,16 +48,16 @@ module Clearance
48
48
  end
49
49
  end
50
50
 
51
- should "store email in lower case" do
51
+ should "store email in exact case" do
52
52
  user = Factory(:user, :email => "John.Doe@example.com")
53
- assert_equal "john.doe@example.com", user.email
53
+ assert_equal "John.Doe@example.com", user.email
54
54
  end
55
55
  end
56
56
 
57
57
  context "When multiple users have signed up" do
58
58
  setup { @user = Factory(:user) }
59
59
 
60
- should_require_unique_attributes :email
60
+ should_validate_uniqueness_of :email
61
61
  end
62
62
 
63
63
  # confirming email
@@ -97,11 +97,6 @@ module Clearance
97
97
  assert @user.authenticated?(@password)
98
98
  end
99
99
 
100
- should "authenticate with good credentials, email in uppercase" do
101
- assert User.authenticate(@user.email.upcase, @password)
102
- assert @user.authenticated?(@password)
103
- end
104
-
105
100
  should "not authenticate with bad credentials" do
106
101
  assert ! User.authenticate(@user.email, 'horribly_wrong_password')
107
102
  assert ! @user.authenticated?('horribly_wrong_password')
@@ -185,6 +180,7 @@ module Clearance
185
180
  assert_nil @user.token
186
181
  @user.forgot_password!
187
182
  end
183
+
188
184
  should "generate token" do
189
185
  assert_not_nil @user.token
190
186
  end
@@ -199,17 +195,20 @@ module Clearance
199
195
  end
200
196
 
201
197
  should_change "@user.encrypted_password"
198
+
202
199
  should "clear token" do
203
200
  assert_nil @user.token
204
201
  end
205
202
  end
203
+
206
204
  context 'with a password without a confirmation' do
207
205
  setup do
208
206
  @user.update_password(
209
207
  :password => "new_password",
210
208
  :password_confirmation => ""
211
209
  )
212
- end
210
+ end
211
+
213
212
  should "not clear token" do
214
213
  assert_not_nil @user.token
215
214
  end
@@ -10,8 +10,6 @@ module Clearance
10
10
  "please pass a User. try: should_be_signed_in_as { @user }"
11
11
  assert_equal user.id, session[:user_id],
12
12
  "session[:user_id] is not set to User's id"
13
- assert_equal user.salt, session[:salt],
14
- "session[:salt] is not set to User's salt"
15
13
  end
16
14
  end
17
15
 
@@ -30,7 +28,6 @@ module Clearance
30
28
  def should_not_be_signed_in
31
29
  should "not be signed in" do
32
30
  assert_nil session[:user_id]
33
- assert_nil session[:salt]
34
31
  end
35
32
  end
36
33
 
@@ -167,7 +164,6 @@ module Clearance
167
164
  end
168
165
  end
169
166
 
170
-
171
167
  # FORMS
172
168
 
173
169
  def should_display_a_password_update_form
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.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoughtbot, inc.
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2009-02-01 21:00:00 -08:00
18
+ date: 2009-02-08 21:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -32,7 +32,6 @@ files:
32
32
  - LICENSE
33
33
  - Rakefile
34
34
  - README.textile
35
- - TODO.textile
36
35
  - generators/clearance
37
36
  - generators/clearance/clearance_generator.rb
38
37
  - generators/clearance/lib
data/TODO.textile DELETED
@@ -1,8 +0,0 @@
1
- (highest priority first)
2
-
3
- # refactor password controller test
4
- # existing_user? methods ... if salt is wrong, user may not be found b/c of invalid credentials. is :not_found the correct code to return in that use case? if not, method probably needs to be split into another conditional.
5
- # document shoulda macros
6
- # will SHA512 hashes fit in all the places they are being used? (db columns - fit now, sessions) 128 characters
7
-
8
- http://adam.speaksoutofturn.com/post/57615195/entication-vs-orization