authlogic 3.4.5 → 3.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +11 -0
- data/README.rdoc +47 -0
- data/authlogic.gemspec +2 -2
- data/lib/authlogic/acts_as_authentic/email.rb +3 -0
- data/lib/authlogic/acts_as_authentic/login.rb +5 -2
- data/lib/authlogic/acts_as_authentic/password.rb +1 -1
- data/lib/authlogic/i18n.rb +1 -0
- data/lib/authlogic/regex.rb +21 -1
- data/lib/authlogic/session/magic_columns.rb +2 -2
- data/test/acts_as_authentic_test/email_test.rb +82 -0
- metadata +17 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e9c7f5c79c3343a9c1d2f15743ffef73e6a5a73d
|
4
|
+
data.tar.gz: 90c6bc0a810fbfeb410c6d5a177148dc9e802329
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b3fedace0a9232fad6ba1ad25994215f76af134a74c82496f24c1554af00c59ed00cab602ca11c480c66228e0b738e555e6612f68764c8205e10fc92e6a07d6
|
7
|
+
data.tar.gz: 20ca2cfb1de0d9f30b90014188e5bd7592fc087b381861c047293d9ecbc6d4084475a8409a74000b2a6ed2ab0ffea6534208e04b4496ecba555a3975b2614649
|
data/CHANGELOG.md
CHANGED
data/README.rdoc
CHANGED
@@ -49,6 +49,10 @@ You may specify how passwords are cryptographically hashed (or encrypted) by set
|
|
49
49
|
|
50
50
|
c.crypto_provider = Authlogic::CryptoProviders::BCrypt
|
51
51
|
|
52
|
+
You may validate international email addresses by enabling the provided alternate regex:
|
53
|
+
|
54
|
+
c.validates_format_of_email_field_options = {:with => Authlogic::Regex.email_nonascii}
|
55
|
+
|
52
56
|
Also, sessions are automatically maintained. You can switch this on and off with configuration, but the following will automatically log a user in after a successful registration:
|
53
57
|
|
54
58
|
User.create(params[:user])
|
@@ -106,6 +110,49 @@ Each of the above has its various sub modules that contain common logic. The sub
|
|
106
110
|
|
107
111
|
For example, if you want to timeout users after a certain period of inactivity, you would look in <b>Authlogic::Session::Timeout</b>. To help you out, I listed the following publicly relevant modules with short descriptions. For the sake of brevity, there are more modules than listed here, the ones not listed are more for internal use, but you can easily read up on them in the {documentation}[http://rdoc.info/projects/binarylogic/authlogic].
|
108
112
|
|
113
|
+
== Example migration
|
114
|
+
|
115
|
+
If you want to enable all the features of Authlogic, a migration to create a
|
116
|
+
+User+ model, for example, might look like this:
|
117
|
+
|
118
|
+
class CreateUser < ActiveRecord::Migration
|
119
|
+
def change
|
120
|
+
create_table :users do |t|
|
121
|
+
# Authlogic::ActsAsAuthentic::Email
|
122
|
+
t.string :email
|
123
|
+
|
124
|
+
# Authlogic::ActsAsAuthentic::Password
|
125
|
+
t.string :crypted_password
|
126
|
+
t.string :password_salt
|
127
|
+
|
128
|
+
# Authlogic::ActsAsAuthentic::PersistenceToken
|
129
|
+
t.string :persistence_token
|
130
|
+
|
131
|
+
# Authlogic::ActsAsAuthentic::SingleAccessToken
|
132
|
+
t.string :single_access_token
|
133
|
+
|
134
|
+
# Authlogic::ActsAsAuthentic::PerishableToken
|
135
|
+
t.string :perishable_token
|
136
|
+
|
137
|
+
# Authlogic::Session::MagicColumns
|
138
|
+
t.integer :login_count, default: 0, null: false
|
139
|
+
t.integer :failed_login_count, default: 0, null: false
|
140
|
+
t.datetime :last_request_at
|
141
|
+
t.datetime :current_login_at
|
142
|
+
t.datetime :last_login_at
|
143
|
+
t.string :current_login_ip
|
144
|
+
t.string :last_login_ip
|
145
|
+
|
146
|
+
# Authlogic::Session::MagicStates
|
147
|
+
t.boolean :active, default: false
|
148
|
+
t.boolean :approved, default: false
|
149
|
+
t.boolean :confirmed, default: false
|
150
|
+
|
151
|
+
t.timestamps
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
109
156
|
== Quick Rails example
|
110
157
|
|
111
158
|
What if creating sessions worked like an ORM library on the surface...
|
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.4.
|
6
|
+
s.version = "3.4.6"
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Ben Johnson"]
|
9
9
|
s.email = ["bjohnson@binarylogic.com"]
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_dependency 'activerecord', '>= 3.2'
|
17
17
|
s.add_dependency 'activesupport', '>= 3.2'
|
18
18
|
s.add_dependency 'request_store', '~> 1.0'
|
19
|
-
s.add_dependency 'scrypt', '
|
19
|
+
s.add_dependency 'scrypt', '>= 1.2', '< 3.0'
|
20
20
|
s.add_development_dependency 'bcrypt', '~> 3.1'
|
21
21
|
s.add_development_dependency 'timecop', '~> 0.7'
|
22
22
|
|
@@ -62,6 +62,9 @@ module Authlogic
|
|
62
62
|
# merge options into it. Checkout the convenience function merge_validates_format_of_email_field_options to merge
|
63
63
|
# options.</b>
|
64
64
|
#
|
65
|
+
# To validate international email addresses, enable the provided alternate regex:
|
66
|
+
# * <tt>validates_format_of_email_field_options({:with => Authlogic::Regex.email_nonascii})</tt>
|
67
|
+
#
|
65
68
|
# * <tt>Default:</tt> {:with => Authlogic::Regex.email, :message => Proc.new {I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}}
|
66
69
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_format_of
|
67
70
|
def validates_format_of_email_field_options(value = nil)
|
@@ -116,10 +116,13 @@ module Authlogic
|
|
116
116
|
relation = if not sensitivity
|
117
117
|
connection.case_insensitive_comparison(arel_table, field.to_s, columns_hash[field.to_s], value)
|
118
118
|
else
|
119
|
-
|
119
|
+
if Gem::Version.new(Rails.version) < Gem::Version.new('4.2')
|
120
|
+
value = connection.case_sensitive_modifier(value)
|
121
|
+
else
|
122
|
+
value = connection.case_sensitive_modifier(value, field.to_s)
|
123
|
+
end
|
120
124
|
relation = arel_table[field.to_s].eq(value)
|
121
125
|
end
|
122
|
-
|
123
126
|
where(relation).first
|
124
127
|
end
|
125
128
|
end
|
@@ -270,7 +270,7 @@ module Authlogic
|
|
270
270
|
def reset_password
|
271
271
|
friendly_token = Authlogic::Random.friendly_token
|
272
272
|
self.password = friendly_token
|
273
|
-
self.password_confirmation = friendly_token
|
273
|
+
self.password_confirmation = friendly_token if self.class.require_password_confirmation
|
274
274
|
end
|
275
275
|
alias_method :randomize_password, :reset_password
|
276
276
|
|
data/lib/authlogic/i18n.rb
CHANGED
@@ -34,6 +34,7 @@ module Authlogic
|
|
34
34
|
# login_invalid: should use only letters, numbers, spaces, and .-_@ please.
|
35
35
|
# consecutive_failed_logins_limit_exceeded: Consecutive failed logins limit exceeded, account is disabled.
|
36
36
|
# email_invalid: should look like an email address.
|
37
|
+
# email_invalid_international: should look like an international email address.
|
37
38
|
# password_blank: can not be blank
|
38
39
|
# password_invalid: is not valid
|
39
40
|
# not_active: Your account is not active
|
data/lib/authlogic/regex.rb
CHANGED
@@ -11,13 +11,33 @@ module Authlogic
|
|
11
11
|
# which is an excellent resource for regular expressions.
|
12
12
|
def self.email
|
13
13
|
@email_regex ||= begin
|
14
|
-
email_name_regex = '[A-Z0-9_
|
14
|
+
email_name_regex = '[A-Z0-9_\.&%\+\-\']+'
|
15
15
|
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
|
16
16
|
domain_tld_regex = '(?:[A-Z]{2,13})'
|
17
17
|
/\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
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:
|
24
|
+
# - email_name_regex disallows: @[]^ !"#$()*,/:;<=>?`{|}~\ and control characters
|
25
|
+
# - domain_head_regex disallows: _%+ and all characters in email_name_regex
|
26
|
+
# - domain_tld_regex disallows: 0123456789- and all characters in domain_head_regex
|
27
|
+
# http://en.wikipedia.org/wiki/Email_address#Internationalization
|
28
|
+
# http://tools.ietf.org/html/rfc6530
|
29
|
+
# http://www.unicode.org/faq/idn.html
|
30
|
+
# http://ruby-doc.org/core-2.1.5/Regexp.html#class-Regexp-label-Character+Classes
|
31
|
+
# http://en.wikipedia.org/wiki/Unicode_character_property#General_Category
|
32
|
+
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
|
39
|
+
end
|
40
|
+
|
21
41
|
# A simple regular expression that only allows for letters, numbers, spaces, and .-_@. Just a standard login / username
|
22
42
|
# regular expression.
|
23
43
|
def self.login
|
@@ -24,9 +24,9 @@ module Authlogic
|
|
24
24
|
|
25
25
|
# Configuration for the magic columns feature.
|
26
26
|
module Config
|
27
|
-
# Every time a session is found the last_request_at field for that record is
|
27
|
+
# Every time a session is found the last_request_at field for that record is updated with the current time, if that field exists.
|
28
28
|
# If you want to limit how frequent that field is updated specify the threshold here. For example, if your user is making a
|
29
|
-
# request every 5 seconds, and you feel this is too frequent, and feel a minute is a good
|
29
|
+
# request every 5 seconds, and you feel this is too frequent, and feel a minute is a good threshold. Set this to 1.minute.
|
30
30
|
# Once a minute has passed in between requests the field will be updated.
|
31
31
|
#
|
32
32
|
# * <tt>Default:</tt> 0
|
@@ -1,7 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
module ActsAsAuthenticTest
|
4
5
|
class EmailTest < ActiveSupport::TestCase
|
6
|
+
|
7
|
+
GOOD_ASCII_EMAILS = [
|
8
|
+
"a@a.com",
|
9
|
+
"damien+test1...etc..@mydomain.com",
|
10
|
+
"dakota.dux+1@gmail.com",
|
11
|
+
"dakota.d'ux@gmail.com",
|
12
|
+
"a&b@c.com",
|
13
|
+
]
|
14
|
+
|
15
|
+
BAD_ASCII_EMAILS = [
|
16
|
+
"",
|
17
|
+
"aaaaaaaaaaaaa",
|
18
|
+
"question?mark@gmail.com",
|
19
|
+
"backslash@g\\mail.com",
|
20
|
+
"<script>alert(123);</script>\nnobody@example.com",
|
21
|
+
]
|
22
|
+
|
23
|
+
# http://en.wikipedia.org/wiki/ISO/IEC_8859-1#Codepage_layout
|
24
|
+
GOOD_ISO88591_EMAILS = [
|
25
|
+
"töm.öm@dömain.fi", # https://github.com/binarylogic/authlogic/issues/176
|
26
|
+
"Pelé@examplé.com", # http://en.wikipedia.org/wiki/Email_address#Internationalization_examples
|
27
|
+
]
|
28
|
+
|
29
|
+
BAD_ISO88591_EMAILS = [
|
30
|
+
"",
|
31
|
+
"öm(@ava.fi", # L paren
|
32
|
+
"é)@domain.com", # R paren
|
33
|
+
"é[@example.com", # L bracket
|
34
|
+
"question?mark@gmail.com", # question mark
|
35
|
+
"back\\slash@gmail.com", # backslash
|
36
|
+
]
|
37
|
+
|
38
|
+
GOOD_UTF8_EMAILS = [
|
39
|
+
"δκιμή@παράδεγμα.δοκμή", # http://en.wikipedia.org/wiki/Email_address#Internationalization_examples
|
40
|
+
"我本@屋企.香港", # http://en.wikipedia.org/wiki/Email_address#Internationalization_examples
|
41
|
+
"甲斐@黒川.日買", # http://en.wikipedia.org/wiki/Email_address#Internationalization_examples
|
42
|
+
"чебурша@ящик-с-пельнами.рф", # Contains dashes in domain head
|
43
|
+
"企斐@黒川.みんな", # https://github.com/binarylogic/authlogic/issues/176#issuecomment-55829320
|
44
|
+
]
|
45
|
+
|
46
|
+
BAD_UTF8_EMAILS = [
|
47
|
+
"",
|
48
|
+
".みんな", # https://github.com/binarylogic/authlogic/issues/176#issuecomment-55829320
|
49
|
+
'δκιμή@παράδεγμα.δ', # short TLD
|
50
|
+
"öm(@ava.fi", # L paren
|
51
|
+
"é)@domain.com", # R paren
|
52
|
+
"é[@example.com", # L bracket
|
53
|
+
"δ]@πράιγμα.δοκμή", # R bracket
|
54
|
+
"我\.香港", # slash
|
55
|
+
"甲;.日本", # semicolon
|
56
|
+
"ч:@ящик-с-пельнами.рф", # colon
|
57
|
+
"斐,.みんな", # comma
|
58
|
+
"香<.香港", # less than
|
59
|
+
"我>.香港", # greater than
|
60
|
+
"我?本@屋企.香港", # question mark
|
61
|
+
"чебурша@ьн\\ами.рф", # backslash
|
62
|
+
"user@domain.com%0A<script>alert('hello')</script>",
|
63
|
+
]
|
64
|
+
|
5
65
|
def test_email_field_config
|
6
66
|
assert_equal :email, User.email_field
|
7
67
|
assert_equal :email, Employee.email_field
|
@@ -53,6 +113,12 @@ module ActsAsAuthenticTest
|
|
53
113
|
assert_equal({:yes => "no"}, User.validates_format_of_email_field_options)
|
54
114
|
User.validates_format_of_email_field_options default
|
55
115
|
assert_equal default, User.validates_format_of_email_field_options
|
116
|
+
|
117
|
+
with_email_nonascii = {:with => Authlogic::Regex.email_nonascii, :message => Proc.new{I18n.t('error_messages.email_invalid_international', :default => "should look like an international email address.")}}
|
118
|
+
User.validates_format_of_email_field_options = with_email_nonascii
|
119
|
+
assert_equal(with_email_nonascii, User.validates_format_of_email_field_options)
|
120
|
+
User.validates_format_of_email_field_options with_email_nonascii
|
121
|
+
assert_equal with_email_nonascii, User.validates_format_of_email_field_options
|
56
122
|
end
|
57
123
|
|
58
124
|
def test_deferred_error_message_translation
|
@@ -120,6 +186,22 @@ module ActsAsAuthenticTest
|
|
120
186
|
u.email = "<script>alert(123);</script>\nnobody@example.com"
|
121
187
|
assert !u.valid?
|
122
188
|
assert u.errors[:email].size > 0
|
189
|
+
|
190
|
+
u.email = "a&b@c.com"
|
191
|
+
u.valid?
|
192
|
+
assert u.errors[:email].size == 0
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_validates_format_of_nonascii_email_field
|
196
|
+
|
197
|
+
(GOOD_ASCII_EMAILS + GOOD_ISO88591_EMAILS + GOOD_UTF8_EMAILS).each do |e|
|
198
|
+
assert e =~ Authlogic::Regex.email_nonascii, "Good email should validate: #{e}"
|
199
|
+
end
|
200
|
+
|
201
|
+
(BAD_ASCII_EMAILS + BAD_ISO88591_EMAILS + BAD_UTF8_EMAILS).each do |e|
|
202
|
+
assert e !~ Authlogic::Regex.email_nonascii, "Bad email should not validate: #{e}"
|
203
|
+
end
|
204
|
+
|
123
205
|
end
|
124
206
|
|
125
207
|
def test_validates_uniqueness_of_email_field
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authlogic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.4.
|
4
|
+
version: 3.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Johnson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '3.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -56,16 +56,22 @@ dependencies:
|
|
56
56
|
name: scrypt
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.2'
|
62
|
+
- - <
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '3.0'
|
62
65
|
type: :runtime
|
63
66
|
prerelease: false
|
64
67
|
version_requirements: !ruby/object:Gem::Requirement
|
65
68
|
requirements:
|
66
|
-
- -
|
69
|
+
- - '>='
|
67
70
|
- !ruby/object:Gem::Version
|
68
71
|
version: '1.2'
|
72
|
+
- - <
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: bcrypt
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,17 +249,17 @@ require_paths:
|
|
243
249
|
- lib
|
244
250
|
required_ruby_version: !ruby/object:Gem::Requirement
|
245
251
|
requirements:
|
246
|
-
- -
|
252
|
+
- - '>='
|
247
253
|
- !ruby/object:Gem::Version
|
248
254
|
version: '0'
|
249
255
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
256
|
requirements:
|
251
|
-
- -
|
257
|
+
- - '>='
|
252
258
|
- !ruby/object:Gem::Version
|
253
259
|
version: '0'
|
254
260
|
requirements: []
|
255
261
|
rubyforge_project:
|
256
|
-
rubygems_version: 2.
|
262
|
+
rubygems_version: 2.0.14
|
257
263
|
signing_key:
|
258
264
|
specification_version: 4
|
259
265
|
summary: A clean, simple, and unobtrusive ruby authentication solution.
|