diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc4ea57..badee74e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ 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). +## [Unreleased] + +### Deprecated + +- The project is deprecated and no longer maintained. No further releases are planned. + +## [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/README.md b/README.md index 1435cb3b..340eb230 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -# 🛠️ sonaropenapi-rules ![Release](https://img.shields.io/badge/release-1.3.5-purple) ![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=flat&logo=openjdk&logoColor=white) [![License: LGPL v3](https://img.shields.io/badge/license-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) +# 🛠️ sonaropenapi-rules ![Status](https://img.shields.io/badge/status-deprecated-red) ![Release](https://img.shields.io/badge/release-1.3.5-purple) ![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=flat&logo=openjdk&logoColor=white) [![License: LGPL v3](https://img.shields.io/badge/license-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) + +> [!WARNING] +> **This project is deprecated and no longer maintained.** No new features, bug fixes or releases are planned. Issues and pull requests may not be reviewed. Existing releases remain available, but use them at your own risk. This repository contains a set of custom SonarQube rules specifically designed to analyze and improve the quality of OpenAPI specifications. By integrating these rules, teams can ensure best practices, maintainability, and consistency in their API definitions. 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: