From ec99908ddde9dc780ed7d1f2b31f0a489e742942 Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 24 Nov 2021 10:33:51 +0100 Subject: [PATCH] SONAR-15681 Support Owasp Top 10 2021 in sonar-plugin-api --- .../api/server/rule/RulesDefinition.java | 22 +++++++++++++++++++ .../server/rule/internal/DefaultNewRule.java | 19 +++++++++++++--- .../rule/internal/DefaultNewRuleTest.java | 18 ++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java index 82b7e3d6f11..0951182ffbc 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java @@ -235,6 +235,20 @@ public interface RulesDefinition { boolean isExternal(); } + enum OwaspTop10Version { + Y2017("2017"), Y2021("2021"); + + private final String label; + + OwaspTop10Version(String label) { + this.label = label; + } + + public String label() { + return label; + } + } + enum OwaspTop10 { A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 } @@ -419,9 +433,17 @@ public interface RulesDefinition { /** * @since 7.3 + * + * @deprecated since 9.3 Supports only OWASP Top 10 2017 standard, use addOwaspTop10(OwaspTop10Version, OwaspTop10...) for 2017,2021... */ + @Deprecated public abstract NewRule addOwaspTop10(OwaspTop10... standards); + /** + * @since 9.3 + */ + public abstract NewRule addOwaspTop10(OwaspTop10Version version, OwaspTop10... standards); + /** * @since 7.3 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java index 317952fda9a..b571f482126 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; import javax.annotation.CheckForNull; @@ -38,6 +39,8 @@ import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RuleTagFormat; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.api.server.rule.RulesDefinition.OwaspTop10; +import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; @@ -225,9 +228,19 @@ class DefaultNewRule extends RulesDefinition.NewRule { } @Override - public DefaultNewRule addOwaspTop10(RulesDefinition.OwaspTop10... standards) { - for (RulesDefinition.OwaspTop10 owaspTop10 : standards) { - String standard = "owaspTop10:" + owaspTop10.name().toLowerCase(Locale.ENGLISH); + public DefaultNewRule addOwaspTop10(OwaspTop10... standards) { + return addOwaspTop10(OwaspTop10Version.Y2017, standards); + } + + @Override + public DefaultNewRule addOwaspTop10(OwaspTop10Version version, OwaspTop10... standards) { + Objects.requireNonNull(version, "Owasp version must not be null"); + + //backward compatibility + String versionPrefix = OwaspTop10Version.Y2017.equals(version) ? "owaspTop10:" : "owaspTop10-" + version.label() + ":"; + + for (OwaspTop10 owaspTop10 : standards) { + String standard = versionPrefix + owaspTop10.name().toLowerCase(Locale.ENGLISH); securityStandards.add(standard); } return this; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java index adb9ccede87..b4fcdf45b4d 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java @@ -26,6 +26,8 @@ import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.api.server.rule.RulesDefinition.OwaspTop10; +import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -33,7 +35,7 @@ import static org.mockito.Mockito.mock; public class DefaultNewRuleTest { - private DefaultNewRule rule = new DefaultNewRule("plugin", "repo", "key"); + private final DefaultNewRule rule = new DefaultNewRule("plugin", "repo", "key"); @Test public void testSimpleSetGet() { @@ -80,6 +82,12 @@ public class DefaultNewRuleTest { rule.addCwe(10); assertThat(rule.securityStandards()).containsOnly("cwe:10", "cwe:12"); + rule.addOwaspTop10(OwaspTop10.A1, OwaspTop10.A2); + rule.addOwaspTop10(OwaspTop10Version.Y2017, OwaspTop10.A4); + rule.addOwaspTop10(OwaspTop10Version.Y2021, OwaspTop10.A5, OwaspTop10.A3); + assertThat(rule.securityStandards()) + .contains("owaspTop10:a1", "owaspTop10:a2", "owaspTop10:a4", "owaspTop10-2021:a3", "owaspTop10-2021:a5"); + rule.setType(RuleType.SECURITY_HOTSPOT); assertThat(rule.type()).isEqualTo(RuleType.SECURITY_HOTSPOT); @@ -111,6 +119,7 @@ public class DefaultNewRuleTest { rule.setMarkdownDescription("markdown"); assertThat(rule.markdownDescription()).isEqualTo("markdown"); } + @Test public void fail_if_severity_is_invalid() { assertThatThrownBy(() -> rule.setSeverity("invalid")) @@ -130,4 +139,11 @@ public class DefaultNewRuleTest { assertThatThrownBy(() -> rule.setStatus(RuleStatus.REMOVED)) .isInstanceOf(IllegalArgumentException.class); } + + @Test + public void fail_if_null_owasp_version() { + assertThatThrownBy(() -> rule.addOwaspTop10((OwaspTop10Version) null , OwaspTop10.A1)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Owasp version must not be null"); + } } -- 2.39.5