quo_vadis 1.1.0 → 1.1.1

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.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+
4
+ ## 1.1.1 (18 October 2011)
5
+
6
+ * Only change password when a non-blank value is given.
7
+ * Add `authenticated?` helper method.
8
+
9
+
3
10
  ## 1.1.0 (7 October 2011)
4
11
 
5
12
  * Correctly handle blank username in password reset.
data/README.md CHANGED
@@ -64,7 +64,7 @@ You have to write the view yourself because you'd inevitably want to change what
64
64
 
65
65
  Remember to serve your sign in form over HTTPS -- to avoid [the credentials being stolen](http://blog.jgc.org/2011/01/code-injected-to-steal-passwords-in.html).
66
66
 
67
- In your layout, use `current_user` to retrieve the signed-in user; and `sign_in_path`, `sign_out_path`, and `forgotten_sign_in_path` as appropriate.
67
+ In your layout, use `current_user` to retrieve the signed-in user; and `sign_in_path`, `sign_out_path`, and `forgotten_sign_in_path` as appropriate. You can also use `authenticated?`.
68
68
 
69
69
 
70
70
  ## Forgotten Password
@@ -1,6 +1,6 @@
1
1
  module ControllerMixin
2
2
  def self.included(base)
3
- base.helper_method :"current_#{QuoVadis.model_instance_name}"
3
+ base.helper_method :"current_#{QuoVadis.model_instance_name}", :authenticated?
4
4
  end
5
5
 
6
6
  protected
@@ -13,6 +13,11 @@ module ControllerMixin
13
13
  private
14
14
 
15
15
  class_eval <<-END, __FILE__, __LINE__ + 1
16
+ # Returns `true` if we have an authenticated user, `false` otherwise.
17
+ def authenticated?
18
+ !!current_#{QuoVadis.model_instance_name}
19
+ end
20
+
16
21
  # Remembers the authenticated <tt>user</tt> (in this session and future sessions).
17
22
  #
18
23
  # If you want to sign in a <tt>user</tt> you have just created, call <tt>sign_in</tt>
@@ -30,7 +35,7 @@ module ControllerMixin
30
35
  # Does nothing if we already have an authenticated user. If we don't have an
31
36
  # authenticated user, it stores the desired URL and redirects to the sign in URL.
32
37
  def authenticate
33
- unless current_#{QuoVadis.model_instance_name}
38
+ unless authenticated?
34
39
  session[:quo_vadis_original_url] = request.fullpath
35
40
  flash[:notice] = t('quo_vadis.flash.sign_in.before') unless t('quo_vadis.flash.sign_in.before').blank?
36
41
  redirect_to sign_in_url
@@ -66,11 +66,15 @@ class QuoVadis::SessionsController < ApplicationController
66
66
  # PUT change_password_path /sign-in/change-password/:token
67
67
  def update
68
68
  if (user = QuoVadis.model_class.valid_token(params[:token]).first)
69
- user.password = params[:password]
70
- if user.save
71
- user.clear_token
72
- flash_if_present :notice, 'quo_vadis.flash.forgotten.password_changed'
73
- sign_in user
69
+ if params[:password].present?
70
+ user.password = params[:password]
71
+ if user.save
72
+ user.clear_token
73
+ flash_if_present :notice, 'quo_vadis.flash.forgotten.password_changed'
74
+ sign_in user
75
+ else
76
+ render 'sessions/edit'
77
+ end
74
78
  else
75
79
  render 'sessions/edit'
76
80
  end
@@ -10,6 +10,9 @@ module ModelMixin
10
10
  # Adds methods to set and authenticate against a password stored encrypted by BCrypt.
11
11
  # Also adds methods to generate and clear a token, used to retrieve the record of a
12
12
  # user who has forgotten their password.
13
+ #
14
+ # Note that if a password isn't supplied when creating a user, the error will be on
15
+ # the `password_digest` attribute.
13
16
  def authenticates
14
17
  send :include, InstanceMethodsOnActivation
15
18
 
@@ -17,7 +20,6 @@ module ModelMixin
17
20
  attr_protected :password_digest
18
21
 
19
22
  validates :username, :presence => true, :uniqueness => true, :if => :should_authenticate?
20
- validates :password, :presence => true, :if => Proc.new { |u| u.should_authenticate? && u.changed.include?('password_digest') }
21
23
  validates :password_digest, :presence => true, :if => :should_authenticate?
22
24
 
23
25
  scope :valid_token, lambda { |token| where("token = ? AND token_created_at > ?", token, 3.hours.ago) }
@@ -54,7 +56,9 @@ module ModelMixin
54
56
 
55
57
  def password=(plain_text_password) # :nodoc:
56
58
  @password = plain_text_password
57
- self.password_digest = BCrypt::Password.create plain_text_password
59
+ unless @password.blank?
60
+ self.password_digest = BCrypt::Password.create plain_text_password
61
+ end
58
62
  end
59
63
 
60
64
  # Generates a unique, timestamped token which can be used in URLs, and
@@ -1,3 +1,3 @@
1
1
  module QuoVadis
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.1'
3
3
  end
@@ -9,17 +9,16 @@
9
9
  <body>
10
10
 
11
11
  <div id='topnav'>
12
- <% if defined?(current_user) && current_user %>
13
- You are signed in as <%= current_user.name %>.
12
+ <% if authenticated? %>
13
+ You are signed in as
14
+ <% if defined?(current_user) %>
15
+ <%= current_user.name %>.
16
+ <% elsif defined?(current_person) %>
17
+ <%= current_person.name %>.
18
+ <% end %>
14
19
  <%= link_to 'Sign out', sign_out_path %>
15
-
16
- <% elsif defined?(current_person) && current_person %>
17
- You are signed in as <%= current_person.name %>.
18
- <%= link_to 'Sign out', sign_out_path %>
19
-
20
20
  <% else %>
21
21
  <%= link_to 'Sign in', sign_in_path %>
22
-
23
22
  <% end %>
24
23
  </div>
25
24
 
@@ -53,7 +53,7 @@ class ForgottenTest < ActiveSupport::IntegrationCase
53
53
  test 'user can follow emailed link while valid to change password' do
54
54
  user_factory 'Bob', 'bob', 'secret', 'bob@example.com'
55
55
  submit_forgotten_details 'bob'
56
-
56
+
57
57
  link_in_email = ActionMailer::Base.deliveries.last.encoded[%r{http://.*}].strip
58
58
  visit link_in_email
59
59
  fill_in :password, :with => 'topsecret'
@@ -69,7 +69,7 @@ class ForgottenTest < ActiveSupport::IntegrationCase
69
69
  test 'user cannot change password to an invalid one' do
70
70
  user_factory 'Bob', 'bob', 'secret', 'bob@example.com'
71
71
  submit_forgotten_details 'bob'
72
-
72
+
73
73
  link_in_email = ActionMailer::Base.deliveries.last.encoded[%r{http://.*}].strip
74
74
  visit link_in_email
75
75
  fill_in :password, :with => ''
@@ -81,7 +81,7 @@ class ForgottenTest < ActiveSupport::IntegrationCase
81
81
  user_factory 'Bob', 'bob', 'secret', 'bob@example.com'
82
82
  submit_forgotten_details 'bob'
83
83
  User.last.update_attributes :token_created_at => 1.day.ago
84
-
84
+
85
85
  link_in_email = ActionMailer::Base.deliveries.last.encoded[%r{http://.*}].strip
86
86
  visit link_in_email
87
87
  assert_equal forgotten_sign_in_path, current_path
@@ -2,10 +2,15 @@ require 'test_helper'
2
2
 
3
3
  class UserTest < ActiveSupport::TestCase
4
4
 
5
+ test 'user must have a unique username' do
6
+ User.create :username => 'bob', :password => 'secret'
7
+ assert User.new(:username => 'bob', :password => 'secret').invalid?
8
+ end
9
+
5
10
  test 'user must have a valid password on create' do
6
- assert !User.create(:username => 'bob', :password => nil).valid?
7
- assert !User.create(:username => 'bob', :password => '').valid?
8
- assert User.create(:username => 'bob', :password => 'secret').valid?
11
+ assert User.create(:username => 'bob', :password => nil).invalid?
12
+ assert User.create(:username => 'bob', :password => '').invalid?
13
+ assert User.create(:username => 'bob', :password => 'secret').valid?
9
14
  end
10
15
 
11
16
  test 'user need not supply password when updating other attributes' do
@@ -13,13 +18,14 @@ class UserTest < ActiveSupport::TestCase
13
18
  user = User.last # reload from database so password is nil
14
19
  assert_nil user.password
15
20
  assert user.update_attributes(:username => 'Robert')
21
+ assert user.update_attributes(:username => 'Robert', :password => nil)
22
+ assert user.update_attributes(:username => 'Robert', :password => '')
23
+ assert User.last.has_matching_password?('secret')
16
24
  end
17
25
 
18
26
  test 'user must have a valid password when updating password' do
19
27
  user = User.create :username => 'bob', :password => 'secret'
20
- assert !user.update_attributes(:password => '')
21
- assert !user.update_attributes(:password => nil)
22
- assert user.update_attributes(:password => 'topsecret')
28
+ assert user.update_attributes(:password => 'topsecret')
23
29
  end
24
30
 
25
31
  test 'has_matching_password?' do
@@ -36,7 +42,7 @@ class UserTest < ActiveSupport::TestCase
36
42
  end
37
43
  END
38
44
  user.username = 'bob'
39
- assert !user.valid?
45
+ assert user.invalid?
40
46
 
41
47
  user.username = 'robert'
42
48
  assert user.valid?
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quo_vadis
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 0
10
- version: 1.1.0
9
+ - 1
10
+ version: 1.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Stewart
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-07 00:00:00 +02:00
18
+ date: 2011-10-18 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency