rubocop-github 0.13.0 → 0.16.2
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/README.md +26 -2
- data/STYLEGUIDE.md +27 -11
- data/config/_default_shared.yml +329 -0
- data/config/_rails_shared.yml +120 -0
- data/config/default.yml +2 -328
- data/config/default_deprecated.yml +4 -0
- data/config/default_edge.yml +4 -0
- data/config/rails.yml +2 -122
- data/config/rails_deprecated.yml +7 -0
- data/config/rails_edge.yml +4 -0
- data/lib/rubocop/cop/github.rb +1 -0
- data/lib/rubocop/cop/github/insecure_hash_algorithm.rb +139 -0
- data/lib/rubocop/cop/github/rails_controller_render_action_symbol.rb +2 -2
- data/lib/rubocop/cop/github/rails_controller_render_literal.rb +32 -21
- data/lib/rubocop/cop/github/rails_controller_render_paths_exist.rb +3 -3
- data/lib/rubocop/cop/github/rails_controller_render_shorthand.rb +1 -1
- data/lib/rubocop/cop/github/rails_render_inline.rb +1 -1
- data/lib/rubocop/cop/github/rails_render_object_collection.rb +1 -1
- data/lib/rubocop/cop/github/rails_view_render_literal.rb +26 -21
- data/lib/rubocop/cop/github/rails_view_render_paths_exist.rb +3 -3
- data/lib/rubocop/cop/github/rails_view_render_shorthand.rb +1 -1
- data/lib/rubocop/cop/github/render_literal_helpers.rb +55 -0
- metadata +36 -15
data/lib/rubocop/cop/github.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rubocop/cop/github/insecure_hash_algorithm"
|
3
4
|
require "rubocop/cop/github/rails_application_record"
|
4
5
|
require "rubocop/cop/github/rails_controller_render_action_symbol"
|
5
6
|
require "rubocop/cop/github/rails_controller_render_literal"
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module GitHub
|
8
|
+
class InsecureHashAlgorithm < Cop
|
9
|
+
MSG = "This hash function is not allowed"
|
10
|
+
UUID_V3_MSG = "uuid_v3 uses MD5, which is not allowed"
|
11
|
+
UUID_V5_MSG = "uuid_v5 uses SHA1, which is not allowed"
|
12
|
+
|
13
|
+
# Matches constants like these:
|
14
|
+
# Digest::MD5
|
15
|
+
# OpenSSL::Digest::MD5
|
16
|
+
def_node_matcher :insecure_const?, <<-PATTERN
|
17
|
+
(const (const _ :Digest) #insecure_algorithm?)
|
18
|
+
PATTERN
|
19
|
+
|
20
|
+
# Matches calls like these:
|
21
|
+
# Digest.new('md5')
|
22
|
+
# Digest.hexdigest('md5', 'str')
|
23
|
+
# OpenSSL::Digest.new('md5')
|
24
|
+
# OpenSSL::Digest.hexdigest('md5', 'str')
|
25
|
+
# OpenSSL::Digest::Digest.new('md5')
|
26
|
+
# OpenSSL::Digest::Digest.hexdigest('md5', 'str')
|
27
|
+
# OpenSSL::Digest::Digest.new(:MD5)
|
28
|
+
# OpenSSL::Digest::Digest.hexdigest(:MD5, 'str')
|
29
|
+
def_node_matcher :insecure_digest?, <<-PATTERN
|
30
|
+
(send
|
31
|
+
(const _ {:Digest :HMAC})
|
32
|
+
#not_just_encoding?
|
33
|
+
#insecure_algorithm?
|
34
|
+
...)
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
# Matches calls like "Digest(:MD5)".
|
38
|
+
def_node_matcher :insecure_hash_lookup?, <<-PATTERN
|
39
|
+
(send _ :Digest #insecure_algorithm?)
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, hash)"
|
43
|
+
def_node_matcher :openssl_hmac_new?, <<-PATTERN
|
44
|
+
(send (const (const _ :OpenSSL) :HMAC) :new ...)
|
45
|
+
PATTERN
|
46
|
+
|
47
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, 'sha1')"
|
48
|
+
def_node_matcher :openssl_hmac_new_insecure?, <<-PATTERN
|
49
|
+
(send (const (const _ :OpenSSL) :HMAC) :new _ #insecure_algorithm?)
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
# Matches Rails's Digest::UUID.
|
53
|
+
def_node_matcher :digest_uuid?, <<-PATTERN
|
54
|
+
(const (const _ :Digest) :UUID)
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def_node_matcher :uuid_v3?, <<-PATTERN
|
58
|
+
(send (const _ :UUID) :uuid_v3 ...)
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
def_node_matcher :uuid_v5?, <<-PATTERN
|
62
|
+
(send (const _ :UUID) :uuid_v5 ...)
|
63
|
+
PATTERN
|
64
|
+
|
65
|
+
def insecure_algorithm?(val)
|
66
|
+
return false if val == :Digest # Don't match "Digest::Digest".
|
67
|
+
case alg_name(val)
|
68
|
+
when *allowed_hash_functions
|
69
|
+
false
|
70
|
+
when Symbol
|
71
|
+
# can't figure this one out, it's nil or a var or const.
|
72
|
+
false
|
73
|
+
else
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def not_just_encoding?(val)
|
79
|
+
!just_encoding?(val)
|
80
|
+
end
|
81
|
+
|
82
|
+
def just_encoding?(val)
|
83
|
+
val == :hexencode || val == :bubblebabble
|
84
|
+
end
|
85
|
+
|
86
|
+
# Built-in hash functions are listed in these docs:
|
87
|
+
# https://ruby-doc.org/stdlib-2.7.0/libdoc/digest/rdoc/Digest.html
|
88
|
+
# https://ruby-doc.org/stdlib-2.7.0/libdoc/openssl/rdoc/OpenSSL/Digest.html
|
89
|
+
DEFAULT_ALLOWED = %w[
|
90
|
+
SHA256
|
91
|
+
SHA384
|
92
|
+
SHA512
|
93
|
+
].freeze
|
94
|
+
|
95
|
+
def allowed_hash_functions
|
96
|
+
@allowed_algorithms ||= cop_config.fetch("Allowed", DEFAULT_ALLOWED).map(&:downcase)
|
97
|
+
end
|
98
|
+
|
99
|
+
def alg_name(val)
|
100
|
+
return :nil if val.nil?
|
101
|
+
return val.to_s.downcase unless val.is_a?(RuboCop::AST::Node)
|
102
|
+
case val.type
|
103
|
+
when :sym, :str
|
104
|
+
val.children.first.to_s.downcase
|
105
|
+
else
|
106
|
+
val.type
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_const(const_node)
|
111
|
+
if insecure_const?(const_node) && !digest_uuid?(const_node)
|
112
|
+
add_offense(const_node, message: MSG)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def on_send(send_node)
|
117
|
+
case
|
118
|
+
when uuid_v3?(send_node)
|
119
|
+
unless allowed_hash_functions.include?("md5")
|
120
|
+
add_offense(send_node, message: UUID_V3_MSG)
|
121
|
+
end
|
122
|
+
when uuid_v5?(send_node)
|
123
|
+
unless allowed_hash_functions.include?("sha1")
|
124
|
+
add_offense(send_node, message: UUID_V5_MSG)
|
125
|
+
end
|
126
|
+
when openssl_hmac_new?(send_node)
|
127
|
+
if openssl_hmac_new_insecure?(send_node)
|
128
|
+
add_offense(send_node, message: MSG)
|
129
|
+
end
|
130
|
+
when insecure_digest?(send_node)
|
131
|
+
add_offense(send_node, message: MSG)
|
132
|
+
when insecure_hash_lookup?(send_node)
|
133
|
+
add_offense(send_node, message: MSG)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -9,11 +9,11 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` with string instead of symbol"
|
10
10
|
|
11
11
|
def_node_matcher :render_sym?, <<-PATTERN
|
12
|
-
(send nil? :render $(sym _))
|
12
|
+
(send nil? {:render :render_to_string} $(sym _))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :render_with_options?, <<-PATTERN
|
16
|
-
(send nil? :render (hash $...))
|
16
|
+
(send nil? {:render :render_to_string} (hash $...))
|
17
17
|
PATTERN
|
18
18
|
|
19
19
|
def_node_matcher :action_key?, <<-PATTERN
|
@@ -1,32 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rubocop"
|
4
|
+
require "rubocop/cop/github/render_literal_helpers"
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
7
8
|
module GitHub
|
8
9
|
class RailsControllerRenderLiteral < Cop
|
9
|
-
|
10
|
+
include RenderLiteralHelpers
|
10
11
|
|
11
|
-
|
12
|
-
({str sym true false nil?} ...)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :render?, <<-PATTERN
|
16
|
-
(send nil? :render ...)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
-
(send nil? :render ({str sym} $_) $...)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def_node_matcher :render_const?, <<-PATTERN
|
24
|
-
(send nil? :render (const _ _) ...)
|
25
|
-
PATTERN
|
26
|
-
|
27
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
28
|
-
(send nil? :render (hash $...))
|
29
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a string literal or an instance of a Class"
|
30
13
|
|
31
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
32
15
|
(pair (sym {
|
@@ -64,10 +47,16 @@ module RuboCop
|
|
64
47
|
}) ...)
|
65
48
|
PATTERN
|
66
49
|
|
50
|
+
def_node_matcher :render_const?, <<-PATTERN
|
51
|
+
(send nil? {:render :render_to_string} (const _ _) ...)
|
52
|
+
PATTERN
|
53
|
+
|
67
54
|
def on_send(node)
|
68
55
|
return unless render?(node)
|
69
56
|
|
70
|
-
if
|
57
|
+
return if render_view_component?(node) || render_const?(node)
|
58
|
+
|
59
|
+
if render_literal?(node)
|
71
60
|
elsif option_pairs = render_with_options?(node)
|
72
61
|
option_pairs = option_pairs.reject { |pair| options_key?(pair) }
|
73
62
|
|
@@ -78,18 +67,40 @@ module RuboCop
|
|
78
67
|
if template_node = option_pairs.map { |pair| template_key?(pair) }.compact.first
|
79
68
|
if !literal?(template_node)
|
80
69
|
add_offense(node, location: :expression)
|
70
|
+
return
|
81
71
|
end
|
82
72
|
else
|
83
73
|
add_offense(node, location: :expression)
|
74
|
+
return
|
84
75
|
end
|
85
76
|
|
86
77
|
if layout_node = option_pairs.map { |pair| layout_key?(pair) }.compact.first
|
87
78
|
if !literal?(layout_node)
|
88
79
|
add_offense(node, location: :expression)
|
80
|
+
return
|
89
81
|
end
|
90
82
|
end
|
91
83
|
else
|
92
84
|
add_offense(node, location: :expression)
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
if render_literal?(node)
|
89
|
+
option_hash = node.arguments[1]
|
90
|
+
if option_hash && !option_hash.hash_type?
|
91
|
+
add_offense(node, location: :expression)
|
92
|
+
return
|
93
|
+
end
|
94
|
+
option_pairs = option_hash && option_hash.pairs
|
95
|
+
else
|
96
|
+
option_pairs = node.arguments[0].pairs
|
97
|
+
end
|
98
|
+
|
99
|
+
if option_pairs
|
100
|
+
locals = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
101
|
+
if locals && (!locals.hash_type? || !hash_with_literal_keys?(locals))
|
102
|
+
add_offense(node, location: :expression)
|
103
|
+
end
|
93
104
|
end
|
94
105
|
end
|
95
106
|
end
|
@@ -7,15 +7,15 @@ module RuboCop
|
|
7
7
|
module GitHub
|
8
8
|
class RailsControllerRenderPathsExist < Cop
|
9
9
|
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
10
|
+
(send nil? {:render :render_to_string} $...)
|
11
11
|
PATTERN
|
12
12
|
|
13
13
|
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $({str sym} $_) ...)
|
14
|
+
(send nil? {:render :render_to_string} $({str sym} $_) ...)
|
15
15
|
PATTERN
|
16
16
|
|
17
17
|
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
18
|
+
(send nil? {:render :render_to_string} (hash $...))
|
19
19
|
PATTERN
|
20
20
|
|
21
21
|
def_node_matcher :render_key?, <<-PATTERN
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` template shorthand"
|
10
10
|
|
11
11
|
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
12
|
+
(send nil? {:render :render_to_string} (hash $...))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :action_key?, <<-PATTERN
|
@@ -1,32 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rubocop"
|
4
|
+
require "rubocop/cop/github/render_literal_helpers"
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
7
8
|
module GitHub
|
8
9
|
class RailsViewRenderLiteral < Cop
|
9
|
-
|
10
|
+
include RenderLiteralHelpers
|
10
11
|
|
11
|
-
|
12
|
-
({str sym true false nil?} ...)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :render?, <<-PATTERN
|
16
|
-
(send nil? :render $...)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
-
(send nil? :render ({str sym} $_) $...)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def_node_matcher :render_const?, <<-PATTERN
|
24
|
-
(send nil? :render (const _ _) ...)
|
25
|
-
PATTERN
|
26
|
-
|
27
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
28
|
-
(send nil? :render (hash $...) ...)
|
29
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a literal template and use literals for locals keys"
|
30
13
|
|
31
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
32
15
|
(pair (sym {
|
@@ -46,7 +29,10 @@ module RuboCop
|
|
46
29
|
def on_send(node)
|
47
30
|
return unless render?(node)
|
48
31
|
|
49
|
-
|
32
|
+
# Ignore "component"-style renders
|
33
|
+
return if render_view_component?(node)
|
34
|
+
|
35
|
+
if render_literal?(node)
|
50
36
|
elsif option_pairs = render_with_options?(node)
|
51
37
|
if option_pairs.any? { |pair| ignore_key?(pair) }
|
52
38
|
return
|
@@ -55,12 +41,31 @@ module RuboCop
|
|
55
41
|
if partial_node = option_pairs.map { |pair| partial_key?(pair) }.compact.first
|
56
42
|
if !literal?(partial_node)
|
57
43
|
add_offense(node, location: :expression)
|
44
|
+
return
|
58
45
|
end
|
59
46
|
else
|
60
47
|
add_offense(node, location: :expression)
|
48
|
+
return
|
61
49
|
end
|
62
50
|
else
|
63
51
|
add_offense(node, location: :expression)
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
55
|
+
if render_literal?(node) && node.arguments.count > 1
|
56
|
+
locals = node.arguments[1]
|
57
|
+
elsif options_pairs = render_with_options?(node)
|
58
|
+
locals = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
59
|
+
end
|
60
|
+
|
61
|
+
if locals
|
62
|
+
if locals.hash_type?
|
63
|
+
if !hash_with_literal_keys?(locals)
|
64
|
+
add_offense(node, location: :expression)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
add_offense(node, location: :expression)
|
68
|
+
end
|
64
69
|
end
|
65
70
|
end
|
66
71
|
end
|
@@ -7,15 +7,15 @@ module RuboCop
|
|
7
7
|
module GitHub
|
8
8
|
class RailsViewRenderPathsExist < Cop
|
9
9
|
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
10
|
+
(send nil? {:render :render_to_string} $...)
|
11
11
|
PATTERN
|
12
12
|
|
13
13
|
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $(str $_) ...)
|
14
|
+
(send nil? {:render :render_to_string} $(str $_) ...)
|
15
15
|
PATTERN
|
16
16
|
|
17
17
|
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
18
|
+
(send nil? {:render :render_to_string} (hash $...))
|
19
19
|
PATTERN
|
20
20
|
|
21
21
|
def_node_matcher :partial_key?, <<-PATTERN
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` partial shorthand"
|
10
10
|
|
11
11
|
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
12
|
+
(send nil? {:render :render_to_string} (hash $...))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :partial_key?, <<-PATTERN
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module GitHub
|
8
|
+
module RenderLiteralHelpers
|
9
|
+
extend NodePattern::Macros
|
10
|
+
|
11
|
+
def_node_matcher :literal?, <<-PATTERN
|
12
|
+
({str sym true false nil?} ...)
|
13
|
+
PATTERN
|
14
|
+
|
15
|
+
def_node_matcher :render?, <<-PATTERN
|
16
|
+
(send nil? {:render :render_to_string} ...)
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
+
(send nil? {:render :render_to_string} ({str sym} $_) $...)
|
21
|
+
PATTERN
|
22
|
+
|
23
|
+
def_node_matcher :render_with_options?, <<-PATTERN
|
24
|
+
(send nil? {:render :render_to_string} (hash $...) ...)
|
25
|
+
PATTERN
|
26
|
+
|
27
|
+
def_node_matcher :render_view_component_instance?, <<-PATTERN
|
28
|
+
(send nil? {:render :render_to_string} (send _ :new ...) ...)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def_node_matcher :render_view_component_instance_with_content?, <<-PATTERN
|
32
|
+
(send nil? {:render :render_to_string} (send (send _ :new ...) `:with_content ...))
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def_node_matcher :render_view_component_collection?, <<-PATTERN
|
36
|
+
(send nil? {:render :render_to_string} (send _ :with_collection ...) ...)
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
def_node_matcher :locals_key?, <<-PATTERN
|
40
|
+
(pair (sym :locals) $_)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
def hash_with_literal_keys?(hash)
|
44
|
+
hash.pairs.all? { |pair| literal?(pair.key) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_view_component?(node)
|
48
|
+
render_view_component_instance_with_content?(node) ||
|
49
|
+
render_view_component_instance?(node) ||
|
50
|
+
render_view_component_collection?(node)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|