rubocop-github 0.12.0 → 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +31 -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 -326
- data/config/default_deprecated.yml +4 -0
- data/config/default_edge.yml +4 -0
- data/config/rails.yml +2 -118
- 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 +31 -16
- 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 -16
- 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 +54 -0
- metadata +49 -14
data/config/rails.yml
CHANGED
@@ -1,118 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
Rails/FindEach:
|
5
|
-
Enabled: false
|
6
|
-
|
7
|
-
Rails/OutputSafety:
|
8
|
-
Enabled: true
|
9
|
-
|
10
|
-
Rails/PluralizationGrammar:
|
11
|
-
Enabled: true
|
12
|
-
|
13
|
-
Rails/RequestReferer:
|
14
|
-
Enabled: true
|
15
|
-
EnforcedStyle: referrer
|
16
|
-
|
17
|
-
Rails/ScopeArgs:
|
18
|
-
Enabled: true
|
19
|
-
|
20
|
-
Rails/UniqBeforePluck:
|
21
|
-
Enabled: true
|
22
|
-
|
23
|
-
GitHub/RailsApplicationRecord:
|
24
|
-
Enabled: true
|
25
|
-
|
26
|
-
GitHub/RailsControllerRenderActionSymbol:
|
27
|
-
Enabled: true
|
28
|
-
Include:
|
29
|
-
- 'app/controllers/**/*.rb'
|
30
|
-
|
31
|
-
GitHub/RailsControllerRenderLiteral:
|
32
|
-
Enabled: true
|
33
|
-
StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md
|
34
|
-
Include:
|
35
|
-
- 'app/controllers/**/*.rb'
|
36
|
-
|
37
|
-
GitHub/RailsControllerRenderPathsExist:
|
38
|
-
Enabled: true
|
39
|
-
ViewPath:
|
40
|
-
- 'app/views'
|
41
|
-
Include:
|
42
|
-
- 'app/controllers/**/*.rb'
|
43
|
-
|
44
|
-
GitHub/RailsControllerRenderShorthand:
|
45
|
-
Enabled: true
|
46
|
-
StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-shorthand.md
|
47
|
-
Include:
|
48
|
-
- 'app/controllers/**/*.rb'
|
49
|
-
|
50
|
-
GitHub/RailsRenderInline:
|
51
|
-
Enabled: true
|
52
|
-
StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-inline.md
|
53
|
-
Include:
|
54
|
-
- 'app/controllers/**/*.rb'
|
55
|
-
- 'app/helpers/**/*.rb'
|
56
|
-
- 'app/view_models/**/*.rb'
|
57
|
-
- 'app/views/**/*.erb'
|
58
|
-
|
59
|
-
GitHub/RailsRenderObjectCollection:
|
60
|
-
Enabled: false
|
61
|
-
|
62
|
-
GitHub/RailsViewRenderLiteral:
|
63
|
-
Enabled: true
|
64
|
-
StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md
|
65
|
-
Include:
|
66
|
-
- 'app/helpers/**/*.rb'
|
67
|
-
- 'app/view_models/**/*.rb'
|
68
|
-
- 'app/views/**/*.erb'
|
69
|
-
|
70
|
-
GitHub/RailsViewRenderPathsExist:
|
71
|
-
Enabled: true
|
72
|
-
ViewPath:
|
73
|
-
- 'app/views'
|
74
|
-
Include:
|
75
|
-
- 'app/helpers/**/*.rb'
|
76
|
-
- 'app/view_models/**/*.rb'
|
77
|
-
- 'app/views/**/*.erb'
|
78
|
-
|
79
|
-
GitHub/RailsViewRenderShorthand:
|
80
|
-
Enabled: true
|
81
|
-
Include:
|
82
|
-
- 'app/helpers/**/*.rb'
|
83
|
-
- 'app/view_models/**/*.rb'
|
84
|
-
- 'app/views/**/*.erb'
|
85
|
-
|
86
|
-
# Exclude Rails ERB files from incompatible cops
|
87
|
-
|
88
|
-
Layout/BlockAlignment:
|
89
|
-
Exclude:
|
90
|
-
- 'app/views/**/*.erb'
|
91
|
-
|
92
|
-
Style/For:
|
93
|
-
Exclude:
|
94
|
-
- 'app/views/**/*.erb'
|
95
|
-
|
96
|
-
Style/OneLineConditional:
|
97
|
-
Exclude:
|
98
|
-
- 'app/views/**/*.erb'
|
99
|
-
|
100
|
-
Style/Semicolon:
|
101
|
-
Exclude:
|
102
|
-
- 'app/views/**/*.erb'
|
103
|
-
|
104
|
-
Layout/SpaceInsideParens:
|
105
|
-
Exclude:
|
106
|
-
- 'app/views/**/*.erb'
|
107
|
-
|
108
|
-
Style/StringLiterals:
|
109
|
-
Exclude:
|
110
|
-
- 'app/views/**/*.erb'
|
111
|
-
|
112
|
-
Layout/TrailingBlankLines:
|
113
|
-
Exclude:
|
114
|
-
- 'app/views/**/*.erb'
|
115
|
-
|
116
|
-
Layout/TrailingWhitespace:
|
117
|
-
Exclude:
|
118
|
-
- 'app/views/**/*.erb'
|
1
|
+
# Inherit from rails_deprecated until 1.0
|
2
|
+
inherit_from: rails_deprecated.yml
|
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,28 +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_with_options?, <<-PATTERN
|
24
|
-
(send nil? :render (hash $...))
|
25
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a string literal or an instance of a Class"
|
26
13
|
|
27
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
28
15
|
(pair (sym {
|
@@ -60,9 +47,15 @@ module RuboCop
|
|
60
47
|
}) ...)
|
61
48
|
PATTERN
|
62
49
|
|
50
|
+
def_node_matcher :render_const?, <<-PATTERN
|
51
|
+
(send nil? {:render :render_to_string} (const _ _) ...)
|
52
|
+
PATTERN
|
53
|
+
|
63
54
|
def on_send(node)
|
64
55
|
return unless render?(node)
|
65
56
|
|
57
|
+
return if render_view_component?(node) || render_const?(node)
|
58
|
+
|
66
59
|
if render_literal?(node)
|
67
60
|
elsif option_pairs = render_with_options?(node)
|
68
61
|
option_pairs = option_pairs.reject { |pair| options_key?(pair) }
|
@@ -74,18 +67,40 @@ module RuboCop
|
|
74
67
|
if template_node = option_pairs.map { |pair| template_key?(pair) }.compact.first
|
75
68
|
if !literal?(template_node)
|
76
69
|
add_offense(node, location: :expression)
|
70
|
+
return
|
77
71
|
end
|
78
72
|
else
|
79
73
|
add_offense(node, location: :expression)
|
74
|
+
return
|
80
75
|
end
|
81
76
|
|
82
77
|
if layout_node = option_pairs.map { |pair| layout_key?(pair) }.compact.first
|
83
78
|
if !literal?(layout_node)
|
84
79
|
add_offense(node, location: :expression)
|
80
|
+
return
|
85
81
|
end
|
86
82
|
end
|
87
83
|
else
|
88
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
|
89
104
|
end
|
90
105
|
end
|
91
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,28 +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_with_options?, <<-PATTERN
|
24
|
-
(send nil? :render (hash $...) ...)
|
25
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a literal template and use literals for locals keys"
|
26
13
|
|
27
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
28
15
|
(pair (sym {
|
@@ -33,6 +20,7 @@ module RuboCop
|
|
33
20
|
def_node_matcher :partial_key?, <<-PATTERN
|
34
21
|
(pair (sym {
|
35
22
|
:file
|
23
|
+
:template
|
36
24
|
:layout
|
37
25
|
:partial
|
38
26
|
}) $_)
|
@@ -41,6 +29,9 @@ module RuboCop
|
|
41
29
|
def on_send(node)
|
42
30
|
return unless render?(node)
|
43
31
|
|
32
|
+
# Ignore "component"-style renders
|
33
|
+
return if render_view_component?(node)
|
34
|
+
|
44
35
|
if render_literal?(node)
|
45
36
|
elsif option_pairs = render_with_options?(node)
|
46
37
|
if option_pairs.any? { |pair| ignore_key?(pair) }
|
@@ -50,12 +41,31 @@ module RuboCop
|
|
50
41
|
if partial_node = option_pairs.map { |pair| partial_key?(pair) }.compact.first
|
51
42
|
if !literal?(partial_node)
|
52
43
|
add_offense(node, location: :expression)
|
44
|
+
return
|
53
45
|
end
|
54
46
|
else
|
55
47
|
add_offense(node, location: :expression)
|
48
|
+
return
|
56
49
|
end
|
57
50
|
else
|
58
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
|
59
69
|
end
|
60
70
|
end
|
61
71
|
end
|