clearance 0.12.0 → 0.13.0

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 (39) hide show
  1. data/Appraisals +2 -7
  2. data/CHANGELOG.md +9 -1
  3. data/CONTRIBUTING.md +38 -0
  4. data/Gemfile +2 -10
  5. data/Gemfile.lock +45 -49
  6. data/LICENSE +1 -1
  7. data/README.md +122 -13
  8. data/Rakefile +1 -1
  9. data/VERSION +1 -1
  10. data/app/views/sessions/_form.html.erb +13 -0
  11. data/app/views/sessions/new.html.erb +1 -13
  12. data/clearance.gemspec +7 -2
  13. data/features/engine/visitor_resets_password.feature +11 -23
  14. data/features/engine/visitor_signs_in.feature +6 -14
  15. data/features/engine/visitor_signs_out.feature +1 -1
  16. data/features/engine/visitor_signs_up.feature +6 -16
  17. data/features/integration.feature +0 -2
  18. data/features/step_definitions/engine/clearance_steps.rb +72 -62
  19. data/features/support/env.rb +2 -2
  20. data/gemfiles/3.0.9.gemfile +5 -10
  21. data/gemfiles/3.0.9.gemfile.lock +28 -33
  22. data/gemfiles/3.1.0.gemfile +13 -0
  23. data/gemfiles/3.1.0.gemfile.lock +187 -0
  24. data/lib/clearance.rb +1 -0
  25. data/lib/clearance/configuration.rb +2 -1
  26. data/lib/clearance/password_strategies.rb +5 -0
  27. data/lib/clearance/password_strategies/sha1.rb +46 -0
  28. data/lib/clearance/user.rb +10 -38
  29. data/lib/generators/clearance/features/features_generator.rb +0 -10
  30. data/spec/models/clearance_user_spec.rb +33 -0
  31. data/spec/models/sha1_spec.rb +43 -0
  32. data/spec/models/user_spec.rb +13 -21
  33. metadata +106 -85
  34. data/features/step_definitions/web_steps.rb +0 -211
  35. data/features/support/appraisal.rb +0 -18
  36. data/features/support/paths.rb +0 -22
  37. data/features/support/selectors.rb +0 -39
  38. data/gemfiles/3.1.0.rc4.gemfile +0 -23
  39. data/gemfiles/3.1.0.rc4.gemfile.lock +0 -216
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "capybara", "~> 1.0.0"
6
+ gem "factory_girl_rails"
7
+ gem "shoulda-matchers", :git=>"git://github.com/thoughtbot/shoulda-matchers.git"
8
+ gem "database_cleaner"
9
+ gem "launchy"
10
+ gem "aruba", "~> 0.4.2"
11
+ gem "rails", "3.1.0"
12
+
13
+ gemspec :path=>"../"
@@ -0,0 +1,187 @@
1
+ GIT
2
+ remote: git://github.com/thoughtbot/shoulda-matchers.git
3
+ revision: 5190a39bba699d4989c2500c98622b505e2de828
4
+ specs:
5
+ shoulda-matchers (1.0.0.beta3)
6
+
7
+ PATH
8
+ remote: /Users/croaky/dev/clearance
9
+ specs:
10
+ clearance (0.12.0)
11
+ diesel (~> 0.1.5)
12
+ rails (>= 3.0)
13
+
14
+ GEM
15
+ remote: http://rubygems.org/
16
+ specs:
17
+ actionmailer (3.1.0)
18
+ actionpack (= 3.1.0)
19
+ mail (~> 2.3.0)
20
+ actionpack (3.1.0)
21
+ activemodel (= 3.1.0)
22
+ activesupport (= 3.1.0)
23
+ builder (~> 3.0.0)
24
+ erubis (~> 2.7.0)
25
+ i18n (~> 0.6)
26
+ rack (~> 1.3.2)
27
+ rack-cache (~> 1.0.3)
28
+ rack-mount (~> 0.8.2)
29
+ rack-test (~> 0.6.1)
30
+ sprockets (~> 2.0.0)
31
+ activemodel (3.1.0)
32
+ activesupport (= 3.1.0)
33
+ bcrypt-ruby (~> 3.0.0)
34
+ builder (~> 3.0.0)
35
+ i18n (~> 0.6)
36
+ activerecord (3.1.0)
37
+ activemodel (= 3.1.0)
38
+ activesupport (= 3.1.0)
39
+ arel (~> 2.2.1)
40
+ tzinfo (~> 0.3.29)
41
+ activeresource (3.1.0)
42
+ activemodel (= 3.1.0)
43
+ activesupport (= 3.1.0)
44
+ activesupport (3.1.0)
45
+ multi_json (~> 1.0)
46
+ addressable (2.2.6)
47
+ appraisal (0.3.8)
48
+ bundler
49
+ rake
50
+ arel (2.2.1)
51
+ aruba (0.4.6)
52
+ bcat (>= 0.6.1)
53
+ childprocess (>= 0.2.0)
54
+ cucumber (>= 1.0.2)
55
+ rdiscount (>= 1.6.8)
56
+ rspec (>= 2.6.0)
57
+ bcat (0.6.1)
58
+ rack (~> 1.0)
59
+ bcrypt-ruby (3.0.0)
60
+ builder (3.0.0)
61
+ capybara (1.0.1)
62
+ mime-types (>= 1.16)
63
+ nokogiri (>= 1.3.3)
64
+ rack (>= 1.0.0)
65
+ rack-test (>= 0.5.4)
66
+ selenium-webdriver (~> 2.0)
67
+ xpath (~> 0.1.4)
68
+ childprocess (0.2.2)
69
+ ffi (~> 1.0.6)
70
+ cucumber (1.0.2)
71
+ builder (>= 2.1.2)
72
+ diff-lcs (>= 1.1.2)
73
+ gherkin (~> 2.4.5)
74
+ json (>= 1.4.6)
75
+ term-ansicolor (>= 1.0.5)
76
+ cucumber-rails (1.0.2)
77
+ capybara (>= 1.0.0)
78
+ cucumber (~> 1.0.0)
79
+ nokogiri (>= 1.4.6)
80
+ database_cleaner (0.6.7)
81
+ diesel (0.1.5)
82
+ railties
83
+ diff-lcs (1.1.3)
84
+ erubis (2.7.0)
85
+ factory_girl (2.0.5)
86
+ factory_girl_rails (1.1.0)
87
+ factory_girl (~> 2.0.0)
88
+ railties (>= 3.0.0)
89
+ ffi (1.0.9)
90
+ gherkin (2.4.16)
91
+ json (>= 1.4.6)
92
+ hike (1.2.1)
93
+ i18n (0.6.0)
94
+ json (1.5.4)
95
+ json_pure (1.5.4)
96
+ spruz (~> 0.2.8)
97
+ launchy (2.0.5)
98
+ addressable (~> 2.2.6)
99
+ mail (2.3.0)
100
+ i18n (>= 0.4.0)
101
+ mime-types (~> 1.16)
102
+ treetop (~> 1.4.8)
103
+ mime-types (1.16)
104
+ mocha (0.9.12)
105
+ multi_json (1.0.3)
106
+ nokogiri (1.5.0)
107
+ polyglot (0.3.2)
108
+ rack (1.3.2)
109
+ rack-cache (1.0.3)
110
+ rack (>= 0.4)
111
+ rack-mount (0.8.3)
112
+ rack (>= 1.0.0)
113
+ rack-ssl (1.3.2)
114
+ rack
115
+ rack-test (0.6.1)
116
+ rack (>= 1.0)
117
+ rails (3.1.0)
118
+ actionmailer (= 3.1.0)
119
+ actionpack (= 3.1.0)
120
+ activerecord (= 3.1.0)
121
+ activeresource (= 3.1.0)
122
+ activesupport (= 3.1.0)
123
+ bundler (~> 1.0)
124
+ railties (= 3.1.0)
125
+ railties (3.1.0)
126
+ actionpack (= 3.1.0)
127
+ activesupport (= 3.1.0)
128
+ rack-ssl (~> 1.3.2)
129
+ rake (>= 0.8.7)
130
+ rdoc (~> 3.4)
131
+ thor (~> 0.14.6)
132
+ rake (0.9.2)
133
+ rdiscount (1.6.8)
134
+ rdoc (3.9.4)
135
+ rspec (2.6.0)
136
+ rspec-core (~> 2.6.0)
137
+ rspec-expectations (~> 2.6.0)
138
+ rspec-mocks (~> 2.6.0)
139
+ rspec-core (2.6.4)
140
+ rspec-expectations (2.6.0)
141
+ diff-lcs (~> 1.1.2)
142
+ rspec-mocks (2.6.0)
143
+ rspec-rails (2.6.1)
144
+ actionpack (~> 3.0)
145
+ activesupport (~> 3.0)
146
+ railties (~> 3.0)
147
+ rspec (~> 2.6.0)
148
+ rubyzip (0.9.4)
149
+ selenium-webdriver (2.5.0)
150
+ childprocess (>= 0.2.1)
151
+ ffi (>= 1.0.7)
152
+ json_pure
153
+ rubyzip
154
+ sprockets (2.0.0)
155
+ hike (~> 1.2)
156
+ rack (~> 1.0)
157
+ tilt (!= 1.3.0, ~> 1.1)
158
+ spruz (0.2.13)
159
+ sqlite3 (1.3.4)
160
+ term-ansicolor (1.0.6)
161
+ thor (0.14.6)
162
+ tilt (1.3.3)
163
+ treetop (1.4.10)
164
+ polyglot
165
+ polyglot (>= 0.3.1)
166
+ tzinfo (0.3.29)
167
+ xpath (0.1.4)
168
+ nokogiri (~> 1.3)
169
+
170
+ PLATFORMS
171
+ ruby
172
+
173
+ DEPENDENCIES
174
+ appraisal (~> 0.3.8)
175
+ aruba (~> 0.4.2)
176
+ bundler (~> 1.0.0)
177
+ capybara (~> 1.0.0)
178
+ clearance!
179
+ cucumber-rails (~> 1.0.2)
180
+ database_cleaner
181
+ factory_girl_rails
182
+ launchy
183
+ mocha
184
+ rails (= 3.1.0)
185
+ rspec-rails (~> 2.6.0)
186
+ shoulda-matchers!
187
+ sqlite3
data/lib/clearance.rb CHANGED
@@ -2,3 +2,4 @@ require 'clearance/configuration'
2
2
  require 'clearance/authentication'
3
3
  require 'clearance/user'
4
4
  require 'clearance/engine'
5
+ require 'clearance/password_strategies'
@@ -1,6 +1,6 @@
1
1
  module Clearance
2
2
  class Configuration
3
- attr_accessor :mailer_sender, :cookie_expiration
3
+ attr_accessor :mailer_sender, :cookie_expiration, :password_strategy
4
4
 
5
5
  def initialize
6
6
  @mailer_sender = 'donotreply@example.com'
@@ -24,6 +24,7 @@ module Clearance
24
24
  # Clearance.configure do |config|
25
25
  # config.mailer_sender = 'me@example.com'
26
26
  # config.cookie_expiration = lambda { 2.weeks.from_now.utc }
27
+ # config.password_strategy = MyPasswordStrategy
27
28
  # end
28
29
  def self.configure
29
30
  self.configuration ||= Configuration.new
@@ -0,0 +1,5 @@
1
+ module Clearance
2
+ module PasswordStrategies
3
+ autoload :SHA1, 'clearance/password_strategies/sha1'
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ require 'digest/sha1'
2
+
3
+ module Clearance
4
+ module PasswordStrategies
5
+ module SHA1
6
+ extend ActiveSupport::Concern
7
+
8
+ # Am I authenticated with given password?
9
+ #
10
+ # @param [String] plain-text password
11
+ # @return [true, false]
12
+ # @example
13
+ # user.authenticated?('password')
14
+ def authenticated?(password)
15
+ encrypted_password == encrypt(password)
16
+ end
17
+
18
+ protected
19
+
20
+ def encrypt_password
21
+ initialize_salt_if_necessary
22
+ if password.present?
23
+ self.encrypted_password = encrypt(password)
24
+ end
25
+ end
26
+
27
+ def generate_hash(string)
28
+ if RUBY_VERSION >= '1.9'
29
+ Digest::SHA1.hexdigest(string).encode('UTF-8')
30
+ else
31
+ Digest::SHA1.hexdigest(string)
32
+ end
33
+ end
34
+
35
+ def encrypt(string)
36
+ generate_hash("--#{salt}--#{string}--")
37
+ end
38
+
39
+ def initialize_salt_if_necessary
40
+ if salt.blank?
41
+ self.salt = generate_random_code
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -10,15 +10,18 @@ module Clearance
10
10
  # extend and include à la carte.
11
11
  #
12
12
  # @example
13
- # include Callbacks
13
+ # include Clearance::User::Callbacks
14
14
  #
15
15
  # @see Validations
16
16
  # @see Callbacks
17
17
  included do
18
- attr_accessor :password, :password_changing
18
+ attr_accessor :password_changing
19
+ attr_reader :password
19
20
 
20
21
  include Validations
21
22
  include Callbacks
23
+
24
+ include (Clearance.configuration.password_strategy || Clearance::PasswordStrategies::SHA1)
22
25
  end
23
26
 
24
27
  module ClassMethods
@@ -60,22 +63,10 @@ module Clearance
60
63
  # salt, token, password encryption are handled before_save.
61
64
  included do
62
65
  before_validation :downcase_email
63
- before_save :initialize_salt,
64
- :encrypt_password
65
66
  before_create :generate_remember_token
66
67
  end
67
68
  end
68
69
 
69
- # Am I authenticated with given password?
70
- #
71
- # @param [String] plain-text password
72
- # @return [true, false]
73
- # @example
74
- # user.authenticated?('password')
75
- def authenticated?(password)
76
- encrypted_password == encrypt(password)
77
- end
78
-
79
70
  # Set the remember token.
80
71
  #
81
72
  # @deprecated Use {#reset_remember_token!} instead
@@ -117,16 +108,13 @@ module Clearance
117
108
  save
118
109
  end
119
110
 
120
- protected
121
-
122
- def generate_hash(string)
123
- if RUBY_VERSION >= '1.9'
124
- Digest::SHA1.hexdigest(string).encode('UTF-8')
125
- else
126
- Digest::SHA1.hexdigest(string)
127
- end
111
+ def password=(unencrypted_password)
112
+ @password = unencrypted_password
113
+ encrypt_password
128
114
  end
129
115
 
116
+ protected
117
+
130
118
  def generate_random_code(length = 20)
131
119
  if RUBY_VERSION >= '1.9'
132
120
  SecureRandom.hex(length).encode('UTF-8')
@@ -135,22 +123,6 @@ module Clearance
135
123
  end
136
124
  end
137
125
 
138
- def encrypt(string)
139
- generate_hash("--#{salt}--#{string}--")
140
- end
141
-
142
- def initialize_salt
143
- if salt.blank?
144
- self.salt = generate_random_code
145
- end
146
- end
147
-
148
- def encrypt_password
149
- if password.present?
150
- self.encrypted_password = encrypt(password)
151
- end
152
- end
153
-
154
126
  def generate_remember_token
155
127
  self.remember_token = generate_random_code
156
128
  end
@@ -3,16 +3,6 @@ require 'diesel/generators/features_base'
3
3
  module Clearance
4
4
  module Generators
5
5
  class FeaturesGenerator < Diesel::Generators::FeaturesBase
6
- def inject_paths
7
- inject_into_file "features/support/paths.rb", :after => "# Add more mappings here.\n" do
8
- " when /the sign up page/i
9
- sign_up_path
10
- when /the sign in page/i
11
- sign_in_path
12
- when /the password reset request page/i
13
- new_password_path\n"
14
- end
15
- end
16
6
  end
17
7
  end
18
8
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clearance::User do
4
+ subject do
5
+ Class.new do
6
+ def self.validates_presence_of(*args); end
7
+ def self.validates_uniqueness_of(*args); end
8
+ def self.validates_format_of(*args); end
9
+ def self.before_validation(*args); end
10
+ def self.before_create(*args); end
11
+
12
+ include Clearance::User
13
+ end.new
14
+ end
15
+
16
+ describe "when Clearance.configuration.password_strategy is set" do
17
+ let(:mock_password_strategy) { Module.new }
18
+
19
+ before { Clearance.configuration.password_strategy = mock_password_strategy }
20
+
21
+ it "includes the value it is set to" do
22
+ subject.should be_kind_of(mock_password_strategy)
23
+ end
24
+ end
25
+
26
+ describe "when Clearance.configuration.password_strategy is not set" do
27
+ before { Clearance.configuration.password_strategy = nil }
28
+
29
+ it "includes Clearance::PasswordStrategies::SHA1" do
30
+ subject.should be_kind_of(Clearance::PasswordStrategies::SHA1)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clearance::PasswordStrategies::SHA1 do
4
+ subject do
5
+ Class.new do
6
+ attr_accessor :salt, :password, :encrypted_password
7
+ include Clearance::PasswordStrategies::SHA1
8
+
9
+ def generate_random_code; "code"; end
10
+ end.new
11
+ end
12
+
13
+ describe "#encrypt_password" do
14
+ context "when the password is set" do
15
+ let(:salt) { "salt" }
16
+ let(:password) { "password" }
17
+
18
+ before do
19
+ subject.salt = salt
20
+ subject.password = password
21
+ subject.send(:encrypt_password)
22
+ end
23
+
24
+ it "should encrypt the password using SHA1 into encrypted_password" do
25
+ expected = Digest::SHA1.hexdigest("--#{salt}--#{password}--")
26
+
27
+ subject.encrypted_password.should == expected
28
+ end
29
+ end
30
+
31
+ context "when the salt is not set" do
32
+ before do
33
+ subject.salt = nil
34
+
35
+ subject.send(:encrypt_password)
36
+ end
37
+
38
+ it "should initialize the salt" do
39
+ subject.salt.should_not be_nil
40
+ end
41
+ end
42
+ end
43
+ end