cocoapods-whitelist 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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/lib/cocoapods-whitelist/gem_version.rb +1 -1
- data/lib/cocoapods-whitelist/helpers/source_helper.rb +29 -0
- data/lib/cocoapods-whitelist/hook/resolver.rb +19 -8
- data/lib/cocoapods-whitelist/model/sources.rb +2 -5
- data/lib/cocoapods-whitelist/validator/source_validator.rb +16 -35
- data/spec/source_helper_spec.rb +66 -0
- data/spec/source_validator_spec.rb +25 -48
- data/spec/whitelist_resolver_spec.rb +4 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a49d340692ecaa352c48b9970b6820303342d5063364296512169b5a317c5db5
|
4
|
+
data.tar.gz: 7e0d1d9a788778ec9dfd2a934a5ef87f7ae12f13d15d3455336fdbcc66966563
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b48688ae3e2269e569c949229aea2a10b10a617d30ddff8ebb3c905c02984910097076c51de843783077d54539fe9fe32a9411ae61539c27edb78d516cc140db
|
7
|
+
data.tar.gz: 51d17dc94984f8ef2fdcec75e79bb50ef3c0c922af9edeaf7ee3d23360dc47d17d3cc9add6a174357b6db11752faa30b1ced9a712163721217efd4687ce32b08
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../model/sources'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
# In charge of host the Pods names that comes from our private sources
|
5
|
+
#
|
6
|
+
# NOTE: The safest way to handle this was to host the complete specification and not only the pods
|
7
|
+
# names as rubydocs specified
|
8
|
+
# (https://www.rubydoc.info/github/CocoaPods/Core/Pod/Source#all_specs-instance_method)
|
9
|
+
# However, the execution time was considerably slower.
|
10
|
+
#
|
11
|
+
class SourceHelper
|
12
|
+
include Singleton
|
13
|
+
attr_accessor :specs
|
14
|
+
|
15
|
+
def initialize()
|
16
|
+
@specs ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup(sources, private_sources)
|
20
|
+
private_sources = sources.select {|s| private_sources.include? s.url}
|
21
|
+
private_sources.each do |s|
|
22
|
+
@specs.concat s.pods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_filled
|
27
|
+
return !@specs.empty?
|
28
|
+
end
|
29
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../validator/source_validator'
|
2
|
+
require_relative '../helpers/source_helper'
|
2
3
|
require_relative '../model/sources'
|
3
4
|
|
4
5
|
module Pod
|
@@ -6,18 +7,28 @@ module Pod
|
|
6
7
|
alias original_search_for search_for
|
7
8
|
## Filter specifications
|
8
9
|
def search_for(dependency)
|
10
|
+
## If you have a dependency problem, then no specification is returned from :search_for
|
9
11
|
specifications = original_search_for(dependency)
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Pod::UI.puts "Dependency #{dependency.root_name} comes from source #{specifications.first.spec_source.url} is NOT allowed".red
|
16
|
-
Pod::UI.puts "If you thing this is a mistake, please check the whitelist".red
|
17
|
-
raise Informative.new()
|
13
|
+
valid_specifications = validate_dependency(dependency,specifications)
|
14
|
+
if valid_specifications.size != specifications.size
|
15
|
+
Pod::UI.puts "WARNING: More than 1 specification for dependency #{dependency.root_name} was found.".yellow
|
16
|
+
Pod::UI.puts "WARNING: Check if this could be a potencial dependency inyection".red
|
18
17
|
end
|
19
18
|
|
20
|
-
|
19
|
+
valid_specifications
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the valids specifications for a given dependency
|
23
|
+
# Params:
|
24
|
+
# +dependency+:: dependency to be validated
|
25
|
+
# +specifications+:: potencial unsecure specs
|
26
|
+
# @returs the result of the validation
|
27
|
+
def validate_dependency(dependency, specifications)
|
28
|
+
private_sources = get_private_sources()
|
29
|
+
SourceHelper.instance.setup(sources, private_sources) unless SourceHelper.instance.is_filled
|
30
|
+
validator = SourceValidator.new(SourceHelper.instance.specs, private_sources)
|
31
|
+
return validator.filter_dependency(dependency.root_name, specifications)
|
21
32
|
end
|
22
33
|
end
|
23
34
|
end
|
@@ -1,52 +1,33 @@
|
|
1
|
-
require_relative '../client/whitelist_resolver'
|
2
1
|
require 'singleton'
|
3
2
|
|
4
3
|
class SourceValidator
|
5
|
-
attr_accessor :
|
6
|
-
|
7
|
-
|
4
|
+
attr_accessor :private_specs
|
5
|
+
attr_accessor :private_sources
|
6
|
+
def initialize(private_specs, private_sources)
|
7
|
+
@private_specs = private_specs
|
8
|
+
@private_sources = private_sources
|
8
9
|
end
|
9
10
|
|
11
|
+
# Filters the valids specifications for a given pod
|
12
|
+
# Params:
|
13
|
+
# +pod+:: podname to be validated
|
14
|
+
# +specifications+:: potencial unsecure specs
|
15
|
+
# @returs valid specs
|
10
16
|
def filter_dependency(pod, specifications)
|
11
|
-
|
12
|
-
return [specifications.first] if DependencyCounter.instance.is_checked(pod) && !specifications.empty?
|
13
|
-
|
14
|
-
filtered = specifications.select { |spec| spec_is_valid(pod, spec) }
|
15
|
-
|
16
|
-
return filtered
|
17
|
+
return specifications.select { |spec| spec_is_valid(pod, spec) }
|
17
18
|
end
|
18
19
|
|
19
20
|
def spec_is_valid(pod, spec)
|
20
|
-
|
21
21
|
# Allow external dependencies (using :git or :path), which create a local podspec
|
22
22
|
return true if !spec.defined_in_file.nil? && spec.defined_in_file.to_s.include?('/Pods/Local Podspecs')
|
23
23
|
|
24
|
-
# Allow every dependency that comes from our
|
25
|
-
return true if spec.spec_source.url
|
26
|
-
|
27
|
-
whitelist = WhitelistResolver.instance.get_whitelist
|
28
|
-
whitelist.each { |dependency|
|
29
|
-
next unless dependency.name == pod
|
30
|
-
return true unless spec.spec_source.url != @sources[dependency.source]
|
31
|
-
}
|
32
|
-
return false
|
33
|
-
end
|
24
|
+
# Allow every dependency that comes from our privates sources
|
25
|
+
return true if @private_sources.include? spec.spec_source.url
|
34
26
|
|
35
|
-
|
27
|
+
# NO dependency that comes from a public source should be in our private specs
|
28
|
+
return true if !@private_specs.include? spec.name
|
36
29
|
|
37
|
-
|
38
|
-
include Singleton
|
39
|
-
attr_accessor :dependencies_checked
|
40
|
-
|
41
|
-
def initialize()
|
42
|
-
@dependencies_checked ||= []
|
43
|
-
end
|
44
|
-
|
45
|
-
def is_checked(podname)
|
46
|
-
included = @dependencies_checked.include? podname
|
47
|
-
@dependencies_checked.push(podname) unless included
|
48
|
-
|
49
|
-
return included
|
30
|
+
return false
|
50
31
|
end
|
51
32
|
|
52
33
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe SourceHelper do
|
4
|
+
describe 'behaviour' do
|
5
|
+
it 'should group the private specs from the differents private sources' do
|
6
|
+
|
7
|
+
SourceHelper.instance.specs = [] # Avoid a non-empty SourceHelper
|
8
|
+
|
9
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git", "git@github.com:testable/testable_specs.git" ]
|
10
|
+
|
11
|
+
private_meli_specs = ["MyMELIPod1", "MyMELIPod2", "MyMELIPod3"]
|
12
|
+
meli_mock = mock()
|
13
|
+
meli_mock.stubs(:url).returns("git@github.com:mercadolibre/mobile-ios_specs.git")
|
14
|
+
meli_mock.stubs(:pods).returns(private_meli_specs)
|
15
|
+
|
16
|
+
private_cocoapods_cdn_specs = ["MyPublicPod1", "MyPublicPod2", "MyPublicPod2"]
|
17
|
+
cocoapods_cdn_mock = mock()
|
18
|
+
cocoapods_cdn_mock.stubs(:url).returns("https://cdn.cocoapods.org/")
|
19
|
+
cocoapods_cdn_mock.stubs(:pods).returns(private_cocoapods_cdn_specs)
|
20
|
+
|
21
|
+
private_testable_specs = ["MyTestablePod1", "MyTestablePod2", "MyTestablePod2"]
|
22
|
+
testable_mock = mock()
|
23
|
+
testable_mock.stubs(:url).returns("git@github.com:testable/testable_specs.git")
|
24
|
+
testable_mock.stubs(:pods).returns(private_testable_specs)
|
25
|
+
|
26
|
+
sources = [meli_mock, cocoapods_cdn_mock, testable_mock]
|
27
|
+
|
28
|
+
expected_result = [ "MyMELIPod1", "MyMELIPod2", "MyMELIPod3", "MyTestablePod1", "MyTestablePod2", "MyTestablePod2" ]
|
29
|
+
|
30
|
+
validator = SourceHelper.instance.setup(sources, private_sources)
|
31
|
+
|
32
|
+
SourceHelper.instance.specs.size.should.equal 6
|
33
|
+
SourceHelper.instance.is_filled.should.be.true
|
34
|
+
SourceHelper.instance.specs.should.equal expected_result
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should not be filled if not specs been added' do
|
38
|
+
|
39
|
+
SourceHelper.instance.specs = [] # Avoid a non-empty SourceHelper
|
40
|
+
|
41
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git", "git@github.com:testable/testable_specs.git" ]
|
42
|
+
|
43
|
+
private_meli_specs = []
|
44
|
+
meli_mock = mock()
|
45
|
+
meli_mock.stubs(:url).returns("git@github.com:mercadolibre/mobile-ios_specs.git")
|
46
|
+
meli_mock.stubs(:pods).returns(private_meli_specs)
|
47
|
+
|
48
|
+
private_cocoapods_cdn_specs = []
|
49
|
+
cocoapods_cdn_mock = mock()
|
50
|
+
cocoapods_cdn_mock.stubs(:url).returns("https://cdn.cocoapods.org/")
|
51
|
+
cocoapods_cdn_mock.stubs(:pods).returns(private_cocoapods_cdn_specs)
|
52
|
+
|
53
|
+
private_testable_specs = []
|
54
|
+
testable_mock = mock()
|
55
|
+
testable_mock.stubs(:url).returns("git@github.com:testable/testable_specs.git")
|
56
|
+
testable_mock.stubs(:pods).returns(private_testable_specs)
|
57
|
+
|
58
|
+
sources = [meli_mock, cocoapods_cdn_mock, testable_mock]
|
59
|
+
|
60
|
+
validator = SourceHelper.instance.setup(sources, private_sources)
|
61
|
+
|
62
|
+
SourceHelper.instance.specs.size.should.equal 0
|
63
|
+
SourceHelper.instance.is_filled.should.not.be.true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -2,91 +2,68 @@ require File.expand_path('../spec_helper', __FILE__)
|
|
2
2
|
|
3
3
|
describe SourceValidator do
|
4
4
|
describe 'functionality' do
|
5
|
-
it 'external dependency that
|
5
|
+
it 'external dependency that comes from a public source should be valid' do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
"private" => "git@github.com:mercadolibre/mobile-ios_specs.git"
|
10
|
-
}
|
7
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git" ]
|
8
|
+
private_specs = ["MyPod1", "MyPod1", "MyPod3"]
|
11
9
|
|
12
10
|
stub_url = stub(:url => 'https://cdn.cocoapods.org/')
|
13
11
|
spec_mock = mock()
|
14
12
|
spec_mock.stubs(:spec_source).returns(stub_url)
|
15
13
|
spec_mock.stubs(:defined_in_file).returns(nil?)
|
14
|
+
spec_mock.stubs(:name).returns("MyExternalPod")
|
16
15
|
|
17
|
-
validator = SourceValidator.new(
|
18
|
-
filtered = validator.filter_dependency(
|
19
|
-
|
20
|
-
filtered.should.empty?
|
16
|
+
validator = SourceValidator.new(private_specs, private_sources)
|
17
|
+
filtered = validator.filter_dependency("MyExternalPod", [spec_mock])
|
21
18
|
|
19
|
+
filtered.size.should.equal 1
|
22
20
|
end
|
23
21
|
|
24
|
-
it '
|
25
|
-
|
26
|
-
|
27
|
-
"public" => "https://cdn.cocoapods.org/",
|
28
|
-
"private" => "git@github.com:mercadolibre/mobile-ios_specs.git"
|
29
|
-
}
|
22
|
+
it 'internal dependency that comes from a public source should not be valid' do
|
23
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git" ]
|
24
|
+
private_specs = ["MyPod1", "MyPod1", "MyPod3", "MyInternalPod"]
|
30
25
|
|
31
26
|
stub_url = stub(:url => 'https://cdn.cocoapods.org/')
|
32
27
|
spec_mock = mock()
|
33
28
|
spec_mock.stubs(:spec_source).returns(stub_url)
|
34
29
|
spec_mock.stubs(:defined_in_file).returns(nil?)
|
30
|
+
spec_mock.stubs(:name).returns("MyInternalPod")
|
35
31
|
|
36
|
-
validator = SourceValidator.new(
|
37
|
-
filtered = validator.filter_dependency(
|
38
|
-
|
39
|
-
filtered.size.should.equal 1
|
32
|
+
validator = SourceValidator.new(private_specs, private_sources)
|
33
|
+
filtered = validator.filter_dependency("MyInternalPod", [spec_mock])
|
40
34
|
|
35
|
+
filtered.should.empty?
|
41
36
|
end
|
42
37
|
|
43
38
|
it 'internal dependency that comes from private source should be valid' do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
}
|
39
|
+
|
40
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git" ]
|
41
|
+
private_specs = ["MyPod1", "MyPod1", "MyPod3", "MyInternalPod"]
|
48
42
|
|
49
43
|
stub_url = stub(:url => 'git@github.com:mercadolibre/mobile-ios_specs.git')
|
50
44
|
spec_mock = mock()
|
51
45
|
spec_mock.stubs(:spec_source).returns(stub_url)
|
52
46
|
spec_mock.stubs(:defined_in_file).returns(nil?)
|
47
|
+
spec_mock.stubs(:name).returns("MyInternalPod")
|
53
48
|
|
54
|
-
validator = SourceValidator.new(
|
55
|
-
filtered = validator.filter_dependency(
|
49
|
+
validator = SourceValidator.new(private_specs, private_sources)
|
50
|
+
filtered = validator.filter_dependency("MyInternalPod", [spec_mock])
|
56
51
|
|
57
52
|
filtered.size.should.equal 1
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'internal dependency that comes from unknown source should not be valid' do
|
62
|
-
sources = {
|
63
|
-
"public" => "https://cdn.cocoapods.org/",
|
64
|
-
"private" => "git@github.com:mercadolibre/mobile-ios_specs.git"
|
65
|
-
}
|
66
|
-
|
67
|
-
stub_url = stub(:url => 'https://cdn.malicious.source.org/')
|
68
|
-
spec_mock = mock()
|
69
|
-
spec_mock.stubs(:spec_source).returns(stub_url)
|
70
|
-
spec_mock.stubs(:defined_in_file).returns(nil?)
|
71
|
-
|
72
|
-
validator = SourceValidator.new(sources)
|
73
|
-
filtered = validator.filter_dependency('MLOnDemandResources', [spec_mock])
|
74
|
-
|
75
|
-
filtered.should.empty?
|
76
53
|
end
|
77
54
|
|
78
55
|
it 'development pods should be valid' do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
}
|
56
|
+
|
57
|
+
private_sources = [ "git@github.com:mercadolibre/mobile-ios_specs.git" ]
|
58
|
+
private_specs = ["MyPod1", "MyPod1", "MyPod3", "MyInternalPod"]
|
83
59
|
|
84
60
|
stub_url = stub(:url => '')
|
85
61
|
spec_mock = mock()
|
86
62
|
spec_mock.stubs(:spec_source).returns(stub_url)
|
87
63
|
spec_mock.stubs(:defined_in_file).returns('./Users/Pods/Local Podspecs/MLMyDevelopmentPod.podspec')
|
64
|
+
spec_mock.stubs(:name).returns("MLMyDevelopmentPod")
|
88
65
|
|
89
|
-
validator = SourceValidator.new(
|
66
|
+
validator = SourceValidator.new(private_specs, private_sources)
|
90
67
|
filtered = validator.filter_dependency('MLMyDevelopmentPod', [spec_mock])
|
91
68
|
|
92
69
|
filtered.size.should.equal 1
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require File.expand_path('../spec_helper', __FILE__)
|
2
2
|
|
3
|
+
WHITELIST_PATH = './spec/mocks/whitelist.json'
|
4
|
+
|
3
5
|
describe WhitelistResolver do
|
4
6
|
describe 'functionality' do
|
5
7
|
it 'whitelist should be loaded from an specific url' do
|
6
|
-
whitelist = WhitelistResolver.instance.get_whitelist(
|
8
|
+
whitelist = WhitelistResolver.instance.get_whitelist(WHITELIST_PATH)
|
7
9
|
whitelist.size.should.equal 6
|
8
10
|
end
|
9
11
|
|
@@ -13,7 +15,7 @@ describe WhitelistResolver do
|
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'whitelist should not be loaded twice' do
|
16
|
-
WhitelistResolver.instance.get_whitelist(
|
18
|
+
WhitelistResolver.instance.get_whitelist(WHITELIST_PATH)
|
17
19
|
loaded = WhitelistResolver.instance.whitelist_loaded
|
18
20
|
|
19
21
|
loaded.should.be.true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-whitelist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mobile Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/cocoapods-whitelist/command.rb
|
60
60
|
- lib/cocoapods-whitelist/command/whitelist.rb
|
61
61
|
- lib/cocoapods-whitelist/gem_version.rb
|
62
|
+
- lib/cocoapods-whitelist/helpers/source_helper.rb
|
62
63
|
- lib/cocoapods-whitelist/hook.rb
|
63
64
|
- lib/cocoapods-whitelist/hook/resolver.rb
|
64
65
|
- lib/cocoapods-whitelist/model/allowed_dependency.rb
|
@@ -87,6 +88,7 @@ files:
|
|
87
88
|
- spec/mocks/with_whitelisted_dependency_fixed_versions_variable.podspec
|
88
89
|
- spec/mocks/without_dependencies.podspec
|
89
90
|
- spec/mocks/without_version.podspec
|
91
|
+
- spec/source_helper_spec.rb
|
90
92
|
- spec/source_validator_spec.rb
|
91
93
|
- spec/spec_helper.rb
|
92
94
|
- spec/whitelist_resolver_spec.rb
|
@@ -137,6 +139,7 @@ test_files:
|
|
137
139
|
- spec/mocks/with_whitelisted_dependency_fixed_versions_variable.podspec
|
138
140
|
- spec/mocks/without_dependencies.podspec
|
139
141
|
- spec/mocks/without_version.podspec
|
142
|
+
- spec/source_helper_spec.rb
|
140
143
|
- spec/source_validator_spec.rb
|
141
144
|
- spec/spec_helper.rb
|
142
145
|
- spec/whitelist_resolver_spec.rb
|