Skip to content

Commit d8cb983

Browse files
wuwu2000Copilotslawekjaranowski
authored
Fix for issues/533 (dual licensed dependency with one license on whitelist and the other on blacklist) (#670)
* issues/533: Prepare changes by asserting current state * issues/533: refactor * issues/533: if a project has 2 licences, only 1 whitelisted licence should be sufficient to allow the project, because this is the licence you choose. * ran 'mvn spotless:apply' * use mockito 4 to be jdk 8 compatible * Update src/test/java/org/codehaus/mojo/license/AbstractAddThirdPartyMojoTest.java fixed spelling Co-authored-by: Copilot <[email protected]> * more spelling from british to american english * more spelling from british to american english --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Slawomir Jaranowski <[email protected]>
1 parent 903de29 commit d8cb983

File tree

3 files changed

+341
-37
lines changed

3 files changed

+341
-37
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,13 @@
289289
<scope>test</scope>
290290
</dependency>
291291

292+
<dependency>
293+
<groupId>org.mockito</groupId>
294+
<artifactId>mockito-core</artifactId>
295+
<version>4.11.0</version>
296+
<scope>test</scope>
297+
</dependency>
298+
292299
<!-- Needed for extended constants in JARs MANIFEST.MF -->
293300
<dependency>
294301
<groupId>org.osgi</groupId>

src/main/java/org/codehaus/mojo/license/AbstractAddThirdPartyMojo.java

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ public abstract class AbstractAddThirdPartyMojo extends AbstractLicenseMojo {
438438
* <ul style="list-style-type:none;">
439439
* <li>The Apache Software License, Version 2.0</li>
440440
* <li>Apache License, Version 2.0</li>
441-
* <li>Bouncy Castle Licence</li>
441+
* <li>Bouncy Castle License</li>
442442
* <li>MIT License</li>
443443
* </ul>
444444
* empty lines will be ignored.</li>
@@ -491,7 +491,7 @@ public abstract class AbstractAddThirdPartyMojo extends AbstractLicenseMojo {
491491
* <ul style="list-style-type:none;">
492492
* <li>The Apache Software License, Version 2.0</li>
493493
* <li>Apache License, Version 2.0</li>
494-
* <li>Bouncy Castle Licence</li>
494+
* <li>Bouncy Castle license</li>
495495
* <li>MIT License</li>
496496
* </ul>
497497
* empty lines will be ignored.</li>
@@ -919,15 +919,15 @@ void checkUnsafeDependencies() {
919919
boolean checkForbiddenLicenses() {
920920
List<String> whiteLicenses = getIncludedLicenses();
921921
List<String> blackLicenses = getExcludedLicenses();
922-
Set<String> unsafeLicenses = new HashSet<>();
922+
LicenseMap unsafeLicenses = new LicenseMap();
923923
if (CollectionUtils.isNotEmpty(blackLicenses)) {
924924
Set<String> licenses = licenseMap.keySet();
925925
LOG.info("Excluded licenses (blacklist): {}", blackLicenses);
926926

927927
for (String excludeLicense : blackLicenses) {
928928
if (licenses.contains(excludeLicense) && CollectionUtils.isNotEmpty(licenseMap.get(excludeLicense))) {
929929
// bad license found
930-
unsafeLicenses.add(excludeLicense);
930+
unsafeLicenses.put(excludeLicense, licenseMap.get(excludeLicense));
931931
}
932932
}
933933
}
@@ -936,59 +936,59 @@ boolean checkForbiddenLicenses() {
936936
Set<String> dependencyLicenses = licenseMap.keySet();
937937
LOG.info("Included licenses (whitelist): {}", whiteLicenses);
938938

939+
for (final String unsafelicense : unsafeLicenses.keySet()) {
940+
for (MavenProject potentiallyUnsafeProject : unsafeLicenses.get(unsafelicense)) {
941+
942+
final boolean whiteListed =
943+
isDependencyWhitelisted(potentiallyUnsafeProject, unsafelicense, whiteLicenses);
944+
945+
if (whiteListed) {
946+
LOG.debug(
947+
"Project {} has black listed license {} but also white listed dependency",
948+
potentiallyUnsafeProject,
949+
unsafelicense);
950+
951+
unsafeLicenses.get(unsafelicense).remove(potentiallyUnsafeProject);
952+
}
953+
}
954+
}
955+
939956
for (String dependencyLicense : dependencyLicenses) {
940957
LOG.debug("Testing license '{}'", dependencyLicense);
958+
941959
if (!whiteLicenses.contains(dependencyLicense)
942960
&& CollectionUtils.isNotEmpty(licenseMap.get(dependencyLicense))) {
943961
LOG.debug("Testing dependency license '{}' against all other licenses", dependencyLicense);
944962

945963
for (MavenProject dependency : licenseMap.get(dependencyLicense)) {
946-
LOG.debug("- testing dependency {}" + dependency);
947-
948-
boolean forbiddenLicenseUsed = true;
949-
950-
for (String otherLicense : dependencyLicenses) {
951-
// skip this license if it is the same as the dependency license
952-
// skip this license if it has no projects assigned
953-
if (otherLicense.equals(dependencyLicense)
954-
|| licenseMap.get(dependencyLicense).isEmpty()) {
955-
continue;
956-
}
957-
958-
// skip this license if it isn't one of the whitelisted
959-
if (!whiteLicenses.contains(otherLicense)) {
960-
continue;
961-
}
962-
963-
if (licenseMap.get(otherLicense).contains(dependency)) {
964-
LOG.info(
965-
"License: '{}' for '{}' is OK since it is also licensed under '{}'",
966-
dependencyLicense,
967-
dependency,
968-
otherLicense);
969-
// this dependency is licensed under another license from white list
970-
forbiddenLicenseUsed = false;
971-
break;
972-
}
973-
}
964+
LOG.debug("testing dependency {}", dependency);
965+
966+
boolean islicenseWhitelistedAndUsed =
967+
isDependencyWhitelisted(dependency, dependencyLicense, whiteLicenses);
974968

975969
// bad license found
976-
if (forbiddenLicenseUsed) {
977-
unsafeLicenses.add(dependencyLicense);
970+
if (!islicenseWhitelistedAndUsed) {
971+
unsafeLicenses.put(dependencyLicense, dependency);
978972
break;
979973
}
980974
}
981975
}
982976
}
983977
}
984978

985-
boolean safe = CollectionUtils.isEmpty(unsafeLicenses);
979+
for (final String s : unsafeLicenses.keySet()) {
980+
if (CollectionUtils.isEmpty(unsafeLicenses.get(s))) {
981+
unsafeLicenses.remove(s);
982+
}
983+
}
984+
985+
boolean safe = CollectionUtils.isEmpty(unsafeLicenses.keySet());
986986

987987
if (!safe) {
988988
LOG.warn("There are {} forbidden licenses used:", unsafeLicenses.size());
989-
for (String unsafeLicense : unsafeLicenses) {
989+
for (String unsafeLicense : unsafeLicenses.keySet()) {
990990

991-
SortedSet<MavenProject> deps = licenseMap.get(unsafeLicense);
991+
SortedSet<MavenProject> deps = unsafeLicenses.get(unsafeLicense);
992992
if (!deps.isEmpty()) {
993993
StringBuilder sb = new StringBuilder();
994994
sb.append("License: '")
@@ -1006,6 +1006,36 @@ boolean checkForbiddenLicenses() {
10061006
return safe;
10071007
}
10081008

1009+
private boolean isDependencyWhitelisted(
1010+
final MavenProject dependency, final String dependencyLicense, final List<String> whiteLicenses) {
1011+
1012+
final Set<String> dependencyLicenses = licenseMap.keySet();
1013+
for (String otherLicense : dependencyLicenses) {
1014+
// skip this license if it is the same as the dependency license
1015+
// skip this license if it has no projects assigned
1016+
if (otherLicense.equals(dependencyLicense)
1017+
|| licenseMap.get(dependencyLicense).isEmpty()) {
1018+
continue;
1019+
}
1020+
1021+
// skip this license if it isn't one of the whitelisted
1022+
if (!whiteLicenses.contains(otherLicense)) {
1023+
continue;
1024+
}
1025+
1026+
if (licenseMap.get(otherLicense).contains(dependency)) {
1027+
LOG.info(
1028+
"License: '{}' for '{}' is OK since it is also licensed under '{}'",
1029+
dependencyLicense,
1030+
dependency,
1031+
otherLicense);
1032+
// this dependency is licensed under another license from white list
1033+
return true;
1034+
}
1035+
}
1036+
return false;
1037+
}
1038+
10091039
void writeThirdPartyFile() throws IOException {
10101040

10111041
if (doGenerate) {

0 commit comments

Comments
 (0)