*/
package org.sonar.xoo.rule;
+import javax.annotation.Nullable;
+import org.sonar.api.SonarRuntime;
import org.sonar.api.rule.RuleScope;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
+import org.sonar.api.utils.Version;
import org.sonar.xoo.Xoo;
import org.sonar.xoo.Xoo2;
import org.sonar.xoo.checks.Check;
private static final String TEN_MIN = "10min";
+ @Nullable
+ private final Version version;
+
+ public XooRulesDefinition() {
+ this(null);
+ }
+
+ public XooRulesDefinition(@Nullable SonarRuntime sonarRuntime) {
+ this.version = sonarRuntime != null ? sonarRuntime.getApiVersion() : null;
+ }
+
@Override
public void define(Context context) {
defineRulesXoo(context);
repo.createRule(MultilineIssuesSensor.RULE_KEY).setName("Creates issues with ranges/multiple locations")
.setHtmlDescription("Issue with range and multiple locations");
- repo.createRule(OneIssuePerUnknownFileSensor.RULE_KEY).setName("Creates issues on each file with extenstion 'unknown'")
+ repo.createRule(OneIssuePerUnknownFileSensor.RULE_KEY).setName("Creates issues on each file with extension 'unknown'")
.setHtmlDescription("This issue is generated on each file with extenstion 'unknown'");
NewRule oneBugIssuePerLine = repo.createRule(OneBugIssuePerLineSensor.RULE_KEY).setName("One Bug Issue Per Line")
hotspot
.setDebtRemediationFunction(hotspot.debtRemediationFunctions().constantPerIssue("2min"));
- repo.done();
+ if (version != null && version.isGreaterThanOrEqual(Version.create(7, 3))) {
+ hotspot
+ .addOwaspTop10(OwaspTop10.A1, OwaspTop10.A3)
+ .addCwe(1, 123, 863);
+ }
+ repo.done();
}
private static void defineRulesXooExternal(Context context) {
private static final Date DATE3 = DateUtils.parseDateTime("2014-03-01T12:10:03+0100");
private static final RuleKey EXTERNAL_RULE_KEY1 = RuleKey.of("external_eslint", "rule1");
+ private static final RuleKey EXTERNAL_HOTSPOT_RULE_KEY = RuleKey.of("external_eslint", "hotspot");
private static final RuleKey RULE_KEY1 = RuleKey.of("fake", "rule1");
private static final RuleKey RULE_KEY2 = RuleKey.of("fake", "rule2");
private static final RuleKey RULE_KEY3 = RuleKey.of("fake", "rule3");
+ private static final RuleKey HOTSPOT_RULE_KEY = RuleKey.of("fake", "hotspot");
private System2 system = mock(System2.class);
execute(new FakeRepositoryV1());
// verify db
- assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
+ assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(3);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), RULE_KEY1);
assertThat(rule1.getName()).isEqualTo("One");
assertThat(rule1.getDescription()).isEqualTo("Description of One");
assertThat(rule1.getPluginKey()).isEqualTo(FAKE_PLUGIN_KEY);
assertThat(rule1.isExternal()).isFalse();
+ RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), HOTSPOT_RULE_KEY);
+ assertThat(hotspotRule.getName()).isEqualTo("Hotspot");
+ assertThat(hotspotRule.getDescription()).isEqualTo("Minimal hotspot");
+ assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime());
+ assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime());
+ assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant());
+ assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3");
+
List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(dbTester.getSession(), RULE_KEY1);
assertThat(params).hasSize(2);
RuleParamDto param = getParam(params, "param1");
// verify index
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), RULE_KEY2);
- assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule2.getId());
+ assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule2.getId(), hotspotRule.getId());
// verify repositories
assertThat(dbClient.ruleRepositoryDao().selectAll(dbTester.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake");
execute(new ExternalRuleRepository());
// verify db
- assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(1);
+ assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), EXTERNAL_RULE_KEY1);
assertThat(rule1.getName()).isEqualTo("One");
assertThat(rule1.getDescription()).isEqualTo("Description of One");
assertThat(rule1.getType()).isEqualTo(RuleType.CODE_SMELL.getDbConstant());
assertThat(rule1.getPluginKey()).isEqualTo(FAKE_PLUGIN_KEY);
assertThat(rule1.isExternal()).isTrue();
+
+ RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), EXTERNAL_HOTSPOT_RULE_KEY);
+ assertThat(hotspotRule.getName()).isEqualTo("Hotspot");
+ assertThat(hotspotRule.getDescription()).isEqualTo("Minimal hotspot");
+ assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime());
+ assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime());
+ assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant());
+ assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3");
}
@Test
@Test
public void update_and_remove_rules_on_changes() {
execute(new FakeRepositoryV1());
- assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
+ assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(3);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
- assertThat(es.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()));
+ RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, HOTSPOT_RULE_KEY);
+ assertThat(es.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()), valueOf(hotspotRule.getId()));
// user adds tags and sets markdown note
rule1.setTags(newHashSet("usertag1", "usertag2"));
assertThat(rule.getSystemTags()).containsOnly("tag1", "tag2");
}
+ @Test
+ public void add_new_security_standards() {
+ execute((RulesDefinition) context -> {
+ NewRepository repo = context.createRepository("fake", "java");
+ repo.createRule("rule1")
+ .setName("Rule One")
+ .setHtmlDescription("Description of Rule One")
+ .addOwaspTop10(RulesDefinition.OwaspTop10.A1)
+ .addCwe(123);
+ repo.done();
+ });
+
+ OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+ RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
+ assertThat(rule.getSecurityStandards()).containsOnly("cwe:123", "owaspTop10:a1");
+
+ execute((RulesDefinition) context -> {
+ NewRepository repo = context.createRepository("fake", "java");
+ repo.createRule("rule1")
+ .setName("Rule One")
+ .setHtmlDescription("Description of Rule One")
+ .addOwaspTop10(RulesDefinition.OwaspTop10.A1, RulesDefinition.OwaspTop10.A3)
+ .addCwe(1, 123, 863);
+ repo.done();
+ });
+
+ rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
+ assertThat(rule.getSecurityStandards()).containsOnly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3");
+ }
+
@Test
public void update_only_rule_name() {
when(system.now()).thenReturn(DATE1.getTime());
@Test
public void do_not_update_rules_when_no_changes() {
execute(new FakeRepositoryV1());
- assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
+ assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(3);
when(system.now()).thenReturn(DATE2.getTime());
execute(new FakeRepositoryV1());
@Test
public void do_not_update_already_removed_rules() {
execute(new FakeRepositoryV1());
- assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
+ assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(3);
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
- assertThat(es.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()));
+ RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, HOTSPOT_RULE_KEY);
+ assertThat(es.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()), valueOf(hotspotRule.getId()));
assertThat(rule2.getStatus()).isEqualTo(RuleStatus.READY);
rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1");
rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default2");
+ repo.createRule(HOTSPOT_RULE_KEY.rule())
+ .setName("Hotspot")
+ .setHtmlDescription("Minimal hotspot")
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .addOwaspTop10(OwaspTop10.A1, OwaspTop10.A3)
+ .addCwe(1, 123, 863);
+
repo.createRule(RULE_KEY2.rule())
.setName("Two")
.setHtmlDescription("Minimal rule");
repo.createRule(RULE_KEY3.rule())
.setName("Three")
.setHtmlDescription("Rule Three");
+
repo.done();
}
}
.setScope(RuleScope.ALL)
.setType(RuleType.CODE_SMELL)
.setStatus(RuleStatus.BETA);
+
+ repo.createRule(EXTERNAL_HOTSPOT_RULE_KEY.rule())
+ .setName("Hotspot")
+ .setHtmlDescription("Minimal hotspot")
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .addOwaspTop10(OwaspTop10.A1, OwaspTop10.A3)
+ .addCwe(1, 123, 863);
+
repo.done();
}
}
private String createdAt;
private String createdBefore;
private String createdInLast;
+ private List<String> cwe;
private List<String> directories;
private String facetMode;
private List<String> facets;
private List<String> moduleUuids;
private String onComponentOnly;
private String organization;
+ private List<String> owaspTop10;
private String p;
private List<String> projectUuids;
private List<String> projects;
private String resolved;
private List<String> rules;
private String s;
+ private List<String> sansTop25;
private List<String> severities;
private String sinceLeakPeriod;
private List<String> statuses;
return createdInLast;
}
+ /**
+ * Example value: "12,125,unknown"
+ */
+ public SearchRequest setCwe(List<String> cwe) {
+ this.cwe = cwe;
+ return this;
+ }
+
+ public List<String> getCwe() {
+ return cwe;
+ }
+
/**
* This is part of the internal API.
* Example value: "src/main/java/org/sonar/server/"
* <li>"languages"</li>
* <li>"tags"</li>
* <li>"types"</li>
+ * <li>"owaspTop10"</li>
+ * <li>"sansTop25"</li>
+ * <li>"cwe"</li>
* <li>"createdAt"</li>
* </ul>
*/
return organization;
}
+ /**
+ * Possible values:
+ * <ul>
+ * <li>"a1"</li>
+ * <li>"a2"</li>
+ * <li>"a3"</li>
+ * <li>"a4"</li>
+ * <li>"a5"</li>
+ * <li>"a6"</li>
+ * <li>"a7"</li>
+ * <li>"a8"</li>
+ * <li>"a9"</li>
+ * <li>"a10"</li>
+ * <li>"unknown"</li>
+ * </ul>
+ */
+ public SearchRequest setOwaspTop10(List<String> owaspTop10) {
+ this.owaspTop10 = owaspTop10;
+ return this;
+ }
+
+ public List<String> getOwaspTop10() {
+ return owaspTop10;
+ }
+
/**
* Example value: "42"
*/
return s;
}
+ /**
+ * Possible values:
+ * <ul>
+ * <li>"insecure-interaction"</li>
+ * <li>"risky-resource"</li>
+ * <li>"porous-defenses"</li>
+ * </ul>
+ */
+ public SearchRequest setSansTop25(List<String> sansTop25) {
+ this.sansTop25 = sansTop25;
+ return this;
+ }
+
+ public List<String> getSansTop25() {
+ return sansTop25;
+ }
+
/**
* Example value: "BLOCKER,CRITICAL"
* Possible values:
* <li>"CODE_SMELL"</li>
* <li>"BUG"</li>
* <li>"VULNERABILITY"</li>
+ * <li>"SECURITY_HOTSPOT"</li>
* </ul>
*/
public SearchRequest setTypes(List<String> types) {