Skip to content

Commit 372fc95

Browse files
CLOUDP-272001: IPA-112: Disallow usages of project in the api
1 parent a167f9b commit 372fc95

File tree

4 files changed

+382
-0
lines changed

4 files changed

+382
-0
lines changed
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-112-avoid-project-field-names', [
5+
{
6+
name: 'valid schema - no project field names',
7+
document: {
8+
components: {
9+
schemas: {
10+
SchemaName: {
11+
properties: {
12+
group: { type: 'string' },
13+
groupId: { type: 'string' },
14+
otherField: { type: 'number' }
15+
}
16+
}
17+
}
18+
}
19+
},
20+
errors: []
21+
},
22+
{
23+
name: 'invalid schema - with project field name',
24+
document: {
25+
components: {
26+
schemas: {
27+
SchemaName: {
28+
properties: {
29+
project: { type: 'string' }
30+
}
31+
}
32+
}
33+
}
34+
},
35+
errors: [
36+
{
37+
code: 'xgen-IPA-112-avoid-project-field-names',
38+
message: 'Field name "project" should be avoided. Consider using "group", "groups", or "groupId" instead.',
39+
path: ['components', 'schemas', 'SchemaName', 'properties', 'project'],
40+
severity: DiagnosticSeverity.Warning
41+
}
42+
]
43+
},
44+
{
45+
name: 'invalid schema - with projects field name',
46+
document: {
47+
components: {
48+
schemas: {
49+
SchemaName: {
50+
properties: {
51+
projects: { type: 'array' }
52+
}
53+
}
54+
}
55+
}
56+
},
57+
errors: [
58+
{
59+
code: 'xgen-IPA-112-avoid-project-field-names',
60+
message: 'Field name "projects" should be avoided. Consider using "group", "groups", or "groupId" instead.',
61+
path: ['components', 'schemas', 'SchemaName', 'properties', 'projects'],
62+
severity: DiagnosticSeverity.Warning
63+
}
64+
]
65+
},
66+
{
67+
name: 'invalid schema - with projectId field name',
68+
document: {
69+
components: {
70+
schemas: {
71+
SchemaName: {
72+
properties: {
73+
projectId: { type: 'string' }
74+
}
75+
}
76+
}
77+
}
78+
},
79+
errors: [
80+
{
81+
code: 'xgen-IPA-112-avoid-project-field-names',
82+
message: 'Field name "projectId" should be avoided. Consider using "group", "groups", or "groupId" instead.',
83+
path: ['components', 'schemas', 'SchemaName', 'properties', 'projectId'],
84+
severity: DiagnosticSeverity.Warning
85+
}
86+
]
87+
},
88+
{
89+
name: 'invalid schema - with different case variants',
90+
document: {
91+
components: {
92+
schemas: {
93+
SchemaName: {
94+
properties: {
95+
Project: { type: 'string' },
96+
PROJECTID: { type: 'string' }
97+
}
98+
}
99+
}
100+
}
101+
},
102+
errors: [
103+
{
104+
code: 'xgen-IPA-112-avoid-project-field-names',
105+
message: 'Field name "Project" should be avoided. Consider using "group", "groups", or "groupId" instead.',
106+
path: ['components', 'schemas', 'SchemaName', 'properties', 'Project'],
107+
severity: DiagnosticSeverity.Warning
108+
},
109+
{
110+
code: 'xgen-IPA-112-avoid-project-field-names',
111+
message: 'Field name "PROJECTID" should be avoided. Consider using "group", "groups", or "groupId" instead.',
112+
path: ['components', 'schemas', 'SchemaName', 'properties', 'PROJECTID'],
113+
severity: DiagnosticSeverity.Warning
114+
}
115+
]
116+
},
117+
{
118+
name: 'invalid schema with exception - project field name with exception',
119+
document: {
120+
components: {
121+
schemas: {
122+
SchemaName: {
123+
properties: {
124+
project: {
125+
type: 'string',
126+
'x-xgen-IPA-exception': {
127+
'xgen-IPA-112-avoid-project-field-names': 'reason'
128+
}
129+
}
130+
}
131+
}
132+
}
133+
}
134+
},
135+
errors: []
136+
},
137+
{
138+
name: 'paths with project field name',
139+
document: {
140+
paths: {
141+
'/api/resource': {
142+
post: {
143+
requestBody: {
144+
content: {
145+
'application/json': {
146+
schema: {
147+
properties: {
148+
project: { type: 'string' }
149+
}
150+
}
151+
}
152+
}
153+
}
154+
}
155+
}
156+
}
157+
},
158+
errors: [
159+
{
160+
code: 'xgen-IPA-112-avoid-project-field-names',
161+
message: 'Field name "project" should be avoided. Consider using "group", "groups", or "groupId" instead.',
162+
path: ['paths', '/api/resource', 'post', 'requestBody', 'content', 'application/json', 'schema', 'properties', 'project'],
163+
severity: DiagnosticSeverity.Warning
164+
}
165+
]
166+
},
167+
{
168+
name: 'field name containing project substring',
169+
document: {
170+
components: {
171+
schemas: {
172+
SchemaName: {
173+
properties: {
174+
myProjectDetails: { type: 'object' }
175+
}
176+
}
177+
}
178+
}
179+
},
180+
errors: [
181+
{
182+
code: 'xgen-IPA-112-avoid-project-field-names',
183+
message: 'Field name "myProjectDetails" should be avoided. Consider using "group", "groups", or "groupId" instead.',
184+
path: ['components', 'schemas', 'SchemaName', 'properties', 'myProjectDetails'],
185+
severity: DiagnosticSeverity.Warning
186+
}
187+
]
188+
},
189+
{
190+
name: 'exception - field with project substring',
191+
document: {
192+
components: {
193+
schemas: {
194+
SchemaName: {
195+
properties: {
196+
myProjectDetails: {
197+
type: 'object',
198+
'x-xgen-IPA-exception': {
199+
'xgen-IPA-112-avoid-project-field-names': 'Legacy field name that cannot be changed'
200+
}
201+
}
202+
}
203+
}
204+
}
205+
}
206+
},
207+
errors: []
208+
},
209+
{
210+
name: 'exception - multiple project fields',
211+
document: {
212+
components: {
213+
schemas: {
214+
SchemaName: {
215+
properties: {
216+
projectId: {
217+
type: 'string',
218+
'x-xgen-IPA-exception': {
219+
'xgen-IPA-112-avoid-project-field-names': 'External API compatibility'
220+
}
221+
},
222+
projects: {
223+
type: 'array',
224+
'x-xgen-IPA-exception': {
225+
'xgen-IPA-112-avoid-project-field-names': 'External API compatibility'
226+
}
227+
}
228+
}
229+
}
230+
}
231+
}
232+
},
233+
errors: []
234+
},
235+
{
236+
name: 'exception - schema level exception for all properties',
237+
document: {
238+
components: {
239+
schemas: {
240+
SchemaName: {
241+
'x-xgen-IPA-exception': {
242+
'xgen-IPA-112-avoid-project-field-names': 'Legacy schema that cannot be changed'
243+
},
244+
properties: {
245+
projectId: { type: 'string' },
246+
projects: { type: 'array' },
247+
myProjectDetails: { type: 'object' }
248+
}
249+
}
250+
}
251+
}
252+
},
253+
errors: []
254+
},
255+
{
256+
name: 'exception - in paths',
257+
document: {
258+
paths: {
259+
'/api/resource': {
260+
post: {
261+
requestBody: {
262+
content: {
263+
'application/json': {
264+
schema: {
265+
properties: {
266+
project: {
267+
type: 'string',
268+
'x-xgen-IPA-exception': {
269+
'xgen-IPA-112-avoid-project-field-names': 'Third-party integration requirement'
270+
}
271+
}
272+
}
273+
}
274+
}
275+
}
276+
}
277+
}
278+
}
279+
}
280+
},
281+
errors: []
282+
},
283+
{
284+
name: 'mixed valid, invalid, and exception fields',
285+
document: {
286+
components: {
287+
schemas: {
288+
SchemaName: {
289+
properties: {
290+
project: {
291+
type: 'string',
292+
'x-xgen-IPA-exception': {
293+
'xgen-IPA-112-avoid-project-field-names': 'Legacy field'
294+
}
295+
},
296+
projectId: { type: 'string' },
297+
group: { type: 'string' }
298+
}
299+
}
300+
}
301+
}
302+
},
303+
errors: [
304+
{
305+
code: 'xgen-IPA-112-avoid-project-field-names',
306+
message: 'Field name "projectId" should be avoided. Consider using "group", "groups", or "groupId" instead.',
307+
path: ['components', 'schemas', 'SchemaName', 'properties', 'projectId'],
308+
severity: DiagnosticSeverity.Warning
309+
}
310+
]
311+
}
312+
]);

tools/spectral/ipa/ipa-spectral.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extends:
77
- ./rulesets/IPA-107.yaml
88
- ./rulesets/IPA-108.yaml
99
- ./rulesets/IPA-109.yaml
10+
- ./rulesets/IPA-112.yaml
1011
- ./rulesets/IPA-113.yaml
1112
- ./rulesets/IPA-123.yaml
1213

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# IPA-112: Field Names
2+
# http://go/ipa/112
3+
4+
functions:
5+
- IPA112AvoidProjectFieldNames
6+
7+
rules:
8+
xgen-IPA-112-avoid-project-field-names:
9+
description: |
10+
Schema field names should avoid using "project", "projects", or "projectId".
11+
12+
##### Implementation details
13+
Rule checks for the following conditions:
14+
- Searches through all schemas in the API definition
15+
- Identifies property names that match "group", "groups", or "groupId" (case-insensitive)
16+
- Reports any instances where these field names are used
17+
- Suggests using "group", "groups", or "groupId" as alternatives
18+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-112-avoid-project-field-names'
19+
severity: warn
20+
given: '$..[?(@.properties)]'
21+
then:
22+
field: @key
23+
function: 'IPA112AvoidProjectFieldNames'
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
import { hasException } from './utils/exceptions.js';
3+
import {
4+
collectAdoption,
5+
collectAndReturnViolation,
6+
collectException, handleInternalError,
7+
} from './utils/collectionUtils.js';
8+
import { resolveObject } from './utils/componentUtils.js';
9+
10+
const RULE_NAME = 'xgen-IPA-112-avoid-project-field-names';
11+
12+
export default (input, _, { path, documentInventory }) => {
13+
const oas = documentInventory.resolved;
14+
const property = resolveObject(oas, path);
15+
16+
if (hasException(property, RULE_NAME)) {
17+
collectException(property, RULE_NAME, path);
18+
return;
19+
}
20+
21+
const errors = checkViolationsAndReturnErrors(input, path);
22+
if (errors.length !== 0) {
23+
return collectAndReturnViolation(path, RULE_NAME, errors);
24+
}
25+
collectAdoption(input, RULE_NAME);
26+
};
27+
28+
function checkViolationsAndReturnErrors(input, path) {
29+
const errors = [];
30+
try {
31+
const prohibitedName = "project";
32+
33+
const lowerPropertyName = input.toLowerCase();
34+
35+
if (lowerPropertyName.includes(prohibitedName)) {
36+
errors.push({
37+
path,
38+
message: `Field name "${input}" should be avoided. Consider using "group", "groups", or "groupId" instead.`
39+
});
40+
}
41+
42+
return errors;
43+
} catch (e) {
44+
handleInternalError(RULE_NAME, path, e);
45+
}
46+
}

0 commit comments

Comments
 (0)