From 47302966c9eaa51f041acd9c02292288999339d9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 10 Feb 2023 05:47:55 -0500 Subject: [PATCH] feat: support Pipenv - Pipfile.lock (#5404) --- ant/pom.xml | 2 +- archetype/pom.xml | 2 +- cli/pom.xml | 2 +- core/pom.xml | 2 +- .../analyzer/PipfileAnalyzer.java | 94 ++- .../analyzer/PipfilelockAnalyzer.java | 219 +++++ ...rg.owasp.dependencycheck.analyzer.Analyzer | 1 + .../analyzer/PipfilelockAnalyzerTest.java | 113 +++ core/src/test/resources/pip/Pipfile | 32 + core/src/test/resources/pip/Pipfile.lock | 760 ++++++++++++++++++ maven/pom.xml | 2 +- pom.xml | 2 +- utils/pom.xml | 2 +- 13 files changed, 1184 insertions(+), 49 deletions(-) create mode 100644 core/src/main/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzer.java create mode 100644 core/src/test/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzerTest.java create mode 100644 core/src/test/resources/pip/Pipfile create mode 100644 core/src/test/resources/pip/Pipfile.lock diff --git a/ant/pom.xml b/ant/pom.xml index d0ca1c04098..62bb89aa6bb 100644 --- a/ant/pom.xml +++ b/ant/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-ant diff --git a/archetype/pom.xml b/archetype/pom.xml index 0af2493825a..86f9a459adb 100644 --- a/archetype/pom.xml +++ b/archetype/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-plugin Dependency-Check Plugin Archetype diff --git a/cli/pom.xml b/cli/pom.xml index da18353cc85..5180769dfe8 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-cli diff --git a/core/pom.xml b/core/pom.xml index 4cc964d440c..061df5bae6c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-core diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfileAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfileAnalyzer.java index c76f516446b..76905edf0bb 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfileAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfileAnalyzer.java @@ -44,7 +44,11 @@ import org.slf4j.LoggerFactory; /** - * Used to analyze Pipfile dependency files named Pipfile. + * Used to analyze dependencies defined in Pipfile. This analyzer works in + * tandem with the `PipfilelockAnalyzer` - and both analyzers use the same key + * to enable/disable the analyzers. The PipfilelockAnalyzer will be used over + * the Pipfile if the lock file exists. + * * * @author fcano */ @@ -55,12 +59,15 @@ public class PipfileAnalyzer extends AbstractFileTypeAnalyzer { /** * The logger. */ - private static final Logger LOGGER = LoggerFactory.getLogger(PythonPackageAnalyzer.class); + private static final Logger LOGGER = LoggerFactory.getLogger(PipfileAnalyzer.class); /** * "Pipfile" file. */ - private static final String REQUIREMENTS = "Pipfile"; - + private static final String PIPFILE = "Pipfile"; + /** + * "Pipfile.lock" file. + */ + private static final String LOCKFILE = "Pipfile.lock"; /** * The name of the analyzer. */ @@ -79,7 +86,7 @@ public class PipfileAnalyzer extends AbstractFileTypeAnalyzer { /** * The file filter used to determine which files this analyzer supports. */ - private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(REQUIREMENTS).build(); + private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(PIPFILE).build(); /** * Returns the FileFilter @@ -124,51 +131,54 @@ protected String getAnalyzerEnabledSettingKey() { @Override protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException { - LOGGER.debug("Checking file {}", dependency.getActualFilePath()); - - if (REQUIREMENTS.equals(dependency.getFileName())) { - engine.removeDependency(dependency); + engine.removeDependency(dependency); + final File lock = new File(dependency.getActualFile().getParentFile(), LOCKFILE); + if (lock.isFile()) { + LOGGER.debug("Skipping {} because a lock file was identified", dependency.getActualFilePath()); + return; + } else { + LOGGER.debug("Checking file {}", dependency.getActualFilePath()); } + final File dependencyFile = dependency.getActualFile(); if (!dependencyFile.isFile() || dependencyFile.length() == 0) { return; } final File actualFile = dependency.getActualFile(); - if (actualFile.getName().equals(REQUIREMENTS)) { - final String contents = getFileContents(actualFile); - if (!contents.isEmpty()) { - final Matcher matcher = PACKAGE_VERSION.matcher(contents); - while (matcher.find()) { - final String identifiedPackage = matcher.group(1); - final String identifiedVersion = matcher.group(2); - LOGGER.debug(String.format("package, version: %s %s", identifiedPackage, identifiedVersion)); - final Dependency d = new Dependency(dependency.getActualFile(), true); - d.setName(identifiedPackage); - d.setVersion(identifiedVersion); - try { - final PackageURL purl = PackageURLBuilder.aPackageURL() - .withType("pypi") - .withName(identifiedPackage) - .withVersion(identifiedVersion) - .build(); - d.addSoftwareIdentifier(new PurlIdentifier(purl, Confidence.HIGHEST)); - } catch (MalformedPackageURLException ex) { - LOGGER.debug("Unable to build package url for pypi", ex); - d.addSoftwareIdentifier(new GenericIdentifier("pypi:" + identifiedPackage + "@" + identifiedVersion, Confidence.HIGH)); - } - d.setPackagePath(String.format("%s:%s", identifiedPackage, identifiedVersion)); - d.setEcosystem(PythonDistributionAnalyzer.DEPENDENCY_ECOSYSTEM); - final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), identifiedPackage, identifiedVersion); - d.setFilePath(filePath); - d.setSha1sum(Checksum.getSHA1Checksum(filePath)); - d.setSha256sum(Checksum.getSHA256Checksum(filePath)); - d.setMd5sum(Checksum.getMD5Checksum(filePath)); - d.addEvidence(EvidenceType.VENDOR, REQUIREMENTS, "vendor", identifiedPackage, Confidence.HIGHEST); - d.addEvidence(EvidenceType.PRODUCT, REQUIREMENTS, "product", identifiedPackage, Confidence.HIGHEST); - d.addEvidence(EvidenceType.VERSION, REQUIREMENTS, "version", identifiedVersion, Confidence.HIGHEST); - engine.addDependency(d); + + final String contents = getFileContents(actualFile); + if (!contents.isEmpty()) { + final Matcher matcher = PACKAGE_VERSION.matcher(contents); + while (matcher.find()) { + final String identifiedPackage = matcher.group(1); + final String identifiedVersion = matcher.group(2); + LOGGER.debug(String.format("package, version: %s %s", identifiedPackage, identifiedVersion)); + final Dependency d = new Dependency(dependency.getActualFile(), true); + d.setName(identifiedPackage); + d.setVersion(identifiedVersion); + try { + final PackageURL purl = PackageURLBuilder.aPackageURL() + .withType("pypi") + .withName(identifiedPackage) + .withVersion(identifiedVersion) + .build(); + d.addSoftwareIdentifier(new PurlIdentifier(purl, Confidence.HIGHEST)); + } catch (MalformedPackageURLException ex) { + LOGGER.debug("Unable to build package url for pypi", ex); + d.addSoftwareIdentifier(new GenericIdentifier("pypi:" + identifiedPackage + "@" + identifiedVersion, Confidence.HIGH)); } + d.setPackagePath(String.format("%s:%s", identifiedPackage, identifiedVersion)); + d.setEcosystem(PythonDistributionAnalyzer.DEPENDENCY_ECOSYSTEM); + final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), identifiedPackage, identifiedVersion); + d.setFilePath(filePath); + d.setSha1sum(Checksum.getSHA1Checksum(filePath)); + d.setSha256sum(Checksum.getSHA256Checksum(filePath)); + d.setMd5sum(Checksum.getMD5Checksum(filePath)); + d.addEvidence(EvidenceType.VENDOR, PIPFILE, "vendor", identifiedPackage, Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, PIPFILE, "product", identifiedPackage, Confidence.HIGHEST); + d.addEvidence(EvidenceType.VERSION, PIPFILE, "version", identifiedVersion, Confidence.HIGHEST); + engine.addDependency(d); } } } diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzer.java new file mode 100644 index 00000000000..525cdcfb6fa --- /dev/null +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzer.java @@ -0,0 +1,219 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2023 The OWASP Foundation. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import org.apache.commons.io.FileUtils; +import com.github.packageurl.MalformedPackageURLException; +import com.github.packageurl.PackageURL; +import com.github.packageurl.PackageURLBuilder; +import java.io.BufferedInputStream; +import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.dependency.Confidence; +import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.utils.FileFilterBuilder; +import org.owasp.dependencycheck.utils.Settings; +import org.owasp.dependencycheck.dependency.EvidenceType; +import org.owasp.dependencycheck.exception.InitializationException; +import org.owasp.dependencycheck.dependency.naming.GenericIdentifier; +import org.owasp.dependencycheck.dependency.naming.PurlIdentifier; +import org.owasp.dependencycheck.utils.Checksum; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Set; +import javax.annotation.concurrent.ThreadSafe; +import javax.json.Json; +import javax.json.JsonException; +import javax.json.JsonObject; +import javax.json.JsonReader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Used to analyze dependencies defined in Pipfile.lock. This analyzer works in + * tandem with the `PipfileAnalyzer` - and both analyzers use the same key to + * enable/disable the analyzers. The PipfileAnalyzer will be skipped if the lock + * file exists, as the lock will provide more accurate version numbers. + * + * @author jeremy.long + */ +@Experimental +@ThreadSafe +public class PipfilelockAnalyzer extends AbstractFileTypeAnalyzer { + + /** + * The logger. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(PipfilelockAnalyzer.class); + /** + * "Pipfile.lock" file. + */ + private static final String LOCKFILE = "Pipfile.lock"; + + /** + * The identifiedPackage of the analyzer. + */ + private static final String ANALYZER_NAME = "Pipfile.lock Analyzer"; + + /** + * The phase that this analyzer is intended to run in. + */ + private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; + + /** + * The file filter used to determine which files this analyzer supports. + */ + private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(LOCKFILE).build(); + + /** + * Returns the FileFilter + * + * @return the FileFilter + */ + @Override + protected FileFilter getFileFilter() { + return FILTER; + } + + /** + * Returns the identifiedPackage of the analyzer. + * + * @return the identifiedPackage of the analyzer. + */ + @Override + public String getName() { + return ANALYZER_NAME; + } + + /** + * Returns the phase that the analyzer is intended to run in. + * + * @return the phase that the analyzer is intended to run in. + */ + @Override + public AnalysisPhase getAnalysisPhase() { + return ANALYSIS_PHASE; + } + + /** + * Returns the key used in the properties file to reference the analyzer's + * enabled property. + * + * @return the analyzer's enabled property setting key + */ + @Override + protected String getAnalyzerEnabledSettingKey() { + return Settings.KEYS.ANALYZER_PIPFILE_ENABLED; + } + + @Override + protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException { + LOGGER.debug("Checking file {}", dependency.getActualFilePath()); + + engine.removeDependency(dependency); + + final File dependencyFile = dependency.getActualFile(); + if (!dependencyFile.isFile() || dependencyFile.length() == 0) { + return; + } + + final File actualFile = dependency.getActualFile(); + try (FileInputStream fin = new FileInputStream(actualFile); + InputStream in = new BufferedInputStream(fin); + JsonReader jsonReader = Json.createReader(in)) { + + final JsonObject jsonLock = jsonReader.readObject(); + final JsonObject develop = jsonLock.getJsonObject("develop"); + final Set keys = develop.keySet(); + for (String identifiedPackage : keys) { + final JsonObject dep = develop.getJsonObject(identifiedPackage); + final String selectedVersion = dep.getString("version", "").trim(); + if (selectedVersion.startsWith("==") && selectedVersion.length() > 2) { + final String identifiedVersion = selectedVersion.substring(2).trim(); + LOGGER.debug("package, version: {} {}", identifiedPackage, identifiedVersion); + + final Dependency d = new Dependency(dependency.getActualFile(), true); + d.setName(identifiedPackage); + d.setVersion(identifiedVersion); + try { + final PackageURL purl = PackageURLBuilder.aPackageURL() + .withType("pypi") + .withName(identifiedPackage) + .withVersion(identifiedVersion) + .build(); + d.addSoftwareIdentifier(new PurlIdentifier(purl, Confidence.HIGHEST)); + } catch (MalformedPackageURLException ex) { + LOGGER.debug("Unable to build package url for pypi", ex); + d.addSoftwareIdentifier(new GenericIdentifier("pypi:" + identifiedPackage + "@" + identifiedVersion, Confidence.HIGH)); + } + d.setPackagePath(String.format("%s:%s", identifiedPackage, identifiedVersion)); + d.setEcosystem(PythonDistributionAnalyzer.DEPENDENCY_ECOSYSTEM); + final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), identifiedPackage, identifiedVersion); + d.setFilePath(filePath); + d.setSha1sum(Checksum.getSHA1Checksum(filePath)); + d.setSha256sum(Checksum.getSHA256Checksum(filePath)); + d.setMd5sum(Checksum.getMD5Checksum(filePath)); + d.addEvidence(EvidenceType.VENDOR, LOCKFILE, "vendor", identifiedPackage, Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, LOCKFILE, "product", identifiedPackage, Confidence.HIGHEST); + d.addEvidence(EvidenceType.VERSION, LOCKFILE, "version", identifiedVersion, Confidence.HIGHEST); + engine.addDependency(d); + } else { + LOGGER.debug("Skipping `{}`: Unknown version `{}` in `{}`", identifiedPackage, selectedVersion, dependency.getActualFilePath()); + } + } + } catch (FileNotFoundException ex) { + throw new RuntimeException(ex); + } catch (IOException | JsonException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Retrieves the contents of a given file. + * + * @param actualFile the file to read + * @return the contents of the file + * @throws AnalysisException thrown if there is an IO Exception + */ + private String getFileContents(final File actualFile) throws AnalysisException { + try { + return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); + } catch (IOException e) { + throw new AnalysisException("Problem occurred while reading dependency file.", e); + } + } + + /** + * Initializes the file type analyzer. + * + * @param engine a reference to the dependency-check engine + * @throws InitializationException thrown if there is an exception during + * initialization + */ + @Override + protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException { + // No initialization needed. + } +} diff --git a/core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer b/core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer index 79e8c6b94f9..c40992ece46 100644 --- a/core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer +++ b/core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer @@ -21,6 +21,7 @@ org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer org.owasp.dependencycheck.analyzer.PipAnalyzer org.owasp.dependencycheck.analyzer.PipfileAnalyzer +org.owasp.dependencycheck.analyzer.PipfilelockAnalyzer org.owasp.dependencycheck.analyzer.PoetryAnalyzer org.owasp.dependencycheck.analyzer.AutoconfAnalyzer org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzerTest.java new file mode 100644 index 00000000000..7410909dbfe --- /dev/null +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/PipfilelockAnalyzerTest.java @@ -0,0 +1,113 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2023 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.owasp.dependencycheck.BaseDBTestCase; +import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.dependency.Dependency; + +import java.io.File; +import org.apache.commons.lang3.ArrayUtils; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Unit tests for PipfilelockAnalyzerTest. + */ +public class PipfilelockAnalyzerTest extends BaseDBTestCase { + + /** + * The analyzer to test. + */ + private PipfilelockAnalyzer analyzer; + + /** + * Correctly setup the analyzer for testing. + * + * @throws Exception thrown if there is a problem + */ + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + analyzer = new PipfilelockAnalyzer(); + analyzer.initialize(getSettings()); + analyzer.setFilesMatched(true); + analyzer.prepare(null); + } + + /** + * Cleanup the analyzer's temp files, etc. + * + * @throws Exception thrown if there is a problem + */ + @After + @Override + public void tearDown() throws Exception { + analyzer.close(); + super.tearDown(); + } + + /** + * Test of getName method, of class PipAnalyzer. + */ + @Test + public void testGetName() { + assertEquals("Pipfile.lock Analyzer", analyzer.getName()); + } + + /** + * Test of supportsExtension method, of class PipAnalyzer. + */ + @Test + public void testSupportsFiles() { + assertFalse(analyzer.accept(new File("Pipfile"))); + assertTrue(analyzer.accept(new File("Pipfile.lock"))); + } + + @Test + public void testAnalyzePackageLock() throws Exception { + try (Engine engine = new Engine(getSettings())) { + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "pip/Pipfile.lock")); + engine.addDependency(result); + analyzer.analyze(result, engine); + assertFalse(ArrayUtils.contains(engine.getDependencies(), result)); + assertEquals(76, engine.getDependencies().length); + boolean found = false; + for (Dependency d : engine.getDependencies()) { + if ("alabaster".equals(d.getName())) { + found = true; + assertEquals("0.7.12", d.getVersion()); + assertThat(d.getDisplayFileName(), equalTo("alabaster:0.7.12")); + assertEquals(PythonDistributionAnalyzer.DEPENDENCY_ECOSYSTEM, d.getEcosystem()); + break; + } + } + assertTrue("Expeced to find urllib3", found); + } + } +} diff --git a/core/src/test/resources/pip/Pipfile b/core/src/test/resources/pip/Pipfile new file mode 100644 index 00000000000..78d413b2755 --- /dev/null +++ b/core/src/test/resources/pip/Pipfile @@ -0,0 +1,32 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[dev-packages] +pipenv = {path = ".", editable = true, extras = ["tests", "dev"]} +sphinx = "==4.*" +sphinx-click = "==4.*" +sphinxcontrib-spelling = "==7.*" +click = "==8.0.3" +pypiserver = "==1.*" +stdeb = {version="*", markers="sys_platform == 'linux'"} +zipp = {version = "==3.6.0", markers = "python_version < '3.10'"} +pre-commit = "==2.*" +atomicwrites = {version = "*", markers="sys_platform == 'win32'"} +pytest-cov = "==3.*" +typing-extensions = "==4.*" +waitress = {version = "*", markers="sys_platform == 'win32'"} +gunicorn = {version = "*", markers="sys_platform == 'linux'"} +parse = "*" +importlib-metadata = {version = "*", markers="python_version < '3.8'"} +colorama= {version = "*", markers="sys_platform == 'win32'"} + +[packages] + +[scripts] +tests = "bash ./run-tests.sh" +test = "pytest -vvs" + +[pipenv] +allow_prereleases = true diff --git a/core/src/test/resources/pip/Pipfile.lock b/core/src/test/resources/pip/Pipfile.lock new file mode 100644 index 00000000000..9e9aad580e9 --- /dev/null +++ b/core/src/test/resources/pip/Pipfile.lock @@ -0,0 +1,760 @@ +{ + "_meta": { + "hash": { + "sha256": "48857cc762ed1cb9fe4ec09aaf5d90931deb1e6875a09f7a09bf6fc5f438b402" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": { + "alabaster": { + "hashes": [ + "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", + "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" + ], + "version": "==0.7.12" + }, + "arpeggio": { + "hashes": [ + "sha256:448e332deb0e9ccd04046f1c6c14529d197f41bc2fdb3931e43fc209042fbdd3", + "sha256:d6b03839019bb8a68785f9292ee6a36b1954eb84b925b84a6b8a5e1e26d3ed3d" + ], + "version": "==2.0.0" + }, + "atomicwrites": { + "hashes": [ + "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11" + ], + "markers": "sys_platform == 'win32'", + "version": "==1.4.1" + }, + "attrs": { + "hashes": [ + "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836", + "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99" + ], + "markers": "python_version >= '3.6'", + "version": "==22.2.0" + }, + "babel": { + "hashes": [ + "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe", + "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6" + ], + "markers": "python_version >= '3.6'", + "version": "==2.11.0" + }, + "beautifulsoup4": { + "hashes": [ + "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30", + "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==4.11.1" + }, + "black": { + "hashes": [ + "sha256:0b945a5a1e5a5321f884de0061d5a8585d947c9b608e37b6d26ceee4dfdf4b62", + "sha256:4db1d8027ce7ae53f0ccf02b0be0b8808fefb291d6cb1543420f4165d96d364c", + "sha256:5fb7641d442ede92538bc70fa0201f884753a7d0f62f26c722b7b00301b95902", + "sha256:63330069d8ec909cf4e2c4d43a7f00aeb03335430ef9fec6cd2328e6ebde8a77", + "sha256:793c9176beb2adf295f6b863d9a4dc953fe2ac359ca3da108d71d14cb2c09e52", + "sha256:85dede655442f5e246e7abd667fe07e14916897ba52f3640b5489bf11f7dbf67", + "sha256:88288a645402106b8eb9f50d7340ae741e16240bb01c2eed8466549153daa96e", + "sha256:88ec25a64063945b4591b6378bead544c5d3260de1c93ad96f3ad2d76ddd76fd", + "sha256:8dff6f0157e47fbbeada046fca144b6557d3be2fb2602d668881cd179f04a352", + "sha256:ca658b69260a18bf7aa0b0a6562dbbd304a737487d1318998aaca5a75901fd2c", + "sha256:ddbf9da228726d46f45c29024263e160d41030a415097254817d65127012d1a2", + "sha256:e88e4b633d64b9e7adc4a6b922f52bb204af9f90d7b1e3317e6490f2b598b1ea" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1a1" + }, + "bs4": { + "hashes": [ + "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a" + ], + "version": "==0.0.1" + }, + "certifi": { + "hashes": [ + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.12.7" + }, + "cfgv": { + "hashes": [ + "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426", + "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736" + ], + "markers": "python_full_version >= '3.6.1'", + "version": "==3.3.1" + }, + "charset-normalizer": { + "hashes": [ + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==2.1.1" + }, + "click": { + "hashes": [ + "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", + "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" + ], + "index": "pypi", + "version": "==8.0.3" + }, + "click-default-group": { + "hashes": [ + "sha256:d9560e8e8dfa44b3562fbc9425042a0fd6d21956fcc2db0077f63f34253ab904" + ], + "version": "==1.2.2" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.6" + }, + "coverage": { + "extras": [ + "toml" + ], + "hashes": [ + "sha256:04691b8e832a900ed15f5bcccc2008fc2d1c8e7411251fd7d1422a84e1d72841", + "sha256:1a613d60be1a02c7a5184ea5c4227f48c08e0635608b9c17ae2b17efef8f2501", + "sha256:1d732b5dcafed67d81c5b5a0c404c31a61e13148946a3b910a340f72fdd1ec95", + "sha256:2b31f7f246dbff339b3b76ee81329e3eca5022ce270c831c65e841dbbb40115f", + "sha256:312fd77258bf1044ef4faa82091f2e88216e4b62dcf1a461d3e917144c8b09b7", + "sha256:321316a7b979892a13c148a9d37852b5a76f26717e4b911b606a649394629532", + "sha256:36c1a1b6d38ebf8a4335f65226ec36b5d6fd67743fdcbad5c52bdcd46c4f5842", + "sha256:38f281bb9bdd4269c451fed9451203512dadefd64676f14ed1e82c77eb5644fc", + "sha256:3a2d81c95d3b02638ee6ae647edc79769fd29bf5e9e5b6b0c29040579f33c260", + "sha256:3d40ad86a348c79c614e2b90566267dd6d45f2e6b4d2bfb794d78ea4a4b60b63", + "sha256:3d72e3d20b03e63bd27b1c4d6b754cd93eca82ecc5dd77b99262d5f64862ca35", + "sha256:3fbb59f84c8549113dcdce7c6d16c5731fe53651d0b46c0a25a5ebc7bb655869", + "sha256:405d8528a0ea07ca516d9007ecad4e1bd10e2eeef27411c6188d78c4e2dfcddc", + "sha256:420f10c852b9a489cf5a764534669a19f49732a0576c76d9489ebf287f81af6d", + "sha256:426895ac9f2938bec193aa998e7a77a3e65d3e46903f348e794b4192b9a5b61e", + "sha256:4438ba539bef21e288092b30ea2fc30e883d9af5b66ebeaf2fd7c25e2f074e39", + "sha256:46db409fc0c3ee5c859b84c7de9cb507166287d588390889fdf06a1afe452e16", + "sha256:483e120ea324c7fced6126bb9bf0535c71e9233d29cbc7e2fc4560311a5f8a32", + "sha256:4d7be755d7544dac2b9814e98366a065d15a16e13847eb1f5473bb714483391e", + "sha256:4e97b21482aa5c21e049e4755c95955ad71fb54c9488969e2f17cf30922aa5f6", + "sha256:5f44ba7c07e0aa4a7a2723b426c254e952da82a33d65b4a52afae4bef74a4203", + "sha256:62e5b942378d5f0b87caace567a70dc634ddd4d219a236fa221dc97d2fc412c8", + "sha256:7c669be1b01e4b2bf23aa49e987d9bedde0234a7da374a9b77ca5416d7c57002", + "sha256:7d47d666e17e57ef65fefc87229fde262bd5c9039ae8424bc53aa2d8f07dc178", + "sha256:7e184aa18f921b612ea08666c25dd92a71241c8ed40917f2824219c92289b8c7", + "sha256:80583c536e7e010e301002088919d4ea90566d1789ee02551574fdf3faa275ae", + "sha256:8217f73faf08623acb25fb2affd5d20cbcd8185213db308e46a37e6fd6a56a49", + "sha256:87d95eea58fb71f69b4f1c761099a19e0e9cb27d45dc1cc7042523128ee56337", + "sha256:8bd466135fb07f693dbdd999a5569ffbc0590e9c64df859243162f0ebee950c8", + "sha256:8e133ca2f8141b415ff396ba789bdeffdea8ff9a5c7fc9996ccf591d7d40ee93", + "sha256:8e6c0ca447b557a32642f22d0987be37950eda51c4f19fc788cebc99426284b6", + "sha256:9de96025ce25b9f4e744fbe558a003e673004af255da9b1f6ec243720ac5deeb", + "sha256:a27a8dca0dc6f0944ed9fd83c556d862e227a5cd4220e62af5d4c750389938f0", + "sha256:a2d4f68e4fa286fb6b00d58a1e87c79840e289d3f6e5dcb912ad7b0fbd9629fb", + "sha256:a6e1c77ff6f10eab496fbbcdaa7dfae84968928a0aadc43ce3c3453cec29bd79", + "sha256:a7b018811a0e1d3869d8d0600849953acd355a3a29c6bee0fbd24d7772bcc0a2", + "sha256:a99b2f2dd1236e8d9dc35974a3dc298a408cdfd512b0bb2451798cff1ce63408", + "sha256:ac1033942851bf01f28c76318155ea92d6648aecb924cab81fa23781d095e9ab", + "sha256:b6936cd38757dd323fefc157823e46436610328f0feb1419a412316f24b77f36", + "sha256:b6eab230b18458707b5c501548e997e42934b1c189fb4d1b78bf5aacc1c6a137", + "sha256:bcb57d175ff0cb4ff97fc547c74c1cb8d4c9612003f6d267ee78dad8f23d8b30", + "sha256:c1f02d016b9b6b5ad21949a21646714bfa7b32d6041a30f97674f05d6d6996e3", + "sha256:c40aaf7930680e0e5f3bd6d3d3dc97a7897f53bdce925545c4b241e0c5c3ca6a", + "sha256:c5e1874c601128cf54c1d4b471e915658a334fbc56d7b3c324ddc7511597ea82", + "sha256:c8805673b1953313adfc487d5323b4c87864e77057944a0888c98dd2f7a6052f", + "sha256:da458bdc9b0bcd9b8ca85bc73148631b18cc8ba03c47f29f4c017809990351aa", + "sha256:dcb708ab06f3f4dfc99e9f84821c9120e5f12113b90fad132311a2cb97525379", + "sha256:dfafc350f43fd7dc67df18c940c3b7ed208ebb797abe9fb3047f0c65be8e4c0f", + "sha256:e8931af864bd599c6af626575a02103ae626f57b34e3af5537d40b040d33d2ad", + "sha256:efa9d943189321f67f71070c309aa6f6130fa1ec35c9dfd0da0ed238938ce573", + "sha256:fd22ee7bff4b5c37bb6385efee1c501b75e29ca40286f037cb91c2182d1348ce" + ], + "markers": "python_version >= '3.7'", + "version": "==7.0.2" + }, + "distlib": { + "hashes": [ + "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46", + "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e" + ], + "version": "==0.3.6" + }, + "docutils": { + "hashes": [ + "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", + "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.17.1" + }, + "exceptiongroup": { + "hashes": [ + "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e", + "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23" + ], + "markers": "python_version < '3.11'", + "version": "==1.1.0" + }, + "execnet": { + "hashes": [ + "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5", + "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.9.0" + }, + "filelock": { + "hashes": [ + "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de", + "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d" + ], + "markers": "python_version >= '3.7'", + "version": "==3.9.0" + }, + "flake8": { + "hashes": [ + "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", + "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==3.9.2" + }, + "flaky": { + "hashes": [ + "sha256:3ad100780721a1911f57a165809b7ea265a7863305acb66708220820caf8aa0d", + "sha256:d6eda73cab5ae7364504b7c44670f70abed9e75f77dd116352f662817592ec9c" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.7.0" + }, + "gunicorn": { + "hashes": [ + "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", + "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" + ], + "index": "pypi", + "markers": "sys_platform == 'linux'", + "version": "==20.1.0" + }, + "identify": { + "hashes": [ + "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c", + "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db" + ], + "markers": "python_version >= '3.7'", + "version": "==2.5.11" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "imagesize": { + "hashes": [ + "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", + "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.4.1" + }, + "importlib-metadata": { + "hashes": [ + "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", + "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + ], + "markers": "python_version < '3.8'", + "version": "==6.0.0" + }, + "incremental": { + "hashes": [ + "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0", + "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51" + ], + "version": "==22.10.0" + }, + "iniconfig": { + "hashes": [ + "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", + "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" + ], + "version": "==1.1.1" + }, + "invoke": { + "hashes": [ + "sha256:41b428342d466a82135d5ab37119685a989713742be46e42a3a399d685579314", + "sha256:d9694a865764dd3fd91f25f7e9a97fb41666e822bbb00e670091e3f43933574d" + ], + "version": "==1.7.3" + }, + "jinja2": { + "hashes": [ + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.2" + }, + "markupsafe": { + "hashes": [ + "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", + "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", + "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", + "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", + "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", + "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", + "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", + "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", + "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", + "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", + "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", + "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", + "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", + "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", + "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", + "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", + "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", + "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", + "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", + "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", + "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", + "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", + "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", + "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", + "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", + "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", + "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", + "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", + "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", + "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", + "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", + "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", + "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", + "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", + "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", + "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", + "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", + "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", + "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", + "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.1" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "mock": { + "hashes": [ + "sha256:335ef0bf9bcd27505c0c1720d4eac2783f18d07d6f45ac49542b57885a1996dd", + "sha256:fd552787228eb2ab8352f270470fa93c9ad8b9cbc565c5558ee3faed8edb3853" + ], + "markers": "python_version >= '3.6'", + "version": "==5.0.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" + }, + "nodeenv": { + "hashes": [ + "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e", + "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==1.7.0" + }, + "packaging": { + "hashes": [ + "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3", + "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3" + ], + "markers": "python_version >= '3.7'", + "version": "==22.0" + }, + "parse": { + "hashes": [ + "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b" + ], + "index": "pypi", + "version": "==1.19.0" + }, + "parver": { + "hashes": [ + "sha256:c66d3347a4858643875ef959d8ba7a269d5964bfb690b0dd998b8f39da930be2", + "sha256:d4a3dbb93c53373ee9a0ba055e4858c44169b204b912e49d003ead95db9a9bca" + ], + "markers": "python_version >= '3.7'", + "version": "==0.4" + }, + "pathspec": { + "hashes": [ + "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6", + "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6" + ], + "markers": "python_version >= '3.7'", + "version": "==0.10.3" + }, + "pipenv": { + "editable": true, + "extras": [ + "dev", + "tests" + ], + "path": "." + }, + "platformdirs": { + "hashes": [ + "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490", + "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2" + ], + "markers": "python_version >= '3.7'", + "version": "==2.6.2" + }, + "pluggy": { + "hashes": [ + "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", + "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" + ], + "markers": "python_version >= '3.6'", + "version": "==1.0.0" + }, + "pre-commit": { + "hashes": [ + "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658", + "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad" + ], + "index": "pypi", + "version": "==2.21.0" + }, + "pycodestyle": { + "hashes": [ + "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", + "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.7.0" + }, + "pyenchant": { + "hashes": [ + "sha256:1cf830c6614362a78aab78d50eaf7c6c93831369c52e1bb64ffae1df0341e637", + "sha256:5a636832987eaf26efe971968f4d1b78e81f62bca2bde0a9da210c7de43c3bce", + "sha256:5facc821ece957208a81423af7d6ec7810dad29697cb0d77aae81e4e11c8e5a6", + "sha256:6153f521852e23a5add923dbacfbf4bebbb8d70c4e4bad609a8e0f9faeb915d1" + ], + "markers": "python_version >= '3.5'", + "version": "==3.2.2" + }, + "pyflakes": { + "hashes": [ + "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", + "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.3.1" + }, + "pygments": { + "hashes": [ + "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", + "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + ], + "markers": "python_version >= '3.6'", + "version": "==2.14.0" + }, + "pypiserver": { + "hashes": [ + "sha256:24804a717ccd4611aa805621eead821f9d389163f6020a500c7e05f191884ba2", + "sha256:bea067627793ebcab6574549b7a7e9099cceeb5b902a73f4df09734c11fc3cdf" + ], + "index": "pypi", + "version": "==1.5.1" + }, + "pytest": { + "hashes": [ + "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", + "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" + ], + "markers": "python_version >= '3.7'", + "version": "==7.2.0" + }, + "pytest-cov": { + "hashes": [ + "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6", + "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470" + ], + "index": "pypi", + "version": "==3.0.0" + }, + "pytest-timeout": { + "hashes": [ + "sha256:c07ca07404c612f8abbe22294b23c368e2e5104b521c1790195561f37e1ac3d9", + "sha256:f6f50101443ce70ad325ceb4473c4255e9d74e3c7cd0ef827309dfa4c0d975c6" + ], + "markers": "python_version >= '3.6'", + "version": "==2.1.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:40fdb8f3544921c5dfcd486ac080ce22870e71d82ced6d2e78fa97c2addd480c", + "sha256:70a76f191d8a1d2d6be69fc440cdf85f3e4c03c08b520fd5dc5d338d6cf07d89" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.0" + }, + "pytz": { + "hashes": [ + "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a", + "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd" + ], + "version": "==2022.7" + }, + "pyyaml": { + "hashes": [ + "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0" + }, + "requests": { + "hashes": [ + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + ], + "markers": "python_version >= '3.7' and python_version < '4'", + "version": "==2.28.1" + }, + "setuptools": { + "hashes": [ + "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", + "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" + ], + "markers": "python_version >= '3.7'", + "version": "==65.6.3" + }, + "snowballstemmer": { + "hashes": [ + "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", + "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a" + ], + "version": "==2.2.0" + }, + "soupsieve": { + "hashes": [ + "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", + "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d" + ], + "markers": "python_version >= '3.6'", + "version": "==2.3.2.post1" + }, + "sphinx": { + "hashes": [ + "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6", + "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226" + ], + "index": "pypi", + "version": "==4.5.0" + }, + "sphinx-click": { + "hashes": [ + "sha256:2821c10a68fc9ee6ce7c92fad26540d8d8c8f45e6d7258f0e4fb7529ae8fab49", + "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48" + ], + "index": "pypi", + "version": "==4.4.0" + }, + "sphinxcontrib-applehelp": { + "hashes": [ + "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", + "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.2" + }, + "sphinxcontrib-devhelp": { + "hashes": [ + "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", + "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.2" + }, + "sphinxcontrib-htmlhelp": { + "hashes": [ + "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07", + "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.0" + }, + "sphinxcontrib-jsmath": { + "hashes": [ + "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", + "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.1" + }, + "sphinxcontrib-qthelp": { + "hashes": [ + "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", + "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.3" + }, + "sphinxcontrib-serializinghtml": { + "hashes": [ + "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd", + "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952" + ], + "markers": "python_version >= '3.5'", + "version": "==1.1.5" + }, + "sphinxcontrib-spelling": { + "hashes": [ + "sha256:56561c3f6a155b0946914e4de988729859315729dc181b5e4dc8a68fe78de35a", + "sha256:95a0defef8ffec6526f9e83b20cc24b08c9179298729d87976891840e3aa3064" + ], + "index": "pypi", + "version": "==7.7.0" + }, + "stdeb": { + "hashes": [ + "sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2" + ], + "index": "pypi", + "markers": "sys_platform == 'linux'", + "version": "==0.10.0" + }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_version < '3.11'", + "version": "==2.0.1" + }, + "towncrier": { + "hashes": [ + "sha256:9767a899a4d6856950f3598acd9e8f08da2663c49fdcda5ea0f9e6ba2afc8eea", + "sha256:9c49d7e75f646a9aea02ae904c0bc1639c8fd14a01292d2b123b8d307564034d" + ], + "markers": "python_version >= '3.7'", + "version": "==22.12.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", + "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" + ], + "index": "pypi", + "version": "==4.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", + "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.13" + }, + "virtualenv": { + "hashes": [ + "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4", + "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058" + ], + "markers": "python_version >= '3.6'", + "version": "==20.17.1" + }, + "virtualenv-clone": { + "hashes": [ + "sha256:418ee935c36152f8f153c79824bb93eaf6f0f7984bae31d3f48f350b9183501a", + "sha256:44d5263bceed0bac3e1424d64f798095233b64def1c5689afa43dc3223caf5b0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.5.7" + }, + "waitress": { + "hashes": [ + "sha256:7500c9625927c8ec60f54377d590f67b30c8e70ef4b8894214ac6e4cad233d2a", + "sha256:780a4082c5fbc0fde6a2fcfe5e26e6efc1e8f425730863c04085769781f51eba" + ], + "markers": "sys_platform == 'win32'", + "version": "==2.1.2" + }, + "zipp": { + "hashes": [ + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + ], + "markers": "python_version < '3.10'", + "version": "==3.6.0" + } + } +} diff --git a/maven/pom.xml b/maven/pom.xml index e5ce1333b45..746ded454cd 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-maven maven-plugin diff --git a/pom.xml b/pom.xml index c67353ea27a..ee10b815181 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT pom diff --git a/utils/pom.xml b/utils/pom.xml index c8ce4842d30..7d48bb73725 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 8.0.3-SNAPSHOT + 8.1.0-SNAPSHOT dependency-check-utils