Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
package apiaddicts.sonar.openapi.checks.operations;

import apiaddicts.sonar.openapi.checks.BaseCheck;
import com.google.common.collect.ImmutableSet;
import com.sonar.sslr.api.AstNodeType;
import org.sonar.check.Rule;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Stream;
import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar;
import org.apiaddicts.apitools.dosonarapi.api.v3.OpenApi3Grammar;
import org.apiaddicts.apitools.dosonarapi.api.v31.OpenApi31Grammar;
import apiaddicts.sonar.openapi.checks.BaseCheck;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.Set;
import java.util.stream.Stream;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;

@Rule(key = OAR017ResourcePathCheck.KEY)
public class OAR017ResourcePathCheck extends BaseCheck {

public static final String KEY = "OAR017";
private static final String MESSAGE = "OAR017.error";
private static final String MESSAGE_PATTERN = "OAR017.error-patterns";
public static final String EXCLUDE_PATTERNS = "get,me,search";

@RuleProperty(
key = "exclude_patterns",
description = "List of exlude pattenrs separated by coma.",
defaultValue = EXCLUDE_PATTERNS)
public String patternsString = EXCLUDE_PATTERNS;

@Override
public Set<AstNodeType> subscribedKinds() {
Expand All @@ -30,11 +39,12 @@ public void visitNode(JsonNode node) {

private void visitV2Node(JsonNode node) {
String path = node.key().getTokenValue();
if (!isCorrect(path)) addIssue(KEY, translate(MESSAGE), node.key());
if (!isCorrect(path,node)) addIssue(KEY, translate(MESSAGE), node.key());
}

private boolean isCorrect(String path) {
private boolean isCorrect(String path, JsonNode node) {
String[] parts = Stream.of(path.split("/")).filter(p -> !p.trim().isEmpty()).toArray(String[]::new);
String[] patterns = Stream.of(patternsString.split(",")).toArray(String[]::new);
if (parts.length == 0) return true;

boolean previousWasVariable = false;
Expand All @@ -43,6 +53,10 @@ private boolean isCorrect(String path) {
for (int i = 0; i < parts.length; i++) {
boolean currentIsVariable = isVariable(parts[i]);

if(!currentIsVariable && Arrays.asList(patterns).contains(parts[i])){
issuePatterns(parts[i],node);
}

if (previousWasVariable && currentIsVariable) {
twoOrMoreVariablesInARow = true;
break;
Expand All @@ -57,4 +71,8 @@ private boolean isCorrect(String path) {
private boolean isVariable(String part) {
return '{' == part.charAt(0) && '}' == part.charAt(part.length() - 1);
}

private void issuePatterns(String pattern,JsonNode node){
addIssue(KEY, translate(MESSAGE_PATTERN,pattern), node.key());
}
}
1 change: 1 addition & 0 deletions src/main/resources/messages/errors.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ OAR012.error=Path params names, query params names, object names and property na
OAR013.error=Default response is required
OAR016.error=Numeric types requires a valid format
OAR017.error=Resource path should alternate static and parametrized parts
OAR017.error-patterns=Pattern ''{0}'' not allowed
OAR018.error=Operation not recommended for resource path: {0}
OAR019.error={0} must be defined as a parameter in this operation
OAR020.error={0} must be defined as a parameter in this operation
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/errors_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ OAR012.error=Los nombres de parámetros de ruta, parámetros de consulta, objeto
OAR013.error=La respuesta por defecto es obligatoria
OAR016.error=Tipos numéricos requieren un formato válido
OAR017.error=El path del recurso debe de alternar entre partes estáticas y parametrizadas
OAR017.error-patterns=Patrón ''{0}'' no permitido
OAR018.error=Acción no recomendada para la ruta de recursos: {0}
OAR019.error={0} debe ser definido como un parámetro en esta operación
OAR020.error={0} debe ser definido como un parámetro en esta operación
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package apiaddicts.sonar.openapi.checks.operations;

import apiaddicts.sonar.openapi.BaseCheckTest;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import apiaddicts.sonar.openapi.BaseCheckTest;

import apiaddicts.sonar.openapi.checks.operations.OAR017ResourcePathCheck;
import org.sonar.api.server.rule.RuleParamType;

public class OAR017ResourcePathCheckTest extends BaseCheckTest {

Expand All @@ -33,4 +32,10 @@ public void verifyRule() {
assertRuleProperties("OAR017 - ResourcePath - Resource path should alternate static and parametrized parts", RuleType.BUG, Severity.MAJOR, tags("operations"));
}

@Override
public void verifyParameters() {
assertNumberOfParameters(1);
assertParameterProperties("exclude_patterns", "get,me,search", RuleParamType.STRING);
}

}
2 changes: 1 addition & 1 deletion src/test/resources/checks/v3/operations/OAR017/plain.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"title" : "Swagger Petstore"
},
"paths" : {
"/one" : {
"/one/me" : { # Noncompliant {{OAR017: Pattern 'me' not allowed}}
"get" : {
"responses" : {
"200" : {
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/checks/v3/operations/OAR017/plain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ info:
version: 1.0.0
title: Swagger Petstore
paths:
/one:
/one/me: # Noncompliant {{OAR017: Pattern 'me' not allowed}}
get:
responses:
200:
Expand Down
Loading