authlogic 3.1.3 → 3.2.0

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

Potentially problematic release.


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

Files changed (35) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +16 -12
  4. data/README.rdoc +3 -3
  5. data/Rakefile +1 -1
  6. data/authlogic.gemspec +4 -2
  7. data/lib/authlogic.rb +1 -0
  8. data/lib/authlogic/acts_as_authentic/base.rb +14 -10
  9. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +1 -1
  10. data/lib/authlogic/acts_as_authentic/login.rb +2 -3
  11. data/lib/authlogic/acts_as_authentic/password.rb +1 -1
  12. data/lib/authlogic/crypto_providers/aes256.rb +2 -2
  13. data/lib/authlogic/crypto_providers/bcrypt.rb +2 -2
  14. data/lib/authlogic/crypto_providers/scrypt.rb +80 -0
  15. data/lib/authlogic/crypto_providers/sha1.rb +2 -2
  16. data/lib/authlogic/crypto_providers/sha256.rb +1 -1
  17. data/lib/authlogic/session/cookies.rb +8 -1
  18. data/lib/authlogic/session/persistence.rb +2 -1
  19. data/lib/authlogic/session/timeout.rb +6 -2
  20. data/test/acts_as_authentic_test/base_test.rb +7 -0
  21. data/test/acts_as_authentic_test/logged_in_status_test.rb +15 -12
  22. data/test/crypto_provider_test/bcrypt_test.rb +2 -2
  23. data/test/crypto_provider_test/scrypt_test.rb +14 -0
  24. data/test/session_test/cookies_test.rb +21 -0
  25. data/test/session_test/persistence_test.rb +12 -1
  26. data/test/session_test/timeout_test.rb +29 -1
  27. data/test/test_helper.rb +1 -0
  28. metadata +37 -9
  29. data/VERSION.yml +0 -5
  30. data/generators/session/session_generator.rb +0 -9
  31. data/generators/session/templates/session.rb +0 -2
  32. data/lib/generators/authlogic/USAGE +0 -8
  33. data/lib/generators/authlogic/session_generator.rb +0 -14
  34. data/lib/generators/authlogic/templates/session.rb +0 -2
  35. data/rails/init.rb +0 -1
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ coverage/*
7
7
  doc/*
8
8
  benchmarks/*
9
9
  .specification
10
+ .rvmrc
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
1
  source :rubygems
2
- gemspec
2
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,32 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authlogic (3.1.2)
4
+ authlogic (3.2.0)
5
5
  activerecord (>= 3.0.0)
6
6
  activesupport (>= 3.0.0)
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (3.2.6)
12
- activesupport (= 3.2.6)
11
+ activemodel (3.2.9)
12
+ activesupport (= 3.2.9)
13
13
  builder (~> 3.0.0)
14
- activerecord (3.2.6)
15
- activemodel (= 3.2.6)
16
- activesupport (= 3.2.6)
14
+ activerecord (3.2.9)
15
+ activemodel (= 3.2.9)
16
+ activesupport (= 3.2.9)
17
17
  arel (~> 3.0.2)
18
18
  tzinfo (~> 0.3.29)
19
- activesupport (3.2.6)
19
+ activesupport (3.2.9)
20
20
  i18n (~> 0.6)
21
21
  multi_json (~> 1.0)
22
22
  arel (3.0.2)
23
23
  bcrypt-ruby (3.0.1)
24
- builder (3.0.0)
25
- i18n (0.6.0)
26
- multi_json (1.3.6)
27
- rake (0.9.2.2)
24
+ builder (3.0.4)
25
+ i18n (0.6.1)
26
+ multi_json (1.4.0)
27
+ rake (10.0.2)
28
+ scrypt (1.1.0)
28
29
  sqlite3 (1.3.6)
29
- tzinfo (0.3.33)
30
+ timecop (0.5.4)
31
+ tzinfo (0.3.35)
30
32
 
31
33
  PLATFORMS
32
34
  ruby
@@ -35,4 +37,6 @@ DEPENDENCIES
35
37
  authlogic!
36
38
  bcrypt-ruby
37
39
  rake
40
+ scrypt
38
41
  sqlite3
42
+ timecop
data/README.rdoc CHANGED
@@ -213,9 +213,9 @@ Or how about persisting the session...
213
213
 
214
214
  == Install & Use
215
215
 
216
- Install the gem
216
+ Add to your gem file
217
217
 
218
- $ gem 'authlogic'
218
+ gem 'authlogic'
219
219
 
220
220
  == Detailed Setup Tutorial
221
221
 
@@ -246,4 +246,4 @@ What inspired me to create Authlogic was the messiness of the current authentica
246
246
  6. <b>Easily extendable.</b> One of the distinct advantages of using a library is the ability to use its API, assuming it has one. Authlogic has an *excellent* public API, meaning it can easily be extended and grow beyond the core library. Checkout the "add ons" list above to see what I mean.
247
247
 
248
248
 
249
- Copyright (c) 2009 {Ben Johnson of Binary Logic}[http://www.binarylogic.com], released under the MIT license
249
+ Copyright (c) 2012 {Ben Johnson of Binary Logic}[http://www.binarylogic.com], released under the MIT license
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'rake'
2
+ require 'bundler'
3
3
 
4
4
  Bundler.setup
5
5
 
data/authlogic.gemspec CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "authlogic"
6
- s.version = "3.1.3"
6
+ s.version = "3.2.0"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Ben Johnson"]
9
9
  s.email = ["bjohnson@binarylogic.com"]
@@ -15,10 +15,12 @@ Gem::Specification.new do |s|
15
15
  s.add_dependency 'activesupport', '>= 3.0.0'
16
16
  s.add_development_dependency 'rake'
17
17
  s.add_development_dependency 'bcrypt-ruby'
18
+ s.add_development_dependency 'scrypt'
18
19
  s.add_development_dependency 'sqlite3'
20
+ s.add_development_dependency 'timecop'
19
21
 
20
22
  s.files = `git ls-files`.split("\n")
21
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
24
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
25
  s.require_paths = ["lib"]
24
- end
26
+ end
data/lib/authlogic.rb CHANGED
@@ -15,6 +15,7 @@ AUTHLOGIC_PATH = File.dirname(__FILE__) + "/authlogic/"
15
15
  "crypto_providers/sha512",
16
16
  "crypto_providers/bcrypt",
17
17
  "crypto_providers/aes256",
18
+ "crypto_providers/scrypt",
18
19
 
19
20
  "authenticates_many/base",
20
21
  "authenticates_many/association",
@@ -10,7 +10,7 @@ module Authlogic
10
10
  extend Config
11
11
  end
12
12
  end
13
-
13
+
14
14
  module Config
15
15
  # This includes a lot of helpful methods for authenticating records which The Authlogic::Session module relies on.
16
16
  # To use it just do:
@@ -28,15 +28,19 @@ module Authlogic
28
28
  # See the various sub modules for the configuration they provide.
29
29
  def acts_as_authentic(unsupported_options = nil, &block)
30
30
  # Stop all configuration if the DB is not set up
31
- raise StandardError.new("You must establish a database connection before using acts_as_authentic") if !db_setup?
32
-
33
- raise ArgumentError.new("You are using the old v1.X.X configuration method for Authlogic. Instead of " +
34
- "passing a hash of configuration options to acts_as_authentic, pass a block: acts_as_authentic { |c| c.my_option = my_value }") if !unsupported_options.nil?
35
-
31
+ return if !db_setup?
32
+
33
+ if !unsupported_options.nil?
34
+ raise ArgumentError.new(
35
+ "You are using the old v1.X.X configuration method for Authlogic. Instead of passing a hash of " +
36
+ "configuration options to acts_as_authentic, pass a block: acts_as_authentic { |c| c.my_option = my_value }"
37
+ )
38
+ end
39
+
36
40
  yield self if block_given?
37
41
  acts_as_authentic_modules.each { |mod| include mod }
38
42
  end
39
-
43
+
40
44
  # Since this part of Authlogic deals with another class, ActiveRecord, we can't just start including things
41
45
  # in ActiveRecord itself. A lot of these module includes need to be triggered by the acts_as_authentic method
42
46
  # call. For example, you don't want to start adding in email validations and what not into a model that has
@@ -54,7 +58,7 @@ module Authlogic
54
58
  modules.uniq!
55
59
  self.acts_as_authentic_modules = modules
56
60
  end
57
-
61
+
58
62
  # This is the same as add_acts_as_authentic_module, except that it removes the module from the list.
59
63
  def remove_acts_as_authentic_module(mod)
60
64
  modules = acts_as_authentic_modules.clone
@@ -71,7 +75,7 @@ module Authlogic
71
75
  false
72
76
  end
73
77
  end
74
-
78
+
75
79
  def rw_config(key, value, default_value = nil, read_value = nil)
76
80
  if value == read_value
77
81
  acts_as_authentic_config.include?(key) ? acts_as_authentic_config[key] : default_value
@@ -82,7 +86,7 @@ module Authlogic
82
86
  value
83
87
  end
84
88
  end
85
-
89
+
86
90
  def first_column_to_exist(*columns_to_check)
87
91
  if db_setup?
88
92
  columns_to_check.each { |column_name| return column_name.to_sym if column_names.include?(column_name.to_s) }
@@ -31,7 +31,7 @@ module Authlogic
31
31
 
32
32
  klass.class_eval do
33
33
  include InstanceMethods
34
- scope :logged_in, lambda{ where("last_request_at > ?", logged_in_timeout.seconds.ago) }
34
+ scope :logged_in, lambda{ where("last_request_at > ? and current_login_at IS NOT NULL", logged_in_timeout.seconds.ago) }
35
35
  scope :logged_out, lambda{ where("last_request_at is NULL or last_request_at <= ?", logged_in_timeout.seconds.ago) }
36
36
  end
37
37
  end
@@ -94,7 +94,7 @@ module Authlogic
94
94
  # manner that they handle that. If you are using the login field and set false for the :case_sensitive option in
95
95
  # validates_uniqueness_of_login_field_options this method will modify the query to look something like:
96
96
  #
97
- # where("#{quoted_table_name}.#{field} LIKE ?", login).first
97
+ # where("LOWER(#{quoted_table_name}.#{login_field}) = ?", login.downcase).first
98
98
  #
99
99
  # If you don't specify this it calls the good old find_by_* method:
100
100
  #
@@ -118,8 +118,7 @@ module Authlogic
118
118
  if sensitivity
119
119
  send("find_by_#{field}", value)
120
120
  else
121
- like_word = ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
122
- where("#{quoted_table_name}.#{field} #{like_word} ?", value.mb_chars).first
121
+ where("LOWER(#{quoted_table_name}.#{field}) = ?", value.mb_chars.downcase).first
123
122
  end
124
123
  end
125
124
  end
@@ -306,7 +306,7 @@ module Authlogic
306
306
  # If the index > 0 then we are using an "transition from" crypto provider.
307
307
  # If the encryptor has a cost and the cost it outdated.
308
308
  # If we aren't using database values
309
- # If we are using database values, only if the password hasnt change so we don't overwrite any changes
309
+ # If we are using database values, only if the password hasn't changed so we don't overwrite any changes
310
310
  def transition_password?(index, encryptor, crypted, check_against_database)
311
311
  (index > 0 || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(send(crypted_password_field)))) &&
312
312
  (!check_against_database || !send("#{crypted_password_field}_changed?"))
@@ -7,7 +7,7 @@ module Authlogic
7
7
  #
8
8
  # Authlogic::CryptoProviders::AES256.key = "my really long and unique key, preferrably a bunch of random characters"
9
9
  #
10
- # My final comment is that this is a strong encryption method, but its main weakness is that its reversible. If you do not need to reverse the hash
10
+ # My final comment is that this is a strong encryption method, but its main weakness is that it's reversible. If you do not need to reverse the hash
11
11
  # then you should consider Sha512 or BCrypt instead.
12
12
  #
13
13
  # Keep your key in a safe place, some even say the key should be stored on a separate server.
@@ -40,4 +40,4 @@ module Authlogic
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -30,7 +30,7 @@ module Authlogic
30
30
  #
31
31
  # You can play around with the cost to get that perfect balance between performance and security.
32
32
  #
33
- # Decided BCrypt is for you? Just insall the bcrypt gem:
33
+ # Decided BCrypt is for you? Just install the bcrypt gem:
34
34
  #
35
35
  # gem install bcrypt-ruby
36
36
  #
@@ -87,4 +87,4 @@ module Authlogic
87
87
  end
88
88
  end
89
89
  end
90
- end
90
+ end
@@ -0,0 +1,80 @@
1
+ begin
2
+ require "scrypt"
3
+ rescue LoadError
4
+ "sudo gem install scrypt"
5
+ end
6
+
7
+ module Authlogic
8
+ module CryptoProviders
9
+ # If you want a stronger hashing algorithm, but would prefer not to use BCrypt, SCrypt is another option.
10
+ # SCrypt is newer and less popular (and so less-tested), but it's designed specifically to avoid a theoretical
11
+ # hardware attack against BCrypt. Just as with BCrypt, you are sacrificing performance relative to SHA2 algorithms,
12
+ # but the increased security may well be worth it. (That performance sacrifice is the exact reason it's much, much
13
+ # harder for an attacker to brute-force your paswords).
14
+ # Decided SCrypt is for you? Just install the bcrypt gem:
15
+ #
16
+ # gem install scrypt
17
+ #
18
+ # Tell acts_as_authentic to use it:
19
+ #
20
+ # acts_as_authentic do |c|
21
+ # c.crypto_provider = Authlogic::CryptoProviders::SCrypt
22
+ # end
23
+ class SCrypt
24
+ class << self
25
+ DEFAULTS = {:key_len => 32, :salt_size => 8, :max_time => 0.2, :max_mem => 1024 * 1024, :max_memfrac => 0.5}
26
+
27
+ attr_writer :key_len, :salt_size, :max_time, :max_mem, :max_memfrac
28
+ # Key length - length in bytes of generated key, from 16 to 512.
29
+ def key_len
30
+ @key_len ||= DEFAULTS[:key_len]
31
+ end
32
+
33
+ # Salt size - size in bytes of random salt, from 8 to 32
34
+ def salt_size
35
+ @salt_size ||= DEFAULTS[:salt_size]
36
+ end
37
+
38
+ # Max time - maximum time spent in computation
39
+ def max_time
40
+ @max_time ||= DEFAULTS[:max_time]
41
+ end
42
+
43
+ # Max memory - maximum memory usage. The minimum is always 1MB
44
+ def max_mem
45
+ @max_mem ||= DEFAULTS[:max_mem]
46
+ end
47
+
48
+ # Max memory fraction - maximum memory out of all available. Always greater than zero and <= 0.5.
49
+ def max_memfrac
50
+ @max_memfrac ||= DEFAULTS[:max_memfrac]
51
+ end
52
+
53
+ # Creates an SCrypt hash for the password passed.
54
+ def encrypt(*tokens)
55
+ ::SCrypt::Password.create(join_tokens(tokens), :key_len => key_len, :salt_size => salt_size, :max_mem => max_mem, :max_memfrac => max_memfrac, :max_time => max_time)
56
+ end
57
+
58
+ # Does the hash match the tokens? Uses the same tokens that were used to encrypt.
59
+ def matches?(hash, *tokens)
60
+ hash = new_from_hash(hash)
61
+ return false if hash.blank?
62
+ hash == join_tokens(tokens)
63
+ end
64
+
65
+ private
66
+ def join_tokens(tokens)
67
+ tokens.flatten.join
68
+ end
69
+
70
+ def new_from_hash(hash)
71
+ begin
72
+ ::SCrypt::Password.new(hash)
73
+ rescue ::SCrypt::Errors::InvalidHash
74
+ return nil
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -3,7 +3,7 @@ require "digest/sha1"
3
3
  module Authlogic
4
4
  module CryptoProviders
5
5
  # This class was made for the users transitioning from restful_authentication. I highly discourage using this
6
- # crypto provider as it inferior to your other options. Please use any other provider offered by Authlogic.
6
+ # crypto provider as it is far inferior to your other options. Please use any other provider offered by Authlogic.
7
7
  class Sha1
8
8
  class << self
9
9
  def join_token
@@ -32,4 +32,4 @@ module Authlogic
32
32
  end
33
33
  end
34
34
  end
35
- end
35
+ end
@@ -27,7 +27,7 @@ module Authlogic
27
27
  class << self
28
28
  attr_accessor :join_token
29
29
 
30
- # The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
30
+ # The number of times to loop through the encryption.
31
31
  def stretches
32
32
  @stretches ||= 20
33
33
  end
@@ -110,6 +110,12 @@ module Authlogic
110
110
  remember_me_for.from_now
111
111
  end
112
112
 
113
+ # Has the cookie expired due to current time being greater than remember_me_until.
114
+ def remember_me_expired?
115
+ return unless remember_me?
116
+ (Time.parse(cookie_credentials[2]) < Time.now)
117
+ end
118
+
113
119
  # If the cookie should be marked as secure (SSL only)
114
120
  def secure
115
121
  return @secure if defined?(@secure)
@@ -164,8 +170,9 @@ module Authlogic
164
170
  end
165
171
 
166
172
  def save_cookie
173
+ remember_me_until_value = "::#{remember_me_until}" if remember_me?
167
174
  controller.cookies[cookie_key] = {
168
- :value => "#{record.persistence_token}::#{record.send(record.class.primary_key)}",
175
+ :value => "#{record.persistence_token}::#{record.send(record.class.primary_key)}#{remember_me_until_value}",
169
176
  :expires => remember_me_until,
170
177
  :secure => secure,
171
178
  :httponly => httponly,
@@ -51,6 +51,7 @@ module Authlogic
51
51
  def persisting?
52
52
  return true if !record.nil?
53
53
  self.attempted_record = nil
54
+ self.remember_me = !cookie_credentials.nil? && !cookie_credentials[2].nil?
54
55
  before_persisting
55
56
  persist
56
57
  ensure_authentication_attempted
@@ -67,4 +68,4 @@ module Authlogic
67
68
  end
68
69
  end
69
70
  end
70
- end
71
+ end
@@ -58,7 +58,11 @@ module Authlogic
58
58
  # Tells you if the record is stale or not. Meaning the record has timed out. This will only return true if you set logout_on_timeout to true in your configuration.
59
59
  # Basically how a bank website works. If you aren't active over a certain period of time your session becomes stale and requires you to log back in.
60
60
  def stale?
61
- !stale_record.nil? || (logout_on_timeout? && record && record.logged_out?)
61
+ if remember_me?
62
+ remember_me_expired?
63
+ else
64
+ !stale_record.nil? || (logout_on_timeout? && record && record.logged_out?)
65
+ end
62
66
  end
63
67
 
64
68
  private
@@ -79,4 +83,4 @@ module Authlogic
79
83
  end
80
84
  end
81
85
  end
82
- end
86
+ end
@@ -14,5 +14,12 @@ module ActsAsAuthenticTest
14
14
  User.acts_as_authentic({})
15
15
  end
16
16
  end
17
+
18
+ def test_acts_as_authentic_with_no_table
19
+ klass = Class.new(ActiveRecord::Base)
20
+ assert_nothing_raised do
21
+ klass.acts_as_authentic
22
+ end
23
+ end
17
24
  end
18
25
  end
@@ -3,41 +3,44 @@ require 'test_helper'
3
3
  module ActsAsAuthenticTest
4
4
  class LoggedInStatusTest < ActiveSupport::TestCase
5
5
  ERROR_MSG = 'Multiple calls to %s should result in different relations'
6
-
6
+
7
7
  def test_logged_in_timeout_config
8
8
  assert_equal 10.minutes.to_i, User.logged_in_timeout
9
9
  assert_equal 10.minutes.to_i, Employee.logged_in_timeout
10
-
10
+
11
11
  User.logged_in_timeout = 1.hour
12
12
  assert_equal 1.hour.to_i, User.logged_in_timeout
13
13
  User.logged_in_timeout 10.minutes
14
14
  assert_equal 10.minutes.to_i, User.logged_in_timeout
15
15
  end
16
-
16
+
17
17
  def test_named_scope_logged_in
18
- # Testing that the scope returned differs, because the time it was called should be
19
- # slightly different. This is an attempt to make sure the scope is lambda wrapped
18
+ # Testing that the scope returned differs, because the time it was called should be
19
+ # slightly different. This is an attempt to make sure the scope is lambda wrapped
20
20
  # so that it is re-evaluated every time its called. My biggest concern is that the
21
21
  # test happens so fast that the test fails... I just don't know a better way to test it!
22
22
  assert User.logged_in.where_values != User.logged_in.where_values, ERROR_MSG % '#logged_in'
23
-
23
+
24
24
  assert_equal 0, User.logged_in.count
25
- User.first.update_attribute(:last_request_at, Time.now)
25
+ user = User.first
26
+ user.last_request_at = Time.now
27
+ user.current_login_at = Time.now
28
+ user.save!
26
29
  assert_equal 1, User.logged_in.count
27
30
  end
28
-
31
+
29
32
  def test_named_scope_logged_out
30
- # Testing that the scope returned differs, because the time it was called should be
31
- # slightly different. This is an attempt to make sure the scope is lambda wrapped
33
+ # Testing that the scope returned differs, because the time it was called should be
34
+ # slightly different. This is an attempt to make sure the scope is lambda wrapped
32
35
  # so that it is re-evaluated every time its called. My biggest concern is that the
33
36
  # test happens so fast that the test fails... I just don't know a better way to test it!
34
37
  assert User.logged_in.where_values != User.logged_out.where_values, ERROR_MSG % '#logged_out'
35
-
38
+
36
39
  assert_equal 2, User.logged_out.count
37
40
  User.first.update_attribute(:last_request_at, Time.now)
38
41
  assert_equal 1, User.logged_out.count
39
42
  end
40
-
43
+
41
44
  def test_logged_in_logged_out
42
45
  u = User.first
43
46
  assert !u.logged_in?
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module CryptoProviderTest
4
- class BCrpytTest < ActiveSupport::TestCase
4
+ class BCryptTest < ActiveSupport::TestCase
5
5
  def test_encrypt
6
6
  assert Authlogic::CryptoProviders::BCrypt.encrypt("mypass")
7
7
  end
@@ -11,4 +11,4 @@ module CryptoProviderTest
11
11
  assert Authlogic::CryptoProviders::BCrypt.matches?(hash, "mypass")
12
12
  end
13
13
  end
14
- end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ module CryptoProviderTest
4
+ class SCryptTest < ActiveSupport::TestCase
5
+ def test_encrypt
6
+ assert Authlogic::CryptoProviders::SCrypt.encrypt("mypass")
7
+ end
8
+
9
+ def test_matches
10
+ hash = Authlogic::CryptoProviders::SCrypt.encrypt("mypass")
11
+ assert Authlogic::CryptoProviders::SCrypt.matches?(hash, "mypass")
12
+ end
13
+ end
14
+ end
@@ -116,6 +116,19 @@ module SessionTest
116
116
  assert_equal ben, session.record
117
117
  end
118
118
 
119
+ def test_remember_me_expired
120
+ ben = users(:ben)
121
+ session = UserSession.new(ben)
122
+ session.remember_me = true
123
+ assert session.save
124
+ assert !session.remember_me_expired?
125
+
126
+ session = UserSession.new(ben)
127
+ session.remember_me = false
128
+ assert session.save
129
+ assert !session.remember_me_expired?
130
+ end
131
+
119
132
  def test_after_save_save_cookie
120
133
  ben = users(:ben)
121
134
  session = UserSession.new(ben)
@@ -123,6 +136,14 @@ module SessionTest
123
136
  assert_equal "#{ben.persistence_token}::#{ben.id}", controller.cookies["user_credentials"]
124
137
  end
125
138
 
139
+ def test_after_save_save_cookie_with_remember_me
140
+ ben = users(:ben)
141
+ session = UserSession.new(ben)
142
+ session.remember_me = true
143
+ assert session.save
144
+ assert_equal "#{ben.persistence_token}::#{ben.id}::#{session.remember_me_until}", controller.cookies["user_credentials"]
145
+ end
146
+
126
147
  def test_after_destroy_destroy_cookie
127
148
  ben = users(:ben)
128
149
  set_cookie_for(ben)
@@ -17,5 +17,16 @@ module SessionTest
17
17
  def test_persisting
18
18
  # tested thoroughly in test_find
19
19
  end
20
+
21
+ def test_should_set_remember_me_on_the_next_request
22
+ ben = users(:ben)
23
+ session = UserSession.new(ben)
24
+ session.remember_me = true
25
+ assert !UserSession.remember_me
26
+ assert session.save
27
+ assert session.remember_me?
28
+ session = UserSession.find(ben)
29
+ assert session.remember_me?
30
+ end
20
31
  end
21
- end
32
+ end
@@ -38,6 +38,34 @@ module SessionTest
38
38
 
39
39
  UserSession.logout_on_timeout = false
40
40
  end
41
+
42
+ def test_should_be_stale_with_expired_remember_date
43
+ UserSession.logout_on_timeout = true
44
+ UserSession.remember_me = true
45
+ UserSession.remember_me_for = 3.months
46
+ ben = users(:ben)
47
+ assert ben.save
48
+ session = UserSession.new(ben)
49
+ assert session.save
50
+ Timecop.freeze(Time.now + 4.month)
51
+ assert session.persisting?
52
+ assert session.stale?
53
+ UserSession.remember_me = false
54
+ end
55
+
56
+ def test_should_not_be_stale_with_valid_remember_date
57
+ UserSession.logout_on_timeout = true # Default is 10.minutes
58
+ UserSession.remember_me = true
59
+ UserSession.remember_me_for = 3.months
60
+ ben = users(:ben)
61
+ assert ben.save
62
+ session = UserSession.new(ben)
63
+ assert session.save
64
+ Timecop.freeze(Time.now + 2.months)
65
+ assert session.persisting?
66
+ assert !session.stale?
67
+ UserSession.remember_me = false
68
+ end
41
69
 
42
70
  def test_successful_login
43
71
  UserSession.logout_on_timeout = true
@@ -49,4 +77,4 @@ module SessionTest
49
77
  end
50
78
  end
51
79
  end
52
- end
80
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,7 @@ require "test/unit"
2
2
  require "rubygems"
3
3
  require "active_record"
4
4
  require "active_record/fixtures"
5
+ require "timecop"
5
6
 
6
7
  #ActiveRecord::Schema.verbose = false
7
8
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-13 00:00:00.000000000 Z
12
+ date: 2012-12-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: scrypt
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  - !ruby/object:Gem::Dependency
79
95
  name: sqlite3
80
96
  requirement: !ruby/object:Gem::Requirement
@@ -91,6 +107,22 @@ dependencies:
91
107
  - - ! '>='
92
108
  - !ruby/object:Gem::Version
93
109
  version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: timecop
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
94
126
  description: A clean, simple, and unobtrusive ruby authentication solution.
95
127
  email:
96
128
  - bjohnson@binarylogic.com
@@ -104,10 +136,7 @@ files:
104
136
  - LICENSE
105
137
  - README.rdoc
106
138
  - Rakefile
107
- - VERSION.yml
108
139
  - authlogic.gemspec
109
- - generators/session/session_generator.rb
110
- - generators/session/templates/session.rb
111
140
  - init.rb
112
141
  - lib/authlogic.rb
113
142
  - lib/authlogic/acts_as_authentic/base.rb
@@ -131,6 +160,7 @@ files:
131
160
  - lib/authlogic/crypto_providers/aes256.rb
132
161
  - lib/authlogic/crypto_providers/bcrypt.rb
133
162
  - lib/authlogic/crypto_providers/md5.rb
163
+ - lib/authlogic/crypto_providers/scrypt.rb
134
164
  - lib/authlogic/crypto_providers/sha1.rb
135
165
  - lib/authlogic/crypto_providers/sha256.rb
136
166
  - lib/authlogic/crypto_providers/sha512.rb
@@ -168,10 +198,6 @@ files:
168
198
  - lib/authlogic/test_case/mock_logger.rb
169
199
  - lib/authlogic/test_case/mock_request.rb
170
200
  - lib/authlogic/test_case/rails_request_adapter.rb
171
- - lib/generators/authlogic/USAGE
172
- - lib/generators/authlogic/session_generator.rb
173
- - lib/generators/authlogic/templates/session.rb
174
- - rails/init.rb
175
201
  - shoulda_macros/authlogic.rb
176
202
  - test/acts_as_authentic_test/base_test.rb
177
203
  - test/acts_as_authentic_test/email_test.rb
@@ -187,6 +213,7 @@ files:
187
213
  - test/authenticates_many_test.rb
188
214
  - test/crypto_provider_test/aes256_test.rb
189
215
  - test/crypto_provider_test/bcrypt_test.rb
216
+ - test/crypto_provider_test/scrypt_test.rb
190
217
  - test/crypto_provider_test/sha1_test.rb
191
218
  - test/crypto_provider_test/sha256_test.rb
192
219
  - test/crypto_provider_test/sha512_test.rb
@@ -266,6 +293,7 @@ test_files:
266
293
  - test/authenticates_many_test.rb
267
294
  - test/crypto_provider_test/aes256_test.rb
268
295
  - test/crypto_provider_test/bcrypt_test.rb
296
+ - test/crypto_provider_test/scrypt_test.rb
269
297
  - test/crypto_provider_test/sha1_test.rb
270
298
  - test/crypto_provider_test/sha256_test.rb
271
299
  - test/crypto_provider_test/sha512_test.rb
data/VERSION.yml DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 3
3
- :minor: 1
4
- :patch: 2
5
- :build:
@@ -1,9 +0,0 @@
1
- class SessionGenerator < Rails::Generator::NamedBase
2
- def manifest
3
- record do |m|
4
- m.class_collisions class_name
5
- m.directory File.join('app/models', class_path)
6
- m.template 'session.rb', File.join('app/models', class_path, "#{file_name}.rb")
7
- end
8
- end
9
- end
@@ -1,2 +0,0 @@
1
- class <%= class_name %> < Authlogic::Session::Base
2
- end
@@ -1,8 +0,0 @@
1
- Description:
2
- Create session model that represents the user’s current session.
3
-
4
- Example:
5
- rails generate authlogic:session UserSession
6
-
7
- This will create:
8
- Model UserSession in app/models directory
@@ -1,14 +0,0 @@
1
- module Authlogic
2
- class SessionGenerator < Rails::Generators::Base
3
- source_root File.expand_path('../templates', __FILE__)
4
- argument :session_class_name, :type => :string, :default => "Session"
5
-
6
- def self.banner
7
- "rails generate authlogic:#{generator_name} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]"
8
- end
9
-
10
- def generate_session
11
- template "session.rb", "app/models/#{session_class_name.underscore}.rb"
12
- end
13
- end
14
- end
@@ -1,2 +0,0 @@
1
- class <%= session_class_name %> < Authlogic::Session::Base
2
- end
data/rails/init.rb DELETED
@@ -1 +0,0 @@
1
- require "authlogic"