Skip to content

Commit 8582d4c

Browse files
committed
feat(ls): provide OpenAPI 3.0.x Security Scheme lint rules
Refs #2033
1 parent 649638e commit 8582d4c

18 files changed

+351
-1
lines changed

packages/apidom-ls/src/config/asyncapi/security-scheme/lint/in--equals-api-key.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { LinterMeta } from '../../../../apidom-language-types';
44
const inEqualsApiKeyLint: LinterMeta = {
55
code: ApilintCodes.ASYNCAPI2_SECURITY_SCHEME_FIELD_IN_EQUALS_API_KEY,
66
source: 'apilint',
7-
message: 'type must be one of allowed values',
7+
message: 'in must be one of allowed values',
88
severity: 1,
99
linterFunction: 'apilintValueOrArray',
1010
linterParams: [['user', 'password']],

packages/apidom-ls/src/config/codes.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,21 @@ enum ApilintCodes {
764764
OPENAPI3_0_XML_FIELD_ATTRIBUTE_TYPE = 5230400,
765765
OPENAPI3_0_XML_FIELD_WRAPPED_TYPE = 5230500,
766766

767+
OPENAPI3_SECURITY_SCHEME = 5240000,
768+
OPENAPI3_SECURITY_SCHEME_FIELD_TYPE_EQUALS = 5240100,
769+
OPENAPI3_SECURITY_SCHEME_FIELD_DESCRIPTION_TYPE = 5240200,
770+
OPENAPI3_SECURITY_SCHEME_FIELD_NAME_TYPE = 5240300,
771+
OPENAPI3_SECURITY_SCHEME_FIELD_NAME_REQUIRED,
772+
OPENAPI3_SECURITY_SCHEME_FIELD_IN_EQUALS = 5240400,
773+
OPENAPI3_SECURITY_SCHEME_FIELD_IN_REQUIRED,
774+
OPENAPI3_SECURITY_SCHEME_FIELD_SCHEME_TYPE = 5240500,
775+
OPENAPI3_SECURITY_SCHEME_FIELD_SCHEME_REQUIRED,
776+
OPENAPI3_SECURITY_SCHEME_FIELD_BEARER_FORMAT_TYPE = 5240600,
777+
OPENAPI3_SECURITY_SCHEME_FIELD_FLOWS_TYPE = 5240700,
778+
OPENAPI3_SECURITY_SCHEME_FIELD_FLOWS_REQUIRED,
779+
OPENAPI3_SECURITY_SCHEME_FIELD_OPEN_ID_CONNECT_URL_FORMAT_URI = 5240800,
780+
OPENAPI3_SECURITY_SCHEME_FIELD_OPEN_ID_CONNECT_URL_REQUIRED,
781+
767782
OPENAPI3_1 = 7000000,
768783

769784
OPENAPI3_1_OPENAPI_VALUE_PATTERN_3_1_0 = 7000100,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const allowedFieldsLint: LinterMeta = {
5+
code: ApilintCodes.NOT_ALLOWED_FIELDS,
6+
source: 'apilint',
7+
message: 'Object includes not allowed fields',
8+
severity: 1,
9+
linterFunction: 'allowedFields',
10+
linterParams: [
11+
['type', 'description', 'name', 'in', 'scheme', 'bearerFormat', 'flows', 'openIdConnectUrl'],
12+
'x-',
13+
],
14+
marker: 'key',
15+
};
16+
17+
export default allowedFieldsLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const bearerFormatTypeLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_BEARER_FORMAT_TYPE,
6+
source: 'apilint',
7+
message: 'bearerFormat must be a string',
8+
severity: 1,
9+
linterFunction: 'apilintType',
10+
linterParams: ['string'],
11+
marker: 'value',
12+
target: 'bearerFormat',
13+
data: {},
14+
};
15+
16+
export default bearerFormatTypeLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const descriptionTypeLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_DESCRIPTION_TYPE,
6+
source: 'apilint',
7+
message: 'description must be a string',
8+
severity: 1,
9+
linterFunction: 'apilintType',
10+
linterParams: ['string'],
11+
marker: 'value',
12+
target: 'description',
13+
data: {},
14+
};
15+
16+
export default descriptionTypeLint;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const flowsRequiredLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_FLOWS_REQUIRED,
6+
source: 'apilint',
7+
message: "should always have a 'flows'",
8+
severity: 1,
9+
linterFunction: 'hasRequiredField',
10+
linterParams: ['flows'],
11+
marker: 'key',
12+
data: {
13+
quickFix: [
14+
{
15+
message: "add 'flows' field",
16+
action: 'addChild',
17+
snippetYaml: 'flows: \n ',
18+
snippetJson: '"flows": {},\n ',
19+
},
20+
],
21+
},
22+
conditions: [
23+
{
24+
targets: [{ path: 'type' }],
25+
function: 'apilintContainsValue',
26+
params: ['oauth2'],
27+
},
28+
],
29+
};
30+
31+
export default flowsRequiredLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const flowsTypeLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_FLOWS_TYPE,
6+
source: 'apilint',
7+
message: 'flows must be an object',
8+
severity: 1,
9+
linterFunction: 'apilintElementOrClass',
10+
linterParams: ['flows'],
11+
marker: 'value',
12+
target: 'flows',
13+
data: {},
14+
};
15+
16+
export default flowsTypeLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const inEqualsLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_IN_EQUALS,
6+
source: 'apilint',
7+
message: "'in' must be one of allowed values",
8+
severity: 1,
9+
linterFunction: 'apilintValueOrArray',
10+
linterParams: [['query', 'header', 'cookie']],
11+
marker: 'value',
12+
target: 'in',
13+
data: {},
14+
};
15+
16+
export default inEqualsLint;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const inRequiredLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_IN_REQUIRED,
6+
source: 'apilint',
7+
message: "should always have a 'in'",
8+
severity: 1,
9+
linterFunction: 'hasRequiredField',
10+
linterParams: ['in'],
11+
marker: 'key',
12+
data: {
13+
quickFix: [
14+
{
15+
message: "add 'in' field",
16+
action: 'addChild',
17+
snippetYaml: 'in: \n ',
18+
snippetJson: '"in": "",\n ',
19+
},
20+
],
21+
},
22+
conditions: [
23+
{
24+
targets: [{ path: 'type' }],
25+
function: 'apilintContainsValue',
26+
params: ['apiKey'],
27+
},
28+
],
29+
};
30+
31+
export default inRequiredLint;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import allowedFieldsLint from './allowed-fields';
2+
import typeEquals3_0Lint from './type--equals-3-0';
3+
import descriptionTypeLint from './description--type';
4+
import nameTypeLint from './name--type';
5+
import nameRequiredLint from './name--required';
6+
import inEqualsLint from './in--equals';
7+
import inRequiredLint from './in--required';
8+
import schemeTypeLint from './scheme--type';
9+
import schemeRequiredLint from './scheme--required';
10+
import bearerFormatTypeLint from './bearer-format--type';
11+
import flowsTypeLint from './flows--type';
12+
import flowsRequiredLint from './flows--required';
13+
import openIdConnectUrlFormatURILint from './open-id-connect-url--format-uri';
14+
import openIdConnectUrlRequiredLint from './open-id-connect-url--required';
15+
16+
const lints = [
17+
typeEquals3_0Lint,
18+
descriptionTypeLint,
19+
nameTypeLint,
20+
nameRequiredLint,
21+
inEqualsLint,
22+
inRequiredLint,
23+
schemeTypeLint,
24+
schemeRequiredLint,
25+
bearerFormatTypeLint,
26+
flowsTypeLint,
27+
flowsRequiredLint,
28+
openIdConnectUrlFormatURILint,
29+
openIdConnectUrlRequiredLint,
30+
allowedFieldsLint,
31+
];
32+
33+
export default lints;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const nameRequiredLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_NAME_REQUIRED,
6+
source: 'apilint',
7+
message: "should always have a 'name'",
8+
severity: 1,
9+
linterFunction: 'hasRequiredField',
10+
linterParams: ['name'],
11+
marker: 'key',
12+
data: {
13+
quickFix: [
14+
{
15+
message: "add 'name' field",
16+
action: 'addChild',
17+
snippetYaml: 'name: \n ',
18+
snippetJson: '"name": "",\n ',
19+
},
20+
],
21+
},
22+
conditions: [
23+
{
24+
targets: [{ path: 'type' }],
25+
function: 'apilintContainsValue',
26+
params: ['apiKey'],
27+
},
28+
],
29+
};
30+
31+
export default nameRequiredLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const nameTypeLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_NAME_TYPE,
6+
source: 'apilint',
7+
message: 'name must be a string',
8+
severity: 1,
9+
linterFunction: 'apilintType',
10+
linterParams: ['string'],
11+
marker: 'value',
12+
target: 'name',
13+
data: {},
14+
};
15+
16+
export default nameTypeLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const openIdConnectUrlFormatURILint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_OPEN_ID_CONNECT_URL_FORMAT_URI,
6+
source: 'apilint',
7+
message: 'openIdConnectUrl MUST be in the format of an absolute URL.',
8+
severity: 1,
9+
linterFunction: 'apilintValidURI',
10+
linterParams: [true],
11+
marker: 'value',
12+
target: 'openIdConnectUrl',
13+
data: {},
14+
};
15+
16+
export default openIdConnectUrlFormatURILint;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const openIdConnectUrlRequiredLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_OPEN_ID_CONNECT_URL_REQUIRED,
6+
source: 'apilint',
7+
message: "should always have a 'openIdConnectUrl'",
8+
severity: 1,
9+
linterFunction: 'hasRequiredField',
10+
linterParams: ['openIdConnectUrl'],
11+
marker: 'key',
12+
data: {
13+
quickFix: [
14+
{
15+
message: "add 'openIdConnectUrl' field",
16+
action: 'addChild',
17+
snippetYaml: 'openIdConnectUrl: \n ',
18+
snippetJson: '"openIdConnectUrl": "",\n ',
19+
},
20+
],
21+
},
22+
conditions: [
23+
{
24+
targets: [{ path: 'type' }],
25+
function: 'apilintContainsValue',
26+
params: ['openIdConnect'],
27+
},
28+
],
29+
};
30+
31+
export default openIdConnectUrlRequiredLint;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const schemeRequiredLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_SCHEME_REQUIRED,
6+
source: 'apilint',
7+
message: "should always have a 'scheme'",
8+
severity: 1,
9+
linterFunction: 'hasRequiredField',
10+
linterParams: ['scheme'],
11+
marker: 'key',
12+
data: {
13+
quickFix: [
14+
{
15+
message: "add 'scheme' field",
16+
action: 'addChild',
17+
snippetYaml: 'scheme: \n ',
18+
snippetJson: '"scheme": {},\n ',
19+
},
20+
],
21+
},
22+
conditions: [
23+
{
24+
targets: [{ path: 'type' }],
25+
function: 'apilintContainsValue',
26+
params: ['http'],
27+
},
28+
],
29+
};
30+
31+
export default schemeRequiredLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
const schemeTypeLint: LinterMeta = {
5+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_SCHEME_TYPE,
6+
source: 'apilint',
7+
message: 'scheme must be a string',
8+
severity: 1,
9+
linterFunction: 'apilintType',
10+
linterParams: ['string'],
11+
marker: 'value',
12+
target: 'scheme',
13+
data: {},
14+
};
15+
16+
export default schemeTypeLint;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ApilintCodes from '../../../codes';
2+
import { LinterMeta } from '../../../../apidom-language-types';
3+
4+
// eslint-disable-next-line @typescript-eslint/naming-convention
5+
const typeEquals3_0Lint: LinterMeta = {
6+
code: ApilintCodes.OPENAPI3_SECURITY_SCHEME_FIELD_TYPE_EQUALS,
7+
source: 'apilint',
8+
message: 'type must be one of allowed values',
9+
severity: 1,
10+
linterFunction: 'apilintValueOrArray',
11+
linterParams: [['apiKey', 'http', 'oauth2', 'openIdConnect']],
12+
marker: 'value',
13+
target: 'type',
14+
};
15+
16+
export default typeEquals3_0Lint;

packages/apidom-ls/src/config/openapi/security-scheme/meta.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import lint from './lint';
12
import completion from './completion';
23
import documentation from './documentation';
34
import { FormatMeta } from '../../../apidom-language-types';
45

56
const meta: FormatMeta = {
7+
lint,
68
completion,
79
documentation,
810
};

0 commit comments

Comments
 (0)