authlogic 3.4.6 → 4.2.0

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.
Files changed (140) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +13 -0
  3. data/.github/triage.md +87 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop.yml +127 -0
  6. data/.rubocop_todo.yml +65 -0
  7. data/.travis.yml +18 -10
  8. data/CHANGELOG.md +156 -6
  9. data/CONTRIBUTING.md +71 -3
  10. data/Gemfile +2 -2
  11. data/README.md +386 -0
  12. data/Rakefile +13 -7
  13. data/UPGRADING.md +22 -0
  14. data/authlogic.gemspec +33 -22
  15. data/lib/authlogic.rb +60 -52
  16. data/lib/authlogic/acts_as_authentic/base.rb +40 -26
  17. data/lib/authlogic/acts_as_authentic/email.rb +96 -32
  18. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +36 -12
  19. data/lib/authlogic/acts_as_authentic/login.rb +114 -49
  20. data/lib/authlogic/acts_as_authentic/magic_columns.rb +17 -6
  21. data/lib/authlogic/acts_as_authentic/password.rb +296 -139
  22. data/lib/authlogic/acts_as_authentic/perishable_token.rb +34 -20
  23. data/lib/authlogic/acts_as_authentic/persistence_token.rb +20 -24
  24. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  25. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +68 -23
  26. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +128 -85
  27. data/lib/authlogic/acts_as_authentic/single_access_token.rb +41 -25
  28. data/lib/authlogic/acts_as_authentic/validations_scope.rb +8 -8
  29. data/lib/authlogic/authenticates_many/association.rb +22 -14
  30. data/lib/authlogic/authenticates_many/base.rb +35 -16
  31. data/lib/authlogic/config.rb +10 -10
  32. data/lib/authlogic/controller_adapters/abstract_adapter.rb +40 -12
  33. data/lib/authlogic/controller_adapters/rack_adapter.rb +15 -8
  34. data/lib/authlogic/controller_adapters/rails_adapter.rb +42 -22
  35. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +3 -3
  36. data/lib/authlogic/crypto_providers.rb +91 -0
  37. data/lib/authlogic/crypto_providers/aes256.rb +42 -14
  38. data/lib/authlogic/crypto_providers/bcrypt.rb +35 -20
  39. data/lib/authlogic/crypto_providers/md5.rb +11 -9
  40. data/lib/authlogic/crypto_providers/scrypt.rb +26 -13
  41. data/lib/authlogic/crypto_providers/sha1.rb +14 -8
  42. data/lib/authlogic/crypto_providers/sha256.rb +16 -12
  43. data/lib/authlogic/crypto_providers/sha512.rb +8 -24
  44. data/lib/authlogic/crypto_providers/wordpress.rb +44 -15
  45. data/lib/authlogic/i18n.rb +33 -20
  46. data/lib/authlogic/i18n/translator.rb +1 -1
  47. data/lib/authlogic/random.rb +12 -29
  48. data/lib/authlogic/regex.rb +59 -27
  49. data/lib/authlogic/session/activation.rb +36 -23
  50. data/lib/authlogic/session/active_record_trickery.rb +13 -10
  51. data/lib/authlogic/session/base.rb +20 -8
  52. data/lib/authlogic/session/brute_force_protection.rb +87 -56
  53. data/lib/authlogic/session/callbacks.rb +99 -49
  54. data/lib/authlogic/session/cookies.rb +128 -59
  55. data/lib/authlogic/session/existence.rb +29 -19
  56. data/lib/authlogic/session/foundation.rb +70 -16
  57. data/lib/authlogic/session/http_auth.rb +39 -31
  58. data/lib/authlogic/session/id.rb +27 -15
  59. data/lib/authlogic/session/klass.rb +17 -13
  60. data/lib/authlogic/session/magic_columns.rb +78 -59
  61. data/lib/authlogic/session/magic_states.rb +50 -27
  62. data/lib/authlogic/session/params.rb +79 -50
  63. data/lib/authlogic/session/password.rb +197 -118
  64. data/lib/authlogic/session/perishable_token.rb +12 -6
  65. data/lib/authlogic/session/persistence.rb +20 -14
  66. data/lib/authlogic/session/priority_record.rb +20 -16
  67. data/lib/authlogic/session/scopes.rb +63 -33
  68. data/lib/authlogic/session/session.rb +40 -25
  69. data/lib/authlogic/session/timeout.rb +51 -34
  70. data/lib/authlogic/session/unauthorized_record.rb +24 -18
  71. data/lib/authlogic/session/validation.rb +32 -21
  72. data/lib/authlogic/test_case.rb +123 -35
  73. data/lib/authlogic/test_case/mock_controller.rb +14 -13
  74. data/lib/authlogic/test_case/mock_cookie_jar.rb +14 -5
  75. data/lib/authlogic/test_case/mock_logger.rb +1 -1
  76. data/lib/authlogic/test_case/mock_request.rb +9 -4
  77. data/lib/authlogic/test_case/rails_request_adapter.rb +8 -7
  78. data/lib/authlogic/version.rb +21 -0
  79. data/test/acts_as_authentic_test/base_test.rb +1 -1
  80. data/test/acts_as_authentic_test/email_test.rb +80 -63
  81. data/test/acts_as_authentic_test/logged_in_status_test.rb +14 -8
  82. data/test/acts_as_authentic_test/login_test.rb +91 -49
  83. data/test/acts_as_authentic_test/magic_columns_test.rb +13 -13
  84. data/test/acts_as_authentic_test/password_test.rb +82 -60
  85. data/test/acts_as_authentic_test/perishable_token_test.rb +31 -25
  86. data/test/acts_as_authentic_test/persistence_token_test.rb +9 -5
  87. data/test/acts_as_authentic_test/restful_authentication_test.rb +18 -9
  88. data/test/acts_as_authentic_test/session_maintenance_test.rb +86 -22
  89. data/test/acts_as_authentic_test/single_access_test.rb +15 -15
  90. data/test/adapter_test.rb +21 -0
  91. data/test/authenticates_many_test.rb +26 -11
  92. data/test/config_test.rb +9 -9
  93. data/test/crypto_provider_test/aes256_test.rb +3 -3
  94. data/test/crypto_provider_test/bcrypt_test.rb +1 -1
  95. data/test/crypto_provider_test/scrypt_test.rb +2 -2
  96. data/test/crypto_provider_test/sha1_test.rb +4 -4
  97. data/test/crypto_provider_test/sha256_test.rb +2 -2
  98. data/test/crypto_provider_test/sha512_test.rb +3 -3
  99. data/test/crypto_provider_test/wordpress_test.rb +24 -0
  100. data/test/gemfiles/Gemfile.rails-4.2.x +2 -2
  101. data/test/gemfiles/Gemfile.rails-5.0.x +6 -0
  102. data/test/gemfiles/Gemfile.rails-5.1.x +6 -0
  103. data/test/gemfiles/Gemfile.rails-5.2.x +6 -0
  104. data/test/gemfiles/Gemfile.rails-master +6 -0
  105. data/test/i18n_test.rb +9 -9
  106. data/test/libs/affiliate.rb +2 -2
  107. data/test/libs/company.rb +4 -4
  108. data/test/libs/employee.rb +2 -2
  109. data/test/libs/employee_session.rb +1 -1
  110. data/test/libs/ldaper.rb +1 -1
  111. data/test/libs/project.rb +1 -1
  112. data/test/libs/user_session.rb +2 -2
  113. data/test/random_test.rb +9 -38
  114. data/test/session_test/activation_test.rb +7 -7
  115. data/test/session_test/active_record_trickery_test.rb +9 -6
  116. data/test/session_test/brute_force_protection_test.rb +26 -21
  117. data/test/session_test/callbacks_test.rb +10 -4
  118. data/test/session_test/cookies_test.rb +54 -20
  119. data/test/session_test/existence_test.rb +45 -23
  120. data/test/session_test/foundation_test.rb +17 -1
  121. data/test/session_test/http_auth_test.rb +11 -12
  122. data/test/session_test/id_test.rb +3 -3
  123. data/test/session_test/klass_test.rb +2 -2
  124. data/test/session_test/magic_columns_test.rb +15 -17
  125. data/test/session_test/magic_states_test.rb +17 -19
  126. data/test/session_test/params_test.rb +26 -20
  127. data/test/session_test/password_test.rb +11 -12
  128. data/test/session_test/perishability_test.rb +5 -5
  129. data/test/session_test/persistence_test.rb +4 -3
  130. data/test/session_test/scopes_test.rb +15 -9
  131. data/test/session_test/session_test.rb +7 -6
  132. data/test/session_test/timeout_test.rb +16 -14
  133. data/test/session_test/unauthorized_record_test.rb +3 -3
  134. data/test/session_test/validation_test.rb +5 -5
  135. data/test/test_helper.rb +115 -49
  136. metadata +107 -36
  137. data/README.rdoc +0 -232
  138. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  139. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
@@ -1,22 +1,25 @@
1
1
  require "digest/sha2"
2
2
 
3
3
  module Authlogic
4
- # The acts_as_authentic method has a crypto_provider option. This allows you to use any type of encryption you like.
5
- # Just create a class with a class level encrypt and matches? method. See example below.
4
+ # The acts_as_authentic method has a crypto_provider option. This allows you
5
+ # to use any type of encryption you like. Just create a class with a class
6
+ # level encrypt and matches? method. See example below.
6
7
  #
7
8
  # === Example
8
9
  #
9
10
  # class MyAwesomeEncryptionMethod
10
11
  # def self.encrypt(*tokens)
11
- # # the tokens passed will be an array of objects, what type of object is irrelevant,
12
- # # just do what you need to do with them and return a single encrypted string.
13
- # # for example, you will most likely join all of the objects into a single string and then encrypt that string
12
+ # # the tokens passed will be an array of objects, what type of object
13
+ # # is irrelevant, just do what you need to do with them and return a
14
+ # # single encrypted string. for example, you will most likely join all
15
+ # # of the objects into a single string and then encrypt that string
14
16
  # end
15
17
  #
16
18
  # def self.matches?(crypted, *tokens)
17
- # # return true if the crypted string matches the tokens.
18
- # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
19
- # # encrypt the tokens and make sure it matches the crypted string, its up to you
19
+ # # return true if the crypted string matches the tokens. Depending on
20
+ # # your algorithm you might decrypt the string then compare it to the
21
+ # # token, or you might encrypt the tokens and make sure it matches the
22
+ # # crypted string, its up to you.
20
23
  # end
21
24
  # end
22
25
  module CryptoProviders
@@ -26,21 +29,22 @@ module Authlogic
26
29
  class Sha256
27
30
  class << self
28
31
  attr_accessor :join_token
29
-
32
+
30
33
  # The number of times to loop through the encryption.
31
34
  def stretches
32
35
  @stretches ||= 20
33
36
  end
34
37
  attr_writer :stretches
35
-
38
+
36
39
  # Turns your raw password into a Sha256 hash.
37
40
  def encrypt(*tokens)
38
41
  digest = tokens.flatten.join(join_token)
39
42
  stretches.times { digest = Digest::SHA256.hexdigest(digest) }
40
43
  digest
41
44
  end
42
-
43
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
45
+
46
+ # Does the crypted password match the tokens? Uses the same tokens that
47
+ # were used to encrypt.
44
48
  def matches?(crypted, *tokens)
45
49
  encrypt(*tokens) == crypted
46
50
  end
@@ -1,24 +1,6 @@
1
1
  require "digest/sha2"
2
2
 
3
3
  module Authlogic
4
- # The acts_as_authentic method has a crypto_provider option. This allows you to use any type of encryption you like.
5
- # Just create a class with a class level encrypt and matches? method. See example below.
6
- #
7
- # === Example
8
- #
9
- # class MyAwesomeEncryptionMethod
10
- # def self.encrypt(*tokens)
11
- # # the tokens passed will be an array of objects, what type of object is irrelevant,
12
- # # just do what you need to do with them and return a single encrypted string.
13
- # # for example, you will most likely join all of the objects into a single string and then encrypt that string
14
- # end
15
- #
16
- # def self.matches?(crypted, *tokens)
17
- # # return true if the crypted string matches the tokens.
18
- # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
19
- # # encrypt the tokens and make sure it matches the crypted string, its up to you
20
- # end
21
- # end
22
4
  module CryptoProviders
23
5
  # = Sha512
24
6
  #
@@ -26,25 +8,27 @@ module Authlogic
26
8
  class Sha512
27
9
  class << self
28
10
  attr_accessor :join_token
29
-
30
- # The number of times to loop through the encryption. This is twenty because that is what restful_authentication defaults to.
11
+
12
+ # The number of times to loop through the encryption. This is twenty
13
+ # because that is what restful_authentication defaults to.
31
14
  def stretches
32
15
  @stretches ||= 20
33
16
  end
34
17
  attr_writer :stretches
35
-
18
+
36
19
  # Turns your raw password into a Sha512 hash.
37
20
  def encrypt(*tokens)
38
21
  digest = tokens.flatten.join(join_token)
39
22
  stretches.times { digest = Digest::SHA512.hexdigest(digest) }
40
23
  digest
41
24
  end
42
-
43
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
25
+
26
+ # Does the crypted password match the tokens? Uses the same tokens that
27
+ # were used to encrypt.
44
28
  def matches?(crypted, *tokens)
45
29
  encrypt(*tokens) == crypted
46
30
  end
47
31
  end
48
32
  end
49
33
  end
50
- end
34
+ end
@@ -1,39 +1,68 @@
1
- require 'digest/md5'
1
+ require "digest/md5"
2
+
3
+ ::ActiveSupport::Deprecation.warn(
4
+ <<-EOS,
5
+ authlogic/crypto_providers/wordpress.rb is deprecated without replacement.
6
+ Yes, the entire file. Don't `require` it. Let us know ASAP if you are still
7
+ using it.
8
+
9
+ Reasons for deprecation: This file is not autoloaded by
10
+ `authlogic/crypto_providers.rb`. It's not documented. There are no tests.
11
+ So, it's likely used by a *very* small number of people, if any. It's never
12
+ had any contributions except by its original author, Jeffry Degrande, in
13
+ 2009. It is unclear why it should live in the main authlogic codebase. It
14
+ could be in a separate gem, authlogic-wordpress, or it could just live in
15
+ Jeffry's codebase, if he still even needs it, in 2018, nine years later.
16
+ EOS
17
+ caller(1)
18
+ )
19
+
2
20
  module Authlogic
3
21
  module CryptoProviders
22
+ # Crypto provider to transition from wordpress user accounts. Written by
23
+ # Jeffry Degrande in 2009. First released in 2.1.3.
24
+ #
25
+ # Problems:
26
+ #
27
+ # - There are no tests.
28
+ # - We can't even figure out how to run this without it crashing.
29
+ # - Presumably it implements some spec, but it doesn't mention which.
30
+ # - It is not documented anywhere.
31
+ # - There is no PR associated with this, and no discussion about it could be found.
32
+ #
4
33
  class Wordpress
5
34
  class << self
6
- ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
35
+ ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".freeze
7
36
 
8
37
  def matches?(crypted, *tokens)
9
- stretches = 1 << ITOA64.index(crypted[3,1])
10
- plain, salt = *tokens
11
- hashed = Digest::MD5.digest(salt+plain)
12
- stretches.times do |i|
13
- hashed = Digest::MD5.digest(hashed+plain)
38
+ stretches = 1 << ITOA64.index(crypted[3, 1])
39
+ plain, salt = *tokens
40
+ hashed = Digest::MD5.digest(salt + plain)
41
+ stretches.times do
42
+ hashed = Digest::MD5.digest(hashed + plain)
14
43
  end
15
- crypted[0,12]+encode_64(hashed, 16) == crypted
44
+ crypted[0, 12] + encode_64(hashed, 16) == crypted
16
45
  end
17
46
 
18
47
  def encode_64(input, length)
19
- output = ""
48
+ output = ""
20
49
  i = 0
21
50
  while i < length
22
- value = input[i]
23
- i+=1
51
+ value = input[i]
52
+ i += 1
24
53
  break if value.nil?
25
54
  output += ITOA64[value & 0x3f, 1]
26
55
  value |= input[i] << 8 if i < length
27
56
  output += ITOA64[(value >> 6) & 0x3f, 1]
28
57
 
29
- i+=1
58
+ i += 1
30
59
  break if i >= length
31
60
  value |= input[i] << 16 if i < length
32
- output += ITOA64[(value >> 12) & 0x3f,1]
61
+ output += ITOA64[(value >> 12) & 0x3f, 1]
33
62
 
34
- i+=1
63
+ i += 1
35
64
  break if i >= length
36
- output += ITOA64[(value >> 18) & 0x3f,1]
65
+ output += ITOA64[(value >> 18) & 0x3f, 1]
37
66
  end
38
67
  output
39
68
  end
@@ -1,38 +1,48 @@
1
1
  require "authlogic/i18n/translator"
2
2
 
3
3
  module Authlogic
4
- # This class allows any message in Authlogic to use internationalization. In earlier versions of Authlogic each message was translated via configuration.
5
- # This cluttered up the configuration and cluttered up Authlogic. So all translation has been extracted out into this class. Now all messages pass through
6
- # this class, making it much easier to implement in I18n library / plugin you want. Use this as a layer that sits between Authlogic and whatever I18n
7
- # library you want to use.
4
+ # This class allows any message in Authlogic to use internationalization. In
5
+ # earlier versions of Authlogic each message was translated via configuration.
6
+ # This cluttered up the configuration and cluttered up Authlogic. So all
7
+ # translation has been extracted out into this class. Now all messages pass
8
+ # through this class, making it much easier to implement in I18n library /
9
+ # plugin you want. Use this as a layer that sits between Authlogic and
10
+ # whatever I18n library you want to use.
8
11
  #
9
- # By default this uses the rails I18n library, if it exists. If it doesnt exist it just returns the default english message. The Authlogic I18n class
10
- # works EXACTLY like the rails I18n class. This is because the arguments are delegated to this class.
12
+ # By default this uses the rails I18n library, if it exists. If it doesn't
13
+ # exist it just returns the default English message. The Authlogic I18n class
14
+ # works EXACTLY like the rails I18n class. This is because the arguments are
15
+ # delegated to this class.
11
16
  #
12
17
  # Here is how all messages are translated internally with Authlogic:
13
18
  #
14
19
  # Authlogic::I18n.t('error_messages.password_invalid', :default => "is invalid")
15
20
  #
16
- # If you use a different I18n library just replace the build-in I18n::Translator class with your own. For example:
21
+ # If you use a different I18n library just replace the build-in
22
+ # I18n::Translator class with your own. For example:
17
23
  #
18
24
  # class MyAuthlogicI18nTranslator
19
25
  # def translate(key, options = {})
20
- # # you will have key which will be something like: "error_messages.password_invalid"
21
- # # you will also have options[:default], which will be the default english version of the message
26
+ # # you will have key which will be something like:
27
+ # # "error_messages.password_invalid"
28
+ # # you will also have options[:default], which will be the default
29
+ # # English version of the message
22
30
  # # do whatever you want here with the arguments passed to you.
23
31
  # end
24
32
  # end
25
- #
33
+ #
26
34
  # Authlogic::I18n.translator = MyAuthlogicI18nTranslator.new
27
35
  #
28
- # That it's! Here is a complete list of the keys that are passed. Just define these however you wish:
36
+ # That it's! Here is a complete list of the keys that are passed. Just define
37
+ # these however you wish:
29
38
  #
30
39
  # authlogic:
31
40
  # error_messages:
32
41
  # login_blank: can not be blank
33
42
  # login_not_found: is not valid
34
- # login_invalid: should use only letters, numbers, spaces, and .-_@ please.
35
- # consecutive_failed_logins_limit_exceeded: Consecutive failed logins limit exceeded, account is disabled.
43
+ # login_invalid: should use only letters, numbers, spaces, and .-_@+ please.
44
+ # consecutive_failed_logins_limit_exceeded: >
45
+ # Consecutive failed logins limit exceeded, account is disabled.
36
46
  # email_invalid: should look like an email address.
37
47
  # email_invalid_international: should look like an international email address.
38
48
  # password_blank: can not be blank
@@ -42,6 +52,7 @@ module Authlogic
42
52
  # not_approved: Your account is not approved
43
53
  # no_authentication_details: You did not provide any details for authentication.
44
54
  # general_credentials_error: Login/Password combination is not valid
55
+ # session_invalid: Your session is invalid and has the following errors:
45
56
  # models:
46
57
  # user_session: UserSession (or whatever name you are using)
47
58
  # attributes:
@@ -53,31 +64,33 @@ module Authlogic
53
64
  module I18n
54
65
  @@scope = :authlogic
55
66
  @@translator = nil
56
-
67
+
57
68
  class << self
58
69
  # Returns the current scope. Defaults to :authlogic
59
70
  def scope
60
71
  @@scope
61
72
  end
62
-
73
+
63
74
  # Sets the current scope. Used to set a custom scope.
64
75
  def scope=(scope)
65
76
  @@scope = scope
66
77
  end
67
-
78
+
68
79
  # Returns the current translator. Defaults to +Translator+.
69
80
  def translator
70
81
  @@translator ||= Translator.new
71
82
  end
72
-
83
+
73
84
  # Sets the current translator. Used to set a custom translator.
74
85
  def translator=(translator)
75
86
  @@translator = translator
76
87
  end
77
-
78
- # All message translation is passed to this method. The first argument is the key for the message. The second is options, see the rails I18n library for a list of options used.
88
+
89
+ # All message translation is passed to this method. The first argument is
90
+ # the key for the message. The second is options, see the rails I18n
91
+ # library for a list of options used.
79
92
  def translate(key, options = {})
80
- translator.translate key, { :scope => I18n.scope }.merge(options)
93
+ translator.translate key, { scope: I18n.scope }.merge(options)
81
94
  end
82
95
  alias :t :translate
83
96
  end
@@ -1,7 +1,7 @@
1
1
  module Authlogic
2
2
  module I18n
3
3
  class Translator
4
- # If the I18n gem is present, calls +I18n.translate+ passing all
4
+ # If the I18n gem is present, calls +I18n.translate+ passing all
5
5
  # arguments, else returns +options[:default]+.
6
6
  def translate(key, options = {})
7
7
  if defined?(::I18n)
@@ -1,33 +1,16 @@
1
+ require "securerandom"
2
+
1
3
  module Authlogic
2
- # Handles generating random strings. If SecureRandom is installed it will default to this and use it instead. SecureRandom comes with ActiveSupport.
3
- # So if you are using this in a rails app you should have this library.
4
+ # Generates random strings using ruby's SecureRandom library.
4
5
  module Random
5
- extend self
6
-
7
- SecureRandom = (defined?(::SecureRandom) && ::SecureRandom) || (defined?(::ActiveSupport::SecureRandom) && ::ActiveSupport::SecureRandom)
8
-
9
- if SecureRandom
10
- def hex_token
11
- SecureRandom.hex(64)
12
- end
13
-
14
- def friendly_token
15
- # use base64url as defined by RFC4648
16
- SecureRandom.base64(15).tr('+/=', '').strip.delete("\n")
17
- end
18
- else
19
- def hex_token
20
- Authlogic::CryptoProviders::Sha512.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
21
- end
22
-
23
- FRIENDLY_CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
24
-
25
- def friendly_token
26
- newpass = ""
27
- 1.upto(20) { |i| newpass << FRIENDLY_CHARS[rand(FRIENDLY_CHARS.size-1)] }
28
- newpass
29
- end
6
+ def self.hex_token
7
+ SecureRandom.hex(64)
8
+ end
9
+
10
+ # Returns a string in base64url format as defined by RFC-3548 and RFC-4648.
11
+ # We call this a "friendly" token because it is short and safe for URLs.
12
+ def self.friendly_token
13
+ SecureRandom.urlsafe_base64(15)
30
14
  end
31
-
32
15
  end
33
- end
16
+ end
@@ -1,47 +1,79 @@
1
- #encoding: utf-8
2
1
  module Authlogic
3
- # This is a module the contains regular expressions used throughout Authlogic. The point of extracting
4
- # them out into their own module is to make them easily available to you for other uses. Ex:
2
+ # This is a module the contains regular expressions used throughout Authlogic.
3
+ # The point of extracting them out into their own module is to make them
4
+ # easily available to you for other uses. Ex:
5
5
  #
6
6
  # validates_format_of :my_email_field, :with => Authlogic::Regex.email
7
7
  module Regex
8
- # A general email regular expression. It allows top level domains (TLD) to be from 2 - 13 in length.
9
- # The decisions behind this regular expression were made by analyzing the list of top-level domains
10
- # maintained by IANA and by reading this website: http://www.regular-expressions.info/email.html,
11
- # which is an excellent resource for regular expressions.
12
- def self.email
13
- @email_regex ||= begin
14
- email_name_regex = '[A-Z0-9_\.&%\+\-\']+'
15
- domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
16
- domain_tld_regex = '(?:[A-Z]{2,13})'
17
- /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
18
- end
19
- end
8
+ # A general email regular expression. It allows top level domains (TLD) to
9
+ # be from 2 - 24 in length. The decisions behind this regular expression
10
+ # were made by analyzing the list of top-level domains maintained by IANA
11
+ # and by reading this website:
12
+ # http://www.regular-expressions.info/email.html, which is an excellent
13
+ # resource for regular expressions.
14
+ EMAIL = /
15
+ \A
16
+ [A-Z0-9_.&%+\-']+ # mailbox
17
+ @
18
+ (?:[A-Z0-9\-]+\.)+ # subdomains
19
+ (?:[A-Z]{2,25}) # TLD
20
+ \z
21
+ /ix
20
22
 
21
- # A draft regular expression for internationalized email addresses.
22
- # Given that the standard may be in flux, this simply emulates @email_regex but rather than
23
- # allowing specific characters for each part, it instead disallows the complement set of characters:
23
+ # A draft regular expression for internationalized email addresses. Given
24
+ # that the standard may be in flux, this simply emulates @email_regex but
25
+ # rather than allowing specific characters for each part, it instead
26
+ # disallows the complement set of characters:
27
+ #
24
28
  # - email_name_regex disallows: @[]^ !"#$()*,/:;<=>?`{|}~\ and control characters
25
29
  # - domain_head_regex disallows: _%+ and all characters in email_name_regex
26
30
  # - domain_tld_regex disallows: 0123456789- and all characters in domain_head_regex
31
+ #
27
32
  # http://en.wikipedia.org/wiki/Email_address#Internationalization
28
33
  # http://tools.ietf.org/html/rfc6530
29
34
  # http://www.unicode.org/faq/idn.html
30
35
  # http://ruby-doc.org/core-2.1.5/Regexp.html#class-Regexp-label-Character+Classes
31
36
  # http://en.wikipedia.org/wiki/Unicode_character_property#General_Category
37
+ EMAIL_NONASCII = /
38
+ \A
39
+ [^[:cntrl:][@\[\]\^ \!"\#$\(\)*,\/:;<=>?`{|}~\\]]+ # mailbox
40
+ @
41
+ (?:[^[:cntrl:][@\[\]\^ \!\"\#$&\(\)*,\/:;<=>\?`{|}~\\_.%+']]+\.)+ # subdomains
42
+ (?:[^[:cntrl:][@\[\]\^ \!\"\#$&\(\)*,\/:;<=>\?`{|}~\\_.%+\-'0-9]]{2,25}) # TLD
43
+ \z
44
+ /x
45
+
46
+ # A simple regular expression that only allows for letters, numbers, spaces, and
47
+ # .-_@+. Just a standard login / username regular expression.
48
+ LOGIN = /\A[a-zA-Z0-9_][a-zA-Z0-9\.+\-_@ ]+\z/
49
+
50
+ # Accessing the above constants using the following methods is deprecated.
51
+
52
+ # @deprecated
53
+ def self.email
54
+ ::ActiveSupport::Deprecation.warn(
55
+ "Authlogic::Regex.email is deprecated, use Authlogic::Regex::EMAIL",
56
+ caller(1)
57
+ )
58
+ EMAIL
59
+ end
60
+
61
+ # @deprecated
32
62
  def self.email_nonascii
33
- @email_nonascii_regex ||= begin
34
- email_name_regex = '[^[:cntrl:][@\[\]\^ \!\"#$\(\)*,/:;<=>\?`{|}~\\\]]+'
35
- domain_head_regex = '(?:[^[:cntrl:][@\[\]\^ \!\"#$&\(\)*,/:;<=>\?`{|}~\\\_\.%\+\']]+\.)+'
36
- domain_tld_regex = '(?:[^[:cntrl:][@\[\]\^ \!\"#$&\(\)*,/:;<=>\?`{|}~\\\_\.%\+\-\'0-9]]{2,13})'
37
- /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/
38
- end
63
+ ::ActiveSupport::Deprecation.warn(
64
+ "Authlogic::Regex.email_nonascii is deprecated, use Authlogic::Regex::EMAIL_NONASCII",
65
+ caller(1)
66
+ )
67
+ EMAIL_NONASCII
39
68
  end
40
69
 
41
- # A simple regular expression that only allows for letters, numbers, spaces, and .-_@. Just a standard login / username
42
- # regular expression.
70
+ # @deprecated
43
71
  def self.login
44
- /\A\w[\w\.+\-_@ ]+\z/
72
+ ::ActiveSupport::Deprecation.warn(
73
+ "Authlogic::Regex.login is deprecated, use Authlogic::Regex::LOGIN",
74
+ caller(1)
75
+ )
76
+ LOGIN
45
77
  end
46
78
  end
47
79
  end