Skip to content

Commit f9de223

Browse files
CLOUDP-306570: Rule xgen-IPA-117-description-must-not-use-html (#604)
1 parent 1448759 commit f9de223

File tree

6 files changed

+206
-2
lines changed

6 files changed

+206
-2
lines changed

tools/spectral/ipa/__tests__/IPA117DescriptionEndsWithPeriod.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ testRule('xgen-IPA-117-description-ends-with-period', [
6161
errors: [],
6262
},
6363
{
64-
name: 'invalid components with exceptions',
64+
name: 'invalid description with exceptions',
6565
document: {
6666
components: {
6767
schemas: {
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-117-description-must-not-use-html', [
5+
{
6+
name: 'valid description',
7+
document: {
8+
components: {
9+
schemas: {
10+
Schema: {
11+
properties: {
12+
valid: {
13+
description: 'Description.',
14+
},
15+
validWithAngleBracket: {
16+
description: 'Must be < 250 characters.',
17+
},
18+
validWithAngleBrackets: {
19+
description: 'For example <username>:<password>',
20+
},
21+
},
22+
},
23+
},
24+
},
25+
},
26+
errors: [],
27+
},
28+
{
29+
name: 'invalid descriptions',
30+
document: {
31+
components: {
32+
schemas: {
33+
Schema: {
34+
properties: {
35+
html: {
36+
description: '<a>Description</a>',
37+
},
38+
link: {
39+
description: 'To learn more, see <a href="https://www.mongodb.com/">MongoDB</a>',
40+
},
41+
inlineHtml: {
42+
description: 'This is something. <a>Description</a>',
43+
},
44+
selfClosingHtml: {
45+
description: 'This is something.<br/>With a line break.',
46+
},
47+
},
48+
},
49+
},
50+
},
51+
},
52+
errors: [
53+
{
54+
code: 'xgen-IPA-117-description-must-not-use-html',
55+
message: 'Descriptions must not use raw HTML.',
56+
path: ['components', 'schemas', 'Schema', 'properties', 'html'],
57+
severity: DiagnosticSeverity.Warning,
58+
},
59+
{
60+
code: 'xgen-IPA-117-description-must-not-use-html',
61+
message:
62+
'Descriptions must not use raw HTML. If you want to link to additional documentation, please use the externalDocumentation property (https://swagger.io/specification/#external-documentation-object).',
63+
path: ['components', 'schemas', 'Schema', 'properties', 'link'],
64+
severity: DiagnosticSeverity.Warning,
65+
},
66+
{
67+
code: 'xgen-IPA-117-description-must-not-use-html',
68+
message: 'Descriptions must not use raw HTML.',
69+
path: ['components', 'schemas', 'Schema', 'properties', 'inlineHtml'],
70+
severity: DiagnosticSeverity.Warning,
71+
},
72+
{
73+
code: 'xgen-IPA-117-description-must-not-use-html',
74+
message: 'Descriptions must not use raw HTML.',
75+
path: ['components', 'schemas', 'Schema', 'properties', 'selfClosingHtml'],
76+
severity: DiagnosticSeverity.Warning,
77+
},
78+
],
79+
},
80+
{
81+
name: 'invalid descriptions with exceptions',
82+
document: {
83+
components: {
84+
schemas: {
85+
Schema: {
86+
properties: {
87+
html: {
88+
description: '<a>Description</a>',
89+
'x-xgen-IPA-exception': {
90+
'xgen-IPA-117-description-must-not-use-html': 'reason',
91+
},
92+
},
93+
inlineHtml: {
94+
description: 'This is something. <a>Description</a>',
95+
'x-xgen-IPA-exception': {
96+
'xgen-IPA-117-description-must-not-use-html': 'reason',
97+
},
98+
},
99+
selfClosingHtml: {
100+
description: 'This is something.</br>With a line break.',
101+
'x-xgen-IPA-exception': {
102+
'xgen-IPA-117-description-must-not-use-html': 'reason',
103+
},
104+
},
105+
},
106+
},
107+
},
108+
},
109+
},
110+
errors: [],
111+
},
112+
]);

tools/spectral/ipa/__tests__/IPA117DescriptionStartsWithUpperCase.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ testRule('xgen-IPA-117-description-starts-with-uppercase', [
4444
],
4545
},
4646
{
47-
name: 'invalid components with exceptions',
47+
name: 'invalid description with exceptions',
4848
document: {
4949
components: {
5050
schemas: {

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ functions:
55
- IPA117HasDescription
66
- IPA117DescriptionStartsWithUpperCase
77
- IPA117DescriptionEndsWithPeriod
8+
- IPA117DescriptionMustNotUseHtml
89

910
rules:
1011
xgen-IPA-117-description:
@@ -81,3 +82,28 @@ rules:
8182
- '$.components.parameters[*]'
8283
then:
8384
function: 'IPA117DescriptionEndsWithPeriod'
85+
xgen-IPA-117-description-must-not-use-html:
86+
description: |
87+
Descriptions must not use raw HTML.
88+
89+
##### Implementation details
90+
Rule checks the format of the descriptions for components:
91+
- Info object
92+
- Tags
93+
- Operation objects
94+
- Inline schema properties for operation object requests and responses
95+
- Parameter objects (in operations and components)
96+
- Schema properties
97+
The rule validates that the description content does not include opening and/or closing HTML tags.
98+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-description-must-not-use-html'
99+
severity: warn
100+
given:
101+
- '$.info'
102+
- '$.tags[*]'
103+
- '$.paths[*][get,put,post,delete,options,head,patch,trace]'
104+
- '$.paths[*][get,put,post,delete,options,head,patch,trace].parameters[*]'
105+
- '$.paths[*][get,put,post,delete,options,head,patch,trace]..content..properties[*]'
106+
- '$.components.schemas..properties[*]'
107+
- '$.components.parameters[*]'
108+
then:
109+
function: 'IPA117DescriptionMustNotUseHtml'

tools/spectral/ipa/rulesets/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,21 @@ Rule checks the format of the description property in the following components:
602602
- Schema properties
603603
The rule ignores descriptions that end with `|`, i.e. inline markdown tables
604604

605+
#### xgen-IPA-117-description-must-not-use-html
606+
607+
![warn](https://img.shields.io/badge/warning-yellow)
608+
Descriptions must not use raw HTML.
609+
610+
##### Implementation details
611+
Rule checks the format of the descriptions for components:
612+
- Info object
613+
- Tags
614+
- Operation objects
615+
- Inline schema properties for operation object requests and responses
616+
- Parameter objects (in operations and components)
617+
- Schema properties
618+
The rule validates that the description content does not include opening and/or closing HTML tags.
619+
605620

606621

607622
### IPA-123
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { hasException } from './utils/exceptions.js';
2+
import {
3+
collectAdoption,
4+
collectAndReturnViolation,
5+
collectException,
6+
handleInternalError,
7+
} from './utils/collectionUtils.js';
8+
9+
const RULE_NAME = 'xgen-IPA-117-description-must-not-use-html';
10+
const ERROR_MESSAGE = 'Descriptions must not use raw HTML.';
11+
12+
export default (input, opts, { path }) => {
13+
// Ignore missing descriptions
14+
if (!input['description']) {
15+
return;
16+
}
17+
18+
if (hasException(input, RULE_NAME)) {
19+
collectException(input, RULE_NAME, path);
20+
return;
21+
}
22+
23+
const errors = checkViolationsAndReturnErrors(input['description'], path);
24+
if (errors.length !== 0) {
25+
return collectAndReturnViolation(path, RULE_NAME, errors);
26+
}
27+
collectAdoption(path, RULE_NAME);
28+
};
29+
30+
function checkViolationsAndReturnErrors(description, path) {
31+
const htmlTagPattern = new RegExp(`<.*>.*</.*>`);
32+
const htmlTagSelfClosingPattern = new RegExp(`<.*/>`);
33+
const linkHtmlPattern = new RegExp(`<a.*>.*</a>`);
34+
35+
try {
36+
if (htmlTagPattern.test(description) || htmlTagSelfClosingPattern.test(description)) {
37+
if (linkHtmlPattern.test(description)) {
38+
return [
39+
{
40+
path,
41+
message: `${ERROR_MESSAGE} If you want to link to additional documentation, please use the externalDocumentation property (https://swagger.io/specification/#external-documentation-object).`,
42+
},
43+
];
44+
}
45+
return [{ path, message: ERROR_MESSAGE }];
46+
}
47+
return [];
48+
} catch (e) {
49+
handleInternalError(RULE_NAME, path, e);
50+
}
51+
}

0 commit comments

Comments
 (0)