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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package Cx
import data.generic.common as common_lib
import data.generic.openapi as openapi_lib

# This two rules verifies schema and schemas without allOf, anyOf and oneOf
# These two rules verify schema and schemas without allOf, anyOf and oneOf
CxPolicy[result] {
doc := input.document[i]
openapi_lib.check_openapi(doc) == "3.0"
Expand Down Expand Up @@ -38,7 +38,7 @@ CxPolicy[result] {
}
}

#This rules verifies anyOf and oneOf
# These rules verify anyOf and oneOf
CxPolicy[result] {
doc := input.document[i]
openapi_lib.check_openapi(doc) == "3.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,60 @@ CxPolicy[result] {
version := openapi_lib.check_openapi(doc)
version != "undefined"

operation := doc.paths[p][op]
operation := doc.paths[path][op]
response := operation.responses[code]
acceptable_response(code, op)

key := get_key_by_version(version)
not common_lib.valid_key(response, key)

results := get_results(response, path, op, code, version, doc)[_]

result := {
"documentId": doc.id,
"searchKey": sprintf("paths.%s.%s.responses.%s", [p, op, code]),
"searchKey": results.searchKey,
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("paths.%s.%s.responses.%s.%s should be defined", [p, op, code, key]),
"keyActualValue": sprintf("paths.%s.%s.responses.%s.%s is undefined", [p, op, code, key]),
"overrideKey": version,
"keyExpectedValue": results.keyExpectedValue,
"keyActualValue": results.keyActualValue,
"searchLine": results.searchLine,
"overrideKey": results.overrideKey,
}
}

CxPolicy[result] {
doc := input.document[i]
version := openapi_lib.check_openapi(doc)
version == "3.0"
get_results(response, path, op, code, version, doc) = output {
key := get_key_by_version(version)
not common_lib.valid_key(response, key)
not has_valid_ref(response, doc, version)

operation := doc.paths[path][op]
response := operation.responses[code]
acceptable_response(code, op)
output := [{
"searchKey": sprintf("paths.%s.%s.responses.%s", [path, op, code]),
"keyExpectedValue": sprintf("paths.%s.%s.responses.%s.%s should be defined", [path, op, code, key]),
"keyActualValue": sprintf("paths.%s.%s.responses.%s.%s is undefined", [path, op, code, key]),
"searchLine": common_lib.build_search_line(["paths", path, op, "responses", code], []),
"overrideKey": version,
}]

} else = output {
version == "3.0"
count(response.content) == 0

result := {
"documentId": doc.id,
output := [{
"searchKey": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content", [path, op, code]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content should have at least one content-type defined", [path, op, code]),
"keyActualValue": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content has no content-type defined", [path, op, code]),
}
}

CxPolicy[result] {
doc := input.document[i]
version := openapi_lib.check_openapi(doc)
"searchLine": common_lib.build_search_line(["paths", path, op, "responses", code, "content"], []),
"overrideKey": "3.0",
}]
} else = output {
version == "3.0"

operation := doc.paths[path][op]
response := operation.responses[code]
acceptable_response(code, op)

responses := response.content[content_type]
not common_lib.valid_key(responses, "schema")

result := {
"documentId": doc.id,
output := [{
"searchKey": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content.{{%s}}", [path, op, code, content_type]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content.{{%s}}.schema should be defined", [path, op, code, content_type]),
"keyActualValue": sprintf("paths.{{%s}}.{{%s}}.responses.{{%s}}.content.{{%s}}.schema is undefined", [path, op, code, content_type]),
}
"searchLine": common_lib.build_search_line(["paths", path, op, "responses", code, "content", content_type], []),
"overrideKey": "3.0",
} | some content_type
responses := response.content[content_type]
not common_lib.valid_key(responses, "schema")
]
}

acceptable_response(code, op) {
Expand All @@ -83,3 +81,40 @@ get_key_by_version(version) = key {

key = keys[version]
}

has_valid_ref(obj, doc, version) {
version == "3.0"
ref := get_ref(obj)

path := split(substring(ref, 2, -1), "/")
type := path[minus(count(path), 2)]
resource := doc.components[type][path[minus(count(path), 1)]]

is_schema_or_has_schema(resource, type)
} else {
version == "2.0"
ref := get_ref(obj)

path := split(substring(ref, 2, -1), "/")
type := path[minus(count(path), 2)]
resource := doc[type][path[minus(count(path), 1)]]

is_schema_or_has_schema(resource, type)
}

get_ref(obj) = res{
res := obj["RefMetadata"]["$ref"] # --enable-openapi-refs
res != null
} else = res {
res := obj["$ref"]
res != null
}

is_schema_or_has_schema(resource, type) {
type == ["schemas","definitions"][_]
resource != null
} else {
common_lib.valid_key(resource, "schema") # swagger 2.0
} else {
common_lib.valid_key(resource[_][_], "schema") # 3.0
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,6 @@
}
}
}
},
"delete": {
"operationId": "deleteVersion",
"summary": "Deletes API versions",
"responses": {
"204": {
"description": "no content"
}
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@
"summary": "List API versions",
"responses": {
"200": {
"description": "200 response"
}
}
},
"delete": {
"operationId": "deleteVersion",
"summary": "Deletes API versions",
"responses": {
"204": {
"description": "no content"
"description": "200 response",
"schema": {
"type": "object",
"discriminator": "ApiVersion",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"version": {
"type": "string"
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
{
"swagger": "2.0",
"openapi": "3.0.3",
"info": {
"title": "Simple API Overview",
"version": "1.0.0",
"contact": {
"name": "contact",
"url": "https://www.google.com/",
"email": "[email protected]"
}
"title": "Tariff Setup API",
"version": "1.0.0"
},
"paths": {
"/": {
"get": {
"operationId": "listVersionsv2",
"summary": "List API versions",
"/CreateTariffSetup": {
"post": {
"summary": "Creates tariff setups.",
"tags": ["Tariff Setups"],
"responses": {
"200": {
"description": "200 response",
"schema": {
"type": "object",
"discriminator": "ApiVersion",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"version": {
"type": "string"
}
}
}
"400": {
"$ref": "#/components/schemas/error"
},
"500": {
"$ref": "#/components/schemas/error"
}
}
},
"delete": {
"operationId": "deleteVersion",
"summary": "Deletes API versions",
"responses": {
"204": {
"description": "no content"
}
}
},
"components": {
"schemas": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string",
"example": "ERR_400"
},
"message": {
"type": "string",
"example": "Invalid request payload"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"openapi": "3.0.3",
"info": {
"title": "Tariff Setup API",
"version": "1.0.0"
},
"paths": {
"/CreateTariffSetup": {
"post": {
"summary": "Creates tariff setups.",
"tags": ["Tariff Setups"],
"responses": {
"400": {
"$ref": "#/components/responses/error"
},
"500": {
"$ref": "#/components/responses/error"
}
}
}
}
},
"components": {
"responses": {
"error": {
"description": "Error response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/error"
}
}
}
}
},
"schemas": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string",
"example": "ERR_400"
},
"message": {
"type": "string",
"example": "Invalid request payload"
}
}
}
}
}
}
Loading
Loading