bundler-organization_audit 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bbae92ba27efe58d7dcd0815e927cee9ee819af
4
- data.tar.gz: 4d282857fa1e954191097cfe40643052c6353747
3
+ metadata.gz: 708695d5b54015a1a14008336d22d1213eeae7e5
4
+ data.tar.gz: 0c2987f848a7d9002aaf8bc883ff4bf3899c707a
5
5
  SHA512:
6
- metadata.gz: 704c1cf251aa4dc836d8b1983a11c2ef11594d265fd396c661a8907511ec6af31ce732c542b2b8f8f06f9300875314743305a6791406f9a71761dccdc120f012
7
- data.tar.gz: acd41b3091c673fae50ef1afb120021da6b33d20a3c2bab3df207df88a9e34e31346b74fe824256de175afc48f7a6d6d5b0afc9c0320c51f3d0b1910ba04594f
6
+ metadata.gz: 0f7f1174ba2f0969add5dba70d8a8758180b3f3cb664c03c75dad520dbbd0e02daa90b0d9e1eedbde9abfa7be60086571c385dc315bfb23d26a6a674083810a3
7
+ data.tar.gz: bb3e994690db9873c403a6f39cfbe53170e7c8762e1e91238a4c9327f91ece2b49b0fea2053dafbfe77782bd6480c6abca04b04b479746a23c78265418d337f5
@@ -15,8 +15,8 @@ options = {
15
15
  :ignore_cves => [],
16
16
  :user => git_config("github.user")
17
17
  }
18
- OptionParser.new do |opts|
19
- opts.banner = <<BANNER
18
+ OptionParser.new do |parser|
19
+ parser.banner = <<BANNER
20
20
  Audit all Gemfiles of a user/organization on github for unpatched versions
21
21
 
22
22
  Usage:
@@ -24,14 +24,11 @@ Usage:
24
24
 
25
25
  Options:
26
26
  BANNER
27
- opts.on("--token TOKEN", "Use token") { |token| options[:token] = token }
28
- opts.on("--user USER", "Use user") { |user| options[:user] = user }
29
- opts.on("--ignore REPO_URL", "Ignore given repo urls (use multiple times)") { |repo_url| options[:ignore] << repo_url }
30
- opts.on("--ignore-gems", "Ignore repos that have a %{repo}.gemspec") { options[:ignore_gems] = true }
31
- opts.on("--ignore-cve CVE_NUMBER", "Ignore CVE that you do not want to get warned about just number or number@gem-version") { |cve| options[:ignore_cves] << cve }
32
- opts.on("--organization ORGANIZATION", "Use user") { |organization| options[:organization] = organization }
33
- opts.on("-h", "--help", "Show this.") { puts opts; exit }
34
- opts.on("-v", "--version", "Show Version"){ puts Bundler::OrganizationAudit::VERSION; exit}
27
+ OrganizationAudit.optparse(parser, options)
28
+ parser.on("--ignore-gems", "Ignore repos that have a %{repo}.gemspec") { options[:ignore_gems] = true }
29
+ parser.on("--ignore-cve CVE_NUMBER", "Ignore CVE that you do not want to get warned about just number or number@gem-version") { |cve| options[:ignore_cves] << cve }
30
+ parser.on("-h", "--help", "Show this.") { puts parser; exit }
31
+ parser.on("-v", "--version", "Show Version"){ puts Bundler::OrganizationAudit::VERSION; exit}
35
32
  end.parse!
36
33
 
37
34
  exit Bundler::OrganizationAudit.run(options)
@@ -1,6 +1,6 @@
1
1
  require "bundler/organization_audit/version"
2
+ require "organization_audit"
2
3
  require "tmpdir"
3
- require "bundler/organization_audit/repo"
4
4
 
5
5
  module Bundler
6
6
  module OrganizationAudit
@@ -24,40 +24,38 @@ module Bundler
24
24
  end
25
25
 
26
26
  def find_vulnerable(options)
27
- Repo.all(options).select do |repo|
28
- next if (options[:ignore] || []).include? repo.url
27
+ ::OrganizationAudit.all(options).select do |repo|
28
+ next if options[:ignore_gems] && repo.gem?
29
29
  audit_repo(repo, options)
30
30
  end
31
31
  end
32
32
 
33
33
  def audit_repo(repo, options)
34
- success = false
35
- $stderr.puts repo.project
34
+ vulnerable = false
35
+ $stderr.puts repo.name
36
36
  in_temp_dir do
37
37
  if download_file(repo, "Gemfile.lock")
38
- if options[:ignore_gems] && repo.gem?
39
- $stderr.puts "Ignored because it's a gem"
40
- else
41
- command = "bundle-audit"
42
- if options[:ignore_cves] && options[:ignore_cves].any?
43
- command << " --ignore #{options[:ignore_cves].map { |cve| "'CVE-#{cve}'" }.join(" ")}"
44
- end
45
- success = !sh(command)
38
+ command = "bundle-audit"
39
+ if options[:ignore_cves] && options[:ignore_cves].any?
40
+ command << " --ignore #{options[:ignore_cves].map { |cve| "'CVE-#{cve}'" }.join(" ")}"
46
41
  end
42
+ vulnerable = !sh(command)
47
43
  else
48
44
  $stderr.puts "No Gemfile.lock found"
49
45
  end
50
46
  end
51
47
  $stderr.puts ""
52
- success
48
+ vulnerable
53
49
  rescue Exception => e
54
- $stderr.puts "Error auditing #{repo.project} (#{e})"
50
+ $stderr.puts "Error auditing #{repo.name} (#{e})"
51
+ true
55
52
  end
56
53
 
57
54
  def in_temp_dir(&block)
58
55
  Dir.mktmpdir { |dir| Dir.chdir(dir, &block) }
59
56
  end
60
57
 
58
+ # http://grosser.it/2010/12/11/sh-without-rake
61
59
  def sh(cmd)
62
60
  $stderr.puts cmd
63
61
  IO.popen(cmd) do |pipe|
@@ -1,5 +1,5 @@
1
1
  module Bundler
2
2
  module OrganizationAudit
3
- VERSION = "0.1.3"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-organization_audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-10 00:00:00.000000000 Z
11
+ date: 2013-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: json
14
+ name: organization_audit
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '>='
@@ -33,7 +33,6 @@ extra_rdoc_files: []
33
33
  files:
34
34
  - bin/bundle-organization-audit
35
35
  - lib/bundler/organization_audit.rb
36
- - lib/bundler/organization_audit/repo.rb
37
36
  - lib/bundler/organization_audit/version.rb
38
37
  homepage: http://github.com/grosser/bundler-organization_audit
39
38
  licenses:
@@ -55,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
54
  version: '0'
56
55
  requirements: []
57
56
  rubyforge_project:
58
- rubygems_version: 2.0.6
57
+ rubygems_version: 2.0.14
59
58
  signing_key:
60
59
  specification_version: 4
61
60
  summary: Audit all Gemfiles of a user/organization on github for unpatched versions
@@ -1,134 +0,0 @@
1
- require "open-uri"
2
- require "json"
3
- require "base64"
4
-
5
- module Bundler
6
- module OrganizationAudit
7
- class Repo
8
- HOST = "https://api.github.com"
9
-
10
- def initialize(data, token=nil)
11
- @data = data
12
- @token = token
13
- end
14
-
15
- def gem?
16
- !!gemspec_content
17
- end
18
-
19
- def gemspec_content
20
- content("#{project}.gemspec")
21
- end
22
-
23
- def url
24
- api_url.sub("api.", "").sub("/repos", "")
25
- end
26
-
27
- def to_s
28
- "#{url} -- #{last_commiter}"
29
- end
30
-
31
- def project
32
- api_url.split("/").last
33
- end
34
-
35
- def self.all(options)
36
- user = if options[:organization]
37
- "orgs/#{options[:organization]}"
38
- elsif options[:user]
39
- "users/#{options[:user]}"
40
- else
41
- "user"
42
- end
43
- url = File.join(HOST, user, "repos")
44
-
45
- token = options[:token]
46
- download_all_pages(url, headers(token)).map { |data| Repo.new(data, token) }
47
- end
48
-
49
- def content(file)
50
- @content ||= {}
51
- @content[file] ||= begin
52
- if private?
53
- download_content_via_api(file)
54
- else
55
- download_content_via_raw(file)
56
- end
57
- end
58
- rescue OpenURI::HTTPError => e
59
- raise "Error downloading #{file} from #{url} (#{e})" unless e.message.start_with?("404")
60
- end
61
-
62
- def private?
63
- @data["private"]
64
- end
65
-
66
- def last_commiter
67
- response = call_api("commits/#{branch}")
68
- committer = response["commit"]["committer"]
69
- "#{committer["name"]} <#{committer["email"]}>"
70
- end
71
-
72
- private
73
-
74
- def self.download_all_pages(url, headers)
75
- results = []
76
- page = 1
77
- loop do
78
- response = decorate_errors do
79
- open("#{url}?page=#{page}", headers).read
80
- end
81
- result = JSON.parse(response)
82
- if result.size == 0
83
- break
84
- else
85
- results.concat(result)
86
- page += 1
87
- end
88
- end
89
- results
90
- end
91
-
92
- def branch
93
- @data["default_branch"] || @data["master_branch"] || "master"
94
- end
95
-
96
- def api_url
97
- @data["url"]
98
- end
99
-
100
- def raw_url
101
- url.sub("://", "://raw.")
102
- end
103
-
104
- # increases api rate limit
105
- def download_content_via_api(file)
106
- content = call_api("contents/#{file}?branch=#{branch}")["content"]
107
- Base64.decode64(content)
108
- end
109
-
110
- def call_api(path)
111
- content = self.class.decorate_errors do
112
- open(File.join(api_url, path), self.class.headers(@token)).read
113
- end
114
- JSON.load(content)
115
- end
116
-
117
- def self.decorate_errors
118
- yield
119
- rescue OpenURI::HTTPError => e
120
- e.message << " -- body: " << e.io.read
121
- raise e
122
- end
123
-
124
- # unlimited
125
- def download_content_via_raw(file)
126
- open(File.join(raw_url, branch, file)).read
127
- end
128
-
129
- def self.headers(token)
130
- token ? {"Authorization" => "token #{token}"} : {}
131
- end
132
- end
133
- end
134
- end