-
Notifications
You must be signed in to change notification settings - Fork 14
CLOUDP-287245: IPA-109: Validate custom method must be GET or POST #313
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
Changes from all commits
f3ae4cc
6abdcb0
2d1b379
b16f606
60c888c
1d0d868
2afb4c9
5b191b2
439edfc
a485904
74cc372
5b05efc
df5a94a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import testRule from './__helpers__/testRule'; | ||
import { DiagnosticSeverity } from '@stoplight/types'; | ||
|
||
testRule('xgen-IPA-109-custom-method-must-be-GET-or-POST', [ | ||
{ | ||
name: 'valid methods', | ||
document: { | ||
paths: { | ||
'/a/{exampleId}:method': { | ||
post: {}, | ||
}, | ||
'/a:method': { | ||
post: {}, | ||
}, | ||
'/b/{exampleId}:method': { | ||
get: {}, | ||
}, | ||
'/b:method': { | ||
get: {}, | ||
}, | ||
'/c/{exampleId}:method': { | ||
get: {}, | ||
'x-xgen-IPA-exception': {}, | ||
}, | ||
'/c:method': { | ||
get: {}, | ||
'x-xgen-IPA-exception': {}, | ||
}, | ||
}, | ||
}, | ||
errors: [], | ||
}, | ||
{ | ||
name: 'invalid methods', | ||
document: { | ||
paths: { | ||
'/a/{exampleId}:method': { | ||
put: {}, | ||
}, | ||
'/a:method': { | ||
put: {}, | ||
}, | ||
'/b/{exampleId}:method': { | ||
get: {}, | ||
put: {}, | ||
}, | ||
'/b:method': { | ||
get: {}, | ||
put: {}, | ||
}, | ||
'/c/{exampleId}:method': { | ||
post: {}, | ||
get: {}, | ||
put: {}, | ||
}, | ||
'/c:method': { | ||
post: {}, | ||
get: {}, | ||
put: {}, | ||
}, | ||
'/d/{exampleId}:method': { | ||
post: {}, | ||
get: {}, | ||
}, | ||
'/d:method': { | ||
post: {}, | ||
get: {}, | ||
}, | ||
}, | ||
}, | ||
errors: [ | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/a/{exampleId}:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/a:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/b/{exampleId}:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/b:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/c/{exampleId}:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/c:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/d/{exampleId}:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
{ | ||
code: 'xgen-IPA-109-custom-method-must-be-GET-or-POST', | ||
message: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109', | ||
path: ['paths', '/d:method'], | ||
severity: DiagnosticSeverity.Warning, | ||
}, | ||
], | ||
}, | ||
]); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
extends: | ||
- ./rulesets/IPA-005.yaml | ||
- ./rulesets/IPA-102.yaml | ||
- ./rulesets/IPA-104.yaml | ||
- ./rulesets/IPA-005.yaml | ||
- ./rulesets/IPA-109.yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# IPA-109: Custom Methods | ||
# http://go/ipa/109 | ||
|
||
functions: | ||
- eachCustomMethodMustBeGetOrPost | ||
|
||
rules: | ||
xgen-IPA-109-custom-method-must-be-GET-or-POST: | ||
description: 'The HTTP method for custom methods must be GET or POST. http://go/ipa/109' | ||
message: '{{error}} http://go/ipa/109' | ||
severity: warn | ||
given: '$.paths[*]' | ||
then: | ||
function: 'eachCustomMethodMustBeGetOrPost' |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,29 @@ | ||||
import { isCustomMethod } from './utils/resourceEvaluation.js'; | ||||
|
||||
const ERROR_MESSAGE = 'The HTTP method for custom methods must be GET or POST.'; | ||||
const ERROR_RESULT = [{ message: ERROR_MESSAGE }]; | ||||
const VALID_METHODS = ['get', 'post']; | ||||
const HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']; | ||||
|
||||
export default (input, opts, { path }) => { | ||||
// Extract the path key (e.g., '/a/{exampleId}:method') from the JSONPath. | ||||
let pathKey = path[1]; | ||||
|
||||
if (!isCustomMethod(pathKey)) return; | ||||
|
||||
//Extract the keys which are equivalent of the http methods | ||||
let keys = Object.keys(input); | ||||
const httpMethods = keys.filter((key) => HTTP_METHODS.includes(key)); | ||||
|
||||
// Check for invalid methods | ||||
if (httpMethods.some((method) => !VALID_METHODS.includes(method))) { | ||||
return ERROR_RESULT; | ||||
} | ||||
Comment on lines
+19
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this return error if the path has an exception extension? Suggestion: use openapi/tools/spectral/.spectral.yaml Line 9 in 98f5b23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it would return error with an exception extension. Good catch! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||
|
||||
// Check for multiple valid methods | ||||
const validMethodCount = httpMethods.filter((method) => VALID_METHODS.includes(method)).length; | ||||
|
||||
if (validMethodCount > 1) { | ||||
return ERROR_RESULT; | ||||
} | ||||
}; |
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.
[Just a note for future rules]: I expect we will have other similar rules coming up, at that point we can consider refactoring out a common method to check for valid/invalid methods to the utils package