phc_string_format 0.3.0 → 0.3.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
- SHA1:
3
- metadata.gz: 9796f936f745ffb9ab58df7b1369eed449de3511
4
- data.tar.gz: 285a076299d2ee829d9db68fd7a1286344999fa0
2
+ SHA256:
3
+ metadata.gz: f2c0d23fc35b585de7e270b87439a5ae61c53213f10442f8b5e576484e985d2d
4
+ data.tar.gz: 5ccf72ce6afe6ac8e16a8fb6904341007e7698daf2ddd85b25296d5179c7cca2
5
5
  SHA512:
6
- metadata.gz: 32ed90c87744f57f92b96bffc1a408985099e06acfe12f0aebba5763dc9ba9e1dea9a46c594e2067c77b84a103850abb8f6d3ec91563a4b9797f3f078d62735d
7
- data.tar.gz: b0bca224d19fce7a6df03f1850f6418aa3d420680c6e16b8d6595c9cf5045e84420bc67b14161d44ecb9bd821c01aebb280da5eb4f4c80aac1bdbe32ca5d166f
6
+ metadata.gz: 59d704eeda40482c8b55c1ee0e398c3da3b09c70fcff60e05106411c8bf2e43246c57d9b6bbaebf2af5f1ae855105ce915847bee79a09bb67f2b3436d5b21bb6
7
+ data.tar.gz: 5518af92641a14e47ba3bc552bf9e3da25ece970b479ac2e5708fe868eebbb6571b4725b22e8b0374eeb0f0215d550e11054ccb4e7a1883bc8d286fa9df51677
data/.reek.yml ADDED
@@ -0,0 +1,25 @@
1
+ ---
2
+ detectors:
3
+
4
+ DuplicateMethodCall:
5
+ exclude:
6
+ - 'PhcStringFormat::PhcString#self.parse'
7
+ FeatureEnvy:
8
+ exclude:
9
+ - 'PhcStringFormat::PhcString#parse_params'
10
+
11
+ LongParameterList:
12
+ max_params: 6
13
+ overrides:
14
+ initialize:
15
+ max_params: 6
16
+
17
+ TooManyStatements:
18
+ max_statements: 10
19
+
20
+ TooManyInstanceVariables:
21
+ max_instance_variables: 6
22
+
23
+ UncommunicativeModuleName:
24
+ accept:
25
+ - B64
data/.rubocop.yml ADDED
@@ -0,0 +1,32 @@
1
+ AllCops:
2
+ Exclude:
3
+ - bin/*
4
+ - pkg/*
5
+ - tmp/**/*
6
+ - lib/*/version.rb
7
+ - spec/spec_helper.rb
8
+ - Gemfile
9
+ - '*.gemspec'
10
+ - Rakefile
11
+
12
+ Metrics/AbcSize:
13
+ Max: 20
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - 'spec/**/*'
18
+
19
+ Metrics/CyclomaticComplexity:
20
+ Max: 10
21
+
22
+ Metrics/LineLength:
23
+ Max: 110
24
+
25
+ Metrics/MethodLength:
26
+ Max: 15
27
+
28
+ Metrics/ParameterLists:
29
+ Max: 6
30
+
31
+ Metrics/PerceivedComplexity:
32
+ Max: 10
data/Gemfile CHANGED
@@ -4,3 +4,7 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in phc_string_format.gemspec
6
6
  gemspec
7
+
8
+ gem "rubocop", "~> 0.58.2", require: false, :groups => [:development, :test]
9
+
10
+ gem "reek", "~> 5.0", require: false, :groups => [:development, :test]
data/Gemfile.lock CHANGED
@@ -1,22 +1,47 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- phc_string_format (0.3.0)
4
+ phc_string_format (0.3.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ ast (2.4.0)
10
+ axiom-types (0.1.1)
11
+ descendants_tracker (~> 0.0.4)
12
+ ice_nine (~> 0.11.0)
13
+ thread_safe (~> 0.3, >= 0.3.1)
9
14
  byebug (10.0.2)
15
+ codeclimate-engine-rb (0.4.1)
16
+ virtus (~> 1.0)
10
17
  coderay (1.1.2)
18
+ coercible (1.0.0)
19
+ descendants_tracker (~> 0.0.1)
20
+ descendants_tracker (0.0.4)
21
+ thread_safe (~> 0.3, >= 0.3.1)
11
22
  diff-lcs (1.3)
23
+ equalizer (0.0.11)
24
+ ice_nine (0.11.2)
25
+ jaro_winkler (1.5.1)
26
+ kwalify (0.7.2)
12
27
  method_source (0.9.0)
28
+ parallel (1.12.1)
29
+ parser (2.5.1.2)
30
+ ast (~> 2.4.0)
31
+ powerpack (0.1.2)
13
32
  pry (0.11.3)
14
33
  coderay (~> 1.1.0)
15
34
  method_source (~> 0.9.0)
16
35
  pry-byebug (3.6.0)
17
36
  byebug (~> 10.0)
18
37
  pry (~> 0.10)
38
+ rainbow (3.0.0)
19
39
  rake (10.5.0)
40
+ reek (5.0.2)
41
+ codeclimate-engine-rb (~> 0.4.0)
42
+ kwalify (~> 0.7.0)
43
+ parser (>= 2.5.0.0, < 2.6, != 2.5.1.1)
44
+ rainbow (>= 2.0, < 4.0)
20
45
  rspec (3.7.0)
21
46
  rspec-core (~> 3.7.0)
22
47
  rspec-expectations (~> 3.7.0)
@@ -30,6 +55,22 @@ GEM
30
55
  diff-lcs (>= 1.2.0, < 2.0)
31
56
  rspec-support (~> 3.7.0)
32
57
  rspec-support (3.7.1)
58
+ rubocop (0.58.2)
59
+ jaro_winkler (~> 1.5.1)
60
+ parallel (~> 1.10)
61
+ parser (>= 2.5, != 2.5.1.1)
62
+ powerpack (~> 0.1)
63
+ rainbow (>= 2.2.2, < 4.0)
64
+ ruby-progressbar (~> 1.7)
65
+ unicode-display_width (~> 1.0, >= 1.0.1)
66
+ ruby-progressbar (1.9.0)
67
+ thread_safe (0.3.6)
68
+ unicode-display_width (1.4.0)
69
+ virtus (1.0.5)
70
+ axiom-types (~> 0.1)
71
+ coercible (~> 1.0)
72
+ descendants_tracker (~> 0.0, >= 0.0.3)
73
+ equalizer (~> 0.0, >= 0.0.9)
33
74
 
34
75
  PLATFORMS
35
76
  ruby
@@ -39,7 +80,9 @@ DEPENDENCIES
39
80
  phc_string_format!
40
81
  pry-byebug (~> 3.6)
41
82
  rake (~> 10.0)
83
+ reek (~> 5.0)
42
84
  rspec (~> 3.0)
85
+ rubocop (~> 0.58.2)
43
86
 
44
87
  BUNDLED WITH
45
88
  1.16.2
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Known Vulnerabilities](https://snyk.io/test/github/naokikimura/phc_string_format/badge.svg?targetFile=Gemfile.lock)](https://snyk.io/test/github/naokikimura/phc_string_format?targetFile=Gemfile.lock)
6
6
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/cbcb6fa3556447a4af16980f3cc6f1eb)](https://app.codacy.com/app/naokikimura/phc_string_format?utm_source=github.com&utm_medium=referral&utm_content=naokikimura/phc_string_format&utm_campaign=badger)
7
7
 
8
- TODO: Describe your gem
8
+ PHC string format implemented by Ruby
9
9
 
10
10
  ## Installation
11
11
 
@@ -25,7 +25,20 @@ Or install it yourself as:
25
25
 
26
26
  ## Usage
27
27
 
28
- TODO: Write usage instructions here
28
+ ```ruby
29
+ require 'phc_string_format'
30
+
31
+ encrypted_password = '$argon2i$v=19$m=4096,t=3,p=1$IfH5R3O3r3501DfGnGr2rw$DfQ8Hv9R2eF2uBs1dR99IGjVjDl/rpkJIkaNyZ1g3pk'
32
+
33
+ # parse
34
+ phc_string_params = PhcStringFormat::Formatter.parse(encrypted_password)
35
+ # => {:id=>"argon2i", :version=>19, :params=>{"m"=>4096, "t"=>3, "p"=>1}, :salt=>"!\xF1\xF9Gs\xB7\xAF~t\xD47\xC6\x9Cj\xF6\xAF", :hash=>"\r\xF4<\x1E\xFFQ\xD9\xE1v\xB8\e5u\x1F} h\xD5\x8C9\x7F\xAE\x99\t\"F\x8D\xC9\x9D`\xDE\x99"}
36
+
37
+ # format
38
+ password_hash = PhcStringFormat::Formatter.format(phc_string_params)
39
+
40
+ password_hash == phc_string_format
41
+ ```
29
42
 
30
43
  ## Development
31
44
 
@@ -1,5 +1,7 @@
1
- require "phc_string_format/version"
2
- require "base64"
1
+ require 'phc_string_format/b64'
2
+ require 'phc_string_format/formatter'
3
+ require 'phc_string_format/phc_string'
4
+ require 'phc_string_format/version'
3
5
 
4
6
  #
5
7
  # PHC string format implemented by Ruby
@@ -8,59 +10,9 @@ require "base64"
8
10
  # $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
9
11
  # ```
10
12
  #
13
+ # See:
14
+ # - https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
15
+ # - https://github.com/P-H-C/phc-string-format/pull/4
16
+ #
11
17
  module PhcStringFormat
12
- module Formatter
13
- def self.format(id:, version: nil, params: {}, salt: '', hash: '', hint: {salt: {encoding: 'base64'}})
14
- raise ArgumentError.new, 'id is required' if id.nil?
15
- raise ArgumentError.new, 'hash needs salt' if (salt.nil? || salt.empty?) && !(hash.nil? || hash.empty?)
16
-
17
- elements = [
18
- id,
19
- ("v=#{version}" if version),
20
- (params.map{|e| e.join '='}.join(',') if params),
21
- hint.dig(:salt, :encoding) == '7bit' ? salt : short_strict_encode64(salt),
22
- short_strict_encode64(hash)
23
- ]
24
- "$#{elements.select{|e| !(e.nil? || e.empty?)}.join('$')}"
25
- end
26
-
27
- def self.parse(string, pick: nil ,hint: {salt: {encoding: 'base64'}})
28
- pick = [:id, :version, :params, :salt, :hash] unless pick
29
- elements = string.split(/\$/, 6)
30
- elements.shift
31
- id = shift_and_parse elements, pick.include?(:id), &-> (e) { e }
32
- version = shift_and_parse(elements, pick.include?(:version), &@@parse_version) if (elements.first || '').start_with?('v=')
33
- params = shift_and_parse(elements, pick.include?(:params), &@@parse_parameter_string) if (elements.first || '').include?('=')
34
- salt = shift_and_parse elements, pick.include?(:salt), &-> (e) {
35
- hint.dig(:salt, :encoding) == '7bit' ? e : short_strict_decode64(e)
36
- }
37
- hash = shift_and_parse elements, pick.include?(:hash), &-> (e) { short_strict_decode64(e) }
38
- {id: id, version: version, params: params, salt: salt, hash: hash}.select {|_,v| v}
39
- end
40
-
41
- def self.shift_and_parse(elements, picks, &proc)
42
- element = elements.shift
43
- proc.call(element) if picks
44
- end
45
-
46
- @@parse_version = -> (string) {
47
- @@parse_parameter_string.call(string)['v']
48
- }
49
-
50
- @@parse_parameter_string = -> (string) {
51
- string.split(/,/).map {|e| e.split '='}.each_with_object({}){|e, h| k, v = e; h[k] = (/\A-?\d+(.\d+)?\Z/.match(v) ? v.to_i : v)}
52
- }
53
-
54
- def self.short_strict_encode64(bin)
55
- return nil unless bin
56
- Base64.strict_encode64(bin).delete('=')
57
- end
58
-
59
- def self.short_strict_decode64(bin)
60
- return nil unless bin
61
- Base64.strict_decode64(bin + '=' * (-bin.size % 4))
62
- end
63
-
64
- private_class_method :short_strict_encode64, :short_strict_decode64
65
- end
66
18
  end
@@ -0,0 +1,21 @@
1
+ require 'base64'
2
+
3
+ module PhcStringFormat
4
+ #
5
+ # Implementation of B64
6
+ #
7
+ # See:
8
+ # - https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#b64
9
+ #
10
+ module B64
11
+ def self.encode(bin)
12
+ return nil unless bin
13
+ Base64.strict_encode64(bin).delete('=')
14
+ end
15
+
16
+ def self.decode(bin)
17
+ return nil unless bin
18
+ Base64.strict_decode64(bin + '=' * (-bin.size % 4))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module PhcStringFormat
2
+ #
3
+ # Formatter for stringifying and parsing PHC-string-format.
4
+ #
5
+ module Formatter
6
+ def self.format(**kwargs)
7
+ PhcString.create(kwargs).to_s
8
+ end
9
+
10
+ def self.parse(string, hint: {}, pick: nil)
11
+ PhcString.parse(string, hint: hint).to_h(pick)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,83 @@
1
+ module PhcStringFormat
2
+ #
3
+ # Parser for parsing PHC-string-format.
4
+ #
5
+ class PhcString
6
+ def self.parse(string, hint: {})
7
+ string ||= ''
8
+ elements = string.split(/\$/, 6)
9
+ elements.shift
10
+ id = elements.shift
11
+ version = elements.shift if (elements.first || '').start_with?('v=')
12
+ params = elements.shift if (elements.first || '').include?('=')
13
+ salt = elements.shift
14
+ hash = elements.shift
15
+ PhcString.new(id, version, params, salt, hash, hint)
16
+ end
17
+
18
+ def self.create(id:, version: nil, params: {}, salt: '', hash: '', hint: {})
19
+ PhcString.new(
20
+ id,
21
+ ("v=#{version}" if version),
22
+ (params.map { |entry| entry.join '=' }.join(',') if params),
23
+ hint.dig(:salt, :encoding) == '7bit' ? salt : B64.encode(salt),
24
+ B64.encode(hash),
25
+ hint
26
+ )
27
+ end
28
+
29
+ def initialize(id, version_string, params_string, encoded_salt, encoded_hash, hint)
30
+ raise ArgumentError.new, 'id is required' unless id
31
+ if (!encoded_salt || encoded_salt.empty?) && !(!encoded_hash || encoded_hash.empty?)
32
+ raise ArgumentError.new, 'hash needs salt'
33
+ end
34
+
35
+ @id = id
36
+ @version_string = version_string
37
+ @params_string = params_string
38
+ @encoded_salt = encoded_salt
39
+ @encoded_hash = encoded_hash
40
+ @hint = hint
41
+ end
42
+
43
+ def to_s
44
+ '$' + [
45
+ @id,
46
+ @version_string,
47
+ @params_string,
48
+ @encoded_salt,
49
+ @encoded_hash
50
+ ].reject { |element| !element || element.empty? }.join('$')
51
+ end
52
+
53
+ def to_h(pick = nil)
54
+ pick ||= %i[id version params salt hash]
55
+ {
56
+ id: (@id if pick.include?(:id)),
57
+ version: (parse_version(@version_string) if pick.include?(:version)),
58
+ params: (parse_params(@params_string) if pick.include?(:params)),
59
+ salt:
60
+ if pick.include?(:salt)
61
+ @hint.dig(:salt, :encoding) == '7bit' ? e : B64.decode(@encoded_salt)
62
+ end,
63
+ hash: (B64.decode(@encoded_hash) if pick.include?(:hash))
64
+ }.select { |_, value| value }
65
+ end
66
+
67
+ private
68
+
69
+ def parse_version(version_string)
70
+ parse_params(version_string)['v']
71
+ end
72
+
73
+ def parse_params(params_string)
74
+ mapper = ->(param) { param.split '=' }
75
+ reducer = lambda do |param, params|
76
+ name, value = param
77
+ params[name] = value =~ /\A-?\d+(.\d+)?\Z/ ? value.to_i : value
78
+ end
79
+ params_string ||= ''
80
+ params_string.split(/,/).map(&mapper).each_with_object({}, &reducer)
81
+ end
82
+ end
83
+ end
@@ -1,3 +1,3 @@
1
1
  module PhcStringFormat
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phc_string_format
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - naokikimura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-05 00:00:00.000000000 Z
11
+ date: 2018-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,7 +74,9 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
+ - ".reek.yml"
77
78
  - ".rspec"
79
+ - ".rubocop.yml"
78
80
  - ".travis.yml"
79
81
  - CODE_OF_CONDUCT.md
80
82
  - Gemfile
@@ -85,6 +87,9 @@ files:
85
87
  - bin/console
86
88
  - bin/setup
87
89
  - lib/phc_string_format.rb
90
+ - lib/phc_string_format/b64.rb
91
+ - lib/phc_string_format/formatter.rb
92
+ - lib/phc_string_format/phc_string.rb
88
93
  - lib/phc_string_format/version.rb
89
94
  - phc_string_format.gemspec
90
95
  homepage: https://github.com/naokikimura/phc_string_format
@@ -109,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
114
  version: '0'
110
115
  requirements: []
111
116
  rubyforge_project:
112
- rubygems_version: 2.5.2.3
117
+ rubygems_version: 2.7.6
113
118
  signing_key:
114
119
  specification_version: 4
115
120
  summary: PHC string format implemented by Ruby.