multi_password 0.1.0 → 0.1.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/CHANGELOG +7 -0
- data/README.md +3 -0
- data/lib/multi_password.rb +7 -1
- data/lib/multi_password/errors.rb +6 -0
- data/lib/multi_password/strategies/argon2.rb +18 -1
- data/lib/multi_password/strategies/bcrypt.rb +13 -1
- data/lib/multi_password/strategies/scrypt.rb +23 -1
- data/lib/multi_password/strategy.rb +4 -0
- data/lib/multi_password/version.rb +1 -1
- metadata +3 -3
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 153b813e37bf5c0c015e3ceed5b169ef4d6c8fb9230b7343d0435b6ba246d33a
|
4
|
+
data.tar.gz: 83614237a55c98420d9ee025df0d5ddfa1b9f4d9ecd72aeb7cfd3826e40a4fa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87572ff497e9018fac1f56428a52bd6cdfce9b5c9fb6f7717d095e29c54997f45ec8dcc42da8372f140536db0abe80a761588f882e138d32e16507380f8d663a
|
7
|
+
data.tar.gz: 1a02471f7dcbb7486262cc173c99fdec3aba716ccc3f6ea6e48e556bfe548216251d7171aea4cdf3a1a5c3c879e4f1017dcef529ff52f80839d4f46ab68932b8
|
data/CHANGELOG
ADDED
data/README.md
CHANGED
@@ -56,6 +56,9 @@ You can also specify algorithm and options on-the-fly:
|
|
56
56
|
manager = MultiPassword.new(algorithm: :scrypt, options: { key_len: 64, max_time: 1 })
|
57
57
|
```
|
58
58
|
|
59
|
+
**NOTE**: `MultiPassword` helps you validate the options when initializing the
|
60
|
+
instance and configuration.
|
61
|
+
|
59
62
|
### Interface
|
60
63
|
|
61
64
|
MultiPassword provides 2 methods: `create` for hashing password and `verify` for
|
data/lib/multi_password.rb
CHANGED
@@ -31,9 +31,15 @@ class MultiPassword
|
|
31
31
|
registers.delete(algorithm)
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.configure(&block)
|
35
|
+
super.tap do
|
36
|
+
new(algorithm: config.default_algorithm, options: config.default_options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
34
40
|
def initialize(algorithm: config.default_algorithm, options: config.default_options)
|
35
41
|
@strategy = registers.fetch(algorithm).new
|
36
|
-
@options = options
|
42
|
+
@options = @strategy.validate_options(options)
|
37
43
|
rescue KeyError
|
38
44
|
raise AlgorithmNotRegistered.new(algorithm)
|
39
45
|
end
|
@@ -12,4 +12,10 @@ class MultiPassword
|
|
12
12
|
super("Algorithm #{algorithm} is not registered. Try requiring 'multi_password/strategies/#{algorithm}'.")
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
class InvalidOptions < Error
|
17
|
+
def initialize(strategy, message)
|
18
|
+
super("Algorithm #{strategy} options: #{message}")
|
19
|
+
end
|
20
|
+
end
|
15
21
|
end
|
@@ -9,12 +9,29 @@ class MultiPassword
|
|
9
9
|
register :argon2
|
10
10
|
|
11
11
|
def create(password, options = {})
|
12
|
-
::Argon2::Password.new(options).create(password)
|
12
|
+
::Argon2::Password.new(validate_options(options)).create(password)
|
13
13
|
end
|
14
14
|
|
15
15
|
def verify(password, encrypted_password)
|
16
16
|
::Argon2::Password.verify_password(password, encrypted_password)
|
17
17
|
end
|
18
|
+
|
19
|
+
def validate_options(options)
|
20
|
+
return options if options.empty?
|
21
|
+
|
22
|
+
t_cost = options[:t_cost]
|
23
|
+
m_cost = options[:m_cost]
|
24
|
+
|
25
|
+
if t_cost && (!t_cost.is_a?(Integer) || t_cost < 1 || t_cost > 750)
|
26
|
+
raise InvalidOptions.new('argon2', 't_cost must be an integer between 1 and 750')
|
27
|
+
end
|
28
|
+
|
29
|
+
if m_cost && (!m_cost.is_a?(Integer) || m_cost < 1 || m_cost > 31)
|
30
|
+
raise InvalidOptions.new('argon2', 'm_cost must be an integer between 1 and 31')
|
31
|
+
end
|
32
|
+
|
33
|
+
options
|
34
|
+
end
|
18
35
|
end
|
19
36
|
end
|
20
37
|
end
|
@@ -9,12 +9,24 @@ class MultiPassword
|
|
9
9
|
register :bcrypt
|
10
10
|
|
11
11
|
def create(password, options = {})
|
12
|
-
::BCrypt::Password.create(password, options).to_s
|
12
|
+
::BCrypt::Password.create(password, validate_options(options)).to_s
|
13
13
|
end
|
14
14
|
|
15
15
|
def verify(password, encrypted_password)
|
16
16
|
::BCrypt::Password.new(encrypted_password) == password
|
17
17
|
end
|
18
|
+
|
19
|
+
def validate_options(options)
|
20
|
+
return options if options.empty?
|
21
|
+
|
22
|
+
cost = options[:cost]
|
23
|
+
|
24
|
+
if !cost.is_a?(Integer) || cost < 4 || cost > 31
|
25
|
+
raise InvalidOptions.new('bcrypt', 'cost must be an integer between 4 and 31')
|
26
|
+
end
|
27
|
+
|
28
|
+
options
|
29
|
+
end
|
18
30
|
end
|
19
31
|
end
|
20
32
|
end
|
@@ -9,12 +9,34 @@ class MultiPassword
|
|
9
9
|
register :scrypt
|
10
10
|
|
11
11
|
def create(password, options = {})
|
12
|
-
::SCrypt::Password.create(password, options).to_s
|
12
|
+
::SCrypt::Password.create(password, validate_options(options)).to_s
|
13
13
|
end
|
14
14
|
|
15
15
|
def verify(password, encrypted_password)
|
16
16
|
::SCrypt::Password.new(encrypted_password) == password
|
17
17
|
end
|
18
|
+
|
19
|
+
def validate_options(options)
|
20
|
+
return options if options.empty?
|
21
|
+
|
22
|
+
key_len = options[:key_len]
|
23
|
+
max_time = options[:max_time]
|
24
|
+
max_mem = options[:max_mem]
|
25
|
+
|
26
|
+
if key_len && (!key_len.is_a?(Integer) || key_len < 16 || key_len > 512)
|
27
|
+
raise InvalidOptions.new('scrypt', 'key_len must be an integer between 16 and 512')
|
28
|
+
end
|
29
|
+
|
30
|
+
if max_time && (!max_time.is_a?(Integer) || max_time < 0 || max_time > 2)
|
31
|
+
raise InvalidOptions.new('scrypt', 'max_time must be an integer between 0 and 2')
|
32
|
+
end
|
33
|
+
|
34
|
+
if max_mem && (!max_mem.is_a?(Numeric) || max_mem < 0 || max_mem > 256)
|
35
|
+
raise InvalidOptions.new('scrypt', 'max_mem must be a number between 0 and 256')
|
36
|
+
end
|
37
|
+
|
38
|
+
options
|
39
|
+
end
|
18
40
|
end
|
19
41
|
end
|
20
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multi_password
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hieu Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -49,7 +49,7 @@ files:
|
|
49
49
|
- ".github/workflows/ruby.yml"
|
50
50
|
- ".gitignore"
|
51
51
|
- ".rspec"
|
52
|
-
-
|
52
|
+
- CHANGELOG
|
53
53
|
- Gemfile
|
54
54
|
- LICENSE.txt
|
55
55
|
- README.md
|