thoughtbot-clearance 0.4.4 → 0.4.5

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/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