From 2d582f78a1b0ce8580308f32a40db6f3eb9c5217 Mon Sep 17 00:00:00 2001 From: Colm O hEigeartaigh Date: Fri, 3 Nov 2023 14:33:02 +0000 Subject: [PATCH] =?UTF-8?q?Add=20a=20new=20Java=20configuration=20option?= =?UTF-8?q?=20to=20recursively=20search=20parent=20poms=E2=80=A6=20(#2274)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add a new Java configuration option to recursively search parent poms for licenses --------- Signed-off-by: Colm O hEigeartaigh Signed-off-by: Christopher Phillips Co-authored-by: Christopher Phillips --- README.md | 14 +- cmd/syft/cli/options/catalog.go | 5 +- cmd/syft/cli/options/java.go | 5 +- syft/pkg/cataloger/config.go | 3 +- syft/pkg/cataloger/java/archive_parser.go | 45 ++++- .../pkg/cataloger/java/archive_parser_test.go | 120 ++++++++++- syft/pkg/cataloger/java/config.go | 3 +- syft/pkg/cataloger/java/options.go | 21 +- .../java/test-fixtures/jar-metadata/Makefile | 4 + .../opensaml-core-3.4.6/META-INF/INDEX.LIST | 27 +++ .../opensaml-core-3.4.6/META-INF/MANIFEST.MF | 12 ++ .../org.opensaml/opensaml-core/pom.properties | 4 + .../maven/org.opensaml/opensaml-core/pom.xml | 75 +++++++ .../opensaml-parent-3.4.6.pom | 186 ++++++++++++++++++ .../maven-xml-responses/parent-7.11.2.pom | 118 +++++++++++ 15 files changed, 612 insertions(+), 30 deletions(-) create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/INDEX.LIST create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/MANIFEST.MF create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.properties create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom diff --git a/README.md b/README.md index 19f6ca4b4..679e1c4a7 100644 --- a/README.md +++ b/README.md @@ -603,13 +603,15 @@ golang: no-proxy: "" java: - # when running across pom.xml files that could have more information, syft will - # explicitly search maven for license information by querying the online pom when this is true eg: - # https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-test/3.1.5/spring-boot-starter-test-3.1.5.pom - # this option is helpful for when the parent pom has this information, - # but it is not accessible from within the final built artifact - search-maven-for-licenses: false maven-url: "https://repo1.maven.org/maven2" + max-parent-recursive-depth: 5 + # enables Syft to use the network to fill in more detailed information about artifacts + # currently this enables searching maven-url for license data + # when running across pom.xml files that could have more information, syft will + # explicitly search maven for license information by querying the online pom when this is true + # this option is helpful for when the parent pom has more data, + # that is not accessible from within the final built artifact + use-network: false linux-kernel: # whether to catalog linux kernel modules found within lib/modules/** directories diff --git a/cmd/syft/cli/options/catalog.go b/cmd/syft/cli/options/catalog.go index 0848912cb..33395c45a 100644 --- a/cmd/syft/cli/options/catalog.go +++ b/cmd/syft/cli/options/catalog.go @@ -140,8 +140,9 @@ func (cfg Catalog) ToCatalogerConfig() cataloger.Config { CatalogModules: cfg.LinuxKernel.CatalogModules, }, Java: javaCataloger.DefaultCatalogerOpts(). - WithSearchMavenForLicenses(cfg.Java.SearchMavenForLicenses). - WithMavenCentralURL(cfg.Java.MavenURL), + WithUseNetwork(cfg.Java.UseNetwork). + WithMavenCentralURL(cfg.Java.MavenURL). + WithMaxParentRecursiveDepth(cfg.Java.MaxParentRecursiveDepth), Python: pythonCataloger.CatalogerConfig{ GuessUnpinnedRequirements: cfg.Python.GuessUnpinnedRequirements, }, diff --git a/cmd/syft/cli/options/java.go b/cmd/syft/cli/options/java.go index 4f1b76b16..7b7b9fd25 100644 --- a/cmd/syft/cli/options/java.go +++ b/cmd/syft/cli/options/java.go @@ -1,6 +1,7 @@ package options type java struct { - SearchMavenForLicenses bool `yaml:"search-maven-for-licenses" json:"search-maven-for-licenses" mapstructure:"search-maven-for-licenses"` - MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"` + UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` + MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"` + MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` } diff --git a/syft/pkg/cataloger/config.go b/syft/pkg/cataloger/config.go index f829bd113..3c283fee0 100644 --- a/syft/pkg/cataloger/config.go +++ b/syft/pkg/cataloger/config.go @@ -37,6 +37,7 @@ func (c Config) JavaConfig() java.Config { return java.Config{ SearchUnindexedArchives: c.Search.IncludeUnindexedArchives, SearchIndexedArchives: c.Search.IncludeIndexedArchives, - SearchMavenForLicenses: c.Java.SearchMavenForLicenses, + UseNetwork: c.Java.UseNetwork, + MaxParentRecursiveDepth: c.Java.MaxParentRecursiveDepth, } } diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 6653738db..109ea5bbc 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -286,8 +286,8 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, versi if version == "" && pomProjectObject != nil { version = pomProjectObject.Version } - if pomProjectObject != nil && j.cfg.SearchMavenForLicenses { - findPomLicenses(pomProjectObject) + if pomProjectObject != nil && j.cfg.UseNetwork { + findPomLicenses(pomProjectObject, j.cfg) } if pomProjectObject != nil { @@ -304,17 +304,20 @@ func artifactIDMatchesFilename(artifactID, fileName string) bool { return strings.HasPrefix(artifactID, fileName) || strings.HasSuffix(fileName, artifactID) } -func findPomLicenses(pomProjectObject *parsedPomProject) { +func findPomLicenses(pomProjectObject *parsedPomProject, cfg Config) { // If we don't have any licenses until now, and if we have a parent Pom, then we'll check the parent pom in maven central for licenses. if pomProjectObject != nil && pomProjectObject.Parent != nil && len(pomProjectObject.Licenses) == 0 { - parentPom, err := getPomFromMavenCentral(pomProjectObject.Parent.GroupID, pomProjectObject.Parent.ArtifactID, pomProjectObject.Parent.Version) + parentLicenses, err := recursivelyFindLicensesFromParentPom( + pomProjectObject.Parent.GroupID, + pomProjectObject.Parent.ArtifactID, + pomProjectObject.Parent.Version, + cfg) if err != nil { // We don't want to abort here as the parent pom might not exist in Maven Central, we'll just log the error log.Tracef("unable to get parent pom from Maven central: %v", err) return } - parentLicenses := parseLicensesFromPom(parentPom) - if len(parentLicenses) > 0 || parentPom == nil || parentPom.Parent == nil { + if len(parentLicenses) > 0 { for _, licenseName := range parentLicenses { pomProjectObject.Licenses = append(pomProjectObject.Licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) } @@ -322,22 +325,44 @@ func findPomLicenses(pomProjectObject *parsedPomProject) { } } -func formatMavenPomURL(groupID, artifactID, version string) (requestURL string, err error) { +func formatMavenPomURL(groupID, artifactID, version, mavenBaseURL string) (requestURL string, err error) { // groupID needs to go from maven.org -> maven/org urlPath := strings.Split(groupID, ".") artifactPom := fmt.Sprintf("%s-%s.pom", artifactID, version) urlPath = append(urlPath, artifactID, version, artifactPom) // ex:"https://repo1.maven.org/maven2/groupID/artifactID/artifactPom - requestURL, err = url.JoinPath(MavenBaseURL, urlPath...) + requestURL, err = url.JoinPath(mavenBaseURL, urlPath...) if err != nil { return requestURL, fmt.Errorf("could not construct maven url: %w", err) } return requestURL, err } -func getPomFromMavenCentral(groupID, artifactID, version string) (*gopom.Project, error) { - requestURL, err := formatMavenPomURL(groupID, artifactID, version) +func recursivelyFindLicensesFromParentPom(groupID, artifactID, version string, cfg Config) ([]string, error) { + var licenses []string + // As there can be nested parent poms, we'll recursively check for licenses until we reach the max depth + for i := 0; i < cfg.MaxParentRecursiveDepth; i++ { + parentPom, err := getPomFromMavenCentral(groupID, artifactID, version, cfg.MavenBaseURL) + if err != nil { + return nil, err + } + parentLicenses := parseLicensesFromPom(parentPom) + if len(parentLicenses) > 0 || parentPom == nil || parentPom.Parent == nil { + licenses = parentLicenses + break + } + + groupID = *parentPom.Parent.GroupID + artifactID = *parentPom.Parent.ArtifactID + version = *parentPom.Parent.Version + } + + return licenses, nil +} + +func getPomFromMavenCentral(groupID, artifactID, version, mavenBaseURL string) (*gopom.Project, error) { + requestURL, err := formatMavenPomURL(groupID, artifactID, version, mavenBaseURL) if err != nil { return nil, err } diff --git a/syft/pkg/cataloger/java/archive_parser_test.go b/syft/pkg/cataloger/java/archive_parser_test.go index 3d05fb868..9b48b34cd 100644 --- a/syft/pkg/cataloger/java/archive_parser_test.go +++ b/syft/pkg/cataloger/java/archive_parser_test.go @@ -4,6 +4,8 @@ import ( "bufio" "fmt" "io" + "net/http" + "net/http/httptest" "os" "os/exec" "path/filepath" @@ -44,6 +46,102 @@ func generateJavaBuildFixture(t *testing.T, fixturePath string) { run(t, cmd) } +func generateMockMavenHandler(responseFixture string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + // Set the Content-Type header to indicate that the response is XML + w.Header().Set("Content-Type", "application/xml") + // Copy the file's content to the response writer + file, err := os.Open(responseFixture) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer file.Close() + _, err = io.Copy(w, file) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } +} + +type handlerPath struct { + path string + handler func(w http.ResponseWriter, r *http.Request) +} + +func TestSearchMavenForLicenses(t *testing.T) { + mux, url, teardown := setup() + defer teardown() + tests := []struct { + name string + fixture string + detectNested bool + config Config + requestPath string + requestHandlers []handlerPath + expectedLicenses []pkg.License + }{ + { + name: "searchMavenForLicenses returns the expected licenses when search is set to true", + fixture: "opensaml-core-3.4.6", + detectNested: false, + config: Config{ + UseNetwork: true, + MavenBaseURL: url, + MaxParentRecursiveDepth: 2, + }, + requestHandlers: []handlerPath{ + { + path: "/org/opensaml/opensaml-parent/3.4.6/opensaml-parent-3.4.6.pom", + handler: generateMockMavenHandler("test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom"), + }, + { + path: "/net/shibboleth/parent/7.11.2/parent-7.11.2.pom", + handler: generateMockMavenHandler("test-fixtures/maven-xml-responses/parent-7.11.2.pom"), + }, + }, + expectedLicenses: []pkg.License{ + { + Type: license.Declared, + Value: `The Apache Software License, Version 2.0`, + SPDXExpression: ``, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + // configure maven central requests + for _, hdlr := range tc.requestHandlers { + mux.HandleFunc(hdlr.path, hdlr.handler) + } + + // setup metadata fixture; note: + // this fixture has a pomProjectObject and has a parent object + // it has no licenses on either which is the condition for testing + // the searchMavenForLicenses functionality + jarName := generateJavaMetadataJarFixture(t, tc.fixture) + fixture, err := os.Open(jarName) + require.NoError(t, err) + + // setup parser + ap, cleanupFn, err := newJavaArchiveParser( + file.LocationReadCloser{ + Location: file.NewLocation(fixture.Name()), + ReadCloser: fixture, + }, tc.detectNested, tc.config) + defer cleanupFn() + + // assert licenses are discovered from upstream + _, _, licenses := ap.guessMainPackageNameAndVersionFromPomInfo() + assert.Equal(t, tc.expectedLicenses, licenses) + }) + } +} + func TestFormatMavenURL(t *testing.T) { tests := []struct { name string @@ -63,7 +161,7 @@ func TestFormatMavenURL(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - requestURL, err := formatMavenPomURL(tc.groupID, tc.artifactID, tc.version) + requestURL, err := formatMavenPomURL(tc.groupID, tc.artifactID, tc.version, MavenBaseURL) assert.NoError(t, err, "expected no err; got %w", err) assert.Equal(t, tc.expected, requestURL) }) @@ -303,7 +401,7 @@ func TestParseJar(t *testing.T) { parser, cleanupFn, err := newJavaArchiveParser(file.LocationReadCloser{ Location: file.NewLocation(fixture.Name()), ReadCloser: fixture, - }, false, Config{SearchMavenForLicenses: false}) + }, false, Config{UseNetwork: false}) defer cleanupFn() require.NoError(t, err) @@ -1303,3 +1401,21 @@ func run(t testing.TB, cmd *exec.Cmd) { } } } + +// setup sets up a test HTTP server for mocking requests to maven central. +// The returned url is injected into the Config so the client uses the test server. +// Tests should register handlers on mux to simulate the expected request/response structure +func setup() (mux *http.ServeMux, serverURL string, teardown func()) { + // mux is the HTTP request multiplexer used with the test server. + mux = http.NewServeMux() + + // We want to ensure that tests catch mistakes where the endpoint URL is + // specified as absolute rather than relative. It only makes a difference + // when there's a non-empty base URL path. So, use that. See issue #752. + apiHandler := http.NewServeMux() + apiHandler.Handle("/", mux) + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + return mux, server.URL, server.Close +} diff --git a/syft/pkg/cataloger/java/config.go b/syft/pkg/cataloger/java/config.go index 07868ca91..bfa526f9b 100644 --- a/syft/pkg/cataloger/java/config.go +++ b/syft/pkg/cataloger/java/config.go @@ -3,6 +3,7 @@ package java type Config struct { SearchUnindexedArchives bool SearchIndexedArchives bool - SearchMavenForLicenses bool + UseNetwork bool MavenBaseURL string + MaxParentRecursiveDepth int } diff --git a/syft/pkg/cataloger/java/options.go b/syft/pkg/cataloger/java/options.go index c25a1d5ff..ddd19cd96 100644 --- a/syft/pkg/cataloger/java/options.go +++ b/syft/pkg/cataloger/java/options.go @@ -3,12 +3,13 @@ package java const MavenBaseURL = "https://repo1.maven.org/maven2" type CatalogerOpts struct { - SearchMavenForLicenses bool - MavenURL string + UseNetwork bool + MavenURL string + MaxParentRecursiveDepth int } -func (j CatalogerOpts) WithSearchMavenForLicenses(input bool) CatalogerOpts { - j.SearchMavenForLicenses = input +func (j CatalogerOpts) WithUseNetwork(input bool) CatalogerOpts { + j.UseNetwork = input return j } @@ -19,9 +20,17 @@ func (j CatalogerOpts) WithMavenCentralURL(input string) CatalogerOpts { return j } +func (j CatalogerOpts) WithMaxParentRecursiveDepth(input int) CatalogerOpts { + if input > 0 { + j.MaxParentRecursiveDepth = input + } + return j +} + func DefaultCatalogerOpts() CatalogerOpts { return CatalogerOpts{ - SearchMavenForLicenses: false, - MavenURL: MavenBaseURL, + UseNetwork: false, + MavenURL: MavenBaseURL, + MaxParentRecursiveDepth: 5, } } diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile index 1fd78b446..f837b37f2 100644 --- a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile @@ -3,6 +3,7 @@ CACHE_PATH = $(shell pwd)/cache JACKSON_CORE = jackson-core-2.15.2 SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2 +OPENSAML_CORE = opensaml-core-3.4.6 API_ALL_SOURCES = api-all-2.0.0-sources $(CACHE_DIR): @@ -14,5 +15,8 @@ $(CACHE_DIR)/$(JACKSON_CORE).jar: $(CACHE_DIR) $(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: $(CACHE_DIR) cd $(SBT_JACKSON_CORE) && zip -r $(CACHE_PATH)/$(SBT_JACKSON_CORE).jar . +$(CACHE_DIR)/$(OPENSAML_CORE).jar: $(CACHE_DIR) + cd $(OPENSAML_CORE) && zip -r $(CACHE_PATH)/$(OPENSAML_CORE).jar . + $(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR) cd $(API_ALL_SOURCES) && zip -r $(CACHE_PATH)/$(API_ALL_SOURCES).jar . \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/INDEX.LIST b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/INDEX.LIST new file mode 100644 index 000000000..5378153c7 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/INDEX.LIST @@ -0,0 +1,27 @@ +JarIndex-Version: 1.0 + +opensaml-core-3.4.6.jar +META-INF +META-INF/maven +META-INF/maven/org.opensaml +META-INF/maven/org.opensaml/opensaml-core +META-INF/services +org +org/opensaml +org/opensaml/core +org/opensaml/core/config +org/opensaml/core/config/provider +org/opensaml/core/criterion +org/opensaml/core/metrics +org/opensaml/core/metrics/impl +org/opensaml/core/xml +org/opensaml/core/xml/config +org/opensaml/core/xml/io +org/opensaml/core/xml/persist +org/opensaml/core/xml/schema +org/opensaml/core/xml/schema/impl +org/opensaml/core/xml/util +schema +default-config.xml +schema-config.xml + diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/MANIFEST.MF b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/MANIFEST.MF new file mode 100644 index 000000000..7ecbea6c9 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Automatic-Module-Name: org.opensaml.core +Built-By: putmanb +Build-Jdk: 1.7.0_80 +Created-By: Apache Maven 3.6.3 +Main-Class: org.opensaml.core.Version + +Name: org/opensaml/core/ +Implementation-Vendor: opensaml.org +Implementation-Title: opensaml-core +Implementation-Version: 3.4.6 + diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.properties b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.properties new file mode 100644 index 000000000..7ddb6e110 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.properties @@ -0,0 +1,4 @@ +#Created by Apache Maven 3.6.3 +version=3.4.6 +groupId=org.opensaml +artifactId=opensaml-core diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.xml b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.xml new file mode 100644 index 000000000..eab703e6e --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/opensaml-core-3.4.6/META-INF/maven/org.opensaml/opensaml-core/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + + + org.opensaml + opensaml-parent + 3.4.6 + ../opensaml-parent + + + OpenSAML :: Core + Core + opensaml-core + jar + + + org.opensaml.core + + + + + + joda-time + joda-time + + + io.dropwizard.metrics + metrics-core + + + + + + + + + + + + + + maven-jar-plugin + + + true + + org.opensaml.core.Version + + + + org/opensaml/core/ + + ${project.artifactId} + ${project.version} + opensaml.org + + + + + + + + + + + + site + dav:${opensaml-module.site.url} + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom b/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom new file mode 100644 index 000000000..e3e2be465 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom @@ -0,0 +1,186 @@ + + + + 4.0.0 + + + net.shibboleth + parent + 7.11.2 + + + OpenSAML + + A library for creating, reading, writing and performing some processing of SAML messages. + + For further information see https://wiki.shibboleth.net/confluence/display/OS30/Home + + + org.opensaml + opensaml-parent + 3.4.6 + pom + + + ../opensaml-core + ../opensaml-storage-api + ../opensaml-security-api + ../opensaml-xmlsec-api + ../opensaml-messaging-api + ../opensaml-soap-api + ../opensaml-saml-api + ../opensaml-xacml-api + ../opensaml-xacml-saml-api + + ../opensaml-storage-impl + ../opensaml-security-impl + ../opensaml-xmlsec-impl + ../opensaml-messaging-impl + ../opensaml-soap-impl + ../opensaml-saml-impl + ../opensaml-xacml-impl + ../opensaml-xacml-saml-impl + ../opensaml-profile-api + ../opensaml-profile-impl + + ../opensaml-bom + ../opensaml-tests-bom + + + + 7.5.2 + 5.4.2 + ${project.basedir}/../opensaml-parent/resources/checkstyle/checkstyle.xml + ${shibboleth.site.url}java-opensaml/${project.version}/ + ${opensaml-parent.site.url}${project.artifactId} + + + + + + + + + net.shibboleth.utilities + java-support + ${java-support.version} + + + commons-codec + commons-codec + + + + + + + + + net.shibboleth.utilities + java-support + ${java-support.version} + test-jar + test + + + org.xmlunit + xmlunit-legacy + test + + + + + + + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + org.hibernate + hibernate-entitymanager + 4.3.5.Final + + + xml-apis + xml-apis + + + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + 1.0.0.Final + + + net.spy + spymemcached + 2.12.3 + + + + + + + + + net.shibboleth.ext + spring-extensions + ${spring-extensions.version} + test + + + + + + + ${shibboleth.scm.connection}java-opensaml + ${shibboleth.scm.developerConnection}java-opensaml + ${shibboleth.scm.url}java-opensaml.git + + + + + site + dav:${opensaml-parent.site.url} + + + + + + + org.apache.maven.plugins + maven-site-plugin + + + attach-descriptor + + attach-descriptor + + + + + ../opensaml-parent/src/site + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ${automatic.module.name} + + + + + + + + \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom b/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom new file mode 100644 index 000000000..a6e4da926 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom @@ -0,0 +1,118 @@ + + + + 4.0.0 + + net.shibboleth + parent + 7.11.2 + pom + + Shibboleth Project V3 Super POM + + A POM containing properties, profiles, plugin configurations, etc. that are common across all Shibboleth V3 projects. + + + + UTF-8 + 1.7 + 1.7 + + 1.59 + 1.1.4 + + org.apache.httpcomponents + 4.5.13 + 4.4.14 + 20.0 + org.eclipse.jetty + 9.2.14.v20151106 + 1.0.13 + 1.2.3 + 3.1.5 + 2.10.4 + org.slf4j + 1.7.30 + org.springframework + 4.3.30.RELEASE + org.springframework.webflow + 2.4.8.RELEASE + 2.0.10 + 2.5.1 + + 8.26 + 3.1.0 + checkstyle.xml + + 3.0.0 + + https://repo1.maven.org/maven2 + https://build.shibboleth.net/nexus/content/sites/site/ + + scm:git:https://git.shibboleth.net/git/ + scm:git:git@git.shibboleth.net: + https://git.shibboleth.net/view/?p= + + + + + + 3.3.1 + + + + + + + + + + + + + + + + + + + + + + + + + http://shibboleth.net/ + + 1999 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + + + + + + + ${shibboleth.scm.connection}java-parent-project-v3 + ${shibboleth.scm.developerConnection}java-parent-project-v3 + ${shibboleth.scm.url}java-parent-project-v3.git + + + + + + + + + + +