multi_password 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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