generated from camaraproject/Template_API_Repository
-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API linting implementation guideline (#1) #110
Merged
rartych
merged 15 commits into
camaraproject:main
from
ravindrapalaskar17:API-linting-Implementation-Guideline
Feb 9, 2024
Merged
Changes from 5 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
ee82212
Draft/api linting implementation guideline (#1)
ravindrapalaskar17 e8c103a
Update Sensitive data spelling and add phoneNumber in array.
ravindrapalaskar17 c42c43b
Update Sensitive spelling from function
ravindrapalaskar17 64e1624
Update API guideline document
ravindrapalaskar17 f5d771c
Replace type pattern with spectral core casing function [ kebab and p…
ravindrapalaskar17 9842099
change megalinter.yml position
ravindrapalaskar17 ad14389
change position of megalinter.yml file
ravindrapalaskar17 c7481b0
change position of javalint.xml
ravindrapalaskar17 91bf9b3
change location of .yamllint.yaml
ravindrapalaskar17 da45a2e
Delete artifacts/linting_rules/lint_function/workflows directory
ravindrapalaskar17 aaeb455
Delete artifacts/Github_templates/.github/workflows directory
ravindrapalaskar17 29e4e9d
Api linting rartych (#2)
rartych 3f3ff60
Update indentation in .spectral.yml file
ravindrapalaskar17 38b97bc
Update megalinter.yml
rartych e30f39a
Update .yamllint.yaml
rartych File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
extends: "spectral:oas" | ||
functions: | ||
- camara-reserved-words | ||
- camara-language-avoid-telco | ||
- camara-security-no-secrets-in-path-or-query-parameters | ||
functionsDir: "./lint_function" | ||
rules: | ||
# Built-in OpenAPI Specification ruleset. Each rule then can be enabled individually. | ||
# The severity keyword is optional in rule definition and can be error, warn, info, hint, or off. The default value is warn. | ||
contact-properties: false | ||
duplicated-entry-in-enum: true | ||
info-contact: true | ||
info-description: true | ||
info-license: true | ||
license-url: true | ||
no-$ref-siblings: error | ||
no-eval-in-markdown: true | ||
no-script-tags-in-markdown: true | ||
openapi-tags: false | ||
openapi-tags-alphabetical: false | ||
openapi-tags-uniqueness: error | ||
operation-description: true | ||
operation-operationId: true | ||
operation-operationId-unique: error | ||
operation-operationId-valid-in-url: true | ||
operation-parameters: true | ||
operation-singular-tag: true | ||
operation-success-response: true | ||
operation-tags: true | ||
operation-tag-defined: true | ||
path-declarations-must-exist: true | ||
path-keys-no-trailing-slash: true | ||
path-not-include-query: true | ||
path-params: error | ||
tag-description: false | ||
typed-enum: true | ||
oas3-api-servers: true | ||
oas3-examples-value-or-externalValue: true | ||
oas3-operation-security-defined: true | ||
oas3-parameter-description: false | ||
oas3-schema: true | ||
oas3-server-not-example.com: false | ||
oas3-server-trailing-slash: true | ||
oas3-unused-component: true | ||
oas3-valid-media-example: true | ||
oas3-valid-schema-example: true | ||
oas3-server-variables: true | ||
|
||
# Custom Rules Utilizing Spectral's Built-in Functions and JavaScript Implementations | ||
|
||
camara-language-avoid-telco: | ||
message: "{{error}}" | ||
severity: hint | ||
description: | | ||
This rule checks for telco-specific terminology in your API definitions and suggests more inclusive terms. | ||
given: "$..*.*" | ||
then: | ||
function: camara-language-avoid-telco | ||
recommended: false # Set to true/false to enable/disable this rule | ||
|
||
camara-oas-version: | ||
message: "OpenAPI Version Error: The OpenAPI specification must adhere to version 3.0.3." | ||
severity: error | ||
description: | | ||
This rule validates the OpenAPI version in your specification and requires compliance with version 3.0.3. | ||
given: "$" | ||
then: | ||
field: openapi | ||
function: pattern | ||
functionOptions: | ||
match: 3.0.3 | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-path-param-id: | ||
message: "Path Parameter Naming Warning: Use 'resource_id' instead of just 'id' in path parameters." | ||
severity: warn | ||
description: | | ||
This rule ensures consistent and descriptive naming for path parameters in your OpenAPI specification. | ||
Please use 'resource_id' instead of just 'id' for your path parameters. | ||
given: "$..parameters[?(@.in == 'path')]" | ||
then: | ||
field: name | ||
function: pattern | ||
functionOptions: | ||
notMatch: \b(id|Id|ID|iD)\b | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-security-no-secrets-in-path-or-query-parameters: | ||
message: "Sensitive data found in path: {{error}} Consider avoiding the use of Sesentive data " | ||
severity: warn | ||
description: | | ||
This rule checks for sensitive data ('MSISDN' and 'IMSI') in API paths and suggests avoiding their use. | ||
given: | ||
- "$.paths" | ||
then: | ||
function: camara-security-no-secrets-in-path-or-query-parameters | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-http-methods: | ||
description: "Ensure that all path URLs have valid HTTP methods (GET, PUT, POST, DELETE, PATCH, OPTIONS)." | ||
message: "Invalid HTTP method for '{{path}}'. Must be one of get, put, post, delete, patch, options." | ||
severity: error | ||
given: $.paths[*][*]~ | ||
then: | ||
function: pattern | ||
functionOptions: | ||
match: "^(get|put|post|delete|patch|options)$" | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-get-no-request-body: | ||
message: There must be no request body for Get and DELETE | ||
severity: error | ||
given: | ||
- "$.paths.*.get" | ||
- "$.paths.*.delete" | ||
then: | ||
field: requestBody | ||
function: falsy | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-reserved-words: | ||
message: "Reserved words found {{error}} Consider avoiding the use of reserved word " | ||
severity: warn | ||
description: | | ||
This rule checks Reserved words must not be used in the following parts of an API specification [Paths, Request Body properties, Component, Operation Id, Security Schema] | ||
given: | ||
- "$.paths" # Paths | ||
- "$..parameters[*]" # Path or Query Parameter Names: | ||
- "$..components.schemas.*.properties.*" # Request and Response body parameter | ||
- "$.paths.*." # Path and Operation Names: | ||
- "$.components.securitySchemes" # Security Schemes: | ||
- "$.components.*.*" # Component Names: | ||
- "$.paths.*.*.operationId" # OperationIds: | ||
then: | ||
function: camara-reserved-words | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-parameters-descriptions: | ||
message: "Parameter description is missing or empty: {{error}}" | ||
severity: warn | ||
description: | | ||
This Spectral rule ensures that each parameter in the API specification, including components and properties, has a descriptive and meaningful description. | ||
given: | ||
- "$.components.*.*" | ||
- "$.components.*.*.properties.*" | ||
then: | ||
field: description | ||
function: truthy | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-operation-summary: | ||
message: "Operation Summary Warning: Each operation should include a short summary for better understanding." | ||
severity: warn | ||
description: | | ||
This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a meaningful summary. | ||
Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. | ||
given: | ||
- "$.paths.*.post" | ||
- "$.paths.*.get" | ||
- "$.paths.*.delete" | ||
- "$.paths.*.put" | ||
- "$.paths.*.patch" | ||
- "$.paths.*.options" | ||
then: | ||
field: summary | ||
function: truthy | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-discriminator-use: | ||
description: | | ||
Ensure that API definition YAML files with oneOf or anyOf sections include a discriminator object for serialization, deserialization, and validation. | ||
severity: warn | ||
given: "$..[?(@.oneOf || @.anyOf)]" | ||
then: | ||
field: discriminator | ||
function: truthy | ||
description: "Discriminator object is required when using oneOf or anyOf." | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-operationid-casing-convention: | ||
message: Operation Id must be in Camel case "{{error}}" | ||
severity: hint | ||
description: | | ||
This rule checks Operation ids should follow a specific case convention: camel case. | ||
given: "$.paths.*.*.operationId" | ||
then: | ||
function: casing | ||
functionOptions: | ||
type: camel | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-schema-casing-convention: | ||
description: This rule checks schema should follow a specific case convention pascal case. | ||
message: "{{property}} should be pascal case (UppperCamelCase)" | ||
severity: warn | ||
given: $.components.schemas[*]~ | ||
then: | ||
function: casing | ||
functionOptions: | ||
type: pascal | ||
recommended: true # Set to true/false to enable/disable this rule | ||
|
||
camara-parameter-casing-convention: | ||
rartych marked this conversation as resolved.
Show resolved
Hide resolved
|
||
description: This rule checks Paths should follow a specific case convention kebab-case. | ||
severity: error | ||
message: "{{property}} should be kebab-case: {{error}}" | ||
given: $.paths[*]~ | ||
then: | ||
function: casing | ||
functionOptions: | ||
type: kebab | ||
recommended: true # Set to true/false to enable/disable this rule |
37 changes: 37 additions & 0 deletions
37
artifacts/linting_rules/lint_function/camara-language-avoid-telco.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const replacements = [ | ||
{ original: 'UE', recommended: 'device' }, | ||
{ original: 'MSISDN', recommended: 'phone number' }, | ||
{ original: 'mobile network', recommended: 'network' } | ||
]; | ||
|
||
export default async function (input) { | ||
const errors = []; | ||
const suggestions = []; | ||
|
||
// Iterate over properties of the input object | ||
for (const path in input) { | ||
const value = input[path]; | ||
|
||
// Check if the value is a string | ||
if (typeof value === 'string') { | ||
for (const replacement of replacements) { | ||
const original = replacement.original; | ||
const recommended = replacement.recommended; | ||
|
||
// Use a regular expression to match 'original' as a standalone word | ||
const regex = new RegExp(`\\b${original}\\b`, 'g'); | ||
|
||
// Check if 'original' exists in the value | ||
if (regex.test(value)) { | ||
errors.push(replacement); | ||
suggestions.push(` Telco-specific terminology found in input: Consider replacing '${original}' with '${recommended}'.`); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Check if any word from 'replacements' is in the suggestions | ||
if (errors.length > 0) { | ||
console.log(`Hint camara-language-avoid-telco ` + suggestions.join(', ')); | ||
} | ||
}; |
95 changes: 95 additions & 0 deletions
95
artifacts/linting_rules/lint_function/camara-reserved-words.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
const reservedWords = [ | ||
'abstract', | ||
'apiclient', | ||
'apiexception', | ||
'apiresponse', | ||
'assert', | ||
'boolean', | ||
'break', | ||
'byte', | ||
'case', | ||
'catch', | ||
'char', | ||
'class', | ||
'configuration', | ||
'const', | ||
'continue', | ||
'do', | ||
'double', | ||
'else', | ||
'extends', | ||
'file', | ||
'final', | ||
'finally', | ||
'float', | ||
'for', | ||
'goto', | ||
'if', | ||
'implements', | ||
'import', | ||
'instanceof', | ||
'int', | ||
'interface', | ||
'list', | ||
'localdate', | ||
'localreturntype', | ||
'localtime', | ||
'localvaraccept', | ||
'localvaraccepts', | ||
'localvarauthnames', | ||
'localvarcollectionqueryparams', | ||
'localvarcontenttype', | ||
'localvarcontenttypes', | ||
'localvarcookieparams', | ||
'localvarformparams', | ||
'localvarheaderparams', | ||
'localvarpath', | ||
'localvarpostbody', | ||
'localvarqueryparams', | ||
'long', | ||
'native', | ||
'new', | ||
'null', | ||
'object', | ||
'offsetdatetime', | ||
'package', | ||
'private', | ||
'protected', | ||
'public', | ||
rartych marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'return', | ||
'short', | ||
'static', | ||
'strictfp', | ||
'stringutil', | ||
'super', | ||
'switch', | ||
'synchronized', | ||
'this', | ||
'throw', | ||
'throws', | ||
'transient', | ||
'try', | ||
'void', | ||
'volatile', | ||
'while' | ||
]; | ||
// Reserved word 'enum' and 'default' are removed from above reserved word array as they are common in openAPI keyword | ||
export default async function lintReservedWords(input) { | ||
// Iterate over properties of the input object | ||
for (const path in input) { | ||
if (typeof path === 'string') { | ||
|
||
for (const word of reservedWords) { | ||
const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word | ||
|
||
if (regex.test(path)) { | ||
const warningRuleName = 'camara-reserved-words'; | ||
const description = `Reserved words found in input: Consider avoiding the use of reserved word '${word}'`; | ||
// const location = `${path}`; | ||
|
||
console.log(`warning ${warningRuleName} ${description} ${path}`); | ||
} | ||
} | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
...cts/linting_rules/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const sensitiveData = ['MSISDN','IMSI','phoneNumber']; | ||
|
||
export default async function (input) { | ||
|
||
// Iterate over properties of the input object | ||
for (const path in input) { | ||
|
||
if (typeof path === 'string') { | ||
for (const word of sensitiveData ) { | ||
const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word | ||
|
||
if (regex.test(path)) { | ||
|
||
const warningRuleName = 'camara-security-no-secrets-in-path-or-query-parameters'; | ||
const description = `sensitiveData Data found in path: Consider avoiding the use of sensitiveData data '${word}'`; | ||
const location = `paths.${path}`; | ||
console.log(`warning ${warningRuleName} ${description} ${location}`); | ||
|
||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not all usages of oneOf/anyOf are related to polymorphism, e.g. https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/qod-api.yaml#L963