Skip to content

Commit 54a3477

Browse files
koicbbatsov
authored andcommitted
Add new Bundler/InsecureProtocolSource cop (#4720)
1 parent bf52e75 commit 54a3477

File tree

7 files changed

+160
-0
lines changed

7 files changed

+160
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* [#4696](https://github.com/bbatsov/rubocop/pull/4696): Add new `Performance/UriDefaultParser` cop. ([@koic][])
3030
* [#4694](https://github.com/bbatsov/rubocop/pull/4694): Add new `Lint/UriRegexp` cop. ([@koic][])
3131
* Add new `Style/MinMax` cop. ([@drenmi][])
32+
* [#4720](https://github.com/bbatsov/rubocop/pull/4720): Add new `Bundler/InsecureProtocolSource` cop. ([@koic][])
3233

3334
### Bug fixes
3435

config/enabled.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,16 @@ Bundler/DuplicatedGem:
18321832
- '**/Gemfile'
18331833
- '**/gems.rb'
18341834

1835+
Bundler/InsecureProtocolSource:
1836+
Description: >-
1837+
The source `:gemcutter`, `:rubygems` and `:rubyforge` are deprecated
1838+
because HTTP requests are insecure. Please change your source to
1839+
'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
1840+
Enabled: true
1841+
Include:
1842+
- '**/Gemfile'
1843+
- '**/gems.rb'
1844+
18351845
Bundler/OrderedGems:
18361846
Description: >-
18371847
Gems within groups in the Gemfile should be alphabetically sorted.

lib/rubocop.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
require 'rubocop/cop/mixin/unused_argument'
137137

138138
require 'rubocop/cop/bundler/duplicated_gem'
139+
require 'rubocop/cop/bundler/insecure_protocol_source'
139140
require 'rubocop/cop/bundler/ordered_gems'
140141

141142
require 'rubocop/cop/layout/access_modifier_indentation'
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Bundler
6+
# The symbol argument `:gemcutter`, `:rubygems` and `:rubyforge`
7+
# are deprecated. So please change your source to URL string that
8+
# 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
9+
#
10+
# This autocorrect will replace these symbols with 'https://rubygems.org'.
11+
# Because it is secure, HTTPS request is strongly recommended. And in
12+
# most use cases HTTPS will be fine.
13+
#
14+
# However, it don't replace all `sources` of `http://` with `https://`.
15+
# For example, when specifying an internal gem server using HTTP on the
16+
# intranet, a use case where HTTPS can not be specified was considered.
17+
# Consider using HTTP only if you can not use HTTPS.
18+
#
19+
# @example
20+
# # bad
21+
# source :gemcutter
22+
# source :rubygems
23+
# source :rubyforge
24+
#
25+
# # good
26+
# source 'https://rubygems.org' # strongly recommended
27+
# source 'http://rubygems.org'
28+
class InsecureProtocolSource < Cop
29+
MSG = 'The source `:%s` is deprecated because HTTP requests are ' \
30+
"insecure. Please change your source to 'https://rubygems.org' " \
31+
"if possible, or 'http://rubygems.org' if not.".freeze
32+
33+
def_node_matcher :insecure_protocol_source?, <<-PATTERN
34+
(send nil :source
35+
(sym ${:gemcutter :rubygems :rubyforge}))
36+
PATTERN
37+
38+
def on_send(node)
39+
insecure_protocol_source?(node) do |source|
40+
message = format(MSG, source)
41+
42+
add_offense(
43+
node, source_range(node.first_argument.loc.expression), message
44+
)
45+
end
46+
end
47+
48+
def autocorrect(node)
49+
lambda do |corrector|
50+
corrector.replace(
51+
node.first_argument.loc.expression, "'https://rubygems.org'"
52+
)
53+
end
54+
end
55+
56+
private
57+
58+
def source_range(node)
59+
range_between(node.begin_pos, node.end_pos)
60+
end
61+
end
62+
end
63+
end
64+
end

manual/cops.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ In the following section you find all available cops:
8989
#### Department [Bundler](cops_bundler.md)
9090

9191
* [Bundler/DuplicatedGem](cops_bundler.md#bundlerduplicatedgem)
92+
* [Bundler/InsecureProtocolSource](cops_bundler.md#bundlerinsecureprotocolsource)
9293
* [Bundler/OrderedGems](cops_bundler.md#bundlerorderedgems)
9394

9495
#### Department [Layout](cops_layout.md)

manual/cops_bundler.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,44 @@ Attribute | Value
3939
--- | ---
4040
Include | \*\*/Gemfile, \*\*/gems.rb
4141

42+
## Bundler/InsecureProtocolSource
43+
44+
Enabled by default | Supports autocorrection
45+
--- | ---
46+
Enabled | Yes
47+
48+
The symbol argument `:gemcutter`, `:rubygems` and `:rubyforge`
49+
are deprecated. So please change your source to URL string that
50+
'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
51+
52+
This autocorrect will replace these symbols with 'https://rubygems.org'.
53+
Because it is secure, HTTPS request is strongly recommended. And in
54+
most use cases HTTPS will be fine.
55+
56+
However, it don't replace all `sources` of `http://` with `https://`.
57+
For example, when specifying an internal gem server using HTTP on the
58+
intranet, a use case where HTTPS can not be specified was considered.
59+
Consider using HTTP only if you can not use HTTPS.
60+
61+
### Example
62+
63+
```ruby
64+
# bad
65+
source :gemcutter
66+
source :rubygems
67+
source :rubyforge
68+
69+
# good
70+
source 'https://rubygems.org' # strongly recommended
71+
source 'http://rubygems.org'
72+
```
73+
74+
### Important attributes
75+
76+
Attribute | Value
77+
--- | ---
78+
Include | \*\*/Gemfile, \*\*/gems.rb
79+
4280
## Bundler/OrderedGems
4381

4482
Enabled by default | Supports autocorrection
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# frozen_string_literal: true
2+
3+
describe RuboCop::Cop::Bundler::InsecureProtocolSource do
4+
let(:config) { RuboCop::Config.new }
5+
subject(:cop) { described_class.new(config) }
6+
7+
it 'registers an offense when using `source :gemcutter`' do
8+
expect_offense(<<-RUBY.strip_indent)
9+
source :gemcutter
10+
^^^^^^^^^^ The source `:gemcutter` is deprecated because HTTP requests are insecure. Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
11+
RUBY
12+
end
13+
14+
it 'registers an offense when using `source :rubygems`' do
15+
expect_offense(<<-RUBY.strip_indent)
16+
source :rubygems
17+
^^^^^^^^^ The source `:rubygems` is deprecated because HTTP requests are insecure. Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
18+
RUBY
19+
end
20+
21+
it 'registers an offense when using `source :rubyforge`' do
22+
expect_offense(<<-RUBY.strip_indent)
23+
source :rubyforge
24+
^^^^^^^^^^ The source `:rubyforge` is deprecated because HTTP requests are insecure. Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
25+
RUBY
26+
end
27+
28+
it 'autocorrects `source :gemcutter`' do
29+
new_source = autocorrect_source('source :gemcutter')
30+
31+
expect(new_source).to eq "source 'https://rubygems.org'"
32+
end
33+
34+
it 'autocorrects `source :rubygems`' do
35+
new_source = autocorrect_source('source :rubygems')
36+
37+
expect(new_source).to eq "source 'https://rubygems.org'"
38+
end
39+
40+
it 'autocorrects `source :rubyforge`' do
41+
new_source = autocorrect_source('source :rubyforge')
42+
43+
expect(new_source).to eq "source 'https://rubygems.org'"
44+
end
45+
end

0 commit comments

Comments
 (0)