-
Notifications
You must be signed in to change notification settings - Fork 98
feat(ibm-redirect-response-body): introduce new validation rule #758
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
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
a8a0703
fix(ibm-response-status-body): introduce new validation rule
diatrcz 3236bb5
feat(ibm-response-status-body): add new rule
diatrcz 0a43d36
feat(ibm-response-status-body): introduce new validation rule
diatrcz 7522be1
feat(ibm-response-status-body): introduce new validation rule
diatrcz 9f94d35
feat(ibm-response-status-body): introduce new validation rule
diatrcz f9ced0d
Merge branch 'main' into lt/add-redirect-rule
diatrcz d04e507
feat(ibm-response-status-body): introduce new validation rule
diatrcz 9a60dbd
Merge branch 'lt/add-redirect-rule' of https://github.com/IBM/openapi…
diatrcz 273663a
feat(ibm-response-status-body): add small fixes to the rule
diatrcz a0c2eda
feat(ibm-response-status-body): add small fixes to the rule
diatrcz 3766dde
feat(ibm-response-status-body): rename rule
diatrcz 927e1e8
feat(ibm-redirect-response-body): rename rule
diatrcz 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 hidden or 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
This file contains hidden or 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
135 changes: 135 additions & 0 deletions
135
packages/ruleset/src/functions/redirect-response-body.js
This file contains hidden or 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,135 @@ | ||
| /** | ||
| * Copyright 2017 - 2025 IBM Corporation. | ||
| * SPDX-License-Identifier: Apache2.0 | ||
| */ | ||
|
|
||
| const { getResolvedSpec } = require('@ibm-cloud/openapi-ruleset-utilities'); | ||
| const { LoggerFactory, getResponseCodes } = require('../utils'); | ||
|
|
||
| let ruleId; | ||
| let logger; | ||
|
|
||
| module.exports = function (operation, _opts, context) { | ||
| if (!logger) { | ||
| ruleId = context.rule.name; | ||
| logger = LoggerFactory.getInstance().getLogger(ruleId); | ||
| } | ||
|
|
||
| return redirectResponseBody( | ||
| operation, | ||
| context.path, | ||
| getResolvedSpec(context) | ||
| ); | ||
| }; | ||
|
|
||
| /** | ||
| * This function performs a few checks on each operation's response field: | ||
| * 1. Only status codes 301, 302, 305, 307 should include a response body for 30x response codes. | ||
| * 2. Every response body for status codes 30x should contain a value for code that matches on of the following values: | ||
| * forwarded, resolved, moved, remote_region, remote_account, version_mismatch. | ||
| * 3. Every response body for status codes 30x should include "code" property. | ||
| * 4. Every response body for status codes 30x should include "message" property. | ||
| * 5. Every response body for status codes 30x should include "target" property. | ||
| * @param {*} operation an operation within the API definition. | ||
| * @param {*} path the array of path segments indicating the "location" of the operation within the API definition. | ||
| */ | ||
| function redirectResponseBody(operation, path) { | ||
| if (!operation.responses) { | ||
| return []; | ||
| } | ||
|
|
||
| logger.debug( | ||
| `${ruleId}: checking response bodies for operation at location: ${path.join( | ||
| '.' | ||
| )}` | ||
| ); | ||
|
|
||
| const errors = []; | ||
|
|
||
| const [statusCodes] = getResponseCodes(operation.responses); | ||
|
|
||
| if (statusCodes.length) { | ||
| const responseCodesWithBody = ['301', '302', '305', '307']; | ||
| const redirectCodes = [ | ||
| 'forwarded', | ||
| 'resolved', | ||
| 'moved', | ||
| 'remote_region', | ||
| 'remote_account', | ||
| 'version_mismatch', | ||
| ]; | ||
|
|
||
| const redirectResponses = statusCodes.filter(code => code.startsWith('3')); | ||
| if (redirectResponses.length) { | ||
| const responseCodes = redirectResponses.filter( | ||
| code => !responseCodesWithBody.includes(code) | ||
| ); | ||
|
|
||
| // 1. Only status codes 301, 302, 305, 307 should include a response body for 30x response codes. | ||
| responseCodes.forEach(responseCode => { | ||
| const response = operation.responses[responseCode]; | ||
| if (response && response.content) { | ||
| errors.push({ | ||
| message: | ||
| 'Only a 301, 302, 305, 307 response should include a response body', | ||
| path: [...path, 'responses'], | ||
| }); | ||
| } | ||
| }); | ||
|
|
||
| responseCodesWithBody.forEach(code => { | ||
| const response = operation.responses[code]; | ||
| if (response && response.content) { | ||
| const applicationJson = response.content['application/json']; | ||
|
|
||
| if (!applicationJson) return; | ||
|
|
||
| const redirectCode = applicationJson['code']; | ||
| const message = applicationJson['message']; | ||
| const target = applicationJson['target']; | ||
|
|
||
| // 2. Every response body for status codes 30x should contain a value for code that matches one of the following values: | ||
| // forwarded, resolved, moved, remote_region, remote_account, version_mismatch. | ||
| // 3. Every response body for status codes 30x should include "code" property. | ||
| if (redirectCode) { | ||
| for (let i = 0; i < redirectCodes.length; i++) { | ||
| if (redirectCode == redirectCodes[i]) break; | ||
| else if (i === redirectCodes.length - 1) { | ||
| errors.push({ | ||
| message: `Redirect code should match one of the following: ${redirectCodes.join( | ||
| ' or ' | ||
| )}`, | ||
| path: [...path, 'responses'], | ||
| }); | ||
| } | ||
| } | ||
| } else { | ||
| errors.push({ | ||
| message: | ||
| 'Response body for response codes 301, 302, 305 and 307 should include "code" field', | ||
| path: [...path, 'responses'], | ||
| }); | ||
| } | ||
|
|
||
| // 4. Every response body for status codes 30x should include "message" property. | ||
| if (!message) | ||
| errors.push({ | ||
| message: | ||
| 'Response body for response codes 301, 302, 305 and 307 should include "message" field', | ||
| path: [...path, 'responses'], | ||
| }); | ||
|
|
||
| // 5. Every response body for status codes 30x should include "target" property. | ||
| if (!target) | ||
| errors.push({ | ||
| message: | ||
| 'Response body for response codes 301, 302, 305 and 307 should include "target" field', | ||
| path: [...path, 'responses'], | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| return errors; | ||
| } | ||
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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 @@ | ||
| /** | ||
| * Copyright 2017 - 2025 IBM Corporation. | ||
| * SPDX-License-Identifier: Apache2.0 | ||
| */ | ||
|
|
||
| const { | ||
| operations, | ||
| } = require('@ibm-cloud/openapi-ruleset-utilities/src/collections'); | ||
| const { oas3 } = require('@stoplight/spectral-formats'); | ||
| const { redirectResponseBody } = require('../functions'); | ||
|
|
||
| module.exports = { | ||
| description: | ||
| 'Performs multiple checks on the response body based on status codes', | ||
| message: '{{error}}', | ||
| formats: [oas3], | ||
| given: operations, | ||
| severity: 'error', | ||
| resolved: true, | ||
| then: { | ||
| function: redirectResponseBody, | ||
| }, | ||
| }; |
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.
Uh oh!
There was an error while loading. Please reload this page.