def test_get_packages_licenses_with_invalid_db_file(self): from safety.errors import DatabaseFileNotFoundError with self.assertRaises(DatabaseFileNotFoundError): safety.get_licenses(db_mirror='/my/invalid/path', cached=False, proxy={}, key=None)
def test_get_packages_licenses_without_api_key(self): from safety.errors import InvalidKeyError # without providing an API-KEY with self.assertRaises(InvalidKeyError) as error: safety.get_licenses(db_mirror=False, cached=False, proxy={}, key=None) db_generic_exception = error.exception self.assertEqual(str(db_generic_exception), 'API-KEY not provided.')
def test_get_cached_packages_licenses(self, requests): import copy from safety.constants import CACHE_FILE licenses_db = { "licenses": { "BSD-3-Clause": 2 }, "packages": { "django": [ { "start_version": "0.0", "license_id": 2 } ] } } original_db = copy.deepcopy(licenses_db) mock = Mock() mock.json.return_value = licenses_db mock.status_code = 200 requests.get.return_value = mock # lets clear the cache first try: with open(CACHE_FILE, 'w') as f: f.write(json.dumps({})) except Exception: pass # In order to cache the db (and get), we must set cached as True response = safety.get_licenses( db_mirror=False, cached=True, proxy={}, key="MY-VALID-KEY" ) self.assertEqual(response, licenses_db) # now we should have the db in cache # changing the "live" db to test if we are getting the cached db licenses_db['licenses']['BSD-3-Clause'] = 123 resp = safety.get_licenses( db_mirror=False, cached=True, proxy={}, key="MY-VALID-KEY" ) self.assertNotEqual(resp, licenses_db) self.assertEqual(resp, original_db)
def test_get_packages_licenses_db_fetch_error(self, requests): from safety.errors import DatabaseFetchError mock = Mock() mock.status_code = 500 requests.get.return_value = mock with self.assertRaises(DatabaseFetchError): safety.get_licenses(db_mirror=False, cached=False, proxy={}, key="MY-VALID-KEY")
def test_get_packages_licenses_very_often(self, requests): from safety.errors import TooManyRequestsError # if the request is made too often, an 429 error is raise by PyUp.io mock = Mock() mock.status_code = 429 requests.get.return_value = mock with self.assertRaises(TooManyRequestsError): safety.get_licenses(db_mirror=False, cached=False, proxy={}, key="MY-VALID-KEY")
def test_get_packages_licenses_with_invalid_api_key(self, requests): from safety.errors import InvalidKeyError mock = Mock() mock.status_code = 403 requests.get.return_value = mock # proving an invalid API-KEY with self.assertRaises(InvalidKeyError): safety.get_licenses(db_mirror=False, cached=False, proxy={}, key="INVALID")
def test_report_licenses_bare(self): from safety.formatter import license_report reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0") packages = util.read_requirements(reqs) # Using DB: test.test_db.licenses.json licenses_db = safety.get_licenses( db_mirror=os.path.join( os.path.dirname(os.path.realpath(__file__)), "test_db" ), cached=False, key=None, proxy={}, ) pkgs_licenses = util.get_packages_licenses(packages, licenses_db) output_report = license_report( packages=packages, licenses=pkgs_licenses, json_report=False, bare_report=True ) self.assertEqual(output_report, "BSD-3-Clause")
def test_get_packages_licenses(self): reqs = StringIO("Django==1.8.1\n\rinvalid==1.0.0") packages = util.read_requirements(reqs) licenses_db = safety.get_licenses( db_mirror=os.path.join( os.path.dirname(os.path.realpath(__file__)), "test_db" ), cached=False, key="foobarqux", proxy={}, ) self.assertIn("licenses", licenses_db) self.assertIn("packages", licenses_db) self.assertIn("BSD-3-Clause", licenses_db['licenses']) self.assertIn("django", licenses_db['packages']) pkg_licenses = util.get_packages_licenses(packages, licenses_db) self.assertIsInstance(pkg_licenses, list) for pkg_license in pkg_licenses: license = pkg_license['license'] version = pkg_license['version'] if pkg_license['package'] == 'django': self.assertEqual(license, 'BSD-3-Clause') self.assertEqual(version, '1.8.1') elif pkg_license['package'] == 'invalid': self.assertEqual(license, 'N/A') self.assertEqual(version, '1.0.0') else: raise AssertionError( "unexpected package '" + pkg_license['package'] + "' was found" )
def license(key, db, cache, files, proxyprotocol, proxyhost, proxyport): if files: packages = list(itertools.chain.from_iterable(read_requirements(f, resolve=True) for f in files)) else: import pkg_resources packages = [ d for d in pkg_resources.working_set if d.key not in {"python", "wsgiref", "argparse"} ] proxy_dictionary = get_proxy_dict(proxyprotocol, proxyhost, proxyport) try: licenses_db = safety.get_licenses(key, db, cache, proxy_dictionary) except InvalidKeyError: click.secho("Your API Key '{key}' is invalid. See {link}".format( key=key, link='https://goo.gl/O7Y1rS'), fg="red", file=sys.stderr) sys.exit(-1) except DatabaseFileNotFoundError: click.secho("Unable to load licenses database from {db}".format(db=db), fg="red", file=sys.stderr) sys.exit(-1) except TooManyRequestsError: click.secho("Unable to load licenses database (Too many requests, please wait before another request)", fg="red", file=sys.stderr ) sys.exit(-1) except DatabaseFetchError: click.secho("Unable to load licenses database", fg="red", file=sys.stderr) sys.exit(-1) filtered_packages_licenses = get_packages_licenses(packages, licenses_db) output_report = license_report(packages=packages, licenses=filtered_packages_licenses) click.secho(output_report, nl=True)
def test_report_licenses_json(self, get_report_brief_info): get_report_brief_info.return_value = { 'scan_target': 'environment', 'scanned': ['/usr/local/lib/python3.9/site-packages'], 'api_key': True, 'packages_found': 2, 'timestamp': '2022-03-03 16:31:30', 'safety_version': '2.0.0.dev6' } reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0") packages = util.read_requirements(reqs) # Using DB: test.test_db.licenses.json licenses_db = safety.get_licenses(db_mirror=os.path.join( os.path.dirname(os.path.realpath(__file__)), "test_db"), cached=0, key=None, proxy={}, telemetry=False) pkgs_licenses = util.get_packages_licenses(packages, licenses_db) output_report = SafetyFormatter(output='json').render_licenses( [], pkgs_licenses) expected_result = json.dumps( { "report_meta": { "scan_target": "environment", "scanned": ["/usr/local/lib/python3.9/site-packages"], "api_key": True, "packages_found": 2, "timestamp": "2022-03-03 16:31:30", "safety_version": "2.0.0.dev6" }, "announcements": [], "licenses": [{ "package": "django", "version": "1.8.1", "license": "BSD-3-Clause" }, { "package": "inexistent", "version": "1.0.0", "license": "unknown", }] }, indent=4) # Packages without license are reported as "N/A" self.assertEqual(output_report.rstrip(), expected_result)
def test_report_licenses_bare(self): reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0") packages = util.read_requirements(reqs) # Using DB: test.test_db.licenses.json licenses_db = safety.get_licenses(db_mirror=os.path.join( os.path.dirname(os.path.realpath(__file__)), "test_db"), cached=0, key=None, proxy={}, telemetry=False) pkgs_licenses = util.get_packages_licenses(packages, licenses_db) output_report = SafetyFormatter(output='bare').render_licenses( [], pkgs_licenses) self.assertEqual(output_report, "BSD-3-Clause unknown")
def test_report_licenses_json(self): from safety.formatter import license_report reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0") packages = util.read_requirements(reqs) # Using DB: test.test_db.licenses.json licenses_db = safety.get_licenses( db_mirror=os.path.join( os.path.dirname(os.path.realpath(__file__)), "test_db" ), cached=False, key=None, proxy={}, ) pkgs_licenses = util.get_packages_licenses(packages, licenses_db) output_report = license_report( packages=packages, licenses=pkgs_licenses, json_report=True, bare_report=False ) expected_result = json.dumps( [{ "license": "BSD-3-Clause", "package": "django", "version": "1.8.1" }, { "license": "N/A", "package": "inexistent", "version": "1.0.0" }], indent=4, sort_keys=True ) # Packages without license are reported as "N/A" self.assertEqual(output_report.rstrip(), expected_result)
def license(ctx, key, db, output, cache, files, proxyprotocol, proxyhost, proxyport): """ Find the open source licenses used by your Python dependencies. """ LOG.info('Running license command') packages = get_packages(files, False) ctx.obj = packages proxy_dictionary = get_proxy_dict(proxyprotocol, proxyhost, proxyport) announcements = [] if not db: announcements = safety.get_announcements( key=key, proxy=proxy_dictionary, telemetry=ctx.parent.telemetry) licenses_db = {} try: licenses_db = safety.get_licenses(key, db, cache, proxy_dictionary, telemetry=ctx.parent.telemetry) except SafetyError as e: LOG.exception('Expected SafetyError happened: %s', e) output_exception(e, exit_code_output=False) except Exception as e: LOG.exception('Unexpected Exception happened: %s', e) exception = e if isinstance(e, SafetyException) else SafetyException( info=e) output_exception(exception, exit_code_output=False) filtered_packages_licenses = get_packages_licenses(packages, licenses_db) output_report = SafetyFormatter(output=output).render_licenses( announcements, filtered_packages_licenses) click.secho(output_report, nl=True)