clearance 0.16.3 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of clearance might be problematic. Click here for more details.

Files changed (85) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +0 -2
  3. data/Appraisals +2 -2
  4. data/CONTRIBUTING.md +10 -19
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +81 -82
  7. data/NEWS.md +17 -4
  8. data/README.md +176 -113
  9. data/app/controllers/clearance/passwords_controller.rb +44 -31
  10. data/app/controllers/clearance/sessions_controller.rb +11 -10
  11. data/app/controllers/clearance/users_controller.rb +8 -12
  12. data/app/mailers/clearance_mailer.rb +4 -5
  13. data/app/views/clearance_mailer/change_password.html.erb +2 -4
  14. data/app/views/layouts/application.html.erb +7 -5
  15. data/app/views/passwords/edit.html.erb +8 -7
  16. data/app/views/passwords/new.html.erb +6 -5
  17. data/app/views/sessions/_form.html.erb +7 -5
  18. data/app/views/sessions/new.html.erb +3 -2
  19. data/app/views/users/_form.html.erb +4 -3
  20. data/clearance.gemspec +29 -27
  21. data/config/routes.rb +10 -13
  22. data/db/migrate/20110111224543_create_clearance_users.rb +18 -0
  23. data/db/schema.rb +4 -5
  24. data/features/engine/visitor_resets_password.feature +0 -7
  25. data/features/engine/visitor_signs_in.feature +7 -0
  26. data/features/engine/visitor_signs_up.feature +2 -2
  27. data/features/integration.feature +0 -1
  28. data/features/integration_with_test_unit.feature +43 -0
  29. data/features/step_definitions/configuration_steps.rb +8 -15
  30. data/features/step_definitions/engine/clearance_steps.rb +38 -38
  31. data/features/support/clearance.rb +1 -1
  32. data/features/support/env.rb +4 -21
  33. data/gemfiles/{3.0.12.gemfile → 3.0.15.gemfile} +1 -1
  34. data/gemfiles/{3.0.12.gemfile.lock → 3.0.15.gemfile.lock} +75 -76
  35. data/gemfiles/{3.2.3.gemfile → 3.1.6.gemfile} +1 -1
  36. data/gemfiles/{3.1.4.gemfile.lock → 3.1.6.gemfile.lock} +79 -80
  37. data/gemfiles/{3.1.4.gemfile → 3.2.6.gemfile} +1 -1
  38. data/gemfiles/{3.2.3.gemfile.lock → 3.2.6.gemfile.lock} +80 -81
  39. data/lib/clearance.rb +1 -0
  40. data/lib/clearance/authentication.rb +37 -69
  41. data/lib/clearance/configuration.rb +3 -18
  42. data/lib/clearance/constraints.rb +2 -0
  43. data/lib/clearance/constraints/signed_in.rb +28 -0
  44. data/lib/clearance/constraints/signed_out.rb +9 -0
  45. data/lib/clearance/engine.rb +4 -4
  46. data/lib/clearance/password_strategies.rb +5 -1
  47. data/lib/clearance/password_strategies/bcrypt.rb +27 -0
  48. data/lib/clearance/password_strategies/bcrypt_migration_from_sha1.rb +52 -0
  49. data/lib/clearance/password_strategies/blowfish.rb +11 -15
  50. data/lib/clearance/password_strategies/fake.rb +23 -0
  51. data/lib/clearance/password_strategies/sha1.rb +15 -21
  52. data/lib/clearance/session.rb +28 -20
  53. data/lib/clearance/testing.rb +8 -3
  54. data/lib/clearance/testing/assertion_error.rb +2 -7
  55. data/lib/clearance/testing/deny_access_matcher.rb +27 -32
  56. data/lib/clearance/testing/helpers.rb +7 -8
  57. data/lib/clearance/user.rb +26 -92
  58. data/lib/clearance/version.rb +1 -1
  59. data/lib/generators/clearance/install/templates/db/migrate/upgrade_clearance_to_diesel.rb +24 -26
  60. data/spec/clearance/constraints/signed_in_spec.rb +51 -0
  61. data/spec/clearance/constraints/signed_out_spec.rb +15 -0
  62. data/spec/clearance/rack_session_spec.rb +8 -7
  63. data/spec/clearance/session_spec.rb +28 -27
  64. data/spec/configuration_spec.rb +7 -6
  65. data/spec/controllers/denies_controller_spec.rb +11 -10
  66. data/spec/controllers/flashes_controller_spec.rb +5 -5
  67. data/spec/controllers/forgeries_controller_spec.rb +9 -9
  68. data/spec/controllers/passwords_controller_spec.rb +42 -55
  69. data/spec/controllers/sessions_controller_spec.rb +26 -33
  70. data/spec/controllers/users_controller_spec.rb +16 -14
  71. data/spec/factories.rb +1 -3
  72. data/spec/mailers/clearance_mailer_spec.rb +4 -4
  73. data/spec/models/bcrypt_migration_from_sha1_spec.rb +71 -0
  74. data/spec/models/bcrypt_spec.rb +40 -0
  75. data/spec/models/blowfish_spec.rb +14 -13
  76. data/spec/models/{clearance_user_spec.rb → password_strategies_spec.rb} +5 -5
  77. data/spec/models/sha1_spec.rb +18 -13
  78. data/spec/models/user_spec.rb +58 -73
  79. data/spec/spec_helper.rb +5 -6
  80. data/spec/support/clearance.rb +0 -4
  81. data/spec/support/cookies.rb +25 -27
  82. data/spec/support/request_with_remember_token.rb +19 -0
  83. metadata +95 -90
  84. data/db/migrate/20110111224543_create_diesel_clearance_users.rb +0 -19
  85. data/init.rb +0 -1
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Clearance::SessionsController do
4
- describe "on GET to /sessions/new" do
4
+ describe 'on GET to /sessions/new' do
5
5
  before { get :new }
6
6
 
7
7
  it { should respond_with(:success) }
@@ -9,95 +9,88 @@ describe Clearance::SessionsController do
9
9
  it { should_not set_the_flash }
10
10
  end
11
11
 
12
- describe "on POST to #create with good credentials" do
12
+ describe 'on POST to #create with good credentials' do
13
13
  before do
14
14
  @user = create(:user)
15
- @user.update_attribute(:remember_token, "old-token")
16
- post :create, :session => {
17
- :email => @user.email,
18
- :password => @user.password }
15
+ @user.update_attribute :remember_token, 'old-token'
16
+ post :create, :session => { :email => @user.email, :password => @user.password }
19
17
  end
20
18
 
21
19
  it { should redirect_to_url_after_create }
22
20
 
23
- it "sets the user in the clearance session" do
21
+ it 'sets the user in the clearance session' do
24
22
  controller.current_user.should == @user
25
23
  end
26
24
 
27
- it "should not change the remember token" do
28
- @user.reload.remember_token.should == "old-token"
25
+ it 'should not change the remember token' do
26
+ @user.reload.remember_token.should == 'old-token'
29
27
  end
30
28
  end
31
29
 
32
- describe "on POST to #create with good credentials and a session return url" do
30
+ describe 'on POST to #create with good credentials and a session return url' do
33
31
  before do
34
32
  @user = create(:user)
35
33
  @return_url = '/url_in_the_session'
36
34
  @request.session[:return_to] = @return_url
37
- post :create, :session => {
38
- :email => @user.email,
39
- :password => @user.password }
35
+ post :create, :session => { :email => @user.email, :password => @user.password }
40
36
  end
41
37
 
42
- it "redirects to the return URL" do
38
+ it 'redirects to the return URL' do
43
39
  should redirect_to(@return_url)
44
40
  end
45
41
  end
46
42
 
47
- describe "on POST to #create with good credentials and a request return url" do
43
+ describe 'on POST to #create with good credentials and a request return url' do
48
44
  before do
49
45
  @user = create(:user)
50
46
  @return_url = '/url_in_the_request'
51
- post :create, :session => {
52
- :email => @user.email,
53
- :password => @user.password },
54
- :return_to => @return_url
47
+ post :create, :session => { :email => @user.email, :password => @user.password },
48
+ :return_to => @return_url
55
49
  end
56
50
 
57
- it "redirects to the return URL" do
51
+ it 'redirects to the return URL' do
58
52
  should redirect_to(@return_url)
59
53
  end
60
54
  end
61
55
 
62
- describe "on POST to #create with good credentials and a session return url and request return url" do
56
+ describe 'on POST to #create with good credentials and a session return url and request return url' do
63
57
  before do
64
58
  @user = create(:user)
65
59
  @return_url = '/url_in_the_session'
66
60
  @request.session[:return_to] = @return_url
67
- post :create, :session => {
68
- :email => @user.email,
69
- :password => @user.password },
70
- :return_to => '/url_in_the_request'
61
+ post :create, :session => { :email => @user.email, :password => @user.password },
62
+ :return_to => '/url_in_the_request'
71
63
  end
72
64
 
73
- it "redirects to the return url" do
65
+ it 'redirects to the return url' do
74
66
  should redirect_to(@return_url)
75
67
  end
76
68
  end
77
69
 
78
- describe "on DELETE to #destroy given a signed out user" do
70
+ describe 'on DELETE to #destroy given a signed out user' do
79
71
  before do
80
72
  sign_out
81
73
  delete :destroy
82
74
  end
75
+
83
76
  it { should redirect_to_url_after_destroy }
84
77
  end
85
78
 
86
- describe "on DELETE to #destroy with a cookie" do
79
+ describe 'on DELETE to #destroy with a cookie' do
87
80
  before do
88
81
  @user = create(:user)
89
- @user.update_attribute(:remember_token, "old-token")
90
- @request.cookies["remember_token"] = "old-token"
82
+ @user.update_attribute :remember_token, 'old-token'
83
+ @request.cookies['remember_token'] = 'old-token'
91
84
  delete :destroy
92
85
  end
93
86
 
94
87
  it { should redirect_to_url_after_destroy }
95
88
 
96
- it "should reset the remember token" do
97
- @user.reload.remember_token.should_not == "old-token"
89
+ it 'should reset the remember token' do
90
+ @user.reload.remember_token.should_not == 'old-token'
98
91
  end
99
92
 
100
- it "should unset the current user" do
93
+ it 'should unset the current user' do
101
94
  @controller.current_user.should be_nil
102
95
  end
103
96
  end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Clearance::UsersController do
4
- describe "when signed out" do
4
+ describe 'when signed out' do
5
5
  before { sign_out }
6
6
 
7
- describe "on GET to #new" do
7
+ describe 'on GET to #new' do
8
8
  before { get :new }
9
9
 
10
10
  it { should respond_with(:success) }
@@ -12,18 +12,18 @@ describe Clearance::UsersController do
12
12
  it { should_not set_the_flash }
13
13
  end
14
14
 
15
- describe "on GET to #new with email" do
15
+ describe 'on GET to #new with email' do
16
16
  before do
17
- @email = "a@example.com"
17
+ @email = 'a@example.com'
18
18
  get :new, :user => { :email => @email }
19
19
  end
20
20
 
21
- it "should set assigned user's email" do
21
+ it 'should set assigned user email' do
22
22
  assigns(:user).email.should == @email
23
23
  end
24
24
  end
25
25
 
26
- describe "on POST to #create with valid attributes" do
26
+ describe 'on POST to #create with valid attributes' do
27
27
  before do
28
28
  user_attributes = FactoryGirl.attributes_for(:user)
29
29
  @old_user_count = User.count
@@ -32,14 +32,14 @@ describe Clearance::UsersController do
32
32
 
33
33
  it { should assign_to(:user) }
34
34
 
35
- it "should create a new user" do
35
+ it 'should create a new user' do
36
36
  User.count.should == @old_user_count + 1
37
37
  end
38
38
 
39
39
  it { should redirect_to_url_after_create }
40
40
  end
41
41
 
42
- describe "on POST to #create with valid attributes and a session return url" do
42
+ describe 'on POST to #create with valid attributes and a session return url' do
43
43
  before do
44
44
  user_attributes = FactoryGirl.attributes_for(:user)
45
45
  @old_user_count = User.count
@@ -50,7 +50,7 @@ describe Clearance::UsersController do
50
50
 
51
51
  it { should assign_to(:user) }
52
52
 
53
- it "should create a new user" do
53
+ it 'should create a new user' do
54
54
  User.count.should == @old_user_count + 1
55
55
  end
56
56
 
@@ -58,22 +58,24 @@ describe Clearance::UsersController do
58
58
  end
59
59
  end
60
60
 
61
- describe "A signed-in user" do
61
+ describe 'A signed-in user' do
62
62
  before do
63
63
  @user = create(:user)
64
64
  sign_in_as @user
65
65
  end
66
66
 
67
- describe "GET to new" do
67
+ describe 'GET to new' do
68
68
  before { get :new }
69
- it "redirects to the home page" do
69
+
70
+ it 'redirects to the home page' do
70
71
  should redirect_to(root_url)
71
72
  end
72
73
  end
73
74
 
74
- describe "POST to create" do
75
+ describe 'POST to create' do
75
76
  before { post :create, :user => {} }
76
- it "redirects to the home page" do
77
+
78
+ it 'redirects to the home page' do
77
79
  should redirect_to(root_url)
78
80
  end
79
81
  end
data/spec/factories.rb CHANGED
@@ -1,12 +1,10 @@
1
1
  FactoryGirl.define do
2
-
3
2
  sequence :email do |n|
4
3
  "user#{n}@example.com"
5
4
  end
6
5
 
7
6
  factory :user do
8
7
  email
9
- password "password"
8
+ password 'password'
10
9
  end
11
-
12
10
  end
@@ -7,21 +7,21 @@ describe ClearanceMailer do
7
7
  @email = ClearanceMailer.change_password(@user)
8
8
  end
9
9
 
10
- it "should be from DO_NOT_REPLY" do
10
+ it 'is from DO_NOT_REPLY' do
11
11
  Clearance.configuration.mailer_sender.should =~ /#{@email.from[0]}/i
12
12
  end
13
13
 
14
- it "should be sent to user" do
14
+ it 'is sent to user' do
15
15
  @email.to.first.should =~ /#{@user.email}/i
16
16
  end
17
17
 
18
- it "should contain a link to edit the user's password" do
18
+ it 'contains a link to edit the password' do
19
19
  host = ActionMailer::Base.default_url_options[:host]
20
20
  regexp = %r{http://#{host}/users/#{@user.id}/password/edit\?token=#{@user.confirmation_token}}
21
21
  @email.body.to_s.should =~ regexp
22
22
  end
23
23
 
24
- it "should set its subject" do
24
+ it 'should set its subject' do
25
25
  @email.subject.should =~ /Change your password/
26
26
  end
27
27
  end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clearance::PasswordStrategies::BCryptMigrationFromSHA1 do
4
+ subject do
5
+ Class.new do
6
+ attr_accessor :encrypted_password
7
+ attr_accessor :salt
8
+ include Clearance::PasswordStrategies::BCryptMigrationFromSHA1
9
+ end.new
10
+ end
11
+
12
+ describe '#password=' do
13
+ let(:salt) { 'salt' }
14
+ let(:password) { 'password' }
15
+ let(:encrypted_password) { stub('encrypted password') }
16
+
17
+ before do
18
+ subject.salt = salt
19
+ subject.encrypted_password = Digest::SHA1.hexdigest("--#{salt}--#{password}--")
20
+ BCrypt::Password.stubs :create => encrypted_password
21
+ subject.password = password
22
+ end
23
+
24
+ it 'encrypts the password into a BCrypt-encrypted encrypted_password' do
25
+ subject.encrypted_password.should == encrypted_password
26
+ end
27
+
28
+ it 'encrypts with BCrypt' do
29
+ BCrypt::Password.should have_received(:create).with(password)
30
+ end
31
+ end
32
+
33
+ describe '#authenticated?' do
34
+ let(:password) { 'password' }
35
+ let(:salt) { 'salt' }
36
+ let(:sha1_hash) { Digest::SHA1.hexdigest("--#{salt}--#{password}--") }
37
+
38
+ context 'with a SHA1-encrypted password' do
39
+ before do
40
+ subject.salt = salt
41
+ subject.encrypted_password = sha1_hash
42
+ end
43
+
44
+ it 'is authenticated' do
45
+ subject.should be_authenticated(password)
46
+ end
47
+
48
+ it 'changes the hash into a BCrypt-encrypted one' do
49
+ subject.authenticated? password
50
+ subject.encrypted_password.should_not == sha1_hash
51
+ end
52
+ end
53
+
54
+ context 'with a BCrypt-encrypted password' do
55
+ let(:bcrypt_hash) { ::BCrypt::Password.create(password) }
56
+
57
+ before do
58
+ subject.encrypted_password = bcrypt_hash
59
+ end
60
+
61
+ it 'is authenticated' do
62
+ subject.should be_authenticated(password)
63
+ end
64
+
65
+ it 'does not change the hash' do
66
+ subject.authenticated? password
67
+ subject.encrypted_password.to_s.should == bcrypt_hash.to_s
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clearance::PasswordStrategies::BCrypt do
4
+ subject do
5
+ Class.new do
6
+ attr_accessor :encrypted_password
7
+ include Clearance::PasswordStrategies::BCrypt
8
+ end.new
9
+ end
10
+
11
+ describe '#password=' do
12
+ let(:password) { 'password' }
13
+ let(:encrypted_password) { stub('encrypted password') }
14
+
15
+ before do
16
+ BCrypt::Password.stubs :create => encrypted_password
17
+ subject.password = password
18
+ end
19
+
20
+ it 'encrypts the password into encrypted_password' do
21
+ subject.encrypted_password.should == encrypted_password
22
+ end
23
+
24
+ it 'encrypts with BCrypt' do
25
+ BCrypt::Password.should have_received(:create).with(password)
26
+ end
27
+ end
28
+
29
+ describe '#authenticated?' do
30
+ let(:password) { 'password' }
31
+
32
+ before do
33
+ subject.password = password
34
+ end
35
+
36
+ it 'is authenticated with BCrypt' do
37
+ subject.should be_authenticated(password)
38
+ end
39
+ end
40
+ end
@@ -3,41 +3,42 @@ require 'spec_helper'
3
3
  describe Clearance::PasswordStrategies::Blowfish do
4
4
  subject do
5
5
  Class.new do
6
- attr_accessor :salt, :password, :encrypted_password
6
+ attr_accessor :salt, :encrypted_password
7
7
  include Clearance::PasswordStrategies::Blowfish
8
8
 
9
- def generate_random_code; "code"; end
9
+ def generate_random_code; 'code'; end
10
10
  end.new
11
11
  end
12
12
 
13
- describe "#encrypt_password" do
14
- context "when the password is set" do
15
- let(:salt) { "salt" }
16
- let(:password) { "password" }
13
+ describe '#password=' do
14
+ context 'when the password is set' do
15
+ let(:salt) { 'salt' }
16
+ let(:password) { 'password' }
17
17
 
18
18
  before do
19
19
  subject.salt = salt
20
20
  subject.password = password
21
- subject.send(:encrypt_password)
22
21
  end
23
22
 
24
- it "should encrypt the password using Blowfish into encrypted_password" do
23
+ it 'does not initialize the salt' do
24
+ subject.salt.should == salt
25
+ end
26
+
27
+ it 'encrypts the password using Blowfish and the existing salt' do
25
28
  cipher = OpenSSL::Cipher::Cipher.new('bf-cbc').encrypt
26
29
  cipher.key = Digest::SHA256.digest(salt)
27
30
  expected = cipher.update("--#{salt}--#{password}--") << cipher.final
28
-
29
31
  subject.encrypted_password.should == expected
30
32
  end
31
33
  end
32
34
 
33
- context "when the salt is not set" do
35
+ context 'when the salt is not set' do
34
36
  before do
35
37
  subject.salt = nil
36
-
37
- subject.send(:encrypt_password)
38
+ subject.password = 'whatever'
38
39
  end
39
40
 
40
- it "should initialize the salt" do
41
+ it 'should initialize the salt' do
41
42
  subject.salt.should_not be_nil
42
43
  end
43
44
  end
@@ -13,21 +13,21 @@ describe Clearance::User do
13
13
  end.new
14
14
  end
15
15
 
16
- describe "when Clearance.configuration.password_strategy is set" do
16
+ describe 'when Clearance.configuration.password_strategy is set' do
17
17
  let(:mock_password_strategy) { Module.new }
18
18
 
19
19
  before { Clearance.configuration.password_strategy = mock_password_strategy }
20
20
 
21
- it "includes the value it is set to" do
21
+ it 'includes the value it is set to' do
22
22
  subject.should be_kind_of(mock_password_strategy)
23
23
  end
24
24
  end
25
25
 
26
- describe "when Clearance.configuration.password_strategy is not set" do
26
+ describe 'when Clearance.configuration.password_strategy is not set' do
27
27
  before { Clearance.configuration.password_strategy = nil }
28
28
 
29
- it "includes Clearance::PasswordStrategies::SHA1" do
30
- subject.should be_kind_of(Clearance::PasswordStrategies::SHA1)
29
+ it 'includes Clearance::PasswordStrategies::BCrypt' do
30
+ subject.should be_kind_of(Clearance::PasswordStrategies::BCrypt)
31
31
  end
32
32
  end
33
33
  end