浏览代码

SONAR-11180 add security facet to api/rules/search

tags/7.8
Michal Duda 5 年前
父节点
当前提交
3b7745121f
共有 20 个文件被更改,包括 366 次插入40 次删除
  1. 6
    1
      server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java
  2. 5
    5
      server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
  3. 47
    0
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java
  4. 58
    0
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java
  5. 9
    0
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
  6. 44
    0
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java
  7. 2
    3
      server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java
  8. 2
    2
      server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
  9. 54
    3
      server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
  10. 5
    4
      server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
  11. 5
    5
      server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
  12. 8
    0
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
  13. 29
    1
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java
  14. 4
    0
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java
  15. 67
    3
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
  16. 6
    6
      server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java
  17. 4
    4
      server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
  18. 5
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java
  19. 5
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java
  20. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java

+ 6
- 1
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java 查看文件

@@ -21,6 +21,7 @@ package org.sonar.db.rule;

import com.google.common.collect.ImmutableSet;
import java.util.Date;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
@@ -319,11 +320,15 @@ public class RuleTesting {
public static Consumer<RuleDefinitionDto> setType(RuleType type) {
return rule -> rule.setType(type);
}
public static Consumer<RuleDefinitionDto> setIsExternal(boolean isExternal) {
return rule -> rule.setIsExternal(isExternal);
}

public static Consumer<RuleDefinitionDto> setSecurityStandards(Set<String> securityStandards) {
return rule -> rule.setSecurityStandards(securityStandards);
}

public static Consumer<RuleDefinitionDto> setIsTemplate(boolean isTemplate) {
return rule -> rule.setIsTemplate(isTemplate);
}

+ 5
- 5
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java 查看文件

@@ -43,11 +43,11 @@ import org.sonar.db.ResultSetIterator;
import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.api.utils.DateUtils.longToDate;
import static org.sonar.db.DatabaseUtils.getLong;
import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe;
import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSecurityStandards;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSonarSourceSecurityCategories;
import static org.sonar.server.security.SecurityStandardHelper.getCwe;
import static org.sonar.server.security.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.security.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.security.SecurityStandardHelper.getSecurityStandards;
import static org.sonar.server.security.SecurityStandardHelper.getSonarSourceSecurityCategories;

/**
* Scrolls over table ISSUES and reads documents to populate

+ 47
- 0
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java 查看文件

@@ -21,6 +21,7 @@ package org.sonar.server.rule.index;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -34,6 +35,7 @@ import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.markdown.Markdown;
import org.sonar.server.es.BaseDoc;
import org.sonar.server.security.SecurityStandardHelper;

import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;

@@ -153,6 +155,46 @@ public class RuleDoc extends BaseDoc {
return this;
}

@CheckForNull
public Collection<String> getOwaspTop10() {
return getNullableField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10);
}

public RuleDoc setOwaspTop10(@Nullable Collection<String> o) {
setField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10, o);
return this;
}

@CheckForNull
public Collection<String> getSansTop25() {
return getNullableField(RuleIndexDefinition.FIELD_RULE_SANS_TOP_25);
}

public RuleDoc setSansTop25(@Nullable Collection<String> s) {
setField(RuleIndexDefinition.FIELD_RULE_SANS_TOP_25, s);
return this;
}

@CheckForNull
public Collection<String> getCwe() {
return getNullableField(RuleIndexDefinition.FIELD_RULE_CWE);
}

public RuleDoc setCwe(@Nullable Collection<String> c) {
setField(RuleIndexDefinition.FIELD_RULE_CWE, c);
return this;
}

@CheckForNull
public Collection<String> getSonarSourceSecurityCategories() {
return getNullableField(RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY);
}

public RuleDoc setSonarSourceSecurityCategories(@Nullable Collection<String> c) {
setField(RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY, c);
return this;
}

@CheckForNull
public RuleStatus status() {
return RuleStatus.valueOf(getField(RuleIndexDefinition.FIELD_RULE_STATUS));
@@ -226,6 +268,7 @@ public class RuleDoc extends BaseDoc {
}

public static RuleDoc of(RuleForIndexingDto dto) {
Collection<String> cwe = SecurityStandardHelper.getCwe(dto.getSecurityStandardsAsSet());
RuleDoc ruleDoc = new RuleDoc()
.setId(dto.getId())
.setKey(dto.getRuleKey().toString())
@@ -234,6 +277,10 @@ public class RuleDoc extends BaseDoc {
.setIsTemplate(dto.isTemplate())
.setIsExternal(dto.isExternal())
.setLanguage(dto.getLanguage())
.setCwe(cwe)
.setOwaspTop10(SecurityStandardHelper.getOwaspTop10(dto.getSecurityStandardsAsSet()))
.setSansTop25(SecurityStandardHelper.getSansTop25(cwe))
.setSonarSourceSecurityCategories(SecurityStandardHelper.getSonarSourceSecurityCategories(cwe))
.setName(dto.getName())
.setRuleKey(dto.getPluginRuleKey())
.setSeverity(dto.getSeverityAsString())

+ 58
- 0
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java 查看文件

@@ -89,6 +89,7 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CREATED_AT;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CWE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION;
@@ -98,9 +99,12 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_IS_TEMP
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_LANGUAGE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_NAME;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_REPOSITORY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_RULE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SANS_TOP_25;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SEVERITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_STATUS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TYPE;
@@ -123,6 +127,10 @@ public class RuleIndex {
public static final String FACET_STATUSES = "statuses";
public static final String FACET_TYPES = "types";
public static final String FACET_OLD_DEFAULT = "true";
public static final String FACET_CWE = "cwe";
public static final String FACET_SANS_TOP_25 = "sansTop25";
public static final String FACET_OWASP_TOP_10 = "owaspTop10";
public static final String FACET_SONARSOURCE_SECURITY = "sonarsourceSecurity";

private static final int MAX_FACET_SIZE = 100;

@@ -271,6 +279,26 @@ public class RuleIndex {
QueryBuilders.termsQuery(FIELD_RULE_SEVERITY, query.getSeverities()));
}

if (isNotEmpty(query.getCwe())) {
filters.put(FIELD_RULE_CWE,
QueryBuilders.termsQuery(FIELD_RULE_CWE, query.getCwe()));
}

if (isNotEmpty(query.getOwaspTop10())) {
filters.put(FIELD_RULE_OWASP_TOP_10,
QueryBuilders.termsQuery(FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10()));
}

if (isNotEmpty(query.getSansTop25())) {
filters.put(FIELD_RULE_SANS_TOP_25,
QueryBuilders.termsQuery(FIELD_RULE_SANS_TOP_25, query.getSansTop25()));
}

if (isNotEmpty(query.getSonarsourceSecurity())) {
filters.put(FIELD_RULE_SONARSOURCE_SECURITY,
QueryBuilders.termsQuery(FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity()));
}

if (StringUtils.isNotEmpty(query.getKey())) {
filters.put(FIELD_RULE_KEY,
QueryBuilders.termQuery(FIELD_RULE_KEY, query.getKey()));
@@ -452,6 +480,36 @@ public class RuleIndex {
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_REPOSITORY, FACET_REPOSITORIES,
(repositories == null) ? (new String[0]) : repositories.toArray()));
}

addDefaultSecurityFacets(query, options, aggregations, stickyFacetBuilder);
}

private static void addDefaultSecurityFacets(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations,
StickyFacetBuilder stickyFacetBuilder) {
if (options.getFacets().contains(FACET_CWE)) {
Collection<String> categories = query.getCwe();
aggregations.put(FACET_CWE,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_CWE, FACET_CWE,
(categories == null) ? (new String[0]) : categories.toArray()));
}
if (options.getFacets().contains(FACET_OWASP_TOP_10)) {
Collection<String> categories = query.getOwaspTop10();
aggregations.put(FACET_OWASP_TOP_10,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_OWASP_TOP_10, FACET_OWASP_TOP_10,
(categories == null) ? (new String[0]) : categories.toArray()));
}
if (options.getFacets().contains(FACET_SANS_TOP_25)) {
Collection<String> categories = query.getSansTop25();
aggregations.put(FACET_SANS_TOP_25,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SANS_TOP_25, FACET_SANS_TOP_25,
(categories == null) ? (new String[0]) : categories.toArray()));
}
if (options.getFacets().contains(FACET_SONARSOURCE_SECURITY)) {
Collection<String> categories = query.getSonarsourceSecurity();
aggregations.put(FACET_SONARSOURCE_SECURITY,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SONARSOURCE_SECURITY, FACET_SONARSOURCE_SECURITY,
(categories == null) ? (new String[0]) : categories.toArray()));
}
}

private static void addStatusFacetIfNeeded(SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {

+ 9
- 0
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java 查看文件

@@ -60,6 +60,10 @@ public class RuleIndexDefinition implements IndexDefinition {
public static final String FIELD_RULE_TYPE = "type";
public static final String FIELD_RULE_CREATED_AT = "createdAt";
public static final String FIELD_RULE_UPDATED_AT = "updatedAt";
public static final String FIELD_RULE_CWE = "cwe";
public static final String FIELD_RULE_OWASP_TOP_10 = "owaspTop10";
public static final String FIELD_RULE_SANS_TOP_25 = "sansTop25";
public static final String FIELD_RULE_SONARSOURCE_SECURITY = "sonarsourceSecurity";

public static final Set<String> SORT_FIELDS = ImmutableSet.of(
FIELD_RULE_NAME,
@@ -143,6 +147,11 @@ public class RuleIndexDefinition implements IndexDefinition {
ruleMapping.createLongField(FIELD_RULE_CREATED_AT);
ruleMapping.createLongField(FIELD_RULE_UPDATED_AT);

ruleMapping.keywordFieldBuilder(FIELD_RULE_CWE).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_OWASP_TOP_10).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_SANS_TOP_25).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_SONARSOURCE_SECURITY).disableNorms().build();

// Active rule
index.createTypeMapping(TYPE_ACTIVE_RULE)
.keywordFieldBuilder(FIELD_ACTIVE_RULE_ID).disableNorms().build()

+ 44
- 0
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java 查看文件

@@ -55,6 +55,10 @@ public class RuleQuery {
private String ruleKey;
private OrganizationDto organization;
private boolean includeExternal;
private Collection<String> owaspTop10;
private Collection<String> sansTop25;
private Collection<String> cwe;
private Collection<String> sonarsourceSecurity;

@CheckForNull
public QProfileDto getQProfile() {
@@ -293,4 +297,44 @@ public class RuleQuery {
this.compareToQProfile = compareToQProfile;
return this;
}

@CheckForNull
public Collection<String> getCwe() {
return cwe;
}

public RuleQuery setCwe(@Nullable Collection<String> cwe) {
this.cwe = cwe;
return this;
}

@CheckForNull
public Collection<String> getOwaspTop10() {
return owaspTop10;
}

public RuleQuery setOwaspTop10(@Nullable Collection<String> owaspTop10) {
this.owaspTop10 = owaspTop10;
return this;
}

@CheckForNull
public Collection<String> getSansTop25() {
return sansTop25;
}

public RuleQuery setSansTop25(@Nullable Collection<String> sansTop25) {
this.sansTop25 = sansTop25;
return this;
}

@CheckForNull
public Collection<String> getSonarsourceSecurity() {
return sonarsourceSecurity;
}

public RuleQuery setSonarsourceSecurity(@Nullable Collection<String> sonarsourceSecurity) {
this.sonarsourceSecurity = sonarsourceSecurity;
return this;
}
}

server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java → server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java 查看文件

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.issue.index;
package org.sonar.server.security;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
@@ -47,7 +47,6 @@ public class SecurityStandardHelper {
private static final Set<String> RISKY_CWE = new HashSet<>(asList("120", "22", "494", "829", "676", "131", "134", "190"));
private static final Set<String> POROUS_CWE = new HashSet<>(asList("306", "862", "798", "311", "807", "250", "863", "732", "327", "307", "759"));


public static final Map<String, List<String>> SONARSOURCE_CWE_MAPPING = ImmutableMap.<String, List<String>>builder()
.put("sql-injection", asList("89", "564"))
.put("command-injection", asList("78", "77"))
@@ -66,7 +65,7 @@ public class SecurityStandardHelper {
.put("xxe", asList("611", "827"))
.put("object-injection", singletonList("470"))
.put("weak-cryptography", asList("326", "295", "326", "327", "297", "780", "328", "327"))
.put("auth", asList("798", "640", "620", "549", "522", "521", "263", "262", "261", "259", "522", "284"))
.put("auth", asList("798", "640", "620", "549", "522", "521", "263", "262", "261", "259", "284"))
.put("insecure-conf", asList("102", "489"))
.put("file-manipulation", asList("97", "73"))
.build();

+ 2
- 2
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java 查看文件

@@ -57,8 +57,8 @@ import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION;

public class IssueIndexerTest {

+ 54
- 3
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java 查看文件

@@ -69,6 +69,7 @@ import static org.sonar.db.rule.RuleTesting.setName;
import static org.sonar.db.rule.RuleTesting.setOrganization;
import static org.sonar.db.rule.RuleTesting.setRepositoryKey;
import static org.sonar.db.rule.RuleTesting.setRuleKey;
import static org.sonar.db.rule.RuleTesting.setSecurityStandards;
import static org.sonar.db.rule.RuleTesting.setSeverity;
import static org.sonar.db.rule.RuleTesting.setStatus;
import static org.sonar.db.rule.RuleTesting.setSystemTags;
@@ -85,6 +86,8 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;

public class RuleIndexTest {

@@ -122,7 +125,7 @@ public class RuleIndexTest {
RuleDefinitionDto cobol1 = createRule(
setRepositoryKey("cobol"),
setRuleKey("X001"));
RuleDefinitionDto php2 = createRule(
createRule(
setRepositoryKey("php"),
setRuleKey("S002"));
index();
@@ -451,6 +454,54 @@ public class RuleIndexTest {
assertThat(underTest.search(query, new SearchOptions()).getIds()).hasSize(2);
}

@Test
public void search_by_security_cwe() {
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("cwe:543", "cwe:123", "owaspTop10:a1")));
RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("cwe:543", "owaspTop10:a1")));
createRule(setSecurityStandards(of("owaspTop10:a1")));
index();

RuleQuery query = new RuleQuery().setCwe(of("543"));
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions().addFacets("cwe"));
assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId());
}

@Test
public void search_by_security_owaspTop10() {
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:543")));
RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:543")));
createRule(setSecurityStandards(of("cwe:543")));
index();

RuleQuery query = new RuleQuery().setOwaspTop10(of("a5", "a10"));
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions().addFacets("owaspTop10"));
assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId());
}

@Test
public void search_by_security_sansTop25() {
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89")));
RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829")));
createRule(setSecurityStandards(of("cwe:306")));
index();

RuleQuery query = new RuleQuery().setSansTop25(of(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE));
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions().addFacets("sansTop25"));
assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId());
}

@Test
public void search_by_security_sonarsource() {
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89")));
createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829")));
RuleDefinitionDto rule3 = createRule(setSecurityStandards(of("cwe:601")));
index();

RuleQuery query = new RuleQuery().setSonarsourceSecurity(of("sql-injection", "open-redirect"));
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions().addFacets("sonarsourceSecurity"));
assertThat(results.getIds()).containsOnly(rule1.getId(), rule3.getId());
}

@Test
public void compare_to_another_profile() {
String xoo = "xoo";
@@ -842,7 +893,7 @@ public class RuleIndexTest {

@Test
public void languages_facet_should_return_top_100_items() {
rangeClosed(1, 101).forEach(i -> db.rules().insert(r -> r.setLanguage("lang" + i)));
rangeClosed(1, 101).forEach(i -> db.rules().insert(r -> r.setLanguage("lang" + i)));
index();

SearchIdResult result = underTest.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(FACET_LANGUAGES)));
@@ -852,7 +903,7 @@ public class RuleIndexTest {

@Test
public void repositories_facet_should_return_top_10_items() {
rangeClosed(1, 11).forEach(i -> db.rules().insert(r -> r.setRepositoryKey("repo" + i)));
rangeClosed(1, 11).forEach(i -> db.rules().insert(r -> r.setRepositoryKey("repo" + i)));
index();

SearchIdResult result = underTest.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(FACET_REPOSITORIES)));

+ 5
- 4
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java 查看文件

@@ -82,6 +82,7 @@ import org.sonar.server.es.StickyFacetBuilder;
import org.sonar.server.issue.index.IssueQuery.PeriodStart;
import org.sonar.server.permission.index.AuthorizationDoc;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.user.UserSession;
import org.sonar.server.view.index.ViewIndexDefinition;

@@ -151,10 +152,10 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STAT
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TAGS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TYPE;
import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.view.index.ViewIndexDefinition.TYPE_VIEW;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_PARAM_AUTHORS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;

+ 5
- 5
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java 查看文件

@@ -76,11 +76,11 @@ import static org.sonar.server.issue.index.IssueIndex.FACET_ASSIGNED_TO_ME;
import static org.sonar.server.issue.index.IssueIndex.FACET_PROJECTS;
import static org.sonar.server.issue.index.IssueQuery.SORT_BY_ASSIGNEE;
import static org.sonar.server.issue.index.IssueQueryFactory.UNKNOWN;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;

+ 8
- 0
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java 查看文件

@@ -38,15 +38,19 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
@@ -105,6 +109,10 @@ public class RuleQueryFactory {
query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY));
query.setTypes(toEnums(request.paramAsStrings(PARAM_TYPES), RuleType.class));
query.setKey(request.param(PARAM_RULE_KEY));
query.setCwe(request.paramAsStrings(PARAM_CWE));
query.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10));
query.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25));
query.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));

String sortParam = request.param(WebService.Param.SORT);
if (sortParam != null) {

+ 29
- 1
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java 查看文件

@@ -35,6 +35,7 @@ import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.qualityprofile.ActiveRuleInheritance;
import org.sonar.server.rule.index.RuleIndexDefinition;
@@ -49,19 +50,25 @@ import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
@@ -130,6 +137,28 @@ public class RuleWsSupport {
.setPossibleValues(Severity.ALL)
.setExampleValue("CRITICAL,BLOCKER");

action
.createParam(PARAM_CWE)
.setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select rules not associated to any CWE.")
.setExampleValue("12,125," + UNKNOWN_STANDARD);

action.createParam(PARAM_OWASP_TOP_10)
.setDescription("Comma-separated list of OWASP Top 10 lowercase categories. Use '" + UNKNOWN_STANDARD + "' to select rules not associated to any OWASP " +
"Top 10 category.")
.setSince("7.3")
.setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", UNKNOWN_STANDARD);

action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setSince("7.3")
.setPossibleValues(SANS_TOP_25_CWE_MAPPING.keySet());

action
.createParam(PARAM_SONARSOURCE_SECURITY)
.setDescription("Comma-separated list of SonarSource report categories.")
.setPossibleValues(SecurityStandardHelper.SONARSOURCE_CWE_MAPPING.keySet())
.setExampleValue("sql-injection,command-injection");

action
.createParam(PARAM_LANGUAGES)
.setDescription("Comma-separated list of languages")
@@ -231,5 +260,4 @@ public class RuleWsSupport {
.setSince("7.2");
}


}

+ 4
- 0
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java 查看文件

@@ -33,6 +33,10 @@ public class RulesWsParameters {
public static final String PARAM_LANGUAGES = "languages";
public static final String PARAM_TAGS = "tags";
public static final String PARAM_TYPES = "types";
public static final String PARAM_CWE = "cwe";
public static final String PARAM_OWASP_TOP_10 = "owaspTop10";
public static final String PARAM_SANS_TOP_25 = "sansTop25";
public static final String PARAM_SONARSOURCE_SECURITY = "sonarsourceSecurity";
public static final String PARAM_INHERITANCE = "inheritance";
public static final String PARAM_ACTIVE_SEVERITIES = "active_severities";
public static final String PARAM_IS_TEMPLATE = "is_template";

+ 67
- 3
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java 查看文件

@@ -66,18 +66,26 @@ import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED;
import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.index.RuleIndex.FACET_CWE;
import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
import static org.sonar.server.rule.index.RuleIndex.FACET_OLD_DEFAULT;
import static org.sonar.server.rule.index.RuleIndex.FACET_OWASP_TOP_10;
import static org.sonar.server.rule.index.RuleIndex.FACET_REPOSITORIES;
import static org.sonar.server.rule.index.RuleIndex.FACET_SANS_TOP_25;
import static org.sonar.server.rule.index.RuleIndex.FACET_SEVERITIES;
import static org.sonar.server.rule.index.RuleIndex.FACET_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES;
import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.rule.ws.RulesWsParameters.OPTIONAL_FIELDS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES;
@@ -95,7 +103,11 @@ public class SearchAction implements RulesWsAction {
FACET_ACTIVE_SEVERITIES,
FACET_STATUSES,
FACET_TYPES,
FACET_OLD_DEFAULT};
FACET_OLD_DEFAULT,
FACET_CWE,
FACET_OWASP_TOP_10,
FACET_SANS_TOP_25,
FACET_SONARSOURCE_SECURITY};

private final RuleQueryFactory ruleQueryFactory;
private final DbClient dbClient;
@@ -265,6 +277,10 @@ public class SearchAction implements RulesWsAction {
addMandatoryFacetValues(results, FACET_ACTIVE_SEVERITIES, Severity.ALL);
addMandatoryFacetValues(results, FACET_TAGS, request.getTags());
addMandatoryFacetValues(results, FACET_TYPES, RuleType.names());
addMandatoryFacetValues(results, FACET_CWE, request.getCwe());
addMandatoryFacetValues(results, FACET_OWASP_TOP_10, request.getOwaspTop10());
addMandatoryFacetValues(results, FACET_SANS_TOP_25, request.getSansTop25());
addMandatoryFacetValues(results, FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity());

Common.Facet.Builder facet = Common.Facet.newBuilder();
Common.FacetValue.Builder value = Common.FacetValue.newBuilder();
@@ -276,6 +292,10 @@ public class SearchAction implements RulesWsAction {
facetValuesByFacetKey.put(FACET_ACTIVE_SEVERITIES, request.getActiveSeverities());
facetValuesByFacetKey.put(FACET_TAGS, request.getTags());
facetValuesByFacetKey.put(FACET_TYPES, request.getTypes());
facetValuesByFacetKey.put(FACET_CWE, request.getCwe());
facetValuesByFacetKey.put(FACET_OWASP_TOP_10, request.getOwaspTop10());
facetValuesByFacetKey.put(FACET_SANS_TOP_25, request.getSansTop25());
facetValuesByFacetKey.put(FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity());

for (String facetName : context.getFacets()) {
facet.clear().setProperty(facetName);
@@ -333,7 +353,11 @@ public class SearchAction implements RulesWsAction {
.setSeverities(request.paramAsStrings(PARAM_SEVERITIES))
.setStatuses(request.paramAsStrings(PARAM_STATUSES))
.setTags(request.paramAsStrings(PARAM_TAGS))
.setTypes(request.paramAsStrings(PARAM_TYPES));
.setTypes(request.paramAsStrings(PARAM_TYPES))
.setCwe(request.paramAsStrings(PARAM_CWE))
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));
}

static class SearchResult {
@@ -416,6 +440,10 @@ public class SearchAction implements RulesWsAction {
private List<String> statuses;
private List<String> tags;
private List<String> types;
private List<String> cwe;
private List<String> owaspTop10;
private List<String> sansTop25;
private List<String> sonarsourceSecurity;

private SearchRequest setActiveSeverities(List<String> activeSeverities) {
this.activeSeverities = activeSeverities;
@@ -507,7 +535,7 @@ public class SearchAction implements RulesWsAction {
return tags;
}

private SearchRequest setTypes(List<String> types) {
private SearchRequest setTypes(@Nullable List<String> types) {
this.types = types;
return this;
}
@@ -515,5 +543,41 @@ public class SearchAction implements RulesWsAction {
private List<String> getTypes() {
return types;
}

public List<String> getCwe() {
return cwe;
}

public SearchRequest setCwe(@Nullable List<String> cwe) {
this.cwe = cwe;
return this;
}

public List<String> getOwaspTop10() {
return owaspTop10;
}

public SearchRequest setOwaspTop10(@Nullable List<String> owaspTop10) {
this.owaspTop10 = owaspTop10;
return this;
}

public List<String> getSansTop25() {
return sansTop25;
}

public SearchRequest setSansTop25(@Nullable List<String> sansTop25) {
this.sansTop25 = sansTop25;
return this;
}

public List<String> getSonarsourceSecurity() {
return sonarsourceSecurity;
}

public SearchRequest setSonarsourceSecurity(@Nullable List<String> sonarsourceSecurity) {
this.sonarsourceSecurity = sonarsourceSecurity;
return this;
}
}
}

+ 6
- 6
server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java 查看文件

@@ -38,7 +38,7 @@ import org.sonar.db.rule.RuleDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.SecurityStandardCategoryStatistics;
import org.sonar.server.issue.index.SecurityStandardHelper;
import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.qualityprofile.QPMeasureData;
import org.sonar.server.qualityprofile.QualityProfile;
import org.sonar.server.user.UserSession;
@@ -51,11 +51,11 @@ import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe;
import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSonarSourceSecurityCategories;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandardHelper.getCwe;
import static org.sonar.server.security.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.security.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.security.SecurityStandardHelper.getSonarSourceSecurityCategories;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25;

+ 4
- 4
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java 查看文件

@@ -54,10 +54,10 @@ import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;

public class IssueIndexSecurityReportsTest {


+ 5
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java 查看文件

@@ -102,7 +102,11 @@ public class ActivateRulesActionTest {
"available_since",
"activation",
"severities",
"organization");
"organization",
"cwe",
"owaspTop10",
"sansTop25",
"sonarsourceSecurity");
WebService.Param targetProfile = definition.param("targetKey");
assertThat(targetProfile.deprecatedKey()).isEqualTo("profile_key");
WebService.Param targetSeverity = definition.param("targetSeverity");

+ 5
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java 查看文件

@@ -100,7 +100,11 @@ public class DeactivateRulesActionTest {
"available_since",
"activation",
"severities",
"organization");
"organization",
"cwe",
"owaspTop10",
"sansTop25",
"sonarsourceSecurity");
WebService.Param targetProfile = definition.param("targetKey");
assertThat(targetProfile.deprecatedKey()).isEqualTo("profile_key");
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java 查看文件

@@ -136,7 +136,7 @@ public class SearchActionTest {
assertThat(def.since()).isEqualTo("4.4");
assertThat(def.isInternal()).isFalse();
assertThat(def.responseExampleAsString()).isNotEmpty();
assertThat(def.params()).hasSize(24);
assertThat(def.params()).hasSize(28);

WebService.Param compareToProfile = def.param("compareToProfile");
assertThat(compareToProfile.since()).isEqualTo("6.5");

正在加载...
取消
保存