summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorCan Eldem <celdem@gitlab.com>2020-01-16 10:24:11 +0000
committerCan Eldem <celdem@gitlab.com>2020-01-16 10:24:11 +0000
commit2074e7e5ea3012be6f3a72bd4af934a42b7202ca (patch)
treece9ec33580f0e6e3f9cf3df1aab2f2cf7b5601cb /lib
parentf4f59927f87944a4d73be26416a7334521875f40 (diff)
parent34f162a4903d852d47bd5440839f7519eb6fa8f0 (diff)
Merge branch '12012-pipfile-lock' into 'master'v2.4.0
Add support for Pipfile.lock See merge request gitlab-org/security-products/license-management!103
Diffstat (limited to 'lib')
-rw-r--r--lib/license/management.rb16
-rw-r--r--lib/license/management/loggable.rb4
-rw-r--r--lib/license/management/python/pipenv.rb64
-rw-r--r--lib/license/management/python/pypi.rb44
-rw-r--r--lib/license/management/version.rb2
5 files changed, 129 insertions, 1 deletions
diff --git a/lib/license/management.rb b/lib/license/management.rb
index a6e0664..ebab5e2 100644
--- a/lib/license/management.rb
+++ b/lib/license/management.rb
@@ -2,9 +2,12 @@
require 'pathname'
require 'yaml'
+require 'json'
require 'license_finder'
require 'license/management/loggable'
require 'license/management/verifiable'
+require 'license/management/python/pipenv'
+require 'license/management/python/pypi'
require 'license/management/repository'
require 'license/management/report'
require 'license/management/version'
@@ -12,6 +15,12 @@ require 'license/management/version'
# This applies a monkey patch to the JsonReport found in the `license_finder` gem.
LicenseFinder::JsonReport.prepend(License::Management::Report)
+# This monkey patch can be removed once https://github.com/pivotal/LicenseFinder/pull/659 is released
+LicenseFinder::Scanner.const_set(
+ :PACKAGE_MANAGERS,
+ LicenseFinder::Scanner::PACKAGE_MANAGERS + [License::Management::Pipenv]
+)
+
# This monkey patch can be removed once we upgrade to license_finder 5.9.2. Details [here](https://gitlab.com/gitlab-org/gitlab/issues/13748#note_235810786).
module LicenseFinder
class Bundler < PackageManager
@@ -31,5 +40,12 @@ module License
def self.root
Pathname.new(File.dirname(__FILE__)).join('../..')
end
+
+ def self.http
+ @http ||= Net::Hippie::Client.new.tap do |client|
+ client.logger = ::Logger.new('http.log')
+ client.follow_redirects = 3
+ end
+ end
end
end
diff --git a/lib/license/management/loggable.rb b/lib/license/management/loggable.rb
index a44d45d..165d8ca 100644
--- a/lib/license/management/loggable.rb
+++ b/lib/license/management/loggable.rb
@@ -10,6 +10,10 @@ module License
def log_info(message)
logger.info(self.class, message)
end
+
+ def log_error(message)
+ logger.info(self.class, message, color: :red)
+ end
end
end
end
diff --git a/lib/license/management/python/pipenv.rb b/lib/license/management/python/pipenv.rb
new file mode 100644
index 0000000..482fd25
--- /dev/null
+++ b/lib/license/management/python/pipenv.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module License
+ module Management
+ class Pipenv < LicenseFinder::PackageManager
+ include Loggable
+
+ def initialize(options = {})
+ super
+ @lockfile = Pathname('Pipfile.lock')
+ end
+
+ def current_packages
+ @current_packages ||=
+ begin
+ packages = {}
+ each_dependency(groups: allowed_groups) do |name, data, group|
+ version = canonicalize(data['version'])
+ package = packages.fetch(key_for(name, version)) do |key|
+ packages[key] = build_package_for(name, version)
+ end
+ package.groups << group
+ end
+ packages.values
+ end
+ end
+
+ def possible_package_paths
+ project_path ? [project_path.join(@lockfile)] : [@lockfile]
+ end
+
+ private
+
+ def each_dependency(groups: [])
+ dependencies = JSON.parse(IO.read(detected_package_path))
+ groups.each do |group|
+ dependencies[group].each do |name, data|
+ yield name, data, group
+ end
+ end
+ end
+
+ def canonicalize(version)
+ version.sub(/^==/, '')
+ end
+
+ def build_package_for(name, version)
+ LicenseFinder::PipPackage.new(name, version, PyPI.definition(name, version))
+ end
+
+ def key_for(name, version)
+ "#{name}-#{version}"
+ end
+
+ def allowed_groups
+ %w[default develop] - ignored_groups
+ end
+
+ def ignored_groups
+ @ignored_groups.to_a || []
+ end
+ end
+ end
+end
diff --git a/lib/license/management/python/pypi.rb b/lib/license/management/python/pypi.rb
new file mode 100644
index 0000000..0397532
--- /dev/null
+++ b/lib/license/management/python/pypi.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'net/hippie'
+
+module License
+ module Management
+ class PyPI
+ include Loggable
+
+ def initialize(http)
+ @http = http
+ end
+
+ def definition_for(name, version)
+ uri = "https://pypi.org/pypi/#{name}/#{version}/json"
+ process(@http.with_retry { |client| client.get(uri) }).tap do |definition|
+ log_info([name, version, definition["license"]].inspect)
+ end
+ rescue *Net::Hippie::CONNECTION_ERRORS
+ {}
+ end
+
+ class << self
+ def definition(name, version)
+ @pypi ||= new(License::Management.http)
+ @pypi.definition_for(name, version)
+ end
+ end
+
+ private
+
+ def process(response)
+ return JSON.parse(response.body).fetch('info', {}) if ok?(response)
+
+ log_error([response.class, response.code, response.body].inspect)
+ {}
+ end
+
+ def ok?(response)
+ response.is_a?(Net::HTTPSuccess)
+ end
+ end
+ end
+end
diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb
index 995dee4..a5e7b07 100644
--- a/lib/license/management/version.rb
+++ b/lib/license/management/version.rb
@@ -2,6 +2,6 @@
module License
module Management
- VERSION = '2.3.1'
+ VERSION = '2.4.0'
end
end