Skip to content

Commit 2c6fff8

Browse files
CLOUDP-304944: Adds xgen-IPA-107-update-method-request-has-no-readonly-fields
1 parent 981b3c8 commit 2c6fff8

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

tools/spectral/ipa/rulesets/IPA-107.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ functions:
55
- IPA107UpdateMethodMustNotHaveQueryParams
66
- IPA107UpdateResponseCodeShouldBe200OK
77
- IPA107UpdateMethodResponseIsGetMethodResponse
8+
- IPA107UpdateMethodRequestHasNoReadonlyFields
89

910
rules:
1011
xgen-IPA-107-put-must-not-have-query-params:
@@ -76,7 +77,7 @@ rules:
7677
##### Implementation details
7778
Rule checks for the following conditions:
7879
- Applies only to single resource paths with JSON content types
79-
- Ignores singleton resources and responses without a schema
80+
- Ignores singleton resources and responses without a schema
8081
- Validation ignores resources without a Get method
8182
- Fails if the Get method doesn't have a schema reference or if the schemas don't match
8283
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
@@ -86,3 +87,19 @@ rules:
8687
then:
8788
field: '@key'
8889
function: 'IPA107UpdateMethodResponseIsGetMethodResponse'
90+
xgen-IPA-107-update-method-request-has-no-readonly-fields:
91+
description: |
92+
Update method Request object must not include fields with readOnly:true.
93+
94+
##### Implementation details
95+
Rule checks for the following conditions:
96+
- Applies only to Update methods on single resource paths
97+
- Applies only to JSON content types
98+
- Searches through the request schema to find any properties marked with readOnly attribute
99+
- Fails if any readOnly properties are found in the request schema
100+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-107-update-method-request-has-no-readonly-fields'
101+
severity: warn
102+
given: '$.paths[*][put,patch].requestBody.content'
103+
then:
104+
field: '@key'
105+
function: 'IPA107UpdateMethodRequestHasNoReadonlyFields'
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { isSingleResourceIdentifier } from './utils/resourceEvaluation.js';
2+
import { resolveObject } from './utils/componentUtils.js';
3+
import { hasException } from './utils/exceptions.js';
4+
import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js';
5+
import { findPropertiesByAttribute } from './utils/schemaUtils.js';
6+
7+
const RULE_NAME = 'xgen-IPA-107-update-method-request-has-no-readonly-fields';
8+
const ERROR_MESSAGE = 'The Update method request object must not include input fields (readOnly properties).';
9+
10+
/**
11+
* Update method (PUT, PATCH) request objects must not include input fields (readOnly properties).
12+
*
13+
* @param {object} input - An update operation request content version
14+
* @param {object} _ - Unused
15+
* @param {{ path: string[], documentInventory: object}} context - The context object containing the path and document
16+
*/
17+
export default (input, _, { path, documentInventory }) => {
18+
const resourcePath = path[1];
19+
const oas = documentInventory.resolved;
20+
21+
if (!isSingleResourceIdentifier(resourcePath) || !input.endsWith('json')) {
22+
return;
23+
}
24+
25+
const requestContentPerMediaType = resolveObject(oas, path);
26+
if (!requestContentPerMediaType || !requestContentPerMediaType.schema) {
27+
return;
28+
}
29+
30+
if (hasException(requestContentPerMediaType, RULE_NAME)) {
31+
collectException(requestContentPerMediaType, RULE_NAME, path);
32+
return;
33+
}
34+
35+
const errors = checkViolationsAndReturnErrors(requestContentPerMediaType, path);
36+
37+
if (errors.length !== 0) {
38+
return collectAndReturnViolation(path, RULE_NAME, errors);
39+
}
40+
41+
collectAdoption(path, RULE_NAME);
42+
};
43+
44+
function checkViolationsAndReturnErrors(contentPerMediaType, path) {
45+
return findPropertiesByAttribute(contentPerMediaType.schema, 'readOnly', path, [], ERROR_MESSAGE);
46+
}

0 commit comments

Comments
 (0)