Add az-operation-security rule
This commit is contained in:
Родитель
7f4abc93e0
Коммит
15bdf3f67f
|
@ -119,6 +119,10 @@ The `Verb` of the `operationId` should be or contain a specific value depending
|
|||
| patch | "Update" | could be "CreateOrUpdate" |
|
||||
| delete | "Delete" | |
|
||||
|
||||
### az-operation-security
|
||||
|
||||
Every operation should have a security requirement (may be defined globally).
|
||||
|
||||
### az-operation-summary-or-description
|
||||
|
||||
Operation should have a summary or description.
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// Check API definition to ensure conformance to Azure security schemes guidelines.
|
||||
|
||||
// Check:
|
||||
// - Operation (input) has a `security`, or there is a global `security`.
|
||||
|
||||
// @param input - an operation
|
||||
module.exports = (input, options, context) => {
|
||||
if (input === null || typeof input !== 'object') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// If there is a global `security`, no need to check the operation.
|
||||
if (context.document.data.security) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const path = context.path || [];
|
||||
|
||||
if (!input.security) {
|
||||
return [{
|
||||
message: 'Operation should have a security requirement.',
|
||||
path: [...path, 'security'],
|
||||
}];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
|
@ -7,6 +7,7 @@ functions:
|
|||
- has-header
|
||||
- operation-id
|
||||
- pagination-parameters
|
||||
- operation-security
|
||||
- pagination-response
|
||||
- param-names
|
||||
- param-names-unique
|
||||
|
@ -183,6 +184,15 @@ rules:
|
|||
then:
|
||||
function: operation-id
|
||||
|
||||
az-operation-security:
|
||||
description: Operation should have a security requirement or globally.
|
||||
message: Operation should have a security requirement.
|
||||
severity: warn
|
||||
formats: ['oas2', 'oas3']
|
||||
given: $.paths.*[get,put,post,patch,delete,options,head]
|
||||
then:
|
||||
function: operation-security
|
||||
|
||||
az-operation-summary-or-description:
|
||||
description: Operation should have a summary or description.
|
||||
message: Operation should have a summary or description.
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
const { linterForRule } = require('./utils');
|
||||
|
||||
let linter;
|
||||
|
||||
beforeAll(async () => {
|
||||
linter = await linterForRule('az-operation-security');
|
||||
return linter;
|
||||
});
|
||||
|
||||
test('az-operation-security should find operations without security', () => {
|
||||
const oasDoc = {
|
||||
swagger: '2.0',
|
||||
paths: {
|
||||
'/test1': {
|
||||
get: {
|
||||
operationId: 'notNounVerb',
|
||||
},
|
||||
post: {
|
||||
operationId: 'fooBarBaz',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return linter.run(oasDoc).then((results) => {
|
||||
expect(results).toHaveLength(2);
|
||||
expect(results[0].path.join('.')).toBe('paths./test1.get');
|
||||
expect(results[1].path.join('.')).toBe('paths./test1.post');
|
||||
results.forEach((result) => expect(result.message).toContain(
|
||||
'Operation should have a security requirement.',
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
test('az-operation-security should find operations without security', () => {
|
||||
const oasDoc = {
|
||||
openapi: '3.0',
|
||||
paths: {
|
||||
'/test1': {
|
||||
get: {
|
||||
operationId: 'notNounVerb',
|
||||
},
|
||||
post: {
|
||||
operationId: 'fooBarBaz',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return linter.run(oasDoc).then((results) => {
|
||||
expect(results).toHaveLength(2);
|
||||
expect(results[0].path.join('.')).toBe('paths./test1.get');
|
||||
expect(results[1].path.join('.')).toBe('paths./test1.post');
|
||||
results.forEach((result) => expect(result.message).toContain(
|
||||
'Operation should have a security requirement.',
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
test('az-operation-security should find no errors', () => {
|
||||
const oasDoc = {
|
||||
swagger: '2.0',
|
||||
paths: {
|
||||
'/test1': {
|
||||
get: {
|
||||
operationId: 'Noun_Get',
|
||||
security: [{
|
||||
apiKey: [],
|
||||
}],
|
||||
},
|
||||
put: {
|
||||
operationId: 'Noun_Create',
|
||||
security: [{
|
||||
apiKey: [],
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return linter.run(oasDoc).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('az-operation-security should find no errors', () => {
|
||||
const oasDoc = {
|
||||
swagger: '2.0',
|
||||
security: [{
|
||||
apiKey: [],
|
||||
}],
|
||||
paths: {
|
||||
'/test1': {
|
||||
get: {
|
||||
operationId: 'Noun_Get',
|
||||
},
|
||||
put: {
|
||||
operationId: 'Noun_Create',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return linter.run(oasDoc).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('az-operation-security should find no errors', () => {
|
||||
const oasDoc = {
|
||||
openapi: '3.0',
|
||||
security: [{
|
||||
apiKey: [],
|
||||
}],
|
||||
paths: {
|
||||
'/test1': {
|
||||
get: {
|
||||
operationId: 'Noun_Get',
|
||||
},
|
||||
put: {
|
||||
operationId: 'Noun_Create',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return linter.run(oasDoc).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче