diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc4ea57..ed59b5bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.7.0-beta-1] - 2026-09-10 + +### Fixed + +- OAR041 - UndefinedAuthTypeForWso2Scope - Fixed the `x-aut-type` typo in the HTML examples (should be `x-auth-type`) and rewrote the Spanish description, which described an unrelated scope-catalog structure instead of the actual check. +- OAR043 - ParsingError - Rewrote the English/Spanish HTML docs with real examples, expanded the JSON titles, and removed the orphaned `core/OAR043.*` resources (not loaded by any registered rule group). +- `tools/IssueDumper.java` - Now recovers from a `ValidationException` during test scanning for `OAR043ParsingErrorCheck`, so schema-invalid fixtures can be cross-checked against Spectral instead of crashing the harness. +- OAR005 - UndefinedWso2ScopeUse - Resolves `$ref`s on `x-wso2-security`/scopes and accepts map-form `x-wso2-scopes`, plus all null spellings for `x-scope`. +- OAR009 / OAR010 - DefaultRequestMediaType / DefaultResponseMediaType - Media type comparisons are now case-insensitive, matching Spectral. +- OAR007 - UndefinedResponseMediaType - Fixed the rule description, which wrongly described request media types (`consumes`) instead of response ones (`produces`). +- OAR026 - TotalParameterDefaultValue - Rewritten to match Spectral: only checks `GET`/`in: query` `$total` parameters, resolves `$ref`s, and no longer flags a missing `default`. +- OAR031 - Examples - Property checks now only cover schemas reachable from the path, traverse `allOf`/`oneOf`/`anyOf`, interpolate the actual name in messages, and fix several line-anchoring and OAS2-exemption divergences from Spectral. + ## [1.6.0] - 2026-09-10 Recopilado de `1.6.0-beta-1` a `1.6.0-beta-5`. diff --git a/pom.xml b/pom.xml index dc70ccd2..93f51587 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.apiaddicts.apitools.dosonarapi sonaropenapi-rules-community - 1.6.0 + 1.7.0-beta-1 sonar-plugin SonarQube OpenAPI Community Rules diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/AbstractWso2ScopesCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/AbstractWso2ScopesCheck.java index 7a0d5899..fa31620b 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/AbstractWso2ScopesCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/AbstractWso2ScopesCheck.java @@ -10,7 +10,6 @@ import apiaddicts.sonar.openapi.utils.JsonNodeUtils; import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode; -import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -33,20 +32,12 @@ protected JsonNode scopesKeyNode() { } private void visitV2NV3Node(JsonNode node) { - JsonNode securityNode = node.get("x-wso2-security"); - if (!securityNode.isMissing()) securityNode = JsonNodeUtils.resolve(securityNode); - JsonNode apimNode = securityNode.get("apim"); - JsonNode scopesNode = apimNode.get("x-wso2-scopes"); - scopesKeyNode = JsonNodeUtils.propertyKey(apimNode, "x-wso2-scopes"); + JsonNode apimNode = JsonNodeUtils.getWso2ApimNode(node); + JsonNode scopesNode = apimNode.get(JsonNodeUtils.WSO2_SCOPES); + scopesKeyNode = JsonNodeUtils.propertyKey(apimNode, JsonNodeUtils.WSO2_SCOPES); visitScopesNode(scopesNode); if (scopesNode.isMissing() || scopesNode.isNull()) return; - List rawScopes = scopesNode.isObject() - ? new ArrayList<>(scopesNode.propertyMap().values()) - : scopesNode.elements(); - List scopes = new ArrayList<>(rawScopes.size()); - for (JsonNode scope : rawScopes) { - scopes.add(JsonNodeUtils.resolve(scope)); - } + List scopes = JsonNodeUtils.getWso2Scopes(scopesNode); visitScopes(scopes); scopes.forEach(this::visitScope); } diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR002ValidWso2ScopesCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR002ValidWso2ScopesCheck.java index e588b1e0..37fcc3a7 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR002ValidWso2ScopesCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR002ValidWso2ScopesCheck.java @@ -1,14 +1,11 @@ package apiaddicts.sonar.openapi.checks.apim.wso2; -import com.google.common.collect.ImmutableSet; -import com.sonar.sslr.api.Token; import org.sonar.check.Rule; import apiaddicts.sonar.openapi.utils.JsonNodeUtils; import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode; import java.util.List; import java.util.Map; -import java.util.Set; @Rule(key = OAR002ValidWso2ScopesCheck.KEY) public class OAR002ValidWso2ScopesCheck extends AbstractWso2ScopesCheck { @@ -16,7 +13,6 @@ public class OAR002ValidWso2ScopesCheck extends AbstractWso2ScopesCheck { public static final String KEY = "OAR002"; private static final String MESSAGE = "OAR002.error"; private static final String MESSAGE_PROP = "OAR002.error-property"; - private static final Set NULL_SPELLINGS = ImmutableSet.of("~", "Null", "NULL"); private JsonNode scopesNode; @@ -63,15 +59,9 @@ private JsonNode scopeLocation(JsonNode scope) { } private boolean isEmpty(JsonNode property) { - if (isNullScalar(property)) return true; + if (JsonNodeUtils.isNullScalar(property)) return true; if (property.isArray()) return property.elements().isEmpty(); if (property.isObject()) return property.propertyMap().isEmpty(); return property.getTokenValue().trim().equals(""); } - - private boolean isNullScalar(JsonNode property) { - if (property.isNull()) return true; - Token token = property.getToken(); - return token != null && NULL_SPELLINGS.contains(token.getOriginalValue()); - } } diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheck.java index 22dc33d3..ad7de94d 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheck.java @@ -2,14 +2,12 @@ import com.sonar.sslr.api.AstNode; import org.sonar.check.Rule; +import apiaddicts.sonar.openapi.utils.JsonNodeUtils; import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode; -import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; -import static java.util.Objects.isNull; - @Rule(key = OAR005UndefinedWso2ScopeUseCheck.KEY) public class OAR005UndefinedWso2ScopeUseCheck extends AbstractWso2OperationCheck { @@ -26,18 +24,13 @@ protected void visitFile(JsonNode root) { private Set getScopes(JsonNode root) { - JsonNode scopes = root - .get("x-wso2-security") - .get("apim") - .get("x-wso2-scopes"); - - if (scopes.isMissing() || scopes.isNull()) { - return Collections.emptySet(); - } + JsonNode scopes = JsonNodeUtils + .getWso2ApimNode(root) + .get(JsonNodeUtils.WSO2_SCOPES); - return scopes.elements().stream() + return JsonNodeUtils.getWso2Scopes(scopes).stream() .map(node -> node.get("name")) - .filter(node -> !node.isMissing() && !node.isNull()) + .filter(node -> !node.isMissing() && !JsonNodeUtils.isNullScalar(node)) .map(AstNode::getTokenValue) .collect(Collectors.toSet()); } @@ -49,12 +42,8 @@ protected void visitOperationNode(JsonNode node) { if (scopeNode.isMissing()) return; - String scope = scopeNode.isNull() - ? null - : scopeNode.getTokenValue(); - - if (isNull(scope) || !definedScopes.contains(scope)) { + if (JsonNodeUtils.isNullScalar(scopeNode) || !definedScopes.contains(scopeNode.getTokenValue())) { addIssue(KEY, translate(MESSAGE), scopeNode); } } -} \ No newline at end of file +} diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheck.java index d174a7f0..3c91e621 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheck.java @@ -8,6 +8,7 @@ import static apiaddicts.sonar.openapi.utils.JsonNodeUtils.isOperation; import com.google.common.collect.ImmutableSet; import com.sonar.sslr.api.AstNodeType; +import java.util.HashSet; import java.util.Set; import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar; import org.apiaddicts.apitools.dosonarapi.api.v3.OpenApi3Grammar; @@ -26,9 +27,12 @@ public class OAR031ExamplesCheck extends BaseCheck { private static final String SCHEMA = "schema"; private static final String PROPERTIES = "properties"; private static final String ITEMS = "items"; + private static final String[] COMBINERS = {"allOf", "oneOf", "anyOf"}; private static final String ERROR_RESPONSE = "OAR031.error-response"; private static final String ERROR_REQUEST = "OAR031.error-request"; + private static final String ERROR_PARAMETER = "OAR031.error-parameter"; + private static final String ERROR_PROPERTY = "OAR031.error-property"; @RuleProperty( key = "validateResponse", @@ -64,6 +68,8 @@ public class OAR031ExamplesCheck extends BaseCheck { private final ExternalRefHandler handleExternalRef = new ExternalRefHandler(); + private final Set reachableSchemaPointers = new HashSet<>(); + @Override public Set subscribedKinds() { return ImmutableSet.of( @@ -76,6 +82,87 @@ public Set subscribedKinds() { ); } + @Override + protected void visitFile(JsonNode root) { + reachableSchemaPointers.clear(); + JsonNode pathsNode = root.get("paths"); + if (!pathsNode.isMissing()) { + for (JsonNode pathItem : pathsNode.properties()) { + for (JsonNode operationProp : pathItem.properties()) { + if (isOperation(operationProp)) { + markOperationSchemasReachable(operationProp); + } + } + } + } + super.visitFile(root); + } + + private void markOperationSchemasReachable(JsonNode operation) { + JsonNode parameters = operation.get("parameters"); + if (!parameters.isMissing() && parameters.isArray()) { + for (JsonNode parameterElement : parameters.elements()) { + handleExternalRef.resolve(parameterElement, resolved -> { + if (OpenApi2Grammar.PARAMETER.equals(resolved.getType())) { + JsonNode inNode = resolved.get("in"); + if (inNode.isMissing() || !"body".equals(inNode.getTokenValue())) { + return; + } + } + markReachable(resolved.get(SCHEMA)); + }); + } + } + + JsonNode requestBody = operation.get("requestBody"); + if (!requestBody.isMissing()) { + handleExternalRef.resolve(requestBody, this::markContentSchemas); + } + + JsonNode responses = operation.get("responses"); + if (!responses.isMissing()) { + for (JsonNode responseNode : responses.properties()) { + if ("204".equals(responseNode.key().getTokenValue())) continue; + handleExternalRef.resolve(responseNode, resolved -> { + markReachable(resolved.get(SCHEMA)); + markContentSchemas(resolved); + }); + } + } + } + + private void markContentSchemas(JsonNode node) { + JsonNode content = node.get("content"); + if (!content.isMissing()) { + content.propertyMap().values().forEach(mediaType -> markReachable(mediaType.get(SCHEMA))); + } + } + + private void markReachable(JsonNode schema) { + if (schema == null || schema.isMissing()) return; + handleExternalRef.resolve(schema, resolved -> { + if (resolved.isMissing()) return; + if (!reachableSchemaPointers.add(resolved.getPointer())) return; + + JsonNode props = resolved.get(PROPERTIES); + if (!props.isMissing() && props.isObject()) { + props.propertyMap().values().forEach(this::markReachable); + } + + JsonNode items = resolved.get(ITEMS); + if (!items.isMissing()) { + markReachable(items); + } + + for (String combiner : COMBINERS) { + JsonNode combinerNode = resolved.get(combiner); + if (!combinerNode.isMissing() && combinerNode.isArray()) { + combinerNode.elements().forEach(this::markReachable); + } + } + }); + } + @Override public void visitNode(JsonNode node) { AstNodeType type = node.getType(); @@ -101,18 +188,35 @@ private void visitParameterNode(JsonNode node) { JsonNode schema = resolved.get(SCHEMA); - // Parameter level: the parameter itself, or its schema's ROOT, must declare an - // example. Examples buried inside schema properties do NOT satisfy this level. + // Parameter level: the parameter itself, its schema's ROOT, or (OAS3) a + // content media-type example, must declare an example. Examples buried inside + // schema properties do NOT satisfy this level. boolean hasExample = !resolved.get(EXAMPLE).isMissing() || !resolved.get(EXAMPLES).isMissing() - || schemaHasRootExample(schema); + || schemaHasRootExample(schema) + || hasContentExample(resolved); if (validateParameter && !hasExample) { - addIssue(KEY, translate("OAR031.error-parameter"), handleExternalRef.getTrueNode(node)); + JsonNode nameNode = resolved.get("name"); + String paramName = nameNode.isMissing() ? "" : nameNode.getTokenValue(); + JsonNode trueNode = handleExternalRef.getTrueNode(node); + JsonNode anchor = trueNode.key().isMissing() ? trueNode : trueNode.key(); + addIssue(KEY, translate(ERROR_PARAMETER, paramName), anchor); } }); } + // OAS3 parameters may declare an example per media type under `content` instead of + // directly on the parameter or its schema root. + private boolean hasContentExample(JsonNode resolved) { + JsonNode content = resolved.get("content"); + if (content.isMissing() || !content.isObject()) return false; + return content.propertyMap().values().stream().anyMatch(mediaType -> + !mediaType.get(EXAMPLE).isMissing() + || !mediaType.get(EXAMPLES).isMissing() + || schemaHasRootExample(mediaType.get(SCHEMA))); + } + private void visitV2Node(JsonNode node) { AstNodeType type = node.getType(); if (OpenApi2Grammar.RESPONSES.equals(type)) { @@ -199,13 +303,22 @@ private boolean isSchemaCovered(JsonNode schemaNode) { } JsonNode props = resolved.get(PROPERTIES); - if (!props.isMissing() && props.isObject()) { - return props.propertyMap().values().stream().anyMatch(this::isSchemaCovered); + if (!props.isMissing() && props.isObject() + && props.propertyMap().values().stream().anyMatch(this::isSchemaCovered)) { + return true; } JsonNode items = resolved.get(ITEMS); - if (!items.isMissing()) { - return isSchemaCovered(items); + if (!items.isMissing() && isSchemaCovered(items)) { + return true; + } + + for (String combiner : COMBINERS) { + JsonNode combinerNode = resolved.get(combiner); + if (!combinerNode.isMissing() && combinerNode.isArray() + && combinerNode.elements().stream().anyMatch(this::isSchemaCovered)) { + return true; + } } return false; @@ -215,6 +328,11 @@ private boolean isSchemaCovered(JsonNode schemaNode) { private void visitSchemaNode(JsonNode node) { if (!validateProperty) return; + JsonNode resolvedNode = handleExternalRef.resolve(node, r -> r); + if (!reachableSchemaPointers.contains(resolvedNode.getPointer())) { + return; + } + JsonNode parentNode = (JsonNode) node.getParent().getParent(); if (parentNode.getType().equals(OpenApi3Grammar.PARAMETER) || parentNode.getType().equals(OpenApi31Grammar.PARAMETER) || parentNode.getType().equals(OpenApi32Grammar.PARAMETER)) { @@ -227,14 +345,9 @@ private void visitSchemaNode(JsonNode node) { || parentNode.getType().toString().equals("BLOCK_MAPPING") || parentNode.getType().toString().equals("FLOW_MAPPING")) { - JsonNode schemaParent = (JsonNode) parentNode.getParent().getParent(); - if (schemaParent != null && !schemaParent.get("allOf").isMissing()) { - return; - } - JsonNode type = getType(node); if (!isObjectType(type) && !type.isMissing() && !isArrayType(type) && node.get(EXAMPLE).isMissing()) { - addIssue(KEY, translate("OAR031.error-property"), node.key()); + addIssue(KEY, translate(ERROR_PROPERTY, node.key().getTokenValue()), node.key()); } } } @@ -247,7 +360,8 @@ private void visitPathNode(JsonNode node) { .map(JsonNode::value) .map(operation -> operation.get("responses")) .filter(responses -> !responses.isMissing()) - .flatMap(responses -> responses.propertyMap().values().stream()) + .flatMap(responses -> responses.properties().stream()) + .filter(responseNode -> !"204".equals(responseNode.key().getTokenValue())) .forEach(response -> handleExternalRef.resolve(response, resolved -> { if (resolved.getType().equals(OpenApi2Grammar.RESPONSE)) { visitSchemaNode2(resolved); @@ -268,16 +382,27 @@ private void visitSchemaNode2(JsonNode responseNode) { JsonNode schemaNode = responseNode.value().get(SCHEMA); if (schemaNode.isMissing()) return; - handleExternalRef.resolve(schemaNode, resolvedSchema -> { - JsonNode props = resolvedSchema.get(PROPERTIES); - if (props.isMissing() || !props.isObject()) return; + handleExternalRef.resolve(schemaNode, this::checkSchemaProperties); + } + private Void checkSchemaProperties(JsonNode resolvedSchema) { + JsonNode props = resolvedSchema.get(PROPERTIES); + if (!props.isMissing() && props.isObject()) { props.propertyMap().forEach((key, propertyNode) -> { JsonNode type = getType(propertyNode); if (!type.isMissing() && !isObjectType(type) && !isArrayType(type) && !isSchemaCovered(propertyNode)) { - addIssue(KEY, translate("OAR031.error-property"), handleExternalRef.getTrueNode(propertyNode.key())); + addIssue(KEY, translate(ERROR_PROPERTY, key), handleExternalRef.getTrueNode(propertyNode.key())); } }); - }); + } + + for (String combiner : COMBINERS) { + JsonNode combinerNode = resolvedSchema.get(combiner); + if (!combinerNode.isMissing() && combinerNode.isArray()) { + combinerNode.elements().forEach(sub -> handleExternalRef.resolve(sub, this::checkSchemaProperties)); + } + } + + return null; } } diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/format/AbstractDefaultMediaTypeCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/format/AbstractDefaultMediaTypeCheck.java index 1da0417d..019a29d1 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/format/AbstractDefaultMediaTypeCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/format/AbstractDefaultMediaTypeCheck.java @@ -41,6 +41,7 @@ public abstract class AbstractDefaultMediaTypeCheck extends BaseCheck { defaultValue = DEFAULT_MEDIA_TYPE_VALUE) public String defaultMediaType = DEFAULT_MEDIA_TYPE_VALUE; + private String defaultMediaTypeLower; private boolean globalSupportsDefaultMimeType = false; protected AbstractDefaultMediaTypeCheck(String key, String section, String message) { @@ -60,6 +61,7 @@ protected void visitFile(JsonNode root) { .map(String::trim) .map(String::toLowerCase) .collect(Collectors.toSet()); + defaultMediaTypeLower = defaultMediaType.toLowerCase(); globalSupportsDefaultMimeType = (root.getType() instanceof OpenApi2Grammar) && supportsDefaultMimeTypeV2(root); } @@ -141,18 +143,21 @@ private boolean supportsDefaultMimeTypeV2(JsonNode node) { List mimeTypes = consumes.elements().stream() .map(AstNode::getTokenValue) + .map(String::toLowerCase) .collect(Collectors.toList()); - return mimeTypes.stream().anyMatch(mediaTypeExceptions::contains) || - mimeTypes.stream().anyMatch(defaultMediaType::equals); + return mimeTypes.stream().anyMatch(mediaTypeExceptions::contains) || + mimeTypes.stream().anyMatch(defaultMediaTypeLower::equals); } private boolean supportsDefaultMimeTypeV3(JsonNode content) { if (content.isMissing() || content.isNull()) return false; - Set keys = content.propertyMap().keySet(); + Set keys = content.propertyMap().keySet().stream() + .map(String::toLowerCase) + .collect(Collectors.toSet()); return keys.stream().anyMatch(mediaTypeExceptions::contains) || - keys.stream().anyMatch(defaultMediaType::equals); + keys.stream().anyMatch(defaultMediaTypeLower::equals); } } diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheck.java index 57f41e5e..30266993 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheck.java @@ -8,6 +8,7 @@ import org.apiaddicts.apitools.dosonarapi.api.v31.OpenApi31Grammar; import org.apiaddicts.apitools.dosonarapi.api.v32.OpenApi32Grammar; import apiaddicts.sonar.openapi.checks.BaseCheck; +import apiaddicts.sonar.openapi.utils.ExternalRefHandler; import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode; import java.util.Set; @@ -17,28 +18,52 @@ public class OAR026TotalParameterDefaultValueCheck extends BaseCheck { protected static final String KEY = "OAR026"; private static final String MESSAGE = "OAR026.error"; + private static final String TOTAL_PARAM_NAME = "$total"; + + private final ExternalRefHandler handleExternalRef = new ExternalRefHandler(); @Override public Set subscribedKinds() { - return ImmutableSet.of(OpenApi2Grammar.PARAMETER, OpenApi3Grammar.PARAMETER, OpenApi31Grammar.PARAMETER, OpenApi32Grammar.PARAMETER); + return ImmutableSet.of( + OpenApi2Grammar.OPERATION, OpenApi3Grammar.OPERATION, + OpenApi31Grammar.OPERATION, OpenApi32Grammar.OPERATION); } @Override public void visitNode(JsonNode node) { - visitV2Node(node); + if (!"get".equals(node.key().getTokenValue())) { + return; + } + + JsonNode parametersNode = node.get("parameters"); + if (parametersNode.isMissing() || !parametersNode.isArray()) { + return; + } + + for (JsonNode parameterElement : parametersNode.elements()) { + handleExternalRef.resolve(parameterElement, this::checkTotalParameter); + } } - private void visitV2Node(JsonNode node) { - if (!"$total".equals(node.get("name").getTokenValue())) return; - JsonNode defaultNode = (node.getType() == OpenApi2Grammar.PARAMETER) ? node.get("default") : node.at("/schema/default"); + private void checkTotalParameter(JsonNode resolved) { + if (resolved.isMissing()) return; + + JsonNode inNode = resolved.get("in"); + if (inNode.isMissing() || !"query".equals(inNode.getTokenValue())) return; + + JsonNode nameNode = resolved.get("name"); + if (nameNode.isMissing() || !TOTAL_PARAM_NAME.equals(nameNode.getTokenValue())) return; + + JsonNode defaultNode = (resolved.getType() == OpenApi2Grammar.PARAMETER) + ? resolved.get("default") + : resolved.at("/schema/default"); + if (defaultNode.isMissing()) { - if (node.key().isMissing()) { - addIssue(KEY, translate(MESSAGE), node); - } else { - addIssue(KEY, translate(MESSAGE), node.key()); - } - } else if (!"false".equals(defaultNode.getTokenValue())) { - addIssue(KEY, translate(MESSAGE), defaultNode); + return; + } + + if (!"false".equals(defaultNode.getTokenValue())) { + addIssue(KEY, translate(MESSAGE), handleExternalRef.getTrueNode(defaultNode)); } } -} \ No newline at end of file +} diff --git a/src/main/java/apiaddicts/sonar/openapi/utils/JsonNodeUtils.java b/src/main/java/apiaddicts/sonar/openapi/utils/JsonNodeUtils.java index 4380a62e..77c657c9 100644 --- a/src/main/java/apiaddicts/sonar/openapi/utils/JsonNodeUtils.java +++ b/src/main/java/apiaddicts/sonar/openapi/utils/JsonNodeUtils.java @@ -18,10 +18,15 @@ import java.io.InputStreamReader; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import com.google.common.collect.ImmutableSet; import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.Token; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -44,6 +49,10 @@ private JsonNodeUtils() { public static final String TYPE_INTEGER = "integer"; public static final String TYPE_BOOLEAN = "boolean"; public static final String TYPE_ANY = "*"; + public static final String WSO2_SECURITY = "x-wso2-security"; + public static final String WSO2_APIM = "apim"; + public static final String WSO2_SCOPES = "x-wso2-scopes"; + private static final Set NULL_SPELLINGS = ImmutableSet.of("~", "Null", "NULL"); private static String lastFetchedContent = ""; public static JsonNode resolve(JsonNode original) { @@ -64,6 +73,31 @@ public static JsonNode resolve(JsonNode original) { return current; } + public static JsonNode getWso2ApimNode(JsonNode root) { + JsonNode securityNode = root.get(WSO2_SECURITY); + if (!securityNode.isMissing()) securityNode = resolve(securityNode); + return securityNode.get(WSO2_APIM); + } + + public static List getWso2Scopes(JsonNode scopesNode) { + if (scopesNode == null || scopesNode.isMissing() || scopesNode.isNull()) return Collections.emptyList(); + List rawScopes = scopesNode.isObject() + ? new ArrayList<>(scopesNode.propertyMap().values()) + : scopesNode.elements(); + List scopes = new ArrayList<>(rawScopes.size()); + for (JsonNode scope : rawScopes) { + scopes.add(resolve(scope)); + } + return scopes; + } + + public static boolean isNullScalar(JsonNode node) { + if (node == null) return true; + if (node.isNull()) return true; + Token token = node.getToken(); + return token != null && NULL_SPELLINGS.contains(token.getOriginalValue()); + } + public static boolean isExternalRef (JsonNode original){ if (original.isRef()) { diff --git a/src/main/resources/messages/errors.properties b/src/main/resources/messages/errors.properties index c659580f..e401ed3e 100644 --- a/src/main/resources/messages/errors.properties +++ b/src/main/resources/messages/errors.properties @@ -32,10 +32,10 @@ OAR028.error={0} must be defined as a parameter in this operation OAR029.error-required-one-property=At least one property must be defined OAR030.error-path=The path ''{0}'' must be declared OAR030.error-verb=Method {0} must be declared -OAR031.error-parameter=Parameters must have one or more examples defined -OAR031.error-response=Responses must have one or more examples defined -OAR031.error-request=Request body must have one or more examples defined -OAR031.error-property=Properties must have an example defined +OAR031.error-parameter=Parameter ''{0}'' must have an example defined +OAR031.error-response=Response must have an example defined +OAR031.error-request=Request body must have an example defined +OAR031.error-property=Property ''{0}'' is missing an example. OAR032.error=Ambiguous path parts not encouraged: {0} OAR033.error-header-required=''{0}'' header must be required OAR035.error=Response code {0} must be defined for operations with security schemes defined diff --git a/src/main/resources/messages/errors_es.properties b/src/main/resources/messages/errors_es.properties index 51ce126b..2dc0ac29 100644 --- a/src/main/resources/messages/errors_es.properties +++ b/src/main/resources/messages/errors_es.properties @@ -32,10 +32,10 @@ OAR028.error={0} debe ser definido como un parámetro en esta operación OAR029.error-required-one-property=Se debe de definir al menos una propiedad OAR030.error-path=El path ''{0}'' debería estar declarado OAR030.error-verb=El método {0} debería estar declarado -OAR031.error-parameter=Los parámetros deben tener uno o más ejemplos definidos -OAR031.error-response=Las respuestas deben tener uno o más ejemplos definidos -OAR031.error-request=El cuerpo de solicitud debe tener uno o más ejemplos definidos -OAR031.error-property=Las propiedades deben definir un ejemplo definido +OAR031.error-parameter=El parámetro ''{0}'' debe tener un ejemplo definido +OAR031.error-response=La respuesta debe tener un ejemplo definido +OAR031.error-request=El cuerpo de la solicitud debe tener un ejemplo definido +OAR031.error-property=La propiedad ''{0}'' no tiene un ejemplo definido OAR032.error=Nombres de partes de path ambiguos no permitidos: {0} OAR033.error-header-required=La cabecera ''{0}'' debe ser obligatoria OAR035.error=El código de respuesta {0} debe estar definido cuando la operación tiene esquemas de seguridad definidos diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR005.html b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR005.html index df268cc0..1cb5f3fc 100644 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR005.html +++ b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR005.html @@ -1,33 +1,9 @@

- Los scopes disponibles se definen al final del documento de definición, a nivel raíz. Se definen mediante la siguiente estructura: + Un scope incorrecto puede causar problemas al importar la definición de la API en WSO2 o permitir que cualquier usuario invoque el endpoint.

-
-x-wso2-security:
-  apim:
-  x-wso2-scopes:
-    - name: Nombre_scope_1
-      description: ""
-      key: Etiqueta_scope_1
-      roles: "Role_1, Role_2, …, Role_n"
-    - name: Nombre_scope_2>
-      description: ""
-      key: Etiqueta_scope_2
-      roles: "Role_1,Role_2,…,Role_n"
-

- Cada elemento del array x-wso2-scopes contiene los siguientes elementos: + El x-scope de la operación debe coincidir con el name de un scope declarado. El key del scope nunca se tiene en cuenta.

-
    -
  • name: El nombre que recibirá el scope. -
      -
    • La nomenclatura es {Código POAP del API}_sc_{nombre-descriptivo}
    • -
    • Por ejemplo: USUG-API_sc_user-scope
    • -
    -
  • -
  • description: Breve descripción del scope. Opcional.
  • -
  • key: Etiqueta del scope. Se recomienda que coincida con el nombre para evitar confusiones.
  • -
  • roles: Cadena con todos los roles asociados al scope separados por coma (se corresponde con los perfiles de cada Aplicación obtenidos de USUG).
  • -

Ejemplo de código no compatible (OpenAPI 2)

 swagger: "2.0"
diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.html b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.html
index 949d12c0..bea3a1bf 100644
--- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.html
+++ b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.html
@@ -1,34 +1,20 @@
-

- Los scopes disponibles se definen al final del documento de definición, a nivel raíz. Se definen mediante la siguiente estructura: -

+

El uso de un scope (x-scope) en una operación siempre requiere que se defina también un tipo de autenticación (x-auth-type).

+

Ejemplo de código no compatible

+swagger: "2.0"
 x-wso2-security:
   apim:
-  x-wso2-scopes:
-    - name: Nombre_scope_1
-      description: ""
-      key: Etiqueta_scope_1
-      roles: "Role_1, Role_2, …, Role_n"
-    - name: Nombre_scope_2>
-      description: ""
-      key: Etiqueta_scope_2
-      roles: "Role_1,Role_2,…,Role_n"
+    x-wso2-scopes:
+    - name: read
+      key: read
+      roles: READ_ROLE
+      description: Allows users to view records
+paths:
+  /pets:
+    get:
+      x-scope: read
 
-

- Cada elemento del array x-wso2-scopes contiene los siguientes elementos: -

-
    -
  • name: El nombre que recibirá el scope. -
      -
    • La nomenclatura es {Código POAP del API}_sc_{nombre-descriptivo}
    • -
    • Por ejemplo: USUG-API_sc_user-scope
    • -
    -
  • -
  • description: Breve descripción del scope. Opcional.
  • -
  • key: Etiqueta del scope. Se recomienda que coincida con el nombre para evitar confusiones.
  • -
  • roles: Cadena con todos los roles asociados al scope separados por coma (se corresponde con los perfiles de cada Aplicación obtenidos de USUG).
  • -
-

Noncompliant

+

Solución compatible

 swagger: "2.0"
 x-wso2-security:
@@ -42,10 +28,11 @@ 

Noncompliant

/pets: get: x-scope: read + x-auth-type: "Application & Application User"
-

Compliant

+

Ejemplo de código no compatible (OpenAPI 3)

-swagger: "2.0"
+openapi: "3.0.0"
 x-wso2-security:
   apim:
     x-wso2-scopes:
@@ -57,5 +44,20 @@ 

Compliant

/pets: get: x-scope: read - x-aut-type: "Application & Application User"
+

Solución compatible (OpenAPI 3)

+
+openapi: "3.0.0"
+x-wso2-security:
+  apim:
+    x-wso2-scopes:
+    - name: read
+      key: read
+      roles: READ_ROLE
+      description: Allows users to view records
+paths:
+  /pets:
+    get:
+      x-scope: read
+      x-auth-type: "Application & Application User"
+
\ No newline at end of file diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.json b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.json index 81bd0427..d9ab20a9 100644 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.json +++ b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/apim/wso2/OAR041.json @@ -1,5 +1,5 @@ { - "title": "OAR041 - UndefinedAuthTypeForWso2Scope - El uso de x-scope require del uso de x-auth-type", + "title": "OAR041 - UndefinedAuthTypeForWso2Scope - El uso de x-scope requiere del uso de x-auth-type", "type": "VULNERABILITY", "status": "ready", "remediation": { diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.html b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.html deleted file mode 100644 index c611114f..00000000 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.html +++ /dev/null @@ -1,190 +0,0 @@ -

El archivo con la especificación OpenAPI no puede contener líneas vacías, esto impedirá su análisis.

-

Ejemplo de código no compatible (OpenAPI 2)

-

JSON

-
-{
-    "swagger": "2.0", 
-    "info": {
-        "title": "Ejemplo de API", 
-        "version": "1.0.0"
-    }, 
-    "paths": {
-        "/clientes": {
-            "get": {
-                "summary": "Obtenci\u00f3n de una colecci\u00f3n de clientes", 
-                "description": "Permite obtener una colecci\u00f3n de clientes.\nPor ejemplo: /usuarios o /expedientes.\nPuede admitir cabeceras, *query parameters* y el objeto $filter en el body.\n\n**Scope Oauth:** clientes_sc_consulta\n", 
-                "responses": {
-                    "200": {
-                        "description": "OK"
-                    }
-                }
-            }
-        }
-    }
-}
-
-

YAML

-
-swagger: "2.0"
-info: 
-  title: Ejemplo de API
-  version: 1.0.0
-paths:
-
-  /clientes:
-  
-    get:
-      # 'summary': Es OBLIGATORIO usar este elemento en todos los paths. Se trata de una breve descripción del endpoint
-      summary: Obtención de una colección de clientes
-      # 'description': es OBLIGATORIO que el contenido de este campo esté cumplimentado y difiera del del campo 'summary'
-      # Debe darse una descripción lo más detallada posible de la funcionalidad del endpoint sin describir la lógica de negocio.
-      # Si el endpoint está protegido por un scope Oauth debe indicarse cuál és en la descripción.
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-
-        **Scope Oauth:** clientes_sc_consulta
-      
-      responses:
-        200:
-          description: OK
-
-

Solución compatible (OpenAPI 2)

-

JSON

-
-{
-    "swagger": "2.0", 
-    "info": {
-        "title": "Ejemplo de API", 
-        "version": "1.0.0"
-    }, 
-    "paths": {
-        "/clientes": {
-            "get": {
-                "summary": "Obtenci\u00f3n de una colecci\u00f3n de clientes", 
-                "description": "Permite obtener una colecci\u00f3n de clientes.\nPor ejemplo: /usuarios o /expedientes.\nPuede admitir cabeceras, *query parameters* y el objeto $filter en el body.\n**Scope Oauth:** clientes_sc_consulta\n", 
-                "responses": {
-                    "200": {
-                        "description": "OK"
-                    }
-                }
-            }
-        }
-    }
-}
-
-

YAML

-
-swagger: "2.0"
-info: 
-  title: Ejemplo de API
-  version: 1.0.0
-paths:
-  /clientes:
-    get:
-      # 'summary': Es OBLIGATORIO usar este elemento en todos los paths. Se trata de una breve descripción del endpoint
-      summary: Obtención de una colección de clientes
-      # 'description': es OBLIGATORIO que el contenido de este campo esté cumplimentado y difiera del del campo 'summary'
-      # Debe darse una descripción lo más detallada posible de la funcionalidad del endpoint sin describir la lógica de negocio.
-      # Si el endpoint está protegido por un scope Oauth debe indicarse cuál és en la descripción.
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-        **Scope Oauth:** clientes_sc_consulta
-      responses:
-        200:
-          description: OK
-
-

Ejemplo de código no compatible (OpenAPI 3)

-

JSON

-
-{
-    "openapi": "3.0.1", 
-    "info": {
-        "title": "Ejemplo de API", 
-        "version": "1.0.0"
-    }, 
-    "paths": {
-        "/clientes": {
-            "get": {
-                "summary": "Obtenci\u00f3n de una colecci\u00f3n de clientes", 
-                "description": "Permite obtener una colecci\u00f3n de clientes.\nPor ejemplo: /usuarios o /expedientes.\nPuede admitir cabeceras, *query parameters* y el objeto $filter en el body.\n\n**Scope Oauth:** clientes_sc_consulta\n", 
-                "responses": {
-                    "200": {
-                        "description": "OK"
-                    }
-                }
-            }
-        }
-    }
-}
-
-

YAML

-
-openapi: 3.0.1
-
-info:
-  title: Ejemplo de API
-  version: 1.0.0
-
-paths:
-
-  /clientes:
-
-    get:
-      summary: Obtención de una colección de clientes
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-
-        **Scope Oauth:** clientes_sc_consulta
-      responses:
-        200:
-          description: OK
-
-

Solución compatible (OpenAPI 3)

-

JSON

-
-{
-    "openapi": "3.0.1", 
-    "info": {
-        "title": "Ejemplo de API", 
-        "version": "1.0.0"
-    }, 
-    "paths": {
-        "/clientes": {
-            "get": {
-                "summary": "Obtenci\u00f3n de una colecci\u00f3n de clientes", 
-                "description": "Permite obtener una colecci\u00f3n de clientes.\nPor ejemplo: /usuarios o /expedientes.\nPuede admitir cabeceras, *query parameters* y el objeto $filter en el body.\n**Scope Oauth:** clientes_sc_consulta\n", 
-                "responses": {
-                    "200": {
-                        "description": "OK"
-                    }
-                }
-            }
-        }
-    }
-}
-
-

YAML

-
-openapi: 3.0.1
-info:
-  title: Ejemplo de API
-  version: 1.0.0
-paths:
-  /clientes:
-    get:
-      summary: Obtención de una colección de clientes
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-        **Scope Oauth:** clientes_sc_consulta
-      responses:
-        200:
-          description: OK
-
\ No newline at end of file diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.json b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.json deleted file mode 100644 index b9eb829f..00000000 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/core/OAR043.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "title": "OAR043 - ParsingError - El archivo no puede ser analizado", - "type": "BUG", - "status": "ready", - "remediation": { - "func": "Constant\/Issue", - "constantCost": "30min" - }, - "tags": [ - "core" - ], - "defaultSeverity": "BLOCKER" -} diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.html b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.html index 7e145323..a12302b8 100644 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.html +++ b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.html @@ -1,116 +1,53 @@ -

El archivo con la especificación OpenAPI no puede contener líneas vacías, esto impedirá su análisis.

-

Ejemplo de código no compatible (OpenAPI 2)

+

Este archivo no es una definición válida de OpenAPI o Swagger. Esto incluye tanto documentos que un parser estricto ni siquiera puede cargar (sintaxis YAML o JSON mal formada) como documentos que sí cargan pero que no superan la validación estructural de la especificación.

+

Ejemplo de código no compatible (indentación YAML incorrecta)

-{
-    "swagger": "2.0", 
-    "info": {
-        "title": "Ejemplo de API", 
-        "version": "1.0.0"
-    }, 
-    "paths": {
-        "/clientes": {
-            "get": {
-                "summary": "Obtenci\u00f3n de una colecci\u00f3n de clientes", 
-                "description": "Permite obtener una colecci\u00f3n de clientes.\nPor ejemplo: /usuarios o /expedientes.\nPuede admitir cabeceras, *query parameters* y el objeto $filter en el body.\n\n**Scope Oauth:** clientes_sc_consulta\n", 
-                "responses": {
-                    "200": {
-                        "description": "OK"
-                    }
-                }
-            }
-        }
-    }
-}
-
-
-swagger: "2.0"
-info: 
-  title: Ejemplo de API
-  version: 1.0.0
-paths:
-
-  /clientes:
-  
-    get:
-      # 'summary': Es OBLIGATORIO usar este elemento en todos los paths. Se trata de una breve descripción del endpoint
-      summary: Obtención de una colección de clientes
-      # 'description': es OBLIGATORIO que el contenido de este campo esté cumplimentado y difiera del del campo 'summary'
-      # Debe darse una descripción lo más detallada posible de la funcionalidad del endpoint sin describir la lógica de negocio.
-      # Si el endpoint está protegido por un scope Oauth debe indicarse cuál és en la descripción.
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-
-        **Scope Oauth:** clientes_sc_consulta
-      
-      responses:
-        200:
-          description: OK
-
-

Solución compatible (OpenAPI 2)

-
-swagger: "2.0"
-info: 
+openapi: "3.0.0"
+info:
   title: Ejemplo de API
-  version: 1.0.0
+  version: "1.0.0"
 paths:
-  /clientes:
+  /pets:
     get:
-      # 'summary': Es OBLIGATORIO usar este elemento en todos los paths. Se trata de una breve descripción del endpoint
-      summary: Obtención de una colección de clientes
-      # 'description': es OBLIGATORIO que el contenido de este campo esté cumplimentado y difiera del del campo 'summary'
-      # Debe darse una descripción lo más detallada posible de la funcionalidad del endpoint sin describir la lógica de negocio.
-      # Si el endpoint está protegido por un scope Oauth debe indicarse cuál és en la descripción.
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-        **Scope Oauth:** clientes_sc_consulta
       responses:
         200:
           description: OK
+       "400":
+          description: Bad Request
 
-

Ejemplo de código no compatible (OpenAPI 3)

+

Solución compatible

-openapi: 3.0.1
-
+openapi: "3.0.0"
 info:
   title: Ejemplo de API
-  version: 1.0.0
-
+  version: "1.0.0"
 paths:
-
-  /clientes:
-
+  /pets:
     get:
-      summary: Obtención de una colección de clientes
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-
-        **Scope Oauth:** clientes_sc_consulta
       responses:
-        200:
+        "200":
           description: OK
+        "400":
+          description: Bad Request
 
-

Solución compatible (OpenAPI 3)

+

Ejemplo de código no compatible (coma colgante en JSON)

-openapi: 3.0.1
-info:
-  title: Ejemplo de API
-  version: 1.0.0
-paths:
-  /clientes:
-    get:
-      summary: Obtención de una colección de clientes
-      description: |
-        Permite obtener una colección de clientes.
-        Por ejemplo: /usuarios o /expedientes.
-        Puede admitir cabeceras, *query parameters* y el objeto $filter en el body.
-        **Scope Oauth:** clientes_sc_consulta
-      responses:
-        200:
-          description: OK
+{
+  "openapi": "3.0.0",
+  "info": {
+    "title": "Ejemplo de API",
+    "version": "1.0.0",
+  },
+  "paths": {}
+}
 
+

Solución compatible

+
+{
+  "openapi": "3.0.0",
+  "info": {
+    "title": "Ejemplo de API",
+    "version": "1.0.0"
+  },
+  "paths": {}
+}
+
\ No newline at end of file diff --git a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.json b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.json index 02a6e096..6ca56a29 100644 --- a/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.json +++ b/src/main/resources/org/sonar/l10n/es/openapi/rules/openapi/operations/OAR043.json @@ -1,5 +1,5 @@ { - "title": "OAR043 - ParsingError - El archivo no puede ser analizado", + "title": "OAR043 - ParsingError - El archivo no puede ser analizado o no supera la validación estructural", "type": "BUG", "status": "ready", "remediation": { diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR005.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR005.html index 97c4df10..a3176ec1 100644 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR005.html +++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR005.html @@ -1,4 +1,5 @@

A wrong scope may cause problems to import the API definition into WSO2 or allow all users to call the endpoint.

+

The operation x-scope must match the name of a declared scope. The scope key is never taken into account.

Noncompliant Code Example (OpenAPI 2)

 swagger: "2.0"
diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR041.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR041.html
index 689f891f..6e4c8b37 100644
--- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR041.html
+++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/apim/wso2/OAR041.html
@@ -28,7 +28,7 @@ 

Compliant Solution

/pets: get: x-scope: read - x-aut-type: "Application & Application User" + x-auth-type: "Application & Application User"

Noncompliant Code Example (OpenAPI 3)

@@ -59,5 +59,5 @@ 

Compliant Solution (OpenAPI 3)

/pets: get: x-scope: read - x-aut-type: "Application & Application User" + x-auth-type: "Application & Application User"
\ No newline at end of file diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.html deleted file mode 100644 index 6d8aedb8..00000000 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.html +++ /dev/null @@ -1 +0,0 @@ -

This file is not a valid OpenAPI or Swagger definition.

diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.json b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.json deleted file mode 100644 index 9b62772f..00000000 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/core/OAR043.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "title": "OAR043 - ParsingError - OpenAPI file cannot be parsed", - "type": "BUG", - "status": "ready", - "remediation": { - "func": "Constant\/Issue", - "constantCost": "30min" - }, - "tags": [ - "core" - ], - "defaultSeverity": "BLOCKER" -} diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/examples/OAR031.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/examples/OAR031.html index c20f54bc..7a862915 100644 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/examples/OAR031.html +++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/examples/OAR031.html @@ -1,6 +1,6 @@

The examples can help developers to understand the response data structure and representation.

Examples are validated as four independent levels: response, request body, parameter and property. The response, request-body and parameter levels require an example declared at the media-type or schema root; examples nested inside individual properties do not satisfy them. 204 responses are excluded.

-

Each level can be enabled or disabled independently with the rule parameters validate-response, validate-request-body, validate-parameter and validate-property (all enabled by default).

+

Each level can be enabled or disabled independently with the rule parameters validateResponse, validateRequestBody, validateParameter and validateProperty (all enabled by default).

Noncompliant Code Example (OpenAPI 2)

 swagger: "2.0"
@@ -87,7 +87,7 @@ 

Noncompliant Code Example (OpenAPI 3)

/pets: get: responses: - 206: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 206: # Noncompliant {{OAR031: Response must have an example defined}} description: Pet list content: application/json: @@ -98,14 +98,14 @@

Noncompliant Code Example (OpenAPI 3)

pet: type: object properties: - name: # Noncompliant {{OAR031: Properties must have an example defined}} + name: # Noncompliant {{OAR031: Property 'name' is missing an example.}} type: string - type: # Noncompliant {{OAR031: Properties must have an example defined}} + type: # Noncompliant {{OAR031: Property 'type' is missing an example.}} type: string pets: type: object properties: - size: # Noncompliant {{OAR031: Properties must have an example defined}} + size: # Noncompliant {{OAR031: Property 'size' is missing an example.}} type: integer pets: type: array diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/format/OAR007.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/format/OAR007.html index 09f6c98c..5a748ea2 100644 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/format/OAR007.html +++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/format/OAR007.html @@ -1,5 +1,5 @@ -

When defining an API, the request data formats must be defined.

-

For OpenAPI 2 specify at least a MIME Type understood by the API in the "consumes" keyword is mandatory.

+

When defining an API, the response data formats must be defined.

+

For OpenAPI 2 specify at least a MIME Type understood by the API in the "produces" keyword is mandatory.

For OpenAPI 3 specify at least a Media Type in the content of the response body is mandatory.

Noncompliant Code Example (OpenAPI 2)

diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.html b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.html
index b2e384a4..21ae94bc 100644
--- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.html
+++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.html
@@ -1 +1,53 @@
-

This file is not a valid OpenAPI or Swagger definition.

\ No newline at end of file +

This file is not a valid OpenAPI or Swagger definition. This includes documents that a strict parser cannot even load (malformed YAML or JSON syntax) as well as documents that load but fail the structural validation of the specification.

+

Noncompliant Code Example (broken YAML indentation)

+
+openapi: "3.0.0"
+info:
+  title: Example API
+  version: "1.0.0"
+paths:
+  /pets:
+    get:
+      responses:
+        200:
+          description: OK
+       "400":
+          description: Bad Request
+
+

Compliant Solution

+
+openapi: "3.0.0"
+info:
+  title: Example API
+  version: "1.0.0"
+paths:
+  /pets:
+    get:
+      responses:
+        "200":
+          description: OK
+        "400":
+          description: Bad Request
+
+

Noncompliant Code Example (trailing comma in JSON)

+
+{
+  "openapi": "3.0.0",
+  "info": {
+    "title": "Example API",
+    "version": "1.0.0",
+  },
+  "paths": {}
+}
+
+

Compliant Solution

+
+{
+  "openapi": "3.0.0",
+  "info": {
+    "title": "Example API",
+    "version": "1.0.0"
+  },
+  "paths": {}
+}
+
\ No newline at end of file diff --git a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.json b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.json index 1910e884..4ecc73f9 100644 --- a/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.json +++ b/src/main/resources/org/sonar/l10n/openapi/rules/openapi/operations/OAR043.json @@ -1,5 +1,5 @@ { - "title": "OAR043 - ParsingError - OpenAPI file cannot be parsed", + "title": "OAR043 - ParsingError - OpenAPI file cannot be parsed or fails structural validation", "type": "BUG", "status": "ready", "remediation": { diff --git a/src/test/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheckTest.java b/src/test/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheckTest.java index d569214d..493e6652 100644 --- a/src/test/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheckTest.java +++ b/src/test/java/apiaddicts/sonar/openapi/checks/apim/wso2/OAR005UndefinedWso2ScopeUseCheckTest.java @@ -72,6 +72,254 @@ public void verifyInV32WithCorrectOperationScope() { verifyV32("with-correct-operation-scope"); } + @Test + public void verifyInV2WithRefSecurity() { + verifyV2("with-ref-security"); + } + @Test + public void verifyInV3WithRefSecurity() { + verifyV3("with-ref-security"); + } + @Test + public void verifyInV31WithRefSecurity() { + verifyV31("with-ref-security"); + } + @Test + public void verifyInV32WithRefSecurity() { + verifyV32("with-ref-security"); + } + + @Test + public void verifyInV2WithChainedRefSecurity() { + verifyV2("with-chained-ref-security"); + } + @Test + public void verifyInV3WithChainedRefSecurity() { + verifyV3("with-chained-ref-security"); + } + @Test + public void verifyInV31WithChainedRefSecurity() { + verifyV31("with-chained-ref-security"); + } + @Test + public void verifyInV32WithChainedRefSecurity() { + verifyV32("with-chained-ref-security"); + } + + @Test + public void verifyInV2WithScopesAsMap() { + verifyV2("with-scopes-as-map"); + } + @Test + public void verifyInV3WithScopesAsMap() { + verifyV3("with-scopes-as-map"); + } + @Test + public void verifyInV31WithScopesAsMap() { + verifyV31("with-scopes-as-map"); + } + @Test + public void verifyInV32WithScopesAsMap() { + verifyV32("with-scopes-as-map"); + } + + @Test + public void verifyInV2WithRefScope() { + verifyV2("with-ref-scope"); + } + @Test + public void verifyInV3WithRefScope() { + verifyV3("with-ref-scope"); + } + @Test + public void verifyInV31WithRefScope() { + verifyV31("with-ref-scope"); + } + @Test + public void verifyInV32WithRefScope() { + verifyV32("with-ref-scope"); + } + + @Test + public void verifyInV2WithScopeKeyNotName() { + verifyV2("with-scope-key-not-name"); + } + @Test + public void verifyInV3WithScopeKeyNotName() { + verifyV3("with-scope-key-not-name"); + } + @Test + public void verifyInV31WithScopeKeyNotName() { + verifyV31("with-scope-key-not-name"); + } + @Test + public void verifyInV32WithScopeKeyNotName() { + verifyV32("with-scope-key-not-name"); + } + + @Test + public void verifyInV2WithoutSecurity() { + verifyV2("without-security"); + } + @Test + public void verifyInV3WithoutSecurity() { + verifyV3("without-security"); + } + @Test + public void verifyInV31WithoutSecurity() { + verifyV31("without-security"); + } + @Test + public void verifyInV32WithoutSecurity() { + verifyV32("without-security"); + } + + @Test + public void verifyInV3WithNullSecurity() { + verifyV3("with-null-security.yaml"); + } + + @Test + public void verifyInV3WithScalarSecurity() { + verifyV3("with-scalar-security.yaml"); + } + + @Test + public void verifyInV3WithArraySecurity() { + verifyV3("with-array-security.yaml"); + } + + @Test + public void verifyInV3WithoutApim() { + verifyV3("without-apim.yaml"); + } + + @Test + public void verifyInV3WithNullApim() { + verifyV3("with-null-apim.yaml"); + } + + @Test + public void verifyInV3WithoutScopes() { + verifyV3("without-scopes.yaml"); + } + + @Test + public void verifyInV3WithNullScopes() { + verifyV3("with-null-scopes.yaml"); + } + + @Test + public void verifyInV3WithEmptyArrayScopes() { + verifyV3("with-empty-array-scopes.yaml"); + } + + @Test + public void verifyInV3WithEmptyObjectScopes() { + verifyV3("with-empty-object-scopes.yaml"); + } + + @Test + public void verifyInV3WithScalarScopes() { + verifyV3("with-scalar-scopes.yaml"); + } + + @Test + public void verifyInV3WithCyclicRefSecurity() { + verifyV3("with-cyclic-ref-security.yaml"); + } + + @Test + public void verifyInV3WithDanglingRefSecurity() { + verifyV3("with-dangling-ref-security.yaml"); + } + + @Test + public void verifyInV3WithMalformedScopes() { + verifyV3("with-malformed-scopes.yaml"); + } + + @Test + public void verifyInV3WithXScopeNullSpellings() { + verifyV3("with-x-scope-null-spellings.yaml"); + } + + @Test + public void verifyInV3WithXScopeScalarTypes() { + verifyV3("with-x-scope-scalar-types.yaml"); + } + + @Test + public void verifyInV3WithXScopeCollections() { + verifyV3("with-x-scope-collections.yaml"); + } + + @Test + public void verifyInV3WithXScopeBlockCollections() { + verifyV3("with-x-scope-block-collections.yaml"); + } + + @Test + public void verifyInV2WithAllVerbs() { + verifyV2("with-all-verbs"); + } + @Test + public void verifyInV3WithAllVerbs() { + verifyV3("with-all-verbs"); + } + @Test + public void verifyInV31WithAllVerbs() { + verifyV31("with-all-verbs"); + } + @Test + public void verifyInV32WithAllVerbs() { + verifyV32("with-all-verbs"); + } + + @Test + public void verifyInV3WithCallbackOperations() { + verifyV3("with-callback-operations"); + } + @Test + public void verifyInV31WithCallbackOperations() { + verifyV31("with-callback-operations"); + } + @Test + public void verifyInV32WithCallbackOperations() { + verifyV32("with-callback-operations"); + } + + @Test + public void verifyInV31WithWebhookOperations() { + verifyV31("with-webhook-operations"); + } + @Test + public void verifyInV32WithWebhookOperations() { + verifyV32("with-webhook-operations"); + } + + @Test + public void verifyInV32WithAdditionalOperations() { + verifyV32("with-additional-operations"); + } + + @Test + public void verifyInV2Extensive() { + verifyV2("extensive-api"); + } + @Test + public void verifyInV3Extensive() { + verifyV3("extensive-api"); + } + @Test + public void verifyInV31Extensive() { + verifyV31("extensive-api"); + } + @Test + public void verifyInV32Extensive() { + verifyV32("extensive-api"); + } + @Override public void verifyRule() { assertRuleProperties("OAR005 - UndefinedWso2ScopeUse - WSO2 scope definition does not exists", RuleType.VULNERABILITY, Severity.BLOCKER, tags("api-manager", "vulnerability", "wso2")); diff --git a/src/test/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheckTest.java b/src/test/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheckTest.java index 4f7f624d..667c257a 100644 --- a/src/test/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheckTest.java +++ b/src/test/java/apiaddicts/sonar/openapi/checks/examples/OAR031ExamplesCheckTest.java @@ -95,6 +95,16 @@ public void verifyInV32NestedProperties() { public void verifyInV2AllOfSchema() { verifyV2("allof-schema"); } + + @Test + public void verifyInV2AllOfSchemaMissingExample() { + verifyV2("allof-schema-missing-example.yaml"); + } + + @Test + public void verifyInV2OrphanSchema() { + verifyV2("orphan-schema.yaml"); + } @Test public void verifyInV3AllOfSchema() { verifyV3("allof-schema"); @@ -108,6 +118,32 @@ public void verifyInV32AllOfSchema() { verifyV32("allof-schema"); } + @Test + public void verifyInV3AllOfSchemaMissingExample() { + verifyV3("allof-schema-missing-example.yaml"); + } + @Test + public void verifyInV31AllOfSchemaMissingExample() { + verifyV31("allof-schema-missing-example.yaml"); + } + @Test + public void verifyInV32AllOfSchemaMissingExample() { + verifyV32("allof-schema-missing-example.yaml"); + } + + @Test + public void verifyInV3OrphanSchema() { + verifyV3("orphan-schema.yaml"); + } + @Test + public void verifyInV31OrphanSchema() { + verifyV31("orphan-schema.yaml"); + } + @Test + public void verifyInV32OrphanSchema() { + verifyV32("orphan-schema.yaml"); + } + @Override public void verifyRule() { assertRuleProperties("OAR031 - Examples - Responses, Request Body, Parameters and Properties must have an example defined", RuleType.BUG, Severity.MAJOR, tags("examples")); diff --git a/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR007UndefinedResponseMediaTypeCheckTest.java b/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR007UndefinedResponseMediaTypeCheckTest.java index 2b4eb51c..559a31a4 100644 --- a/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR007UndefinedResponseMediaTypeCheckTest.java +++ b/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR007UndefinedResponseMediaTypeCheckTest.java @@ -38,6 +38,11 @@ public void verifyInV2WithoutAnything() { verifyV2("without-anything"); } + @Test + public void verifyInV2WithSpecificPut() { + verifyV2("with-specific-put"); + } + @Test public void verifyInV3WithoutAnything() { verifyV3("without-anything"); @@ -51,6 +56,110 @@ public void verifyInV32WithoutAnything() { verifyV32("without-anything"); } + @Test + public void verifyInV3WithSpecific() { + verifyV3("with-specific"); + } + @Test + public void verifyInV31WithSpecific() { + verifyV31("with-specific"); + } + @Test + public void verifyInV32WithSpecific() { + verifyV32("with-specific"); + } + + @Test + public void verifyInV3WithMultipleOperations() { + verifyV3("with-multiple-operations"); + } + @Test + public void verifyInV31WithMultipleOperations() { + verifyV31("with-multiple-operations"); + } + @Test + public void verifyInV32WithMultipleOperations() { + verifyV32("with-multiple-operations"); + } + + @Test + public void verifyInV3WithDefaultAndRef() { + verifyV3("with-default-and-ref"); + } + @Test + public void verifyInV31WithDefaultAndRef() { + verifyV31("with-default-and-ref"); + } + @Test + public void verifyInV32WithDefaultAndRef() { + verifyV32("with-default-and-ref"); + } + + @Test + public void verifyInV3WithWrongRef() { + verifyV3("with-wrong-ref"); + } + @Test + public void verifyInV31WithWrongRef() { + verifyV31("with-wrong-ref"); + } + @Test + public void verifyInV32WithWrongRef() { + verifyV32("with-wrong-ref"); + } + + @Test + public void verifyInV3WithChainedRef() { + verifyV3("with-chained-ref"); + } + @Test + public void verifyInV31WithChainedRef() { + verifyV31("with-chained-ref"); + } + @Test + public void verifyInV32WithChainedRef() { + verifyV32("with-chained-ref"); + } + + @Test + public void verifyInV3WithExternalRef() { + verifyV3("with-external-ref"); + } + @Test + public void verifyInV31WithExternalRef() { + verifyV31("with-external-ref"); + } + @Test + public void verifyInV32WithExternalRef() { + verifyV32("with-external-ref"); + } + + @Test + public void verifyInV3With204Response() { + verifyV3("with-204-response"); + } + @Test + public void verifyInV31With204Response() { + verifyV31("with-204-response"); + } + @Test + public void verifyInV32With204Response() { + verifyV32("with-204-response"); + } + + @Test + public void verifyInV3WithDefaultResponseKey() { + verifyV3("with-default-response-key"); + } + @Test + public void verifyInV31WithDefaultResponseKey() { + verifyV31("with-default-response-key"); + } + @Test + public void verifyInV32WithDefaultResponseKey() { + verifyV32("with-default-response-key"); + } + @Override public void verifyRule() { assertRuleProperties("OAR007 - UndefinedResponseMediaType - APIs must define response media types supported by the API", RuleType.BUG, Severity.BLOCKER, tags("format")); diff --git a/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR010DefaultResponseMediaTypeCheckTest.java b/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR010DefaultResponseMediaTypeCheckTest.java index f18c65a5..8cea8c98 100644 --- a/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR010DefaultResponseMediaTypeCheckTest.java +++ b/src/test/java/apiaddicts/sonar/openapi/checks/format/OAR010DefaultResponseMediaTypeCheckTest.java @@ -49,6 +49,11 @@ public void verifyInV2WithoutAnything() { verifyV2("without-anything"); } + @Test + public void verifyInV2WithDefaultMixedCase() { + verifyV2("with-default-mixed-case"); + } + @Test public void verifyInV3WithDefault() { verifyV3("with-default-and-$ref"); @@ -127,6 +132,50 @@ public void verifyInV32WithoutAnything() { verifyV32("without-anything"); } + @Test + public void verifyInV3WithDefaultMixedCase() { + verifyV3("with-default-mixed-case"); + } + @Test + public void verifyInV31WithDefaultMixedCase() { + verifyV31("with-default-mixed-case"); + } + @Test + public void verifyInV32WithDefaultMixedCase() { + verifyV32("with-default-mixed-case"); + } + + @Test + public void verifyInV3WithWrongDefaultAndRef() { + verifyV3("with-wrong-default-and-ref"); + } + @Test + public void verifyInV31WithWrongDefaultAndRef() { + verifyV31("with-wrong-default-and-ref"); + } + @Test + public void verifyInV32WithWrongDefaultAndRef() { + verifyV32("with-wrong-default-and-ref"); + } + + @Test + public void verifyInV3With204Response() { + verifyV3("with-204-response"); + } + @Test + public void verifyInV31With204Response() { + verifyV31("with-204-response"); + } + @Test + public void verifyInV32With204Response() { + verifyV32("with-204-response"); + } + + @Test + public void verifyInV3WithExternalRef() { + verifyV3("with-external-ref"); + } + @Override public void verifyRule() { assertRuleProperties("OAR010 - DefaultResponseMediaType - Should indicate the default response media type", RuleType.BUG, Severity.MINOR, tags("format")); diff --git a/src/test/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheckTest.java b/src/test/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheckTest.java index c1c619a2..155db84d 100644 --- a/src/test/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheckTest.java +++ b/src/test/java/apiaddicts/sonar/openapi/checks/parameters/OAR026TotalParameterDefaultValueCheckTest.java @@ -63,6 +63,21 @@ public void verifyInV2WithoutParameters() { verifyV2("without-parameters"); } + @Test + public void verifyInV2PostOperationWith$total() { + verifyV2("post-with-$total-with-defval-true"); + } + + @Test + public void verifyInV2HeaderParamWith$total() { + verifyV2("header-with-$total-with-defval-true"); + } + + @Test + public void verifyInV2With$refUnreferencedWith$total() { + verifyV2("with-$ref-unreferenced-with-$total-with-defval-true"); + } + @Test public void verifyInV3With$totalWithDefvalFalse() { verifyV3("plain-with-$total-with-defval-false"); @@ -107,15 +122,142 @@ public void verifyInV2WithoutParameters() { public void verifyInV3WithoutParameters() { verifyV3("without-parameters"); } + + @Test + public void verifyInV3PostOperationWith$total() { + verifyV3("post-with-$total-with-defval-true"); + } + + @Test + public void verifyInV3HeaderParamWith$total() { + verifyV3("header-with-$total-with-defval-true"); + } + + @Test + public void verifyInV3With$refUnreferencedWith$total() { + verifyV3("with-$ref-unreferenced-with-$total-with-defval-true"); + } + + @Test + public void verifyInV31With$totalWithDefvalFalse() { + verifyV31("plain-with-$total-with-defval-false"); + } + + @Test + public void verifyInV31With$totalWithDefvalTrue() { + verifyV31("plain-with-$total-with-defval-true"); + } + + @Test + public void verifyInV31With$totalWithoutDefval() { + verifyV31("plain-with-$total-without-defval"); + } + + @Test + public void verifyInV31Without$total() { + verifyV31("plain-without-$total"); + } + + @Test + public void verifyInV31With$refWith$totalWithDefvalFalse() { + verifyV31("with-$ref-with-$total-with-defval-false"); + } + + @Test + public void verifyInV31With$refWith$totalWithDefvalTrue() { + verifyV31("with-$ref-with-$total-with-defval-true"); + } + + @Test + public void verifyInV31With$refWith$totalWithoutDefval() { + verifyV31("with-$ref-with-$total-without-defval"); + } + + @Test + public void verifyInV31With$refWithout$total() { + verifyV31("with-$ref-without-$total"); + } + @Test public void verifyInV31WithoutParameters() { verifyV31("without-parameters"); } + + @Test + public void verifyInV31PostOperationWith$total() { + verifyV31("post-with-$total-with-defval-true"); + } + + @Test + public void verifyInV31HeaderParamWith$total() { + verifyV31("header-with-$total-with-defval-true"); + } + + @Test + public void verifyInV31With$refUnreferencedWith$total() { + verifyV31("with-$ref-unreferenced-with-$total-with-defval-true"); + } + + @Test + public void verifyInV32With$totalWithDefvalFalse() { + verifyV32("plain-with-$total-with-defval-false"); + } + + @Test + public void verifyInV32With$totalWithDefvalTrue() { + verifyV32("plain-with-$total-with-defval-true"); + } + + @Test + public void verifyInV32With$totalWithoutDefval() { + verifyV32("plain-with-$total-without-defval"); + } + + @Test + public void verifyInV32Without$total() { + verifyV32("plain-without-$total"); + } + + @Test + public void verifyInV32With$refWith$totalWithDefvalFalse() { + verifyV32("with-$ref-with-$total-with-defval-false"); + } + + @Test + public void verifyInV32With$refWith$totalWithDefvalTrue() { + verifyV32("with-$ref-with-$total-with-defval-true"); + } + + @Test + public void verifyInV32With$refWith$totalWithoutDefval() { + verifyV32("with-$ref-with-$total-without-defval"); + } + + @Test + public void verifyInV32With$refWithout$total() { + verifyV32("with-$ref-without-$total"); + } + @Test public void verifyInV32WithoutParameters() { verifyV32("without-parameters"); } + @Test + public void verifyInV32PostOperationWith$total() { + verifyV32("post-with-$total-with-defval-true"); + } + + @Test + public void verifyInV32HeaderParamWith$total() { + verifyV32("header-with-$total-with-defval-true"); + } + + @Test + public void verifyInV32With$refUnreferencedWith$total() { + verifyV32("with-$ref-unreferenced-with-$total-with-defval-true"); + } + @Override public void verifyRule() { assertRuleProperties("OAR026 - TotalParameterDefaultValue - The $total parameter default value should be false", RuleType.BUG, Severity.CRITICAL, tags("parameters")); diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.json b/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.json new file mode 100644 index 00000000..ea7a8928 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.json @@ -0,0 +1,241 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "2.1.0", + "title" : "Retail Storefront API", + "description" : "Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration." + }, + "paths" : { + "/catalog/products" : { + "get" : { + "operationId" : "get_catalog_products", + "summary" : "List products", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "post" : { + "operationId" : "post_catalog_products", + "summary" : "Create a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/catalog/products/{productId}" : { + "get" : { + "operationId" : "get_catalog_products_productId", + "summary" : "Get a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "put" : { + "operationId" : "put_catalog_products_productId", + "summary" : "Replace a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + }, + "delete" : { + "operationId" : "delete_catalog_products_productId", + "summary" : "Delete a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/orders" : { + "get" : { + "operationId" : "get_orders", + "summary" : "List orders", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "post" : { + "operationId" : "post_orders", + "summary" : "Place an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/orders/{orderId}" : { + "get" : { + "operationId" : "get_orders_orderId", + "summary" : "Get an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "delete" : { + "operationId" : "delete_orders_orderId", + "summary" : "Cancel an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/account/profile" : { + "get" : { + "operationId" : "get_account_profile", + "summary" : "Get the caller's profile", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_READ" + }, + "put" : { + "operationId" : "put_account_profile", + "summary" : "Update the caller's profile - undeclared scope", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_WRITE" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + }, + "/admin/users" : { + "get" : { + "operationId" : "get_admin_users", + "summary" : "List platform users - matches key not name", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "admin_all" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "operationId" : "post_admin_users", + "summary" : "Create a platform user", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + }, + "/admin/audit-log" : { + "get" : { + "operationId" : "get_admin_audit-log", + "summary" : "Read the audit log", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "CATALOG_SC_READ", + "key" : "catalog_read", + "roles" : "ROLE_CATALOG_READ", + "description" : "Allows users to browse the product catalog" + }, { + "name" : "CATALOG_SC_WRITE", + "key" : "catalog_write", + "roles" : "ROLE_CATALOG_WRITE", + "description" : "Allows users to create or update products" + }, { + "name" : "ORDERS_SC_READ", + "key" : "orders_read", + "roles" : "ROLE_ORDERS_READ", + "description" : "Allows users to view orders" + }, { + "name" : "ORDERS_SC_WRITE", + "key" : "orders_write", + "roles" : "ROLE_ORDERS_WRITE", + "description" : "Allows users to place or cancel orders" + }, { + "name" : "ACCOUNT_SC_READ", + "key" : "account_read", + "roles" : "ROLE_ACCOUNT_READ", + "description" : "Allows users to view their own account" + }, { + "name" : "ADMIN_SC_ALL", + "key" : "admin_all", + "roles" : "ROLE_ADMIN", + "description" : "Full administrative access" + } ] + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.yaml new file mode 100644 index 00000000..1477fc6a --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/extensive-api.yaml @@ -0,0 +1,167 @@ +swagger: "2.0" +info: + version: 2.1.0 + title: Retail Storefront API + description: Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration. +paths: + /catalog/products: + get: + operationId: get_catalog_products + summary: List products + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + post: + operationId: post_catalog_products + summary: Create a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /catalog/products/{productId}: + get: + operationId: get_catalog_products_productId + summary: Get a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + put: + operationId: put_catalog_products_productId + summary: Replace a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + delete: + operationId: delete_catalog_products_productId + summary: Delete a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /orders: + get: + operationId: get_orders + summary: List orders + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + post: + operationId: post_orders + summary: Place an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /orders/{orderId}: + get: + operationId: get_orders_orderId + summary: Get an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + delete: + operationId: delete_orders_orderId + summary: Cancel an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /account/profile: + get: + operationId: get_account_profile + summary: Get the caller's profile + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_READ + put: + operationId: put_account_profile + summary: Update the caller's profile - undeclared scope + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_WRITE # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /admin/users: + get: + operationId: get_admin_users + summary: List platform users - matches key not name + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: admin_all # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + operationId: post_admin_users + summary: Create a platform user + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + /admin/audit-log: + get: + operationId: get_admin_audit-log + summary: Read the audit log + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + +x-wso2-security: + apim: + x-wso2-scopes: + - name: CATALOG_SC_READ + key: catalog_read + roles: ROLE_CATALOG_READ + description: Allows users to browse the product catalog + - name: CATALOG_SC_WRITE + key: catalog_write + roles: ROLE_CATALOG_WRITE + description: Allows users to create or update products + - name: ORDERS_SC_READ + key: orders_read + roles: ROLE_ORDERS_READ + description: Allows users to view orders + - name: ORDERS_SC_WRITE + key: orders_write + roles: ROLE_ORDERS_WRITE + description: Allows users to place or cancel orders + - name: ACCOUNT_SC_READ + key: account_read + roles: ROLE_ACCOUNT_READ + description: Allows users to view their own account + - name: ADMIN_SC_ALL + key: admin_all + roles: ROLE_ADMIN + description: Full administrative access diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.json new file mode 100644 index 00000000..9f34cfee --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.json @@ -0,0 +1,77 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "options" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "head" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "patch" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.yaml new file mode 100644 index 00000000..358bc36f --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-all-verbs.yaml @@ -0,0 +1,49 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + patch: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.json new file mode 100644 index 00000000..c4866112 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.json @@ -0,0 +1,50 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/alias" + }, + "x-wso2-definitions" : { + "alias" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.yaml new file mode 100644 index 00000000..c80432d1 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-chained-ref-security.yaml @@ -0,0 +1,33 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/alias" +x-wso2-definitions: + alias: + $ref: "#/x-wso2-definitions/security" + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.json new file mode 100644 index 00000000..2038f1e4 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.json @@ -0,0 +1,55 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "$ref" : "#/x-wso2-definitions/scopeTwo" + } ] + } + }, + "x-wso2-definitions" : { + "scopeTwo" : { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.yaml new file mode 100644 index 00000000..6e21fea4 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-scope.yaml @@ -0,0 +1,36 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one + post: + responses: + 200: + description: Ok + x-scope: scope_two + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - $ref: "#/x-wso2-definitions/scopeTwo" +x-wso2-definitions: + scopeTwo: + name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.json new file mode 100644 index 00000000..498b2903 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.json @@ -0,0 +1,47 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "x-wso2-definitions" : { + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.yaml new file mode 100644 index 00000000..1f5d9318 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-ref-security.yaml @@ -0,0 +1,31 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/security" +x-wso2-definitions: + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.json new file mode 100644 index 00000000..82040f6b --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.json @@ -0,0 +1,37 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "catalogue_read" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "catalogue_read", + "description" : "catalogue_read", + "key" : "read", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.yaml new file mode 100644 index 00000000..aa81780b --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scope-key-not-name.yaml @@ -0,0 +1,24 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: catalogue_read + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: catalogue_read + description: catalogue_read + key: read + roles: role_one diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.json b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.json new file mode 100644 index 00000000..ffb790f6 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.json @@ -0,0 +1,66 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read_scope" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "write_scope" + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : { + "read" : { + "name" : "read_scope", + "key" : "read", + "roles" : "ROLE_READ", + "description" : "Allows users to read the catalogue" + }, + "write" : { + "$ref" : "#/x-wso2-definitions/writeScope" + } + } + } + }, + "x-wso2-definitions" : { + "writeScope" : { + "name" : "write_scope", + "key" : "write", + "roles" : "ROLE_WRITE", + "description" : "Allows users to write the catalogue" + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.yaml new file mode 100644 index 00000000..4fce63a7 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/with-scopes-as-map.yaml @@ -0,0 +1,43 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: read_scope + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: write_scope + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + read: + name: read_scope + key: read + roles: ROLE_READ + description: Allows users to read the catalogue + write: + $ref: "#/x-wso2-definitions/writeScope" +x-wso2-definitions: + writeScope: + name: write_scope + key: write + roles: ROLE_WRITE + description: Allows users to write the catalogue diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.json b/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.json new file mode 100644 index 00000000..ed4974f3 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.json @@ -0,0 +1,26 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.yaml b/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.yaml new file mode 100644 index 00000000..9eaae866 --- /dev/null +++ b/src/test/resources/checks/v2/apim/wso2/OAR005/without-security.yaml @@ -0,0 +1,15 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v2/examples/OAR031/allof-schema-missing-example.yaml b/src/test/resources/checks/v2/examples/OAR031/allof-schema-missing-example.yaml new file mode 100644 index 00000000..fbf92f9a --- /dev/null +++ b/src/test/resources/checks/v2/examples/OAR031/allof-schema-missing-example.yaml @@ -0,0 +1,28 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +definitions: + BaseEntity: + type: object + properties: + id: # Noncompliant {{OAR031: Property 'id' is missing an example.}} + type: integer + Pet: + allOf: + - $ref: '#/definitions/BaseEntity' + properties: + name: + type: string + example: "Fluffy" +paths: + /pets: + get: + responses: + 200: + description: Ok + schema: + $ref: '#/definitions/Pet' + examples: + application/json: + name: Fluffy diff --git a/src/test/resources/checks/v2/examples/OAR031/externalref.yaml b/src/test/resources/checks/v2/examples/OAR031/externalref.yaml index 18b488c1..102e8d94 100644 --- a/src/test/resources/checks/v2/examples/OAR031/externalref.yaml +++ b/src/test/resources/checks/v2/examples/OAR031/externalref.yaml @@ -10,14 +10,14 @@ paths: /users: get: responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: OK schema: type: array items: $ref: '#/definitions/User' 400: - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response /users/{userId}: get: @@ -27,7 +27,7 @@ paths: required: true type: string responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: A single user schema: $ref: '#/definitions/User' @@ -41,8 +41,10 @@ definitions: name: type: string example: "John" + # `Error` is intentionally never referenced by any path: it exercises the + # orphan-schema exclusion (property-level checks only cover reachable schemas). Error: type: object properties: - message: # Noncompliant {{OAR031: Properties must have an example defined}} + message: type: string \ No newline at end of file diff --git a/src/test/resources/checks/v2/examples/OAR031/nested-properties-examples.yaml b/src/test/resources/checks/v2/examples/OAR031/nested-properties-examples.yaml index 6b0b4816..defbd10c 100644 --- a/src/test/resources/checks/v2/examples/OAR031/nested-properties-examples.yaml +++ b/src/test/resources/checks/v2/examples/OAR031/nested-properties-examples.yaml @@ -6,7 +6,7 @@ paths: /profile: put: parameters: - - name: body # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + - name: body # Noncompliant {{OAR031: Parameter 'body' must have an example defined}} in: body required: true schema: @@ -34,5 +34,5 @@ paths: type: string example: "28001" responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: OK \ No newline at end of file diff --git a/src/test/resources/checks/v2/examples/OAR031/orphan-schema.yaml b/src/test/resources/checks/v2/examples/OAR031/orphan-schema.yaml new file mode 100644 index 00000000..f4f1f1dd --- /dev/null +++ b/src/test/resources/checks/v2/examples/OAR031/orphan-schema.yaml @@ -0,0 +1,28 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + schema: + $ref: '#/definitions/pet' + examples: + application/json: + name: Fluffy +definitions: + pet: + type: object + properties: + name: + type: string + example: "Fluffy" + # Never referenced by any path - must not be flagged (orphan-schema exclusion). + UnusedSchema: + type: object + properties: + unused_field: + type: string diff --git a/src/test/resources/checks/v2/examples/OAR031/valid.json b/src/test/resources/checks/v2/examples/OAR031/valid.json index ae8000e6..ed1ab2da 100644 --- a/src/test/resources/checks/v2/examples/OAR031/valid.json +++ b/src/test/resources/checks/v2/examples/OAR031/valid.json @@ -84,7 +84,7 @@ } }, "responses" : { - "server_error_response" : { # Noncompliant {{OAR031: Responses must have one or more examples defined}} + "server_error_response" : { # Noncompliant {{OAR031: Response must have an example defined}} "description" : "Default error response", "schema" : { "type" : "object", diff --git a/src/test/resources/checks/v2/examples/OAR031/without-examples.json b/src/test/resources/checks/v2/examples/OAR031/without-examples.json index 4e6beec9..c38288bd 100644 --- a/src/test/resources/checks/v2/examples/OAR031/without-examples.json +++ b/src/test/resources/checks/v2/examples/OAR031/without-examples.json @@ -11,7 +11,7 @@ "204": { "description": "No content" }, - "206" : { # Noncompliant {{OAR031: Responses must have one or more examples defined}} + "206" : { # Noncompliant {{OAR031: Response must have an example defined}} "description" : "Pet list", "schema" : { "$ref" : "#/definitions/pets" @@ -29,7 +29,7 @@ "$ref" : "#/parameters/id" } ], "responses" : { - "200" : { # Noncompliant {{OAR031: Responses must have one or more examples defined}} + "200" : { # Noncompliant {{OAR031: Response must have an example defined}} "description" : "One pet", "schema" : { "$ref" : "#/definitions/pet" @@ -57,10 +57,10 @@ "pet" : { "type" : "object", "properties" : { - "name" : { # Noncompliant {{OAR031: Properties must have an example defined}} + "name" : { # Noncompliant {{OAR031: Property 'name' is missing an example.}} "type" : "string" }, - "type" : { # Noncompliant {{OAR031: Properties must have an example defined}} + "type" : { # Noncompliant {{OAR031: Property 'type' is missing an example.}} "type" : "string" } } @@ -68,7 +68,7 @@ "pets" : { "type" : "object", "properties" : { - "size" : { # Noncompliant {{OAR031: Properties must have an example defined}} + "size" : { # Noncompliant {{OAR031: Property 'size' is missing an example.}} "type" : "integer" }, "pets" : { @@ -81,12 +81,12 @@ } }, "responses" : { - "server_error_response" : { # Noncompliant {{OAR031: Responses must have one or more examples defined}} + "server_error_response" : { # Noncompliant {{OAR031: Response must have an example defined}} "description" : "Default error response", "schema" : { "type" : "object", "properties" : { - "error" : { # Noncompliant {{OAR031: Properties must have an example defined}} + "error" : { # Noncompliant {{OAR031: Property 'error' is missing an example.}} "type" : "string" } } diff --git a/src/test/resources/checks/v2/examples/OAR031/without-examples.yaml b/src/test/resources/checks/v2/examples/OAR031/without-examples.yaml index cfb67cc7..8f2e2edf 100644 --- a/src/test/resources/checks/v2/examples/OAR031/without-examples.yaml +++ b/src/test/resources/checks/v2/examples/OAR031/without-examples.yaml @@ -8,7 +8,7 @@ paths: responses: 204: description: No content - 206: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 206: # Noncompliant {{OAR031: Response must have an example defined}} description: Pet list schema: $ref: '#/definitions/pets' @@ -19,7 +19,7 @@ paths: parameters: - $ref: "#/parameters/id" responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: One pet schema: $ref: "#/definitions/pet" @@ -39,24 +39,24 @@ definitions: pet: type: object properties: - name: # Noncompliant {{OAR031: Properties must have an example defined}} + name: # Noncompliant {{OAR031: Property 'name' is missing an example.}} type: string - type: # Noncompliant {{OAR031: Properties must have an example defined}} + type: # Noncompliant {{OAR031: Property 'type' is missing an example.}} type: string pets: type: object properties: - size: # Noncompliant {{OAR031: Properties must have an example defined}} + size: # Noncompliant {{OAR031: Property 'size' is missing an example.}} type: integer pets: type: array items: $ref: '#/definitions/pet' responses: - server_error_response: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + server_error_response: # Noncompliant {{OAR031: Response must have an example defined}} description: Default error response schema: type: object properties: - error: # Noncompliant {{OAR031: Properties must have an example defined}} + error: # Noncompliant {{OAR031: Property 'error' is missing an example.}} type: string \ No newline at end of file diff --git a/src/test/resources/checks/v2/format/OAR007/with-specific-put.json b/src/test/resources/checks/v2/format/OAR007/with-specific-put.json new file mode 100644 index 00000000..8b798cb3 --- /dev/null +++ b/src/test/resources/checks/v2/format/OAR007/with-specific-put.json @@ -0,0 +1,21 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/format/OAR007/with-specific-put.yaml b/src/test/resources/checks/v2/format/OAR007/with-specific-put.yaml new file mode 100644 index 00000000..21362e15 --- /dev/null +++ b/src/test/resources/checks/v2/format/OAR007/with-specific-put.yaml @@ -0,0 +1,13 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + +paths: + /pets: + put: + produces: + - application/json + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.json b/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.json new file mode 100644 index 00000000..30267930 --- /dev/null +++ b/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.json @@ -0,0 +1,21 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "produces": [ + "Application/JSON" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.yaml b/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.yaml new file mode 100644 index 00000000..c954d326 --- /dev/null +++ b/src/test/resources/checks/v2/format/OAR010/with-default-mixed-case.yaml @@ -0,0 +1,13 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + +paths: + /pets: + post: + produces: + - Application/JSON + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.json b/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.json new file mode 100644 index 00000000..c8e9d445 --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.json @@ -0,0 +1,24 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "parameters" : [ { + "in" : "header", + "name" : "$total", + "type" : "boolean", + "default" : true + } ], + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.yaml b/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..6a2b4dfd --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/header-with-$total-with-defval-true.yaml @@ -0,0 +1,15 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + parameters: + - in: header + name: $total + type: boolean + default: true + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.json b/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.json index 75b84003..1eae98e3 100644 --- a/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.json +++ b/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.json @@ -14,7 +14,7 @@ "items" : { "type" : "string" } - }, { # Noncompliant {{OAR026: The $total parameter default value should be false}} + }, { "in" : "query", "name" : "$total", "type" : "boolean" diff --git a/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.yaml b/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.yaml index b3f78a09..8c52f6e3 100644 --- a/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v2/parameters/OAR026/plain-with-$total-without-defval.yaml @@ -11,7 +11,7 @@ paths: type: array items: type: string - - in: query # Noncompliant {{OAR026: The $total parameter default value should be false}} + - in: query name: $total type: boolean responses: diff --git a/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.json b/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.json new file mode 100644 index 00000000..83837ae9 --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.json @@ -0,0 +1,24 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "post" : { + "parameters" : [ { + "in" : "query", + "name" : "$total", + "type" : "boolean", + "default" : true + } ], + "responses" : { + "201" : { + "description" : "Created" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.yaml b/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..ee010c1e --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/post-with-$total-with-defval-true.yaml @@ -0,0 +1,15 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + parameters: + - in: query + name: $total + type: boolean + default: true + responses: + 201: + description: Created diff --git a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json new file mode 100644 index 00000000..45ec80db --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "parameters" : { + "total" : { + "in" : "query", + "name" : "$total", + "type" : "boolean", + "default" : true + } + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..5de71af2 --- /dev/null +++ b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore +parameters: + total: + in: query + name: $total + type: boolean + default: true +paths: + /pets: + get: + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.json b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.json index 7c43ee1c..52632ee9 100644 --- a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.json +++ b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.json @@ -13,7 +13,7 @@ "type" : "string" } }, - "total" : { # Noncompliant {{OAR026: The $total parameter default value should be false}} + "total" : { "in" : "query", "name" : "$total", "type" : "boolean" diff --git a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.yaml b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.yaml index 9c6b56e2..663e7277 100644 --- a/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v2/parameters/OAR026/with-$ref-with-$total-without-defval.yaml @@ -9,7 +9,7 @@ parameters: type: array items: type: string - total: # Noncompliant {{OAR026: The $total parameter default value should be false}} + total: in: query name: $total type: boolean diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.json b/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.json new file mode 100644 index 00000000..62484806 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.json @@ -0,0 +1,241 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "2.1.0", + "title" : "Retail Storefront API", + "description" : "Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration." + }, + "paths" : { + "/catalog/products" : { + "get" : { + "operationId" : "get_catalog_products", + "summary" : "List products", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "post" : { + "operationId" : "post_catalog_products", + "summary" : "Create a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/catalog/products/{productId}" : { + "get" : { + "operationId" : "get_catalog_products_productId", + "summary" : "Get a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "put" : { + "operationId" : "put_catalog_products_productId", + "summary" : "Replace a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + }, + "delete" : { + "operationId" : "delete_catalog_products_productId", + "summary" : "Delete a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/orders" : { + "get" : { + "operationId" : "get_orders", + "summary" : "List orders", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "post" : { + "operationId" : "post_orders", + "summary" : "Place an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/orders/{orderId}" : { + "get" : { + "operationId" : "get_orders_orderId", + "summary" : "Get an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "delete" : { + "operationId" : "delete_orders_orderId", + "summary" : "Cancel an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/account/profile" : { + "get" : { + "operationId" : "get_account_profile", + "summary" : "Get the caller's profile", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_READ" + }, + "put" : { + "operationId" : "put_account_profile", + "summary" : "Update the caller's profile - undeclared scope", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_WRITE" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + }, + "/admin/users" : { + "get" : { + "operationId" : "get_admin_users", + "summary" : "List platform users - matches key not name", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "admin_all" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "operationId" : "post_admin_users", + "summary" : "Create a platform user", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + }, + "/admin/audit-log" : { + "get" : { + "operationId" : "get_admin_audit-log", + "summary" : "Read the audit log", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "CATALOG_SC_READ", + "key" : "catalog_read", + "roles" : "ROLE_CATALOG_READ", + "description" : "Allows users to browse the product catalog" + }, { + "name" : "CATALOG_SC_WRITE", + "key" : "catalog_write", + "roles" : "ROLE_CATALOG_WRITE", + "description" : "Allows users to create or update products" + }, { + "name" : "ORDERS_SC_READ", + "key" : "orders_read", + "roles" : "ROLE_ORDERS_READ", + "description" : "Allows users to view orders" + }, { + "name" : "ORDERS_SC_WRITE", + "key" : "orders_write", + "roles" : "ROLE_ORDERS_WRITE", + "description" : "Allows users to place or cancel orders" + }, { + "name" : "ACCOUNT_SC_READ", + "key" : "account_read", + "roles" : "ROLE_ACCOUNT_READ", + "description" : "Allows users to view their own account" + }, { + "name" : "ADMIN_SC_ALL", + "key" : "admin_all", + "roles" : "ROLE_ADMIN", + "description" : "Full administrative access" + } ] + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.yaml new file mode 100644 index 00000000..669fc5ad --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/extensive-api.yaml @@ -0,0 +1,167 @@ +openapi: "3.0.0" +info: + version: 2.1.0 + title: Retail Storefront API + description: Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration. +paths: + /catalog/products: + get: + operationId: get_catalog_products + summary: List products + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + post: + operationId: post_catalog_products + summary: Create a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /catalog/products/{productId}: + get: + operationId: get_catalog_products_productId + summary: Get a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + put: + operationId: put_catalog_products_productId + summary: Replace a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + delete: + operationId: delete_catalog_products_productId + summary: Delete a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /orders: + get: + operationId: get_orders + summary: List orders + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + post: + operationId: post_orders + summary: Place an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /orders/{orderId}: + get: + operationId: get_orders_orderId + summary: Get an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + delete: + operationId: delete_orders_orderId + summary: Cancel an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /account/profile: + get: + operationId: get_account_profile + summary: Get the caller's profile + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_READ + put: + operationId: put_account_profile + summary: Update the caller's profile - undeclared scope + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_WRITE # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /admin/users: + get: + operationId: get_admin_users + summary: List platform users - matches key not name + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: admin_all # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + operationId: post_admin_users + summary: Create a platform user + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + /admin/audit-log: + get: + operationId: get_admin_audit-log + summary: Read the audit log + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + +x-wso2-security: + apim: + x-wso2-scopes: + - name: CATALOG_SC_READ + key: catalog_read + roles: ROLE_CATALOG_READ + description: Allows users to browse the product catalog + - name: CATALOG_SC_WRITE + key: catalog_write + roles: ROLE_CATALOG_WRITE + description: Allows users to create or update products + - name: ORDERS_SC_READ + key: orders_read + roles: ROLE_ORDERS_READ + description: Allows users to view orders + - name: ORDERS_SC_WRITE + key: orders_write + roles: ROLE_ORDERS_WRITE + description: Allows users to place or cancel orders + - name: ACCOUNT_SC_READ + key: account_read + roles: ROLE_ACCOUNT_READ + description: Allows users to view their own account + - name: ADMIN_SC_ALL + key: admin_all + roles: ROLE_ADMIN + description: Full administrative access diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.json new file mode 100644 index 00000000..f5588a67 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.json @@ -0,0 +1,85 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "options" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "head" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "patch" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "trace" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.yaml new file mode 100644 index 00000000..50261884 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-all-verbs.yaml @@ -0,0 +1,54 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + patch: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + trace: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-array-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-array-security.yaml new file mode 100644 index 00000000..64e6a744 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-array-security.yaml @@ -0,0 +1,18 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: [] + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.json new file mode 100644 index 00000000..e3da2608 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.json @@ -0,0 +1,72 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one", + "callbacks" : { + "onEvent" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five", # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + "callbacks" : { + "onNested" : { + "'{$request.body#/nestedUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + } + } + } + } + } + } + }, + "components" : { + "callbacks" : { + "sharedCallback" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.yaml new file mode 100644 index 00000000..6077bdbd --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-callback-operations.yaml @@ -0,0 +1,43 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + post: + responses: + 200: + description: Ok + x-scope: scope_one + callbacks: + onEvent: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + callbacks: + onNested: + '{$request.body#/nestedUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} +components: + callbacks: + sharedCallback: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.json new file mode 100644 index 00000000..260b93ae --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.json @@ -0,0 +1,50 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/alias" + }, + "x-wso2-definitions" : { + "alias" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.yaml new file mode 100644 index 00000000..d1c9cff1 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-chained-ref-security.yaml @@ -0,0 +1,33 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/alias" +x-wso2-definitions: + alias: + $ref: "#/x-wso2-definitions/security" + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-cyclic-ref-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-cyclic-ref-security.yaml new file mode 100644 index 00000000..92925adc --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-cyclic-ref-security.yaml @@ -0,0 +1,24 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + $ref: "#/x-wso2-definitions/securityA" +x-wso2-definitions: + securityA: + $ref: "#/x-wso2-definitions/securityB" + securityB: + $ref: "#/x-wso2-definitions/securityA" + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-dangling-ref-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-dangling-ref-security.yaml new file mode 100644 index 00000000..01fd7d47 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-dangling-ref-security.yaml @@ -0,0 +1,26 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + $ref: "#/x-wso2-definitions/missing" +x-wso2-definitions: + present: + apim: + x-wso2-scopes: + - name: scope_other + key: scope_other + roles: role_other + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-array-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-array-scopes.yaml new file mode 100644 index 00000000..8d2f3826 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-array-scopes.yaml @@ -0,0 +1,20 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: + x-wso2-scopes: [] + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-object-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-object-scopes.yaml new file mode 100644 index 00000000..e815be8b --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-empty-object-scopes.yaml @@ -0,0 +1,20 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: + x-wso2-scopes: {} + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-malformed-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-malformed-scopes.yaml new file mode 100644 index 00000000..6e03e645 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-malformed-scopes.yaml @@ -0,0 +1,57 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one + put: + responses: + 200: + description: Ok + x-scope: no_name # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: null_name # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: empty_name # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: plain_scalar_element # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: array_element # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one + description: A well formed scope + - key: no_name + roles: role_two + description: No name property at all + - name: null + key: null_name + roles: role_three + description: Null name + - name: + key: empty_name + roles: role_four + description: Name with no value + - plain_scalar_element + - [array_element] diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-apim.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-apim.yaml new file mode 100644 index 00000000..ff80f556 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-apim.yaml @@ -0,0 +1,19 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: null + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-scopes.yaml new file mode 100644 index 00000000..50a7649a --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-scopes.yaml @@ -0,0 +1,20 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: + x-wso2-scopes: null + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-security.yaml new file mode 100644 index 00000000..56297463 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-null-security.yaml @@ -0,0 +1,18 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: null + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.json new file mode 100644 index 00000000..93e31a8d --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.json @@ -0,0 +1,55 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "$ref" : "#/x-wso2-definitions/scopeTwo" + } ] + } + }, + "x-wso2-definitions" : { + "scopeTwo" : { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.yaml new file mode 100644 index 00000000..e9272308 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-scope.yaml @@ -0,0 +1,36 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one + post: + responses: + 200: + description: Ok + x-scope: scope_two + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - $ref: "#/x-wso2-definitions/scopeTwo" +x-wso2-definitions: + scopeTwo: + name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.json new file mode 100644 index 00000000..8d4b2f83 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.json @@ -0,0 +1,47 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "x-wso2-definitions" : { + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.yaml new file mode 100644 index 00000000..58cec9c0 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-ref-security.yaml @@ -0,0 +1,31 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/security" +x-wso2-definitions: + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-scopes.yaml new file mode 100644 index 00000000..73621af2 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-scopes.yaml @@ -0,0 +1,20 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: + x-wso2-scopes: read + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-security.yaml new file mode 100644 index 00000000..b6380e7f --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scalar-security.yaml @@ -0,0 +1,18 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: none + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.json new file mode 100644 index 00000000..38dafeb3 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.json @@ -0,0 +1,37 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "catalogue_read" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "catalogue_read", + "description" : "catalogue_read", + "key" : "read", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.yaml new file mode 100644 index 00000000..dfe73644 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scope-key-not-name.yaml @@ -0,0 +1,24 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: catalogue_read + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: catalogue_read + description: catalogue_read + key: read + roles: role_one diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.json b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.json new file mode 100644 index 00000000..612864ed --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.json @@ -0,0 +1,66 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read_scope" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "write_scope" + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : { + "read" : { + "name" : "read_scope", + "key" : "read", + "roles" : "ROLE_READ", + "description" : "Allows users to read the catalogue" + }, + "write" : { + "$ref" : "#/x-wso2-definitions/writeScope" + } + } + } + }, + "x-wso2-definitions" : { + "writeScope" : { + "name" : "write_scope", + "key" : "write", + "roles" : "ROLE_WRITE", + "description" : "Allows users to write the catalogue" + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.yaml new file mode 100644 index 00000000..ed635286 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-scopes-as-map.yaml @@ -0,0 +1,43 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: read_scope + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: write_scope + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + read: + name: read_scope + key: read + roles: ROLE_READ + description: Allows users to read the catalogue + write: + $ref: "#/x-wso2-definitions/writeScope" +x-wso2-definitions: + writeScope: + name: write_scope + key: write + roles: ROLE_WRITE + description: Allows users to write the catalogue diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-block-collections.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-block-collections.yaml new file mode 100644 index 00000000..6267f884 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-block-collections.yaml @@ -0,0 +1,25 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: + - scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: + name: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-collections.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-collections.yaml new file mode 100644 index 00000000..b39e467b --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-collections.yaml @@ -0,0 +1,33 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: [] # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: {} # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: [scope_one] # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: {name: scope_one} # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-null-spellings.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-null-spellings.yaml new file mode 100644 index 00000000..2b0f5e99 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-null-spellings.yaml @@ -0,0 +1,49 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: null # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: ~ # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: Null # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: NULL # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: "null" + head: + responses: + 200: + description: Ok + x-scope: + trace: + responses: + 200: + description: Ok + x-scope: "" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: "null" + key: quoted_null + roles: role_null + description: A scope whose name is the literal text null diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-scalar-types.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-scalar-types.yaml new file mode 100644 index 00000000..015fa8b7 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/with-x-scope-scalar-types.yaml @@ -0,0 +1,54 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one + put: + responses: + 200: + description: Ok + x-scope: "scope_one" + post: + responses: + 200: + description: Ok + x-scope: "" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: 42 + options: + responses: + 200: + description: Ok + x-scope: 7 # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: true + trace: + responses: + 200: + description: Ok + x-scope: false # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one + - name: 42 + key: num_scope + roles: role_num + - name: true + key: bool_scope + roles: role_bool diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/without-apim.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/without-apim.yaml new file mode 100644 index 00000000..8f7a667f --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/without-apim.yaml @@ -0,0 +1,20 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + other: + x-wso2-scopes: [] + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/without-scopes.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/without-scopes.yaml new file mode 100644 index 00000000..5421c457 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/without-scopes.yaml @@ -0,0 +1,19 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /b: + get: + responses: + 200: + description: Ok +x-wso2-security: + apim: {} + diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.json b/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.json new file mode 100644 index 00000000..33930da4 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.yaml b/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.yaml new file mode 100644 index 00000000..469e5f38 --- /dev/null +++ b/src/test/resources/checks/v3/apim/wso2/OAR005/without-security.yaml @@ -0,0 +1,15 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v3/examples/OAR031/allof-schema-missing-example.yaml b/src/test/resources/checks/v3/examples/OAR031/allof-schema-missing-example.yaml new file mode 100644 index 00000000..9080133a --- /dev/null +++ b/src/test/resources/checks/v3/examples/OAR031/allof-schema-missing-example.yaml @@ -0,0 +1,32 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + schemas: + BaseEntity: + type: object + properties: + id: # Noncompliant {{OAR031: Property 'id' is missing an example.}} + type: integer + Pet: + allOf: + - $ref: '#/components/schemas/BaseEntity' + properties: + name: + type: string + example: "Fluffy" +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + example: + name: Fluffy + 204: + description: No content diff --git a/src/test/resources/checks/v3/examples/OAR031/externalref.yaml b/src/test/resources/checks/v3/examples/OAR031/externalref.yaml index e747a397..24da3812 100644 --- a/src/test/resources/checks/v3/examples/OAR031/externalref.yaml +++ b/src/test/resources/checks/v3/examples/OAR031/externalref.yaml @@ -14,7 +14,7 @@ paths: summary: Get all users description: Returns a list of users. responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A JSON array of user objects content: application/json: @@ -23,7 +23,7 @@ paths: items: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response /users/{userId}: get: @@ -40,14 +40,14 @@ paths: name: Puppy type: dog responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A single user object content: application/json: schema: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response components: schemas: diff --git a/src/test/resources/checks/v3/examples/OAR031/nested-properties-examples.yaml b/src/test/resources/checks/v3/examples/OAR031/nested-properties-examples.yaml index 9a67dda1..0f027b25 100644 --- a/src/test/resources/checks/v3/examples/OAR031/nested-properties-examples.yaml +++ b/src/test/resources/checks/v3/examples/OAR031/nested-properties-examples.yaml @@ -6,7 +6,7 @@ paths: /profile: put: summary: Update user profile - requestBody: # Noncompliant {{OAR031: Request body must have one or more examples defined}} + requestBody: # Noncompliant {{OAR031: Request body must have an example defined}} required: true content: application/json: @@ -35,5 +35,5 @@ paths: type: string example: "28001" responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: OK \ No newline at end of file diff --git a/src/test/resources/checks/v3/examples/OAR031/orphan-schema.yaml b/src/test/resources/checks/v3/examples/OAR031/orphan-schema.yaml new file mode 100644 index 00000000..9ed22c0d --- /dev/null +++ b/src/test/resources/checks/v3/examples/OAR031/orphan-schema.yaml @@ -0,0 +1,32 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/pet' + example: + name: Fluffy + 204: + description: No content +components: + schemas: + pet: + type: object + properties: + name: + type: string + example: "Fluffy" + # Never referenced by any path - must not be flagged (orphan-schema exclusion). + UnusedSchema: + type: object + properties: + unused_field: + type: string diff --git a/src/test/resources/checks/v3/examples/OAR031/without-examples.yaml b/src/test/resources/checks/v3/examples/OAR031/without-examples.yaml index ec8cd2a0..eec0c9a7 100644 --- a/src/test/resources/checks/v3/examples/OAR031/without-examples.yaml +++ b/src/test/resources/checks/v3/examples/OAR031/without-examples.yaml @@ -6,7 +6,7 @@ paths: /pets: get: responses: - 206: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 206: # Noncompliant {{OAR031: Response must have an example defined}} description: Pet list content: application/json: @@ -16,7 +16,7 @@ paths: $ref: "#/components/responses/server_error_response" /pets/{id}: parameters: - - in: query # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + - in: query # Noncompliant {{OAR031: Parameter '$start' must have an example defined}} name: $start schema: type: integer @@ -24,7 +24,7 @@ paths: parameters: - $ref: "#/components/parameters/id" responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: One pet content: application/json: @@ -35,8 +35,8 @@ paths: components: parameters: - id: - in: path # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + id: # Noncompliant {{OAR031: Parameter 'id' must have an example defined}} + in: path name: id schema: type: integer @@ -48,26 +48,26 @@ components: pet: type: object properties: - name: # Noncompliant {{OAR031: Properties must have an example defined}} + name: # Noncompliant {{OAR031: Property 'name' is missing an example.}} type: string - type: # Noncompliant {{OAR031: Properties must have an example defined}} + type: # Noncompliant {{OAR031: Property 'type' is missing an example.}} type: string pets: type: object properties: - size: # Noncompliant {{OAR031: Properties must have an example defined}} + size: # Noncompliant {{OAR031: Property 'size' is missing an example.}} type: integer pets: type: array items: $ref: '#/components/schemas/pet' responses: - server_error_response: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + server_error_response: # Noncompliant {{OAR031: Response must have an example defined}} description: Default error response content: application/json: schema: type: object properties: - error: # Noncompliant {{OAR031: Properties must have an example defined}} + error: # Noncompliant {{OAR031: Property 'error' is missing an example.}} type: string \ No newline at end of file diff --git a/src/test/resources/checks/v3/format/OAR007/with-204-response.json b/src/test/resources/checks/v3/format/OAR007/with-204-response.json new file mode 100644 index 00000000..619f4f86 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-204-response.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-204-response.yaml b/src/test/resources/checks/v3/format/OAR007/with-204-response.yaml new file mode 100644 index 00000000..e323bc65 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-204-response.yaml @@ -0,0 +1,10 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v3/format/OAR007/with-chained-ref.json b/src/test/resources/checks/v3/format/OAR007/with-chained-ref.json new file mode 100644 index 00000000..9f44591c --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-chained-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "A": { + "$ref": "#/components/responses/B" + }, + "B": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/A" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-chained-ref.yaml b/src/test/resources/checks/v3/format/OAR007/with-chained-ref.yaml new file mode 100644 index 00000000..b507aa65 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-chained-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + A: + $ref: '#/components/responses/B' + B: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/A' diff --git a/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.json b/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.json new file mode 100644 index 00000000..d962e59d --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { + "description": "OK", + "content": { + "application/json": {} + } + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.yaml b/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.yaml new file mode 100644 index 00000000..c0fa3518 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: + description: OK + content: + application/json: {} +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v3/format/OAR007/with-default-response-key.json b/src/test/resources/checks/v3/format/OAR007/with-default-response-key.json new file mode 100644 index 00000000..c350e397 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-default-response-key.json @@ -0,0 +1,19 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "default": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Unexpected error", + "content": {} + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-default-response-key.yaml b/src/test/resources/checks/v3/format/OAR007/with-default-response-key.yaml new file mode 100644 index 00000000..b20f7779 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-default-response-key.yaml @@ -0,0 +1,11 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + default: # Noncompliant {{OAR007: Section content is mandatory}} + description: Unexpected error + content: {} diff --git a/src/test/resources/checks/v3/format/OAR007/with-external-ref.json b/src/test/resources/checks/v3/format/OAR007/with-external-ref.json new file mode 100644 index 00000000..f683b50d --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-external-ref.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-external-ref.yaml b/src/test/resources/checks/v3/format/OAR007/with-external-ref.yaml new file mode 100644 index 00000000..84ec98f9 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-external-ref.yaml @@ -0,0 +1,11 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + $ref: >- + http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse diff --git a/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.json b/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.json new file mode 100644 index 00000000..682a2222 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.json @@ -0,0 +1,53 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "get": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content" + } + } + }, + "post": { + "responses": { + "201": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Created" + } + } + } + }, + "/owners": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/xml": {} + } + }, + "400": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Bad Request" + } + } + }, + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.yaml b/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.yaml new file mode 100644 index 00000000..d6f3fb5f --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-multiple-operations.yaml @@ -0,0 +1,31 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + post: + responses: + '201': # Noncompliant {{OAR007: Section content is mandatory}} + description: Created + /owners: + put: + responses: + '200': + description: Ok + content: + application/xml: {} + '400': # Noncompliant {{OAR007: Section content is mandatory}} + description: Bad Request + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v3/format/OAR007/with-specific.json b/src/test/resources/checks/v3/format/OAR007/with-specific.json new file mode 100644 index 00000000..f32afc92 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-specific.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-specific.yaml b/src/test/resources/checks/v3/format/OAR007/with-specific.yaml new file mode 100644 index 00000000..ff100bb5 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-specific.yaml @@ -0,0 +1,12 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + description: Ok + content: + application/json: {} diff --git a/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.json b/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.json new file mode 100644 index 00000000..7d523b2e --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.json @@ -0,0 +1,25 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.yaml b/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.yaml new file mode 100644 index 00000000..6ff09a2e --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR007/with-wrong-ref.yaml @@ -0,0 +1,14 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v3/format/OAR010/with-204-response.json b/src/test/resources/checks/v3/format/OAR010/with-204-response.json new file mode 100644 index 00000000..b6328902 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-204-response.json @@ -0,0 +1,27 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content", + "content": { + "application/xml": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR010/with-204-response.yaml b/src/test/resources/checks/v3/format/OAR010/with-204-response.yaml new file mode 100644 index 00000000..257dd57b --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-204-response.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + content: + application/xml: {} diff --git a/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.json b/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.json new file mode 100644 index 00000000..8ced2d72 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "Application/JSON": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.yaml b/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.yaml new file mode 100644 index 00000000..5758d03b --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-default-mixed-case.yaml @@ -0,0 +1,12 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + Application/JSON: {} diff --git a/src/test/resources/checks/v3/format/OAR010/with-external-ref.json b/src/test/resources/checks/v3/format/OAR010/with-external-ref.json new file mode 100644 index 00000000..c5603828 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-external-ref.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "$ref": "http://localhost:18089/OAR010.yaml#/components/responses/SuccessResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR010/with-external-ref.yaml b/src/test/resources/checks/v3/format/OAR010/with-external-ref.yaml new file mode 100644 index 00000000..fa887704 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-external-ref.yaml @@ -0,0 +1,11 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + $ref: >- + http://localhost:18089/OAR010.yaml#/components/responses/SuccessResponse diff --git a/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.json b/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.json new file mode 100644 index 00000000..0d842352 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "XmlOnlyResponse": { + "description": "OK", + "content": { # Noncompliant {{OAR010: Should indicate the default response media type}} + "application/xml": {} + } + } + } + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "$ref": "#/components/responses/XmlOnlyResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.yaml b/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.yaml new file mode 100644 index 00000000..53a3b8e4 --- /dev/null +++ b/src/test/resources/checks/v3/format/OAR010/with-wrong-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + XmlOnlyResponse: + description: OK + content: # Noncompliant {{OAR010: Should indicate the default response media type}} + application/xml: {} +paths: + /pets: + post: + responses: + '200': + $ref: '#/components/responses/XmlOnlyResponse' diff --git a/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.json b/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.json new file mode 100644 index 00000000..5387f7ac --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "parameters" : [ { + "in" : "header", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.yaml b/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..e3a6097e --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/header-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + parameters: + - in: header + name: $total + schema: + type: boolean + default: true + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.json b/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.json index d756597f..46579305 100644 --- a/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.json +++ b/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.json @@ -16,7 +16,7 @@ "type" : "string" } } - }, { # Noncompliant {{OAR026: The $total parameter default value should be false}} + }, { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.yaml b/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.yaml index c2580dc0..c9eb7ad3 100644 --- a/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v3/parameters/OAR026/plain-with-$total-without-defval.yaml @@ -12,7 +12,7 @@ paths: type: array items: type: string - - in: query # Noncompliant {{OAR026: The $total parameter default value should be false}} + - in: query name: $total schema: type: boolean diff --git a/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.json b/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.json new file mode 100644 index 00000000..8366d62e --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "post" : { + "parameters" : [ { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "201" : { + "description" : "Created" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.yaml b/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..b1de7fb3 --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/post-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + parameters: + - in: query + name: $total + schema: + type: boolean + default: true + responses: + 201: + description: Created diff --git a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json new file mode 100644 index 00000000..7fd799f0 --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json @@ -0,0 +1,30 @@ +{ + "openapi" : "3.0.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "components" : { + "parameters" : { + "total" : { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } + } + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..ad5a0bbe --- /dev/null +++ b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml @@ -0,0 +1,18 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + parameters: + total: + in: query + name: $total + schema: + type: boolean + default: true +paths: + /pets: + get: + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.json b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.json index 9c5ef562..dc7533fc 100644 --- a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.json +++ b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.json @@ -16,7 +16,7 @@ } } }, - "total" : { # Noncompliant {{OAR026: The $total parameter default value should be false}} + "total" : { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.yaml b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.yaml index 68f5a74b..702bb880 100644 --- a/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v3/parameters/OAR026/with-$ref-with-$total-without-defval.yaml @@ -11,7 +11,7 @@ components: type: array items: type: string - total: # Noncompliant {{OAR026: The $total parameter default value should be false}} + total: in: query name: $total schema: diff --git a/src/test/resources/checks/v31/apim/OAR005/extensive-api.json b/src/test/resources/checks/v31/apim/OAR005/extensive-api.json new file mode 100644 index 00000000..1f4512a9 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/extensive-api.json @@ -0,0 +1,241 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "2.1.0", + "title" : "Retail Storefront API", + "description" : "Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration." + }, + "paths" : { + "/catalog/products" : { + "get" : { + "operationId" : "get_catalog_products", + "summary" : "List products", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "post" : { + "operationId" : "post_catalog_products", + "summary" : "Create a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/catalog/products/{productId}" : { + "get" : { + "operationId" : "get_catalog_products_productId", + "summary" : "Get a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "put" : { + "operationId" : "put_catalog_products_productId", + "summary" : "Replace a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + }, + "delete" : { + "operationId" : "delete_catalog_products_productId", + "summary" : "Delete a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/orders" : { + "get" : { + "operationId" : "get_orders", + "summary" : "List orders", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "post" : { + "operationId" : "post_orders", + "summary" : "Place an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/orders/{orderId}" : { + "get" : { + "operationId" : "get_orders_orderId", + "summary" : "Get an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "delete" : { + "operationId" : "delete_orders_orderId", + "summary" : "Cancel an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/account/profile" : { + "get" : { + "operationId" : "get_account_profile", + "summary" : "Get the caller's profile", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_READ" + }, + "put" : { + "operationId" : "put_account_profile", + "summary" : "Update the caller's profile - undeclared scope", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_WRITE" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + }, + "/admin/users" : { + "get" : { + "operationId" : "get_admin_users", + "summary" : "List platform users - matches key not name", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "admin_all" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "operationId" : "post_admin_users", + "summary" : "Create a platform user", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + }, + "/admin/audit-log" : { + "get" : { + "operationId" : "get_admin_audit-log", + "summary" : "Read the audit log", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "CATALOG_SC_READ", + "key" : "catalog_read", + "roles" : "ROLE_CATALOG_READ", + "description" : "Allows users to browse the product catalog" + }, { + "name" : "CATALOG_SC_WRITE", + "key" : "catalog_write", + "roles" : "ROLE_CATALOG_WRITE", + "description" : "Allows users to create or update products" + }, { + "name" : "ORDERS_SC_READ", + "key" : "orders_read", + "roles" : "ROLE_ORDERS_READ", + "description" : "Allows users to view orders" + }, { + "name" : "ORDERS_SC_WRITE", + "key" : "orders_write", + "roles" : "ROLE_ORDERS_WRITE", + "description" : "Allows users to place or cancel orders" + }, { + "name" : "ACCOUNT_SC_READ", + "key" : "account_read", + "roles" : "ROLE_ACCOUNT_READ", + "description" : "Allows users to view their own account" + }, { + "name" : "ADMIN_SC_ALL", + "key" : "admin_all", + "roles" : "ROLE_ADMIN", + "description" : "Full administrative access" + } ] + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/extensive-api.yaml b/src/test/resources/checks/v31/apim/OAR005/extensive-api.yaml new file mode 100644 index 00000000..b788d01f --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/extensive-api.yaml @@ -0,0 +1,167 @@ +openapi: "3.1.0" +info: + version: 2.1.0 + title: Retail Storefront API + description: Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration. +paths: + /catalog/products: + get: + operationId: get_catalog_products + summary: List products + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + post: + operationId: post_catalog_products + summary: Create a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /catalog/products/{productId}: + get: + operationId: get_catalog_products_productId + summary: Get a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + put: + operationId: put_catalog_products_productId + summary: Replace a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + delete: + operationId: delete_catalog_products_productId + summary: Delete a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /orders: + get: + operationId: get_orders + summary: List orders + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + post: + operationId: post_orders + summary: Place an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /orders/{orderId}: + get: + operationId: get_orders_orderId + summary: Get an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + delete: + operationId: delete_orders_orderId + summary: Cancel an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /account/profile: + get: + operationId: get_account_profile + summary: Get the caller's profile + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_READ + put: + operationId: put_account_profile + summary: Update the caller's profile - undeclared scope + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_WRITE # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /admin/users: + get: + operationId: get_admin_users + summary: List platform users - matches key not name + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: admin_all # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + operationId: post_admin_users + summary: Create a platform user + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + /admin/audit-log: + get: + operationId: get_admin_audit-log + summary: Read the audit log + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + +x-wso2-security: + apim: + x-wso2-scopes: + - name: CATALOG_SC_READ + key: catalog_read + roles: ROLE_CATALOG_READ + description: Allows users to browse the product catalog + - name: CATALOG_SC_WRITE + key: catalog_write + roles: ROLE_CATALOG_WRITE + description: Allows users to create or update products + - name: ORDERS_SC_READ + key: orders_read + roles: ROLE_ORDERS_READ + description: Allows users to view orders + - name: ORDERS_SC_WRITE + key: orders_write + roles: ROLE_ORDERS_WRITE + description: Allows users to place or cancel orders + - name: ACCOUNT_SC_READ + key: account_read + roles: ROLE_ACCOUNT_READ + description: Allows users to view their own account + - name: ADMIN_SC_ALL + key: admin_all + roles: ROLE_ADMIN + description: Full administrative access diff --git a/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.json b/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.json new file mode 100644 index 00000000..219d8f44 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.json @@ -0,0 +1,85 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "options" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "head" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "patch" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "trace" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.yaml b/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.yaml new file mode 100644 index 00000000..d74abfcd --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-all-verbs.yaml @@ -0,0 +1,54 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + patch: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + trace: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.json b/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.json new file mode 100644 index 00000000..29fab7f4 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.json @@ -0,0 +1,72 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one", + "callbacks" : { + "onEvent" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five", # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + "callbacks" : { + "onNested" : { + "'{$request.body#/nestedUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + } + } + } + } + } + } + }, + "components" : { + "callbacks" : { + "sharedCallback" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.yaml b/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.yaml new file mode 100644 index 00000000..b40822e3 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-callback-operations.yaml @@ -0,0 +1,43 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + post: + responses: + 200: + description: Ok + x-scope: scope_one + callbacks: + onEvent: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + callbacks: + onNested: + '{$request.body#/nestedUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} +components: + callbacks: + sharedCallback: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.json b/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.json new file mode 100644 index 00000000..6e69412f --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.json @@ -0,0 +1,50 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/alias" + }, + "x-wso2-definitions" : { + "alias" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.yaml b/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.yaml new file mode 100644 index 00000000..c6ebb0f1 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-chained-ref-security.yaml @@ -0,0 +1,33 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/alias" +x-wso2-definitions: + alias: + $ref: "#/x-wso2-definitions/security" + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.json b/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.json new file mode 100644 index 00000000..62234c28 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.json @@ -0,0 +1,55 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "$ref" : "#/x-wso2-definitions/scopeTwo" + } ] + } + }, + "x-wso2-definitions" : { + "scopeTwo" : { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.yaml b/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.yaml new file mode 100644 index 00000000..017514ad --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-ref-scope.yaml @@ -0,0 +1,36 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one + post: + responses: + 200: + description: Ok + x-scope: scope_two + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - $ref: "#/x-wso2-definitions/scopeTwo" +x-wso2-definitions: + scopeTwo: + name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v31/apim/OAR005/with-ref-security.json b/src/test/resources/checks/v31/apim/OAR005/with-ref-security.json new file mode 100644 index 00000000..e21f46b8 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-ref-security.json @@ -0,0 +1,47 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "x-wso2-definitions" : { + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-ref-security.yaml b/src/test/resources/checks/v31/apim/OAR005/with-ref-security.yaml new file mode 100644 index 00000000..6391da4e --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-ref-security.yaml @@ -0,0 +1,31 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/security" +x-wso2-definitions: + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.json b/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.json new file mode 100644 index 00000000..ce2403ae --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.json @@ -0,0 +1,37 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "catalogue_read" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "catalogue_read", + "description" : "catalogue_read", + "key" : "read", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.yaml b/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.yaml new file mode 100644 index 00000000..7bd94393 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-scope-key-not-name.yaml @@ -0,0 +1,24 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: catalogue_read + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: catalogue_read + description: catalogue_read + key: read + roles: role_one diff --git a/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.json b/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.json new file mode 100644 index 00000000..c00db5f5 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.json @@ -0,0 +1,66 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read_scope" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "write_scope" + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : { + "read" : { + "name" : "read_scope", + "key" : "read", + "roles" : "ROLE_READ", + "description" : "Allows users to read the catalogue" + }, + "write" : { + "$ref" : "#/x-wso2-definitions/writeScope" + } + } + } + }, + "x-wso2-definitions" : { + "writeScope" : { + "name" : "write_scope", + "key" : "write", + "roles" : "ROLE_WRITE", + "description" : "Allows users to write the catalogue" + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.yaml b/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.yaml new file mode 100644 index 00000000..e9d0a792 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-scopes-as-map.yaml @@ -0,0 +1,43 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: read_scope + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: write_scope + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + read: + name: read_scope + key: read + roles: ROLE_READ + description: Allows users to read the catalogue + write: + $ref: "#/x-wso2-definitions/writeScope" +x-wso2-definitions: + writeScope: + name: write_scope + key: write + roles: ROLE_WRITE + description: Allows users to write the catalogue diff --git a/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.json b/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.json new file mode 100644 index 00000000..386fd1c4 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.json @@ -0,0 +1,60 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "$ref" : "#/components/pathItems/PetsPath" + } + }, + "webhooks" : { + "newPet" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "components" : { + "pathItems" : { + "PetsPath" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "webhooks" : { + "reusableWebhook" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.yaml b/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.yaml new file mode 100644 index 00000000..6b1fa4b7 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/with-webhook-operations.yaml @@ -0,0 +1,38 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + $ref: "#/components/pathItems/PetsPath" +webhooks: + newPet: + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +components: + pathItems: + PetsPath: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + webhooks: + reusableWebhook: + post: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v31/apim/OAR005/without-security.json b/src/test/resources/checks/v31/apim/OAR005/without-security.json new file mode 100644 index 00000000..eff68435 --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/without-security.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/apim/OAR005/without-security.yaml b/src/test/resources/checks/v31/apim/OAR005/without-security.yaml new file mode 100644 index 00000000..e2b8f1aa --- /dev/null +++ b/src/test/resources/checks/v31/apim/OAR005/without-security.yaml @@ -0,0 +1,15 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v31/examples/OAR031/allof-schema-missing-example.yaml b/src/test/resources/checks/v31/examples/OAR031/allof-schema-missing-example.yaml new file mode 100644 index 00000000..5705e186 --- /dev/null +++ b/src/test/resources/checks/v31/examples/OAR031/allof-schema-missing-example.yaml @@ -0,0 +1,32 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + schemas: + BaseEntity: + type: object + properties: + id: # Noncompliant {{OAR031: Property 'id' is missing an example.}} + type: integer + Pet: + allOf: + - $ref: '#/components/schemas/BaseEntity' + properties: + name: + type: string + example: "Fluffy" +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + example: + name: Fluffy + 204: + description: No content diff --git a/src/test/resources/checks/v31/examples/OAR031/externalref.yaml b/src/test/resources/checks/v31/examples/OAR031/externalref.yaml index 4e6e96e7..4473d4db 100644 --- a/src/test/resources/checks/v31/examples/OAR031/externalref.yaml +++ b/src/test/resources/checks/v31/examples/OAR031/externalref.yaml @@ -14,7 +14,7 @@ paths: summary: Get all users description: Returns a list of users. responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A JSON array of user objects content: application/json: @@ -23,7 +23,7 @@ paths: items: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response /users/{userId}: get: @@ -40,14 +40,14 @@ paths: name: Puppy type: dog responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A single user object content: application/json: schema: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response components: schemas: diff --git a/src/test/resources/checks/v31/examples/OAR031/nested-properties-examples.yaml b/src/test/resources/checks/v31/examples/OAR031/nested-properties-examples.yaml index c48f0f18..86b9cc6b 100644 --- a/src/test/resources/checks/v31/examples/OAR031/nested-properties-examples.yaml +++ b/src/test/resources/checks/v31/examples/OAR031/nested-properties-examples.yaml @@ -6,7 +6,7 @@ paths: /profile: put: summary: Update user profile - requestBody: # Noncompliant {{OAR031: Request body must have one or more examples defined}} + requestBody: # Noncompliant {{OAR031: Request body must have an example defined}} required: true content: application/json: @@ -35,5 +35,5 @@ paths: type: string example: "28001" responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: OK \ No newline at end of file diff --git a/src/test/resources/checks/v31/examples/OAR031/orphan-schema.yaml b/src/test/resources/checks/v31/examples/OAR031/orphan-schema.yaml new file mode 100644 index 00000000..8e7784ca --- /dev/null +++ b/src/test/resources/checks/v31/examples/OAR031/orphan-schema.yaml @@ -0,0 +1,32 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/pet' + example: + name: Fluffy + 204: + description: No content +components: + schemas: + pet: + type: object + properties: + name: + type: string + example: "Fluffy" + # Never referenced by any path - must not be flagged (orphan-schema exclusion). + UnusedSchema: + type: object + properties: + unused_field: + type: string diff --git a/src/test/resources/checks/v31/examples/OAR031/without-examples.yaml b/src/test/resources/checks/v31/examples/OAR031/without-examples.yaml index 5fa170e9..42f0f6f9 100644 --- a/src/test/resources/checks/v31/examples/OAR031/without-examples.yaml +++ b/src/test/resources/checks/v31/examples/OAR031/without-examples.yaml @@ -6,7 +6,7 @@ paths: /pets: get: responses: - 206: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 206: # Noncompliant {{OAR031: Response must have an example defined}} description: Pet list content: application/json: @@ -16,7 +16,7 @@ paths: $ref: "#/components/responses/server_error_response" /pets/{id}: parameters: - - in: query # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + - in: query # Noncompliant {{OAR031: Parameter '$start' must have an example defined}} name: $start schema: type: integer @@ -24,7 +24,7 @@ paths: parameters: - $ref: "#/components/parameters/id" responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: One pet content: application/json: @@ -35,8 +35,8 @@ paths: components: parameters: - id: - in: path # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + id: # Noncompliant {{OAR031: Parameter 'id' must have an example defined}} + in: path name: id schema: type: integer @@ -48,26 +48,26 @@ components: pet: type: object properties: - name: # Noncompliant {{OAR031: Properties must have an example defined}} + name: # Noncompliant {{OAR031: Property 'name' is missing an example.}} type: string - type: # Noncompliant {{OAR031: Properties must have an example defined}} + type: # Noncompliant {{OAR031: Property 'type' is missing an example.}} type: string pets: type: object properties: - size: # Noncompliant {{OAR031: Properties must have an example defined}} + size: # Noncompliant {{OAR031: Property 'size' is missing an example.}} type: integer pets: type: array items: $ref: '#/components/schemas/pet' responses: - server_error_response: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + server_error_response: # Noncompliant {{OAR031: Response must have an example defined}} description: Default error response content: application/json: schema: type: object properties: - error: # Noncompliant {{OAR031: Properties must have an example defined}} + error: # Noncompliant {{OAR031: Property 'error' is missing an example.}} type: string \ No newline at end of file diff --git a/src/test/resources/checks/v31/format/OAR007/with-204-response.json b/src/test/resources/checks/v31/format/OAR007/with-204-response.json new file mode 100644 index 00000000..1ccf567f --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-204-response.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-204-response.yaml b/src/test/resources/checks/v31/format/OAR007/with-204-response.yaml new file mode 100644 index 00000000..bb080d5e --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-204-response.yaml @@ -0,0 +1,10 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v31/format/OAR007/with-chained-ref.json b/src/test/resources/checks/v31/format/OAR007/with-chained-ref.json new file mode 100644 index 00000000..3260aa1c --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-chained-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "A": { + "$ref": "#/components/responses/B" + }, + "B": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/A" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-chained-ref.yaml b/src/test/resources/checks/v31/format/OAR007/with-chained-ref.yaml new file mode 100644 index 00000000..0ea40fa0 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-chained-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + A: + $ref: '#/components/responses/B' + B: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/A' diff --git a/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.json b/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.json new file mode 100644 index 00000000..f3d84a94 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { + "description": "OK", + "content": { + "application/json": {} + } + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.yaml b/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.yaml new file mode 100644 index 00000000..a20959a4 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: + description: OK + content: + application/json: {} +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v31/format/OAR007/with-default-response-key.json b/src/test/resources/checks/v31/format/OAR007/with-default-response-key.json new file mode 100644 index 00000000..ceaf057f --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-default-response-key.json @@ -0,0 +1,19 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "default": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Unexpected error", + "content": {} + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-default-response-key.yaml b/src/test/resources/checks/v31/format/OAR007/with-default-response-key.yaml new file mode 100644 index 00000000..9ad855e3 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-default-response-key.yaml @@ -0,0 +1,11 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + default: # Noncompliant {{OAR007: Section content is mandatory}} + description: Unexpected error + content: {} diff --git a/src/test/resources/checks/v31/format/OAR007/with-external-ref.json b/src/test/resources/checks/v31/format/OAR007/with-external-ref.json new file mode 100644 index 00000000..f6567e42 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-external-ref.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-external-ref.yaml b/src/test/resources/checks/v31/format/OAR007/with-external-ref.yaml new file mode 100644 index 00000000..3b7d240d --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-external-ref.yaml @@ -0,0 +1,11 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + $ref: >- + http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse diff --git a/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.json b/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.json new file mode 100644 index 00000000..a9c4e4dc --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.json @@ -0,0 +1,53 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "get": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content" + } + } + }, + "post": { + "responses": { + "201": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Created" + } + } + } + }, + "/owners": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/xml": {} + } + }, + "400": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Bad Request" + } + } + }, + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.yaml b/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.yaml new file mode 100644 index 00000000..bb48e6b3 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-multiple-operations.yaml @@ -0,0 +1,31 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + post: + responses: + '201': # Noncompliant {{OAR007: Section content is mandatory}} + description: Created + /owners: + put: + responses: + '200': + description: Ok + content: + application/xml: {} + '400': # Noncompliant {{OAR007: Section content is mandatory}} + description: Bad Request + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v31/format/OAR007/with-specific.json b/src/test/resources/checks/v31/format/OAR007/with-specific.json new file mode 100644 index 00000000..9afb31e4 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-specific.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-specific.yaml b/src/test/resources/checks/v31/format/OAR007/with-specific.yaml new file mode 100644 index 00000000..fa9f955c --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-specific.yaml @@ -0,0 +1,12 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + description: Ok + content: + application/json: {} diff --git a/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.json b/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.json new file mode 100644 index 00000000..7a86ba86 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.json @@ -0,0 +1,25 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.yaml b/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.yaml new file mode 100644 index 00000000..dfafb717 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR007/with-wrong-ref.yaml @@ -0,0 +1,14 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v31/format/OAR010/with-204-response.json b/src/test/resources/checks/v31/format/OAR010/with-204-response.json new file mode 100644 index 00000000..6f132667 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-204-response.json @@ -0,0 +1,27 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content", + "content": { + "application/xml": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR010/with-204-response.yaml b/src/test/resources/checks/v31/format/OAR010/with-204-response.yaml new file mode 100644 index 00000000..1b8999ec --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-204-response.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + content: + application/xml: {} diff --git a/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.json b/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.json new file mode 100644 index 00000000..79e3af7a --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "Application/JSON": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.yaml b/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.yaml new file mode 100644 index 00000000..cca3f65f --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-default-mixed-case.yaml @@ -0,0 +1,12 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + Application/JSON: {} diff --git a/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.json b/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.json new file mode 100644 index 00000000..005c8be1 --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "XmlOnlyResponse": { + "description": "OK", + "content": { # Noncompliant {{OAR010: Should indicate the default response media type}} + "application/xml": {} + } + } + } + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "$ref": "#/components/responses/XmlOnlyResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.yaml b/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.yaml new file mode 100644 index 00000000..76fbf25d --- /dev/null +++ b/src/test/resources/checks/v31/format/OAR010/with-wrong-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + XmlOnlyResponse: + description: OK + content: # Noncompliant {{OAR010: Should indicate the default response media type}} + application/xml: {} +paths: + /pets: + post: + responses: + '200': + $ref: '#/components/responses/XmlOnlyResponse' diff --git a/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.json b/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.json new file mode 100644 index 00000000..940f0f1d --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "parameters" : [ { + "in" : "header", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.yaml b/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..7936548a --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/header-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + parameters: + - in: header + name: $total + schema: + type: boolean + default: true + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.json b/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.json index fe56facb..9278595e 100644 --- a/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.json +++ b/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.json @@ -16,7 +16,7 @@ "type" : "string" } } - }, { # Noncompliant {{OAR026: The $total parameter default value should be false}} + }, { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.yaml b/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.yaml index 76791b5a..d18a1745 100644 --- a/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v31/parameters/OAR026/plain-with-$total-without-defval.yaml @@ -12,7 +12,7 @@ paths: type: array items: type: string - - in: query # Noncompliant {{OAR026: The $total parameter default value should be false}} + - in: query name: $total schema: type: boolean diff --git a/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.json b/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.json new file mode 100644 index 00000000..418764a4 --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "post" : { + "parameters" : [ { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "201" : { + "description" : "Created" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.yaml b/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..9f7796c6 --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/post-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + parameters: + - in: query + name: $total + schema: + type: boolean + default: true + responses: + 201: + description: Created diff --git a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json new file mode 100644 index 00000000..8ba32f08 --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json @@ -0,0 +1,30 @@ +{ + "openapi" : "3.1.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "components" : { + "parameters" : { + "total" : { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } + } + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..595b9232 --- /dev/null +++ b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml @@ -0,0 +1,18 @@ +openapi: "3.1.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + parameters: + total: + in: query + name: $total + schema: + type: boolean + default: true +paths: + /pets: + get: + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.json b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.json index a550035d..bd00551f 100644 --- a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.json +++ b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.json @@ -16,7 +16,7 @@ } } }, - "total" : { # Noncompliant {{OAR026: The $total parameter default value should be false}} + "total" : { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.yaml b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.yaml index a7888290..985a84f6 100644 --- a/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v31/parameters/OAR026/with-$ref-with-$total-without-defval.yaml @@ -11,7 +11,7 @@ components: type: array items: type: string - total: # Noncompliant {{OAR026: The $total parameter default value should be false}} + total: in: query name: $total schema: diff --git a/src/test/resources/checks/v32/apim/OAR005/extensive-api.json b/src/test/resources/checks/v32/apim/OAR005/extensive-api.json new file mode 100644 index 00000000..80e2569e --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/extensive-api.json @@ -0,0 +1,241 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "2.1.0", + "title" : "Retail Storefront API", + "description" : "Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration." + }, + "paths" : { + "/catalog/products" : { + "get" : { + "operationId" : "get_catalog_products", + "summary" : "List products", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "post" : { + "operationId" : "post_catalog_products", + "summary" : "Create a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/catalog/products/{productId}" : { + "get" : { + "operationId" : "get_catalog_products_productId", + "summary" : "Get a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_READ" + }, + "put" : { + "operationId" : "put_catalog_products_productId", + "summary" : "Replace a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + }, + "delete" : { + "operationId" : "delete_catalog_products_productId", + "summary" : "Delete a product", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "CATALOG_SC_WRITE" + } + }, + "/orders" : { + "get" : { + "operationId" : "get_orders", + "summary" : "List orders", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "post" : { + "operationId" : "post_orders", + "summary" : "Place an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/orders/{orderId}" : { + "get" : { + "operationId" : "get_orders_orderId", + "summary" : "Get an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_READ" + }, + "delete" : { + "operationId" : "delete_orders_orderId", + "summary" : "Cancel an order", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ORDERS_SC_WRITE" + } + }, + "/account/profile" : { + "get" : { + "operationId" : "get_account_profile", + "summary" : "Get the caller's profile", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_READ" + }, + "put" : { + "operationId" : "put_account_profile", + "summary" : "Update the caller's profile - undeclared scope", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ACCOUNT_SC_WRITE" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + }, + "/admin/users" : { + "get" : { + "operationId" : "get_admin_users", + "summary" : "List platform users - matches key not name", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "admin_all" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "operationId" : "post_admin_users", + "summary" : "Create a platform user", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + }, + "/admin/audit-log" : { + "get" : { + "operationId" : "get_admin_audit-log", + "summary" : "Read the audit log", + "responses" : { + "200" : { + "description" : "Ok" + }, + "400" : { + "description" : "Bad request" + } + }, + "x-scope" : "ADMIN_SC_ALL" + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "CATALOG_SC_READ", + "key" : "catalog_read", + "roles" : "ROLE_CATALOG_READ", + "description" : "Allows users to browse the product catalog" + }, { + "name" : "CATALOG_SC_WRITE", + "key" : "catalog_write", + "roles" : "ROLE_CATALOG_WRITE", + "description" : "Allows users to create or update products" + }, { + "name" : "ORDERS_SC_READ", + "key" : "orders_read", + "roles" : "ROLE_ORDERS_READ", + "description" : "Allows users to view orders" + }, { + "name" : "ORDERS_SC_WRITE", + "key" : "orders_write", + "roles" : "ROLE_ORDERS_WRITE", + "description" : "Allows users to place or cancel orders" + }, { + "name" : "ACCOUNT_SC_READ", + "key" : "account_read", + "roles" : "ROLE_ACCOUNT_READ", + "description" : "Allows users to view their own account" + }, { + "name" : "ADMIN_SC_ALL", + "key" : "admin_all", + "roles" : "ROLE_ADMIN", + "description" : "Full administrative access" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/extensive-api.yaml b/src/test/resources/checks/v32/apim/OAR005/extensive-api.yaml new file mode 100644 index 00000000..651b1ae9 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/extensive-api.yaml @@ -0,0 +1,167 @@ +openapi: "3.2.0" +info: + version: 2.1.0 + title: Retail Storefront API + description: Public-facing REST API for the retail storefront covering product catalog browsing, order placement, account management, and platform administration. +paths: + /catalog/products: + get: + operationId: get_catalog_products + summary: List products + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + post: + operationId: post_catalog_products + summary: Create a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /catalog/products/{productId}: + get: + operationId: get_catalog_products_productId + summary: Get a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_READ + put: + operationId: put_catalog_products_productId + summary: Replace a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + delete: + operationId: delete_catalog_products_productId + summary: Delete a product + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: CATALOG_SC_WRITE + /orders: + get: + operationId: get_orders + summary: List orders + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + post: + operationId: post_orders + summary: Place an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /orders/{orderId}: + get: + operationId: get_orders_orderId + summary: Get an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_READ + delete: + operationId: delete_orders_orderId + summary: Cancel an order + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ORDERS_SC_WRITE + /account/profile: + get: + operationId: get_account_profile + summary: Get the caller's profile + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_READ + put: + operationId: put_account_profile + summary: Update the caller's profile - undeclared scope + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ACCOUNT_SC_WRITE # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + /admin/users: + get: + operationId: get_admin_users + summary: List platform users - matches key not name + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: admin_all # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + operationId: post_admin_users + summary: Create a platform user + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + /admin/audit-log: + get: + operationId: get_admin_audit-log + summary: Read the audit log + responses: + 200: + description: Ok + 400: + description: Bad request + x-scope: ADMIN_SC_ALL + +x-wso2-security: + apim: + x-wso2-scopes: + - name: CATALOG_SC_READ + key: catalog_read + roles: ROLE_CATALOG_READ + description: Allows users to browse the product catalog + - name: CATALOG_SC_WRITE + key: catalog_write + roles: ROLE_CATALOG_WRITE + description: Allows users to create or update products + - name: ORDERS_SC_READ + key: orders_read + roles: ROLE_ORDERS_READ + description: Allows users to view orders + - name: ORDERS_SC_WRITE + key: orders_write + roles: ROLE_ORDERS_WRITE + description: Allows users to place or cancel orders + - name: ACCOUNT_SC_READ + key: account_read + roles: ROLE_ACCOUNT_READ + description: Allows users to view their own account + - name: ADMIN_SC_ALL + key: admin_all + roles: ROLE_ADMIN + description: Full administrative access diff --git a/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.json b/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.json new file mode 100644 index 00000000..8e4e8bb3 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.json @@ -0,0 +1,60 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "query" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "additionalOperations" : { + "PURGE" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + }, + "webhooks" : { + "newPet" : { + "query" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "additionalOperations" : { + "LINK" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_eight" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.yaml b/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.yaml new file mode 100644 index 00000000..d5ec9127 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-additional-operations.yaml @@ -0,0 +1,37 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + query: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + additionalOperations: + PURGE: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} +webhooks: + newPet: + query: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + additionalOperations: + LINK: + responses: + 200: + description: Ok + x-scope: scope_eight # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.json b/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.json new file mode 100644 index 00000000..87f4f4dc --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.json @@ -0,0 +1,93 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "options" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "head" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "patch" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "trace" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "query" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.yaml b/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.yaml new file mode 100644 index 00000000..3a51a562 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-all-verbs.yaml @@ -0,0 +1,59 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + options: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + head: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + patch: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + trace: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + query: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.json b/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.json new file mode 100644 index 00000000..e967307f --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.json @@ -0,0 +1,72 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/a" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one", + "callbacks" : { + "onEvent" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five", # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + "callbacks" : { + "onNested" : { + "'{$request.body#/nestedUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + } + } + } + } + } + } + }, + "components" : { + "callbacks" : { + "sharedCallback" : { + "'{$request.body#/callbackUrl}'" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.yaml b/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.yaml new file mode 100644 index 00000000..ea61929f --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-callback-operations.yaml @@ -0,0 +1,43 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /a: + post: + responses: + 200: + description: Ok + x-scope: scope_one + callbacks: + onEvent: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + callbacks: + onNested: + '{$request.body#/nestedUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} +components: + callbacks: + sharedCallback: + '{$request.body#/callbackUrl}': + post: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.json b/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.json new file mode 100644 index 00000000..8b8fe22d --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.json @@ -0,0 +1,50 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/alias" + }, + "x-wso2-definitions" : { + "alias" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.yaml b/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.yaml new file mode 100644 index 00000000..ba388fec --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-chained-ref-security.yaml @@ -0,0 +1,33 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/alias" +x-wso2-definitions: + alias: + $ref: "#/x-wso2-definitions/security" + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.json b/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.json new file mode 100644 index 00000000..f061e098 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.json @@ -0,0 +1,55 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "$ref" : "#/x-wso2-definitions/scopeTwo" + } ] + } + }, + "x-wso2-definitions" : { + "scopeTwo" : { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.yaml b/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.yaml new file mode 100644 index 00000000..a4549e95 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-ref-scope.yaml @@ -0,0 +1,36 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one + post: + responses: + 200: + description: Ok + x-scope: scope_two + put: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - $ref: "#/x-wso2-definitions/scopeTwo" +x-wso2-definitions: + scopeTwo: + name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v32/apim/OAR005/with-ref-security.json b/src/test/resources/checks/v32/apim/OAR005/with-ref-security.json new file mode 100644 index 00000000..647837ec --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-ref-security.json @@ -0,0 +1,47 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_two" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "$ref" : "#/x-wso2-definitions/security" + }, + "x-wso2-definitions" : { + "security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "description" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + }, { + "name" : "scope_two", + "description" : "scope_two", + "key" : "scope_two", + "roles" : "role_two" + } ] + } + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-ref-security.yaml b/src/test/resources/checks/v32/apim/OAR005/with-ref-security.yaml new file mode 100644 index 00000000..1a88793d --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-ref-security.yaml @@ -0,0 +1,31 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_two + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + $ref: "#/x-wso2-definitions/security" +x-wso2-definitions: + security: + apim: + x-wso2-scopes: + - name: scope_one + description: scope_one + key: scope_one + roles: role_one + - name: scope_two + description: scope_two + key: scope_two + roles: role_two diff --git a/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.json b/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.json new file mode 100644 index 00000000..0022eb31 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.json @@ -0,0 +1,37 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "catalogue_read" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "catalogue_read", + "description" : "catalogue_read", + "key" : "read", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.yaml b/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.yaml new file mode 100644 index 00000000..97955637 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-scope-key-not-name.yaml @@ -0,0 +1,24 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: catalogue_read + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: catalogue_read + description: catalogue_read + key: read + roles: role_one diff --git a/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.json b/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.json new file mode 100644 index 00000000..dde82ce2 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.json @@ -0,0 +1,66 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read_scope" + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "read" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "put" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "write_scope" + }, + "delete" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : { + "read" : { + "name" : "read_scope", + "key" : "read", + "roles" : "ROLE_READ", + "description" : "Allows users to read the catalogue" + }, + "write" : { + "$ref" : "#/x-wso2-definitions/writeScope" + } + } + } + }, + "x-wso2-definitions" : { + "writeScope" : { + "name" : "write_scope", + "key" : "write", + "roles" : "ROLE_WRITE", + "description" : "Allows users to write the catalogue" + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.yaml b/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.yaml new file mode 100644 index 00000000..4c837278 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-scopes-as-map.yaml @@ -0,0 +1,43 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: read_scope + post: + responses: + 200: + description: Ok + x-scope: read # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + put: + responses: + 200: + description: Ok + x-scope: write_scope + delete: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + read: + name: read_scope + key: read + roles: ROLE_READ + description: Allows users to read the catalogue + write: + $ref: "#/x-wso2-definitions/writeScope" +x-wso2-definitions: + writeScope: + name: write_scope + key: write + roles: ROLE_WRITE + description: Allows users to write the catalogue diff --git a/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.json b/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.json new file mode 100644 index 00000000..75423a0a --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.json @@ -0,0 +1,60 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "$ref" : "#/components/pathItems/PetsPath" + } + }, + "webhooks" : { + "newPet" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_five" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "components" : { + "pathItems" : { + "PetsPath" : { + "x-scope" : "scope_one", + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_six" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + }, + "webhooks" : { + "reusableWebhook" : { + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_seven" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + } + } + } + }, + "x-wso2-security" : { + "apim" : { + "x-wso2-scopes" : [ { + "name" : "scope_one", + "key" : "scope_one", + "roles" : "role_one" + } ] + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.yaml b/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.yaml new file mode 100644 index 00000000..5524e9f4 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/with-webhook-operations.yaml @@ -0,0 +1,38 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + $ref: "#/components/pathItems/PetsPath" +webhooks: + newPet: + post: + responses: + 200: + description: Ok + x-scope: scope_five # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +components: + pathItems: + PetsPath: + x-scope: scope_one + get: + responses: + 200: + description: Ok + x-scope: scope_six # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + webhooks: + reusableWebhook: + post: + responses: + 200: + description: Ok + x-scope: scope_seven # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + +x-wso2-security: + apim: + x-wso2-scopes: + - name: scope_one + key: scope_one + roles: role_one diff --git a/src/test/resources/checks/v32/apim/OAR005/without-security.json b/src/test/resources/checks/v32/apim/OAR005/without-security.json new file mode 100644 index 00000000..fd2319a3 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/without-security.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "Ok" + } + }, + "x-scope" : "scope_one" # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + }, + "post" : { + "responses" : { + "200" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/apim/OAR005/without-security.yaml b/src/test/resources/checks/v32/apim/OAR005/without-security.yaml new file mode 100644 index 00000000..3339db32 --- /dev/null +++ b/src/test/resources/checks/v32/apim/OAR005/without-security.yaml @@ -0,0 +1,15 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + x-scope: scope_one # Noncompliant {{OAR005: WSO2 scope definition does not exists}} + post: + responses: + 200: + description: Ok diff --git a/src/test/resources/checks/v32/examples/OAR031/allof-schema-missing-example.yaml b/src/test/resources/checks/v32/examples/OAR031/allof-schema-missing-example.yaml new file mode 100644 index 00000000..7e9327df --- /dev/null +++ b/src/test/resources/checks/v32/examples/OAR031/allof-schema-missing-example.yaml @@ -0,0 +1,32 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + schemas: + BaseEntity: + type: object + properties: + id: # Noncompliant {{OAR031: Property 'id' is missing an example.}} + type: integer + Pet: + allOf: + - $ref: '#/components/schemas/BaseEntity' + properties: + name: + type: string + example: "Fluffy" +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + example: + name: Fluffy + 204: + description: No content diff --git a/src/test/resources/checks/v32/examples/OAR031/externalref.yaml b/src/test/resources/checks/v32/examples/OAR031/externalref.yaml index 2c326a8b..e003f0f5 100644 --- a/src/test/resources/checks/v32/examples/OAR031/externalref.yaml +++ b/src/test/resources/checks/v32/examples/OAR031/externalref.yaml @@ -14,7 +14,7 @@ paths: summary: Get all users description: Returns a list of users. responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A JSON array of user objects content: application/json: @@ -23,7 +23,7 @@ paths: items: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response /users/{userId}: get: @@ -40,14 +40,14 @@ paths: name: Puppy type: dog responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: A single user object content: application/json: schema: $ref: '#/components/schemas/User' '400': - $ref: >- # Noncompliant {{OAR031: Responses must have one or more examples defined}} + $ref: >- # Noncompliant {{OAR031: Response must have an example defined}} http://localhost:18089/OAR031.yaml#/components/responses/server_error_response components: schemas: diff --git a/src/test/resources/checks/v32/examples/OAR031/nested-properties-examples.yaml b/src/test/resources/checks/v32/examples/OAR031/nested-properties-examples.yaml index e93c96a9..c9656aff 100644 --- a/src/test/resources/checks/v32/examples/OAR031/nested-properties-examples.yaml +++ b/src/test/resources/checks/v32/examples/OAR031/nested-properties-examples.yaml @@ -6,7 +6,7 @@ paths: /profile: put: summary: Update user profile - requestBody: # Noncompliant {{OAR031: Request body must have one or more examples defined}} + requestBody: # Noncompliant {{OAR031: Request body must have an example defined}} required: true content: application/json: @@ -35,5 +35,5 @@ paths: type: string example: "28001" responses: - '200': # Noncompliant {{OAR031: Responses must have one or more examples defined}} + '200': # Noncompliant {{OAR031: Response must have an example defined}} description: OK \ No newline at end of file diff --git a/src/test/resources/checks/v32/examples/OAR031/orphan-schema.yaml b/src/test/resources/checks/v32/examples/OAR031/orphan-schema.yaml new file mode 100644 index 00000000..391fd0fc --- /dev/null +++ b/src/test/resources/checks/v32/examples/OAR031/orphan-schema.yaml @@ -0,0 +1,32 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/pet' + example: + name: Fluffy + 204: + description: No content +components: + schemas: + pet: + type: object + properties: + name: + type: string + example: "Fluffy" + # Never referenced by any path - must not be flagged (orphan-schema exclusion). + UnusedSchema: + type: object + properties: + unused_field: + type: string diff --git a/src/test/resources/checks/v32/examples/OAR031/without-examples.yaml b/src/test/resources/checks/v32/examples/OAR031/without-examples.yaml index 9f62c796..1f5c0ad6 100644 --- a/src/test/resources/checks/v32/examples/OAR031/without-examples.yaml +++ b/src/test/resources/checks/v32/examples/OAR031/without-examples.yaml @@ -6,7 +6,7 @@ paths: /pets: get: responses: - 206: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 206: # Noncompliant {{OAR031: Response must have an example defined}} description: Pet list content: application/json: @@ -16,7 +16,7 @@ paths: $ref: "#/components/responses/server_error_response" /pets/{id}: parameters: - - in: query # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + - in: query # Noncompliant {{OAR031: Parameter '$start' must have an example defined}} name: $start schema: type: integer @@ -24,7 +24,7 @@ paths: parameters: - $ref: "#/components/parameters/id" responses: - 200: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + 200: # Noncompliant {{OAR031: Response must have an example defined}} description: One pet content: application/json: @@ -35,8 +35,8 @@ paths: components: parameters: - id: - in: path # Noncompliant {{OAR031: Parameters must have one or more examples defined}} + id: # Noncompliant {{OAR031: Parameter 'id' must have an example defined}} + in: path name: id schema: type: integer @@ -48,26 +48,26 @@ components: pet: type: object properties: - name: # Noncompliant {{OAR031: Properties must have an example defined}} + name: # Noncompliant {{OAR031: Property 'name' is missing an example.}} type: string - type: # Noncompliant {{OAR031: Properties must have an example defined}} + type: # Noncompliant {{OAR031: Property 'type' is missing an example.}} type: string pets: type: object properties: - size: # Noncompliant {{OAR031: Properties must have an example defined}} + size: # Noncompliant {{OAR031: Property 'size' is missing an example.}} type: integer pets: type: array items: $ref: '#/components/schemas/pet' responses: - server_error_response: # Noncompliant {{OAR031: Responses must have one or more examples defined}} + server_error_response: # Noncompliant {{OAR031: Response must have an example defined}} description: Default error response content: application/json: schema: type: object properties: - error: # Noncompliant {{OAR031: Properties must have an example defined}} + error: # Noncompliant {{OAR031: Property 'error' is missing an example.}} type: string \ No newline at end of file diff --git a/src/test/resources/checks/v32/format/OAR007/with-204-response.json b/src/test/resources/checks/v32/format/OAR007/with-204-response.json new file mode 100644 index 00000000..bab1a2ca --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-204-response.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-204-response.yaml b/src/test/resources/checks/v32/format/OAR007/with-204-response.yaml new file mode 100644 index 00000000..92acae09 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-204-response.yaml @@ -0,0 +1,10 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v32/format/OAR007/with-chained-ref.json b/src/test/resources/checks/v32/format/OAR007/with-chained-ref.json new file mode 100644 index 00000000..969d51ca --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-chained-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "A": { + "$ref": "#/components/responses/B" + }, + "B": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/A" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-chained-ref.yaml b/src/test/resources/checks/v32/format/OAR007/with-chained-ref.yaml new file mode 100644 index 00000000..7b7d9803 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-chained-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + A: + $ref: '#/components/responses/B' + B: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/A' diff --git a/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.json b/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.json new file mode 100644 index 00000000..ae69aeff --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { + "description": "OK", + "content": { + "application/json": {} + } + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.yaml b/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.yaml new file mode 100644 index 00000000..36a3ed7d --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: + description: OK + content: + application/json: {} +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v32/format/OAR007/with-default-response-key.json b/src/test/resources/checks/v32/format/OAR007/with-default-response-key.json new file mode 100644 index 00000000..0ca74d2d --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-default-response-key.json @@ -0,0 +1,19 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "default": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Unexpected error", + "content": {} + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-default-response-key.yaml b/src/test/resources/checks/v32/format/OAR007/with-default-response-key.yaml new file mode 100644 index 00000000..1b5d2fae --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-default-response-key.yaml @@ -0,0 +1,11 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + default: # Noncompliant {{OAR007: Section content is mandatory}} + description: Unexpected error + content: {} diff --git a/src/test/resources/checks/v32/format/OAR007/with-external-ref.json b/src/test/resources/checks/v32/format/OAR007/with-external-ref.json new file mode 100644 index 00000000..3efefeac --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-external-ref.json @@ -0,0 +1,18 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-external-ref.yaml b/src/test/resources/checks/v32/format/OAR007/with-external-ref.yaml new file mode 100644 index 00000000..b5813931 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-external-ref.yaml @@ -0,0 +1,11 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + $ref: >- + http://localhost:18089/OAR007.yaml#/components/responses/SuccessResponse diff --git a/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.json b/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.json new file mode 100644 index 00000000..d94df219 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.json @@ -0,0 +1,53 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "get": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content" + } + } + }, + "post": { + "responses": { + "201": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Created" + } + } + } + }, + "/owners": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/xml": {} + } + }, + "400": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "Bad Request" + } + } + }, + "delete": { + "responses": { + "204": { + "description": "No Content" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.yaml b/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.yaml new file mode 100644 index 00000000..92260973 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-multiple-operations.yaml @@ -0,0 +1,31 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + post: + responses: + '201': # Noncompliant {{OAR007: Section content is mandatory}} + description: Created + /owners: + put: + responses: + '200': + description: Ok + content: + application/xml: {} + '400': # Noncompliant {{OAR007: Section content is mandatory}} + description: Bad Request + delete: + responses: + '204': + description: No Content diff --git a/src/test/resources/checks/v32/format/OAR007/with-specific.json b/src/test/resources/checks/v32/format/OAR007/with-specific.json new file mode 100644 index 00000000..f722e678 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-specific.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-specific.yaml b/src/test/resources/checks/v32/format/OAR007/with-specific.yaml new file mode 100644 index 00000000..f74596be --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-specific.yaml @@ -0,0 +1,12 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + put: + responses: + '200': + description: Ok + content: + application/json: {} diff --git a/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.json b/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.json new file mode 100644 index 00000000..47e7b3c7 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.json @@ -0,0 +1,25 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "PetsResponse": { # Noncompliant {{OAR007: Section content is mandatory}} + "description": "No content defined" + } + } + }, + "paths": { + "/pets": { + "put": { + "responses": { + "200": { + "$ref": "#/components/responses/PetsResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.yaml b/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.yaml new file mode 100644 index 00000000..9a687bef --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR007/with-wrong-ref.yaml @@ -0,0 +1,14 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + PetsResponse: # Noncompliant {{OAR007: Section content is mandatory}} + description: No content defined +paths: + /pets: + put: + responses: + '200': + $ref: '#/components/responses/PetsResponse' diff --git a/src/test/resources/checks/v32/format/OAR010/with-204-response.json b/src/test/resources/checks/v32/format/OAR010/with-204-response.json new file mode 100644 index 00000000..4c4eaec2 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-204-response.json @@ -0,0 +1,27 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": {} + } + }, + "204": { + "description": "No Content", + "content": { + "application/xml": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR010/with-204-response.yaml b/src/test/resources/checks/v32/format/OAR010/with-204-response.yaml new file mode 100644 index 00000000..1882ff1f --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-204-response.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + application/json: {} + '204': + description: No Content + content: + application/xml: {} diff --git a/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.json b/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.json new file mode 100644 index 00000000..d73a6340 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "description": "Ok", + "content": { + "Application/JSON": {} + } + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.yaml b/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.yaml new file mode 100644 index 00000000..10787780 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-default-mixed-case.yaml @@ -0,0 +1,12 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + responses: + '200': + description: Ok + content: + Application/JSON: {} diff --git a/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.json b/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.json new file mode 100644 index 00000000..7b069a9d --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore" + }, + "components": { + "responses": { + "XmlOnlyResponse": { + "description": "OK", + "content": { # Noncompliant {{OAR010: Should indicate the default response media type}} + "application/xml": {} + } + } + } + }, + "paths": { + "/pets": { + "post": { + "responses": { + "200": { + "$ref": "#/components/responses/XmlOnlyResponse" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.yaml b/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.yaml new file mode 100644 index 00000000..69695377 --- /dev/null +++ b/src/test/resources/checks/v32/format/OAR010/with-wrong-default-and-ref.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + responses: + XmlOnlyResponse: + description: OK + content: # Noncompliant {{OAR010: Should indicate the default response media type}} + application/xml: {} +paths: + /pets: + post: + responses: + '200': + $ref: '#/components/responses/XmlOnlyResponse' diff --git a/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.json b/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.json new file mode 100644 index 00000000..9f80a425 --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "get" : { + "parameters" : [ { + "in" : "header", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.yaml b/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..8ef384dd --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/header-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + parameters: + - in: header + name: $total + schema: + type: boolean + default: true + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.json b/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.json index 82d1bd2c..72777f11 100644 --- a/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.json +++ b/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.json @@ -16,7 +16,7 @@ "type" : "string" } } - }, { # Noncompliant {{OAR026: The $total parameter default value should be false}} + }, { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.yaml b/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.yaml index fc709154..24b90ca9 100644 --- a/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v32/parameters/OAR026/plain-with-$total-without-defval.yaml @@ -12,7 +12,7 @@ paths: type: array items: type: string - - in: query # Noncompliant {{OAR026: The $total parameter default value should be false}} + - in: query name: $total schema: type: boolean diff --git a/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.json b/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.json new file mode 100644 index 00000000..d2712597 --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.json @@ -0,0 +1,26 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "paths" : { + "/pets" : { + "post" : { + "parameters" : [ { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } ], + "responses" : { + "201" : { + "description" : "Created" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.yaml b/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..81041fd2 --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/post-with-$total-with-defval-true.yaml @@ -0,0 +1,16 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + post: + parameters: + - in: query + name: $total + schema: + type: boolean + default: true + responses: + 201: + description: Created diff --git a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json new file mode 100644 index 00000000..76c2f81a --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.json @@ -0,0 +1,30 @@ +{ + "openapi" : "3.2.0", + "info" : { + "version" : "1.0.0", + "title" : "Swagger Petstore" + }, + "components" : { + "parameters" : { + "total" : { + "in" : "query", + "name" : "$total", + "schema" : { + "type" : "boolean", + "default" : true + } + } + } + }, + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "206" : { + "description" : "Ok" + } + } + } + } + } +} diff --git a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml new file mode 100644 index 00000000..aefbef29 --- /dev/null +++ b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-unreferenced-with-$total-with-defval-true.yaml @@ -0,0 +1,18 @@ +openapi: "3.2.0" +info: + version: 1.0.0 + title: Swagger Petstore +components: + parameters: + total: + in: query + name: $total + schema: + type: boolean + default: true +paths: + /pets: + get: + responses: + 206: + description: Ok diff --git a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.json b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.json index 0c9c05b7..11e2235a 100644 --- a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.json +++ b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.json @@ -16,7 +16,7 @@ } } }, - "total" : { # Noncompliant {{OAR026: The $total parameter default value should be false}} + "total" : { "in" : "query", "name" : "$total", "schema": { diff --git a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.yaml b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.yaml index 3ac00495..57681126 100644 --- a/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.yaml +++ b/src/test/resources/checks/v32/parameters/OAR026/with-$ref-with-$total-without-defval.yaml @@ -11,7 +11,7 @@ components: type: array items: type: string - total: # Noncompliant {{OAR026: The $total parameter default value should be false}} + total: in: query name: $total schema: