bundler-organization_audit 0.1.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.
Binary file
@@ -0,0 +1 @@
1
+ spec/private.yml
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - ree
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+ gemspec
3
+
4
+ gem "bump"
5
+ gem "rake"
6
+ gem "rspec", "~>2"
7
+ gem "bundler-audit"
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bundler-organization_audit (0.1.0)
5
+ json
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ bump (0.3.9)
11
+ bundler-audit (0.1.2)
12
+ bundler (~> 1.2)
13
+ diff-lcs (1.1.3)
14
+ json (1.7.7)
15
+ rake (10.0.3)
16
+ rspec (2.12.0)
17
+ rspec-core (~> 2.12.0)
18
+ rspec-expectations (~> 2.12.0)
19
+ rspec-mocks (~> 2.12.0)
20
+ rspec-core (2.12.2)
21
+ rspec-expectations (2.12.1)
22
+ diff-lcs (~> 1.1.3)
23
+ rspec-mocks (2.12.2)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bump
30
+ bundler-audit
31
+ bundler-organization_audit!
32
+ rake
33
+ rspec (~> 2)
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "bump/tasks"
3
+
4
+ task :default do
5
+ sh "rspec spec/"
6
+ end
@@ -0,0 +1,76 @@
1
+ Audit all Gemfiles of a user/organization on Github for unpatched versions
2
+
3
+ gem install bundler-organization_audit
4
+
5
+ Usage
6
+ =====
7
+
8
+ ### Public repos
9
+ For yourself (git config github.user)
10
+ ```Bash
11
+ bundle-organization-audit
12
+ parallel
13
+ No Gemfile.lock found
14
+
15
+ parllel_tests
16
+ bundle-audit
17
+ No unpatched versions found
18
+
19
+ rails_example_app
20
+ bundle-audit
21
+ Name: rack
22
+ Version: 1.4.4
23
+ CVE: 2013-0263
24
+ Criticality: High
25
+ URL: http://osvdb.org/show/osvdb/89939
26
+ Title: Rack Rack::Session::Cookie Function Timing Attack Remote Code Execution
27
+ Patched Versions: ~> 1.1.6, ~> 1.2.8, ~> 1.3.10, ~> 1.4.5, >= 1.5.2
28
+
29
+ Vulnerable:
30
+ https://github.com/grosser/rails_example_app
31
+ ```
32
+
33
+ For someone elese
34
+ ```Bash
35
+ bundle-organization-audit --user grosser
36
+ ```
37
+
38
+ Ignore gems (ignores repos that have a %{repo}.gemspec)
39
+ ```Bash
40
+ bundle-organization-audit --ignore-gems
41
+ ```
42
+
43
+ For pipe -> only show vulnerable repos
44
+ ```
45
+ bundle-organization-audit 2>/dev/null
46
+ ```
47
+
48
+ Use for CI -> ignore old/unmaintained proejcts
49
+ ```
50
+ bundle-organization-audit \
51
+ --ignore https://github.com/xxx/a \
52
+ --ignore https://github.com/xxx/b \
53
+ --organization xxx \
54
+ --token yyy
55
+ ```
56
+
57
+ ### Private repos
58
+
59
+ ```Bash
60
+ # create a token that has access to your repositories
61
+ curl -v -u your-user-name -X POST https://api.github.com/authorizations --data '{"scopes":["repo"]}'
62
+ enter your password -> TOKEN
63
+
64
+ bundle-organization-audit --user your-user --token TOKEN --organization your-organization
65
+ ```
66
+
67
+ Dev
68
+ ===
69
+ - test private repo fetching via `cp spec/private{.example,}.yml` and filling it out
70
+
71
+ Author
72
+ ======
73
+ [Michael Grosser](http://grosser.it)<br/>
74
+ michael@grosser.it<br/>
75
+ License: MIT<br/>
76
+ [![Build Status](https://travis-ci.org/grosser/bundler-organization_audit.png)](https://travis-ci.org/grosser/bundler-organization_audit)
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "optparse"
4
+
5
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
6
+ require "bundler/organization_audit"
7
+
8
+ def git_config(thing)
9
+ result = `git config #{thing}`.strip
10
+ result.empty? ? nil : result
11
+ end
12
+
13
+ options = {
14
+ :ignore => [],
15
+ :user => git_config("github.user")
16
+ }
17
+ OptionParser.new do |opts|
18
+ opts.banner = <<BANNER
19
+ Audit all Gemfiles of a user/organization on github for unpatched versions
20
+
21
+ Usage:
22
+ bundle-organization-audit your-user-name
23
+
24
+ Options:
25
+ BANNER
26
+ opts.on("--token TOKEN", "Use token") { |token| options[:token] = token }
27
+ opts.on("--user USER", "Use user") { |user| options[:user] = user }
28
+ opts.on("--ignore REPO_URL", "Ignore given repo urls (use multiple times)") { |repo_url| options[:ignore] << repo_url }
29
+ opts.on("--ignore-gems", "Ignore repos that have a %{repo}.gemspec") { options[:ignore_gems] = true }
30
+ opts.on("--organization ORGANIZATION", "Use user") { |organization| options[:organization] = organization }
31
+ opts.on("-h", "--help", "Show this.") { puts opts; exit }
32
+ opts.on("-v", "--version", "Show Version"){ puts Bundler::OrganizationAudit::VERSION; exit}
33
+ end.parse!
34
+
35
+ exit Bundler::OrganizationAudit.run(options)
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ name = "bundler-organization_audit"
3
+ require "#{name.gsub("-","/")}/version"
4
+
5
+ Gem::Specification.new name, Bundler::OrganizationAudit::VERSION do |s|
6
+ s.summary = s.description = "Audit all Gemfiles of a user/organization on github for unpatched versions"
7
+ s.authors = ["Michael Grosser"]
8
+ s.email = "michael@grosser.it"
9
+ s.homepage = "http://github.com/grosser/#{name}"
10
+ s.files = `git ls-files`.split("\n")
11
+ s.license = "MIT"
12
+ s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem")
13
+ s.executables = ["bundle-organization-audit"]
14
+ s.cert_chain = ["gem-public_cert.pem"]
15
+ s.add_runtime_dependency "json"
16
+ end
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
3
+ YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
4
+ MB4XDTEzMDIwMzE4MTMxMVoXDTE0MDIwMzE4MTMxMVowPzEQMA4GA1UEAwwHbWlj
5
+ aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
6
+ dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
7
+ MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
8
+ cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
9
+ 6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
10
+ h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
11
+ FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
12
+ /88CAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUsiNnXHtKeMYYcr4yJVmQ
13
+ WONL+IwwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAlyN7kKo/NQCQ0
14
+ AOzZLZ3WAePvStkCFIJ53tsv5Kyo4pMAllv+BgPzzBt7qi605mFSL6zBd9uLou+W
15
+ Co3s48p1dy7CjjAfVQdmVNHF3MwXtfC2OEyvSQPi4xKR8iba8wa3xp9LVo1PuLpw
16
+ /6DsrChWw74HfsJN6qJOK684hJeT8lBYAUfiC3wD0owoPSg+XtyAAddisR+KV5Y1
17
+ NmVHuLtQcNTZy+gRht3ahJRMuC6QyLmkTsf+6MaenwAMkAgHdswGsJztOnNnBa3F
18
+ y0kCSWmK6D+x/SbfS6r7Ke07MRqziJdB9GuE1+0cIRuFh8EQ+LN6HXCKM5pon/GU
19
+ ycwMXfl0
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,68 @@
1
+ require "bundler/organization_audit/version"
2
+ require "tmpdir"
3
+ require "bundler/organization_audit/repo"
4
+
5
+ module Bundler
6
+ module OrganizationAudit
7
+ class << self
8
+ def run(options)
9
+ vulnerable = find_vulnerable(options).map(&:url)
10
+ vulnerable -= (options[:ignore] || [])
11
+ if vulnerable.size == 0
12
+ 0
13
+ else
14
+ $stderr.puts "Vulnerable:"
15
+ puts vulnerable
16
+ 1
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def download_file(repo, file, options)
23
+ return unless content = repo.content(file, options)
24
+ File.open(file, "w") { |f| f.write content }
25
+ end
26
+
27
+ def find_vulnerable(options)
28
+ Repo.all(options).select do |repo|
29
+ audit_repo(repo, options)
30
+ end
31
+ end
32
+
33
+ def audit_repo(repo, options)
34
+ success = false
35
+ $stderr.puts repo.project
36
+ in_temp_dir do
37
+ if download_file(repo, "Gemfile.lock", options)
38
+ if options[:ignore_gems] && repo.gem?(options)
39
+ $stderr.puts "Ignored because it's a gem"
40
+ else
41
+ success = !sh("bundle-audit")
42
+ end
43
+ else
44
+ $stderr.puts "No Gemfile.lock found"
45
+ end
46
+ end
47
+ $stderr.puts ""
48
+ success
49
+ rescue Exception => e
50
+ $stderr.puts "Error auditing #{repo.project} (#{e})"
51
+ end
52
+
53
+ def in_temp_dir(&block)
54
+ Dir.mktmpdir { |dir| Dir.chdir(dir, &block) }
55
+ end
56
+
57
+ def sh(cmd)
58
+ $stderr.puts cmd
59
+ IO.popen(cmd) do |pipe|
60
+ while str = pipe.gets
61
+ $stderr.puts str
62
+ end
63
+ end
64
+ $?.success?
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,101 @@
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)
11
+ @data = data
12
+ end
13
+
14
+ def gem?(options={})
15
+ !!content("#{project}.gemspec", options)
16
+ end
17
+
18
+ def url
19
+ api_url.sub("api.", "").sub("/repos", "")
20
+ end
21
+ alias_method :to_s, :url
22
+
23
+ def project
24
+ api_url.split("/").last
25
+ end
26
+
27
+ def self.all(options)
28
+ user = if options[:organization]
29
+ "orgs/#{options[:organization]}"
30
+ elsif options[:user]
31
+ "users/#{options[:user]}"
32
+ else
33
+ "user"
34
+ end
35
+ url = File.join(HOST, user, "repos")
36
+
37
+ download_all_pages(url, headers(options[:token])).map { |data| Repo.new(data) }
38
+ end
39
+
40
+ def content(file, options={})
41
+ if private?
42
+ download_content_via_api(file, options)
43
+ else
44
+ download_content_via_raw(file)
45
+ end
46
+ rescue OpenURI::HTTPError => e
47
+ raise "Error downloading #{file} from #{url} (#{e})" unless e.message.start_with?("404")
48
+ end
49
+
50
+ def private?
51
+ @data["private"]
52
+ end
53
+
54
+ private
55
+
56
+ def self.download_all_pages(url, headers)
57
+ results = []
58
+ page = 1
59
+ loop do
60
+ result = JSON.parse(open("#{url}?page=#{page}", headers).read)
61
+ if result.size == 0
62
+ break
63
+ else
64
+ results.concat(result)
65
+ page += 1
66
+ end
67
+ end
68
+ results
69
+ end
70
+
71
+ def branch
72
+ @data["default_branch"] || @data["master_branch"] || "master"
73
+ end
74
+
75
+ def api_url
76
+ @data["url"]
77
+ end
78
+
79
+ def raw_url
80
+ url.sub("://", "://raw.")
81
+ end
82
+
83
+ # increases api rate limit
84
+ def download_content_via_api(file, options)
85
+ url = File.join(api_url, "contents", file, "?ref=#{branch}")
86
+ content = open(url, self.class.headers(options.fetch(:token))).read
87
+ content = JSON.load(content)["content"]
88
+ Base64.decode64(content)
89
+ end
90
+
91
+ # unlimited
92
+ def download_content_via_raw(file)
93
+ open(File.join(raw_url, branch, file)).read
94
+ end
95
+
96
+ def self.headers(token)
97
+ token ? {"Authorization" => "token #{token}"} : {}
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module Bundler
2
+ module OrganizationAudit
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ describe Bundler::OrganizationAudit::Repo do
4
+ let(:config){ YAML.load_file("spec/private.yml") }
5
+ let(:repo) do
6
+ Bundler::OrganizationAudit::Repo.new(
7
+ "url" => "https://api.github.com/repos/grosser/parallel"
8
+ )
9
+ end
10
+
11
+ describe ".all" do
12
+ it "returns the list of public repositories" do
13
+ # use a big account -> make sure pagination works
14
+ list = Bundler::OrganizationAudit::Repo.all(:user => "grosser")
15
+ list.map(&:url).should include("https://github.com/grosser/parallel")
16
+ end
17
+
18
+ if File.exist?("spec/private.yml")
19
+ it "returns the list of private repositories from a user" do
20
+ list = Bundler::OrganizationAudit::Repo.all(:token => config["token"])
21
+ list.map(&:url).should include("https://github.com/#{config["user"]}/#{config["expected_user"]}")
22
+ end
23
+
24
+ it "returns the list of private repositories from a organization" do
25
+ list = Bundler::OrganizationAudit::Repo.all(:token => config["token"], :organization => config["organization"])
26
+ list.map(&:url).should include("https://github.com/#{config["organization"]}/#{config["expected_organization"]}")
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#content" do
32
+ it "can download a public file" do
33
+ repo.content("Gemfile.lock").should include('rspec (2')
34
+ end
35
+
36
+ if File.exist?("spec/private.yml")
37
+ it "can download a private file" do
38
+ url = "https://api.github.com/repos/#{config["organization"]}/#{config["expected_organization"]}"
39
+ repo = Bundler::OrganizationAudit::Repo.new(
40
+ "url" => url, "private" => true
41
+ )
42
+ content = repo.content("Gemfile.lock", :token => config["token"], :user => config["user"])
43
+ content.should include('i18n (0.')
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#gem?" do
49
+ it "is a gem if it has a gemspec" do
50
+ repo.should be_gem
51
+ end
52
+
53
+ it "is not a gem if it has no gemspec" do
54
+ Bundler::OrganizationAudit::Repo.new("url" => "https://api.github.com/repos/grosser/dotfiles").should_not be_gem
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,112 @@
1
+ require "spec_helper"
2
+
3
+ describe Bundler::OrganizationAudit do
4
+ it "has a VERSION" do
5
+ Bundler::OrganizationAudit::VERSION.should =~ /^[\.\da-z]+$/
6
+ end
7
+
8
+ describe Bundler::OrganizationAudit do
9
+ let(:repo) do
10
+ Bundler::OrganizationAudit::Repo.new(
11
+ "url" => "https://api.github.com/repos/grosser/parallel"
12
+ )
13
+ end
14
+
15
+ describe ".audit_repo" do
16
+ it "audits public repos" do
17
+ out = record_out do
18
+ Bundler::OrganizationAudit.send(:audit_repo, repo, {})
19
+ end
20
+ out.strip.should == "parallel\nbundle-audit\nNo unpatched versions found"
21
+ end
22
+
23
+ it "does not audit ignored repos" do
24
+ out = record_out do
25
+ Bundler::OrganizationAudit.send(:audit_repo, repo, :ignore_gems => true)
26
+ end
27
+ out.strip.should == "parallel\nIgnored because it's a gem"
28
+ end
29
+ end
30
+
31
+ describe ".run" do
32
+ before do
33
+ Bundler::OrganizationAudit.stub(:puts)
34
+ end
35
+
36
+ it "is successful when failed are empty" do
37
+ Bundler::OrganizationAudit.should_receive(:find_vulnerable).and_return([])
38
+ record_out do
39
+ Bundler::OrganizationAudit.run({}).should == 0
40
+ end
41
+ end
42
+
43
+ it "fails with failed" do
44
+ Bundler::OrganizationAudit.should_receive(:find_vulnerable).and_return([repo])
45
+ record_out do
46
+ Bundler::OrganizationAudit.run({}).should == 1
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ context "CLI" do
53
+ it "can audit a user" do
54
+ result = audit("--user anamartinez")
55
+ result.should include "I18N-tools\nNo Gemfile.lock found" # did not use audit when not necessary
56
+ result.should include "js-cldr-timezones\nbundle-audit\nNo unpatched versions found" # used audit where necessary
57
+ end
58
+
59
+ it "can audit a unpatched user" do
60
+ result = audit("--user user-with-unpatched-apps", :fail => true)
61
+ result.should include "unpatched\nbundle-audit\nName: json\nVersion: 1.5.3" # Individual vulnerabilities
62
+ result.should include "Vulnerable:\nhttps://github.com/user-with-unpatched-apps/unpatched" # Summary
63
+ end
64
+
65
+ it "only shows failed projects on stdout" do
66
+ result = audit("--user user-with-unpatched-apps 2>/dev/null", :fail => true, :keep_output => true)
67
+ result.should == "https://github.com/user-with-unpatched-apps/unpatched\n"
68
+ end
69
+
70
+ it "ignores projects in --ignore" do
71
+ result = audit("--user user-with-unpatched-apps --ignore https://github.com/user-with-unpatched-apps/unpatched 2>/dev/null", :keep_output => true)
72
+ result.should == ""
73
+ end
74
+
75
+ it "shows --version" do
76
+ audit("--version").should include(Bundler::OrganizationAudit::VERSION)
77
+ end
78
+
79
+ it "shows --help" do
80
+ audit("--help").should include("Audit all Gemfiles")
81
+ end
82
+
83
+ def audit(command, options={})
84
+ sh("bin/bundle-organization-audit #{command}", options)
85
+ end
86
+
87
+ def sh(command, options={})
88
+ result = `#{command} #{"2>&1" unless options[:keep_output]}`
89
+ raise "FAILED #{command}\n#{result}" if $?.success? == !!options[:fail]
90
+ decolorize(result)
91
+ end
92
+ end
93
+
94
+ def decolorize(string)
95
+ string.gsub(/\e\[\d+m/, "")
96
+ end
97
+
98
+ def record_out
99
+ recorder = StringIO.new
100
+ $stdout, out = recorder, $stdout
101
+ $stderr, err = recorder, $stderr
102
+ yield
103
+ decolorize(recorder.string)
104
+ ensure
105
+ $stdout = out
106
+ $stderr = err
107
+ end
108
+
109
+ def in_temp_dir(&block)
110
+ Dir.mktmpdir { |dir| Dir.chdir(dir, &block) }
111
+ end
112
+ end
@@ -0,0 +1,7 @@
1
+ token: your-token-see-readme
2
+
3
+ user: your-user
4
+ expected_user: your-private-repo
5
+
6
+ organization: org
7
+ expected_organization: org-private-repo
@@ -0,0 +1 @@
1
+ require "bundler/organization_audit"
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bundler-organization_audit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Grosser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - !binary |-
13
+ LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhxZ0F3SUJB
14
+ Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREEvTVJBd0RnWURWUVFEREFkdGFX
15
+ Tm8KWVdWc01SY3dGUVlLQ1pJbWlaUHlMR1FCR1JZSFozSnZjM05sY2pFU01C
16
+ QUdDZ21TSm9tVDhpeGtBUmtXQW1sMApNQjRYRFRFek1ESXdNekU0TVRNeE1W
17
+ b1hEVEUwTURJd016RTRNVE14TVZvd1B6RVFNQTRHQTFVRUF3d0hiV2xqCmFH
18
+ RmxiREVYTUJVR0NnbVNKb21UOGl4a0FSa1dCMmR5YjNOelpYSXhFakFRQmdv
19
+ SmtpYUprL0lzWkFFWkZnSnAKZERDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFB
20
+ RGdnRVBBRENDQVFvQ2dnRUJBTW9yWG8vaGdiVXE5NytrSUk5SApNc1FjTGRD
21
+ Lzd3UTFaUDJPc2hWSFBrZVAwcUg4TUJIR2c2ZVlpc09YMnViTmFnRjlZVENa
22
+ V25ocmRLcndwTE9PCmNQTGFaYmpVamxqSjNjUVIzQjhZbjF2ZVY1SWhHODZR
23
+ c2VUQmp5bXpKV3NMcHFKMVVaR3BmQjl0WGNzRnR1eE8KNnZIdmNJSGR6dmMv
24
+ T1VrSUN0dExiSCsxcWI2cnNIVWNlcWgrSnJINEdyc0o1SDRoQWZJZHlTMlhN
25
+ SzdZUktiaApoK0lCdTZkRldKSkJ5ekZzWW1WMVBEWGxuM1VCbWdBdDY1Y21D
26
+ dTRxUGZUaGlvQ0dEemJTSnJHREdMbXcvcEZYCkZQcFZDbTF6Z1lTYjF2NlFu
27
+ ZjNjZ1hhMmYyd1lHbTE3K3pBVnlJRHB3cnlGcnU5eUYvakp4RTM4ei9EUnNk
28
+ OVIKLzg4Q0F3RUFBYU01TURjd0NRWURWUjBUQkFJd0FEQWRCZ05WSFE0RUZn
29
+ UVVzaU5uWEh0S2VNWVljcjR5SlZtUQpXT05MK0l3d0N3WURWUjBQQkFRREFn
30
+ U3dNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUFseU43a0tvL05RQ1EwCkFP
31
+ elpMWjNXQWVQdlN0a0NGSUo1M3RzdjVLeW80cE1BbGx2K0JnUHp6QnQ3cWk2
32
+ MDVtRlNMNnpCZDl1TG91K1cKQ28zczQ4cDFkeTdDampBZlZRZG1WTkhGM013
33
+ WHRmQzJPRXl2U1FQaTR4S1I4aWJhOHdhM3hwOUxWbzFQdUxwdwovNkRzckNo
34
+ V3c3NEhmc0pONnFKT0s2ODRoSmVUOGxCWUFVZmlDM3dEMG93b1BTZytYdHlB
35
+ QWRkaXNSK0tWNVkxCk5tVkh1THRRY05UWnkrZ1JodDNhaEpSTXVDNlF5TG1r
36
+ VHNmKzZNYWVud0FNa0FnSGRzd0dzSnp0T25ObkJhM0YKeTBrQ1NXbUs2RCt4
37
+ L1NiZlM2cjdLZTA3TVJxemlKZEI5R3VFMSswY0lSdUZoOEVRK0xONkhYQ0tN
38
+ NXBvbi9HVQp5Y3dNWGZsMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
+ date: 2013-02-18 00:00:00.000000000 Z
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ description: Audit all Gemfiles of a user/organization on github for unpatched versions
58
+ email: michael@grosser.it
59
+ executables:
60
+ - bundle-organization-audit
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - .gitignore
65
+ - .travis.yml
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - Rakefile
69
+ - Readme.md
70
+ - bin/bundle-organization-audit
71
+ - bundler-organization_audit.gemspec
72
+ - gem-public_cert.pem
73
+ - lib/bundler/organization_audit.rb
74
+ - lib/bundler/organization_audit/repo.rb
75
+ - lib/bundler/organization_audit/version.rb
76
+ - spec/bundler/organization_audit/repo_spec.rb
77
+ - spec/bundler/organization_audit_spec.rb
78
+ - spec/private.example.yml
79
+ - spec/spec_helper.rb
80
+ homepage: http://github.com/grosser/bundler-organization_audit
81
+ licenses:
82
+ - MIT
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ segments:
94
+ - 0
95
+ hash: 75415256473976345
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ segments:
103
+ - 0
104
+ hash: 75415256473976345
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.24
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Audit all Gemfiles of a user/organization on github for unpatched versions
111
+ test_files: []
Binary file