cobalt-rubocop 0.1.0 → 0.2.0

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: c08db73a41f4beaee02f72349ba019f38884ed65030ca622cffb6e2bb76d0dfe
4
- data.tar.gz: '06588084616ac4a8e65741a3c251de8988faf4e2157bef50a8f290f64c7a5dd4'
3
+ metadata.gz: 6f2801ac2078b352088c701af34b58f9b88674b73699e40940a89c53c7be4843
4
+ data.tar.gz: 0e8c1af2bd5fe8d4bee073fb226e10de3b8fdf4a526fdff0133ead3abf543636
5
5
  SHA512:
6
- metadata.gz: ccf9019e8758ea7b9c170c89a6f4cda9417251a114776b0682e9dd08da99df921641efd67d1bb4e64746af9d895576ddebe3cd6d56430ddc3011ed9c92958335
7
- data.tar.gz: 35fdb07709b25dbb699f730a8aa3c13d30a244aad2d7745f1db4542d03e063dd8cc5dc7922fed21311faf941ab9e8982e479110af7b97fe1e57d8a22d92e862d
6
+ metadata.gz: 8f76c80ad5ff76cc3bc14ef1f40226af2ca7fb3ba4ca26feff3be987cb233535ecc3eb1d77d59a1155b5de971e8bfab9b2d6466e8368d7bbb200897ad413c044
7
+ data.tar.gz: eeb89417bc4035669050d7007c2eda9b010664e8d8bbb88a07c28ef2fa4181a6e8c24dfe8b5b2b26bb87d6faf4e8a20dc75fc42811aba415a04bb944a135ba6d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
- # 0.1.0
1
+ # CHANGELOG
2
2
 
3
+ ## 0.2.0 (2021-04-14)
4
+ * Avoid warnings on RSpec `let` with parameter arrays ([#5](https://github.com/cobalthq/cobalt-rubocop/pull/5))
5
+ * Add new cop `InsecureHashAlgorithm`. ([#3](https://github.com/cobalthq/cobalt-rubocop/pull/3))
6
+ * Possible need to re-generate `.rubocop_todo.yml` when updating.
7
+
8
+ ## 0.1.0 (2021-02-10)
3
9
  * Introduce default rules
4
10
  * Introduce rails rules
5
11
  * Introduce rspec rules
data/README.md CHANGED
@@ -1,19 +1,37 @@
1
1
  # Cobalt RuboCop
2
+ [![Gem Version](https://badge.fury.io/rb/cobalt-rubocop.svg)](https://badge.fury.io/rb/cobalt-rubocop)
3
+ [![GitHub License](https://img.shields.io/github/license/cobalthq/cobalt-rubocop.svg)](https://github.com/cobalthq/cobalt-rubocop/blob/main/LICENSE)
4
+ ![Gem Downloads](https://img.shields.io/gem/dt/cobalt-rubocop)
5
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop-hq/rubocop)
2
6
 
3
7
  This repository provides recommended linting rules for Ruby repositories.
4
8
 
5
9
  ## Installation
6
10
 
7
11
  ### Gemfile
12
+ #### Add
13
+ ```ruby
14
+ group :development do
15
+ gem 'cobalt-rubocop', require: false
16
+ end
17
+ ```
8
18
 
9
- ```ruby
10
- group :development do
11
- gem 'cobalt-rubocop', require: false, git: 'https://github.com/cobalthq/cobalt-rubocop', branch: :main
12
- end
13
- ```
19
+ #### Remove
20
+ ```ruby
21
+ gem 'rubocop', require: false
22
+ gem 'rubocop-performance', require: false
23
+ gem 'rubocop-rails', require: false
24
+ gem 'rubocop-rspec', require: false
25
+ ```
14
26
 
15
- ### .rubocop.yml
27
+ [Specific versions](https://github.com/cobalthq/cobalt-rubocop/blob/main/cobalt-rubocop.gemspec) installed for:
28
+ - `rubocop`
29
+ - `rubocop-performance`
30
+ - `rubocop-rails`
31
+ - `rubocop-rspec`
16
32
 
33
+ ### .rubocop.yml
34
+ Configuration Options:
17
35
  ```yaml
18
36
  inherit_gem:
19
37
  cobalt-rubocop:
@@ -41,6 +59,32 @@ The number of offences can be counted:
41
59
  grep "Offense count" .rubocop_todo.yml | awk -F: '{sum+=$2} END {print sum}'
42
60
  ```
43
61
 
62
+ ## Custom Cops
63
+ ### InsecureHashAlgorithm
64
+ See [Ruby Docs](https://ruby-doc.org/stdlib-2.7.2/libdoc/openssl/rdoc/OpenSSL/Digest.html) for built in hash functions.
65
+
66
+ - Default Configuration:
67
+ ```yml
68
+ Cobalt/InsecureHashAlgorithm:
69
+ Allowed:
70
+ - SHA256
71
+ - SHA384
72
+ - SHA512
73
+ ```
74
+
75
+ ```ruby
76
+ # bad
77
+ OpenSSL::Digest::MD5.digest('abc')
78
+ OpenSSL::Digest::SHA1.digest('abc')
79
+ OpenSSL::HMAC.new('abc', 'sha1')
80
+
81
+ # good
82
+ OpenSSL::Digest::SHA256.digest('abc')
83
+ OpenSSL::Digest::SHA384.digest('abc')
84
+ OpenSSL::Digest::SHA512.digest('abc')
85
+ OpenSSL::HMAC.new('abc', 'sha256')
86
+ ```
87
+
44
88
  ## Development
45
89
  ```shell
46
90
  git clone git@github.com:cobalthq/cobalt-rubocop.git
@@ -55,10 +99,14 @@ In your application, use the `path` attribute to point to your local copy of the
55
99
  gem 'cobalt-rubocop', path: '../cobalt-rubocop', require: false
56
100
  ```
57
101
 
58
- ### Publishing the gem
59
- If you have access to publish the gem on rubygems:
60
- ```shell
61
- rake build
62
- cd pkg
63
- gem push cobalt-rubocop-<version_number>.gem
64
- ```
102
+ Alternatively:
103
+ - `rake build`
104
+ - `gem install pkg/cobalt-rubocop-<version_number>.gem`
105
+
106
+ ## Publish (internal)
107
+ > Note: Publishing a new version of this gem is only meant for maintainers.
108
+ - Ensure you have access to publish on [rubygems](https://rubygems.org/gems/cobalt-rubocop).
109
+ - Update [CHANGELOG](https://github.com/cobalthq/cobalt-rubocop/blob/main/CHANGELOG.md).
110
+ - Update [`VERSION`](https://github.com/cobalthq/cobalt-rubocop/blob/main/lib/rubocop/cobalt/version.rb).
111
+ - `rake release`
112
+ - This command builds the gem, creates a tag and publishes to rubygems, see [bundler docs](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
data/config/default.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  require:
2
2
  - rubocop-performance
3
+ - rubocop/cop/cobalt
3
4
 
4
5
  AllCops:
5
6
  NewCops: enable
@@ -57,3 +58,6 @@ Style/IfUnlessModifier:
57
58
 
58
59
  Style/ClassAndModuleChildren:
59
60
  EnforcedStyle: nested
61
+
62
+ Cobalt/InsecureHashAlgorithm:
63
+ Enabled: true
data/config/rspec.yml CHANGED
@@ -14,6 +14,7 @@ RSpec/MessageSpies:
14
14
  RSpec/VariableName:
15
15
  IgnoredPatterns:
16
16
  - ^Authorization
17
+ - '\[\]$' # For array parameters in rswag like `let(:'<parameter_name>[]')`
17
18
 
18
19
  RSpec/MultipleMemoizedHelpers:
19
20
  Max: 17
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cobalt
5
+ VERSION = '0.2.0'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop/cop/cobalt/insecure_hash_algorithm'
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ # original code from https://github.com/github/rubocop-github/blob/master/lib/rubocop/cop/github/insecure_hash_algorithm.rb
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Cobalt
8
+ class InsecureHashAlgorithm < Cop
9
+ # Matches constants like these:
10
+ # Digest::MD5
11
+ # OpenSSL::Digest::MD5
12
+ def_node_matcher :insecure_const?, <<-PATTERN
13
+ (const (const _ :Digest) #insecure_algorithm?)
14
+ PATTERN
15
+
16
+ # Matches calls like these:
17
+ # Digest.new('md5')
18
+ # Digest.hexdigest('md5', 'str')
19
+ # OpenSSL::Digest.new('md5')
20
+ # OpenSSL::Digest.hexdigest('md5', 'str')
21
+ # OpenSSL::Digest::Digest.new('md5')
22
+ # OpenSSL::Digest::Digest.hexdigest('md5', 'str')
23
+ # OpenSSL::Digest::Digest.new(:MD5)
24
+ # OpenSSL::Digest::Digest.hexdigest(:MD5, 'str')
25
+ def_node_matcher :insecure_digest?, <<-PATTERN
26
+ (send
27
+ (const _ {:Digest :HMAC})
28
+ #not_just_encoding?
29
+ #insecure_algorithm?
30
+ ...)
31
+ PATTERN
32
+
33
+ # Matches calls like "Digest(:MD5)".
34
+ def_node_matcher :insecure_hash_lookup?, <<-PATTERN
35
+ (send _ :Digest #insecure_algorithm?)
36
+ PATTERN
37
+
38
+ # Matches calls like "OpenSSL::HMAC.new(secret, hash)"
39
+ def_node_matcher :openssl_hmac_new?, <<-PATTERN
40
+ (send (const (const _ :OpenSSL) :HMAC) :new ...)
41
+ PATTERN
42
+
43
+ # Matches calls like "OpenSSL::HMAC.new(secret, 'sha1')"
44
+ def_node_matcher :openssl_hmac_new_insecure?, <<-PATTERN
45
+ (send (const (const _ :OpenSSL) :HMAC) :new _ #insecure_algorithm?)
46
+ PATTERN
47
+
48
+ # Matches Rails's Digest::UUID.
49
+ def_node_matcher :digest_uuid?, <<-PATTERN
50
+ (const (const _ :Digest) :UUID)
51
+ PATTERN
52
+
53
+ def_node_matcher :uuid_v3?, <<-PATTERN
54
+ (send (const _ :UUID) :uuid_v3 ...)
55
+ PATTERN
56
+
57
+ def_node_matcher :uuid_v5?, <<-PATTERN
58
+ (send (const _ :UUID) :uuid_v5 ...)
59
+ PATTERN
60
+
61
+ def insecure_algorithm?(val)
62
+ return false if val == :Digest # Don't match "Digest::Digest".
63
+
64
+ case alg_name(val)
65
+ when *allowed_hash_functions, Symbol
66
+ false
67
+ else
68
+ true
69
+ end
70
+ end
71
+
72
+ def not_just_encoding?(val)
73
+ !just_encoding?(val)
74
+ end
75
+
76
+ def just_encoding?(val)
77
+ %i[hexencode bubblebabble].include?(val)
78
+ end
79
+
80
+ DEFAULT_ALLOWED = %w[
81
+ SHA256
82
+ SHA384
83
+ SHA512
84
+ ].freeze
85
+
86
+ def allowed_hash_functions
87
+ @allowed_hash_functions ||= cop_config.fetch('Allowed', DEFAULT_ALLOWED).map(&:downcase)
88
+ end
89
+
90
+ def alg_name(val)
91
+ return :nil if val.nil?
92
+ return val.to_s.downcase unless val.is_a?(RuboCop::AST::Node)
93
+
94
+ case val.type
95
+ when :sym, :str
96
+ val.children.first.to_s.downcase
97
+ else
98
+ val.type
99
+ end
100
+ end
101
+
102
+ def on_const(const_node)
103
+ add_offense(const_node, message: default_message) if insecure_const?(const_node) && !digest_uuid?(const_node)
104
+ end
105
+
106
+ def on_send(send_node)
107
+ if uuid_v3?(send_node) && !allowed_hash_functions.include?('md5')
108
+ add_offense(send_node, message: "uuid_v3 uses MD5, which is not allowed. Prefer: #{allowed_hash_functions.join(', ')}")
109
+ elsif uuid_v5?(send_node) && !allowed_hash_functions.include?('sha1')
110
+ add_offense(send_node, message: "uuid_v5 uses SHA1, which is not allowed. Prefer: #{allowed_hash_functions.join(', ')}")
111
+ elsif openssl_hmac_new?(send_node) && openssl_hmac_new_insecure?(send_node) ||
112
+ insecure_digest?(send_node) || insecure_hash_lookup?(send_node)
113
+ add_offense(send_node, message: default_message)
114
+ end
115
+ end
116
+
117
+ def default_message
118
+ "This hash function is not allowed. Prefer: #{allowed_hash_functions.join(', ')}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cobalt-rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cobalt Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-10 00:00:00.000000000 Z
11
+ date: 2021-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 2.2.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 3.10.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 3.10.0
83
97
  description: Ruby code linting for Cobalt Ruby repositories
84
98
  email:
85
99
  executables: []
@@ -92,6 +106,9 @@ files:
92
106
  - config/default.yml
93
107
  - config/rails.yml
94
108
  - config/rspec.yml
109
+ - lib/rubocop/cobalt/version.rb
110
+ - lib/rubocop/cop/cobalt.rb
111
+ - lib/rubocop/cop/cobalt/insecure_hash_algorithm.rb
95
112
  homepage: https://github.com/cobalthq/cobalt-rubocop
96
113
  licenses:
97
114
  - MIT
@@ -115,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
132
  - !ruby/object:Gem::Version
116
133
  version: '0'
117
134
  requirements: []
118
- rubygems_version: 3.1.2
135
+ rubygems_version: 3.0.9
119
136
  signing_key:
120
137
  specification_version: 4
121
138
  summary: Cobalt RuboCop