sequel_password 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +41 -1
- data/lib/sequel_password/hashers.rb +28 -0
- data/lib/sequel_password.rb +28 -0
- data/sequel_password.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4483adb4a3a79018a1b330b14d7695c7695e508
|
4
|
+
data.tar.gz: d8129c412da70b141fe8ca6a7883b7ae0f876fd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c785779cf2df01c32339bb4175bb68a7b9184e2658c5a5914bc3fdf9d75d33b20f51b7ab2c950bb032c28107fe1885dc0811e0f033263cf2d0cf8e2b3e4957d8
|
7
|
+
data.tar.gz: 9dc83bf6afcc90646a7c0d46028f68a6ee0f4ed142400096dd2b57f1d4674b271e9cb8eb1103322dd0bd64e664c39d701c1a03790f7bca0bce99544ee803ca19
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,10 +3,50 @@
|
|
3
3
|
This sequel plugin adds authentication and password hashing to Sequel models.
|
4
4
|
It supports pbkdf2 and bcrypt hashers.
|
5
5
|
|
6
|
-
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Install it directly using gem:
|
9
|
+
|
10
|
+
```
|
11
|
+
gem install sequel_password
|
12
|
+
```
|
13
|
+
|
14
|
+
Or adding it to your ``Gemfile``:
|
15
|
+
|
16
|
+
```
|
17
|
+
gem "sequel_password"
|
18
|
+
```
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
### Configure
|
23
|
+
|
24
|
+
A straightforward example, using the password column for storage explicitely,
|
25
|
+
and using the default hashers:
|
7
26
|
|
8
27
|
```ruby
|
9
28
|
class User < Sequel::Model
|
10
29
|
plugin :password, column: :password
|
11
30
|
end
|
12
31
|
```
|
32
|
+
|
33
|
+
You can also specify a custom list of hashers to be used. The first hashers will
|
34
|
+
be considered as the default, choose carefully:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
class User < Sequel::Model
|
38
|
+
plugin :password, hashers: {
|
39
|
+
pbkdf2_sha256: PBKDF2Hasher.new,
|
40
|
+
bcrypt_sha256: BCryptSHA256Hasher.new
|
41
|
+
}
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Authenticate
|
46
|
+
|
47
|
+
To authenticate users with their given plain text password:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
user = User[email: email]
|
51
|
+
user && user.authenticate(password)
|
52
|
+
```
|
@@ -7,22 +7,43 @@ require "securerandom"
|
|
7
7
|
module Sequel
|
8
8
|
module Plugins
|
9
9
|
module Password
|
10
|
+
# @!attribute [r] algorithm
|
11
|
+
# @return [Symbol] name of the alogorithm implemented by the hasher
|
12
|
+
# @abstract Subclass or override this class to implements a custom
|
13
|
+
# Hasher.
|
10
14
|
class Hasher
|
11
15
|
attr_reader :algorithm
|
12
16
|
|
17
|
+
# Returns salt value to be used for hashing.
|
18
|
+
#
|
19
|
+
# @return [String] random salt value.
|
13
20
|
def salt
|
14
21
|
# 72 bits
|
15
22
|
SecureRandom.hex(9)
|
16
23
|
end
|
17
24
|
|
25
|
+
# Returns if the given password match the encoded password.
|
26
|
+
#
|
27
|
+
# @param [String] password in plain text
|
28
|
+
# @param [String] encoded password to be matched
|
29
|
+
# @return [Boolean] if password match encoded password.
|
18
30
|
def verify(password, encoded)
|
19
31
|
raise NotImplementedError
|
20
32
|
end
|
21
33
|
|
34
|
+
# Returns given password encoded with the given salt.
|
35
|
+
#
|
36
|
+
# @param [String] password in plain text
|
37
|
+
# @param [String] salt to be used during hashing
|
38
|
+
# @return [String] given password hashed using the given salt
|
22
39
|
def encode(password, salt)
|
23
40
|
raise NotImplementedError
|
24
41
|
end
|
25
42
|
|
43
|
+
# Returns if given encoded password needs to be updated.
|
44
|
+
#
|
45
|
+
# @param [String] encoded password
|
46
|
+
# @return [Boolean] if encoded password needs to be updated
|
26
47
|
def must_update(encoded)
|
27
48
|
false
|
28
49
|
end
|
@@ -36,6 +57,8 @@ module Sequel
|
|
36
57
|
end
|
37
58
|
end
|
38
59
|
|
60
|
+
# PBKDF2Hasher implements a PBKDF2 password hasher using 24000 iterations
|
61
|
+
# by default.
|
39
62
|
class PBKDF2Hasher < Hasher
|
40
63
|
def initialize
|
41
64
|
@algorithm = :pbkdf2_sha256
|
@@ -63,6 +86,7 @@ module Sequel
|
|
63
86
|
end
|
64
87
|
end
|
65
88
|
|
89
|
+
# BCryptSHA256Hasher implements a BCrypt password hasher using SHA256.
|
66
90
|
class BCryptSHA256Hasher < Hasher
|
67
91
|
def initialize
|
68
92
|
@algorithm = :bcrypt_sha256
|
@@ -88,6 +112,7 @@ module Sequel
|
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
115
|
+
# BCryptHasher implements a BCrypt password hasher.
|
91
116
|
class BCryptHasher < BCryptSHA256Hasher
|
92
117
|
def initialize
|
93
118
|
@algorithm = :bcrypt
|
@@ -96,6 +121,9 @@ module Sequel
|
|
96
121
|
end
|
97
122
|
end
|
98
123
|
|
124
|
+
# SHA1Hasher implements a SHA1 password hasher.
|
125
|
+
#
|
126
|
+
# @deprecated This hasher is present only for backward compatibility.
|
99
127
|
class SHA1Hasher < Hasher
|
100
128
|
def initialize
|
101
129
|
@algorithm = :sha1
|
data/lib/sequel_password.rb
CHANGED
@@ -18,12 +18,23 @@ module Sequel
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
# @!attribute [r] column
|
22
|
+
# @return [Symbol] name of the column where password is stored
|
23
|
+
# @!attribute [r] hashers
|
24
|
+
# @return [Hash] hash of the algorithms and their corresponding Hasher
|
21
25
|
module ClassMethods
|
22
26
|
attr_reader :column, :hashers
|
23
27
|
|
24
28
|
Plugins.inherited_instance_variables(self,
|
25
29
|
"@column": :digest, "@hashers": {})
|
26
30
|
|
31
|
+
# Returns the given password hash. It will return an unusable
|
32
|
+
# hash if given password is nil.
|
33
|
+
#
|
34
|
+
# @param [String, nil] password to be hashed
|
35
|
+
# @param [String, nil] salt to be used during hashing
|
36
|
+
# @param [Symbol] algorithm to be used for hashing
|
37
|
+
# @return [String] the given password hashed
|
27
38
|
def make_password(password, salt: nil, algorithm: :default)
|
28
39
|
return "!#{SecureRandom.hex(20)}" if password.nil?
|
29
40
|
|
@@ -31,6 +42,10 @@ module Sequel
|
|
31
42
|
hasher(algorithm).encode(password, salt)
|
32
43
|
end
|
33
44
|
|
45
|
+
# Returns if encoded hash is a usable password.
|
46
|
+
#
|
47
|
+
# @param [String] encoded hash
|
48
|
+
# @return [Boolean] if password is usable
|
34
49
|
def usable_password?(encoded)
|
35
50
|
return false if encoded.nil? || encoded.start_with?("!")
|
36
51
|
|
@@ -38,6 +53,14 @@ module Sequel
|
|
38
53
|
!hasher(algorithm).nil?
|
39
54
|
end
|
40
55
|
|
56
|
+
# Check if password match, and upgrade to newest hashing algorithm
|
57
|
+
# if needed.
|
58
|
+
#
|
59
|
+
# @param [String] password in plain text
|
60
|
+
# @param [String] encoded password for comparision
|
61
|
+
# @param [Proc] setter accepting an encoded password
|
62
|
+
# @param [Symbol] algorithm to be used for hashing
|
63
|
+
# @return [Boolean] if password match encoded password
|
41
64
|
def check_password(password, encoded, setter: nil, algorithm: :default)
|
42
65
|
return false if password.nil? || !usable_password?(encoded)
|
43
66
|
|
@@ -61,6 +84,10 @@ module Sequel
|
|
61
84
|
end
|
62
85
|
|
63
86
|
module InstanceMethods
|
87
|
+
# Check if given password match the existing one.
|
88
|
+
#
|
89
|
+
# @param [String] password in plain text
|
90
|
+
# @return [Boolean] if given password match
|
64
91
|
def authenticate(password)
|
65
92
|
encoded = send(model.column)
|
66
93
|
model.check_password(password, encoded, setter: method(:"#{model.column}="))
|
@@ -73,6 +100,7 @@ module Sequel
|
|
73
100
|
super(attr, value || plain)
|
74
101
|
end
|
75
102
|
|
103
|
+
# Sets the password as unusable.
|
76
104
|
def set_unusable_password
|
77
105
|
send("#{model.column}=", nil)
|
78
106
|
end
|
data/sequel_password.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
14
|
gem.name = "sequel_password"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version = '0.2.
|
16
|
+
gem.version = '0.2.1'
|
17
17
|
|
18
18
|
gem.add_runtime_dependency 'sequel', '~> 4.21', '>= 4.21.0'
|
19
19
|
gem.add_runtime_dependency 'bcrypt', '~> 3.1', '>= 3.1.10'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_password
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timothée Peignier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -163,3 +163,4 @@ summary: Add passwords hashing to sequel models.
|
|
163
163
|
test_files:
|
164
164
|
- spec/sequel_password_spec.rb
|
165
165
|
- spec/spec_helper.rb
|
166
|
+
has_rdoc:
|