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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bedf3cb4f2713cd269dc2299186bfc4b9da288d336a59e20d0e6c11fc467541
4
- data.tar.gz: c69c01925c5588d2d95ec94984977304655e1090b9e6c1e8040c2f41df15943b
3
+ metadata.gz: 153b813e37bf5c0c015e3ceed5b169ef4d6c8fb9230b7343d0435b6ba246d33a
4
+ data.tar.gz: 83614237a55c98420d9ee025df0d5ddfa1b9f4d9ecd72aeb7cfd3826e40a4fa9
5
5
  SHA512:
6
- metadata.gz: 5033e7251658eb78f0925e65fcb93103d2d110cbc3df3513ecf4e5a0f8b489162d3834c5f1956dac2403a9e084f2e3dc21409798f7bd807b44a8264fce0656ed
7
- data.tar.gz: 6c0d5089fa54596cfe0d531fcd3d38c33fff7b5756edd6bad13c66a85920bab3e0b89e3f7cb3202780e079142bebd9cc5cf376785f1fdf6efb4de0ed719a1035
6
+ metadata.gz: 87572ff497e9018fac1f56428a52bd6cdfce9b5c9fb6f7717d095e29c54997f45ec8dcc42da8372f140536db0abe80a761588f882e138d32e16507380f8d663a
7
+ data.tar.gz: 1a02471f7dcbb7486262cc173c99fdec3aba716ccc3f6ea6e48e556bfe548216251d7171aea4cdf3a1a5c3c879e4f1017dcef529ff52f80839d4f46ab68932b8
@@ -0,0 +1,7 @@
1
+ # 0.1.1
2
+
3
+ - Validate cost options for all algorithms
4
+
5
+ # 0.1.0
6
+
7
+ - Initial release
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
@@ -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
@@ -17,5 +17,9 @@ class MultiPassword
17
17
  def verify(_password, _encrypted_password)
18
18
  raise MethodNotImplemented, 'verify'
19
19
  end
20
+
21
+ def validate_options(_options)
22
+ raise MethodNotImplemented, 'validate_options'
23
+ end
20
24
  end
21
25
  end
@@ -1,3 +1,3 @@
1
1
  class MultiPassword
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  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.0
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-04 00:00:00.000000000 Z
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
- - ".travis.yml"
52
+ - CHANGELOG
53
53
  - Gemfile
54
54
  - LICENSE.txt
55
55
  - README.md
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.6.6
6
- before_install: gem install bundler -v 2.1.4