Skip to content

Commit

Permalink
feat(ns-openapi-3-1): add security normalization refractor plugin (#2368
Browse files Browse the repository at this point in the history
)

Refs #2362
  • Loading branch information
char0n authored Dec 13, 2022
1 parent 6d0b84a commit 5ca21e3
Show file tree
Hide file tree
Showing 11 changed files with 1,063 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/apidom-ns-openapi-3-1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export { default } from './namespace';

export { default as refractorPluginReplaceEmptyElement } from './refractor/plugins/replace-empty-element';
export { default as refractorPluginNormalizeParameters } from './refractor/plugins/normalize-parameters';
export { default as refractorPluginNormalizeSecurityRequirements } from './refractor/plugins/normalize-security-requirements';

export {
isCallbackElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const parameterEquals = (parameter1: ParameterElement, parameter2: ParameterElem
};

/**
* Duplication of Parameter Objects.
* Inheritance of Parameter Objects.
*
* OpenAPI 3.1 specification excerpt that defines the duplication behavior:
* OpenAPI 3.1 specification excerpt that defines the inheritance behavior:
*
* A list of parameters that are applicable for this operation. If a parameter is already defined at the Path Item,
* the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { isArrayElement, ArrayElement } from '@swagger-api/apidom-core';
import { OperationSecurityElement } from '@swagger-api/apidom-ns-openapi-3-0';

import OpenApi3_1Element from '../../elements/OpenApi3-1';
import OperationElement from '../../elements/Operation';
import { isComponentsElement } from '../../predicates';

/**
* Override of Security Requirement Objects.
*
* OpenAPI 3.1 specification excerpt that defines the override behavior:
*
* Operation.security definition overrides any declared top-level security.
* To remove a top-level security declaration, an empty array can be used.
* When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object,
* only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.
*/

/* eslint-disable no-param-reassign */
const plugin = () => () => {
let topLevelSecurity: ArrayElement | undefined;

return {
visitor: {
OpenApi3_1Element: {
enter(openapiElement: OpenApi3_1Element) {
if (isArrayElement(openapiElement.security)) {
topLevelSecurity = openapiElement.security;
return undefined;
}
return false;
},
leave() {
topLevelSecurity = undefined;
},
},
OperationElement: {
leave(
operationElement: OperationElement,
key: any,
parent: any,
path: any,
ancestors: any[],
) {
// skip visiting this Operation
if (ancestors.some(isComponentsElement)) {
return false;
}

const missingOperationLevelSecurity = typeof operationElement.security === 'undefined';
const hasTopLevelSecurity = typeof topLevelSecurity !== 'undefined';

if (missingOperationLevelSecurity && hasTopLevelSecurity) {
operationElement.security = new OperationSecurityElement(topLevelSecurity?.content);
}

return undefined;
},
},
},
};
};
/* eslint-enable */

export default plugin;
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`refractor plugins normalize-security-requirements given OpenAPI.security fixed field is defined and Operation.security contains single Security Requirement should not inherit Security Requirements from OpenAPI.security field 1`] = `
(OpenApi3_1Element
(MemberElement
(StringElement)
(OpenapiElement))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement))))))
(MemberElement
(StringElement)
(PathsElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(CallbackElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement)))))))))))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement)))))))))))))
`;

exports[`refractor plugins normalize-security-requirements given OpenAPI.security fixed field is defined and Operation.security is defined as empty list should not inherit Security Requirements from OpenAPI.security field 1`] = `
(OpenApi3_1Element
(MemberElement
(StringElement)
(OpenapiElement))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement))))))
(MemberElement
(StringElement)
(PathsElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(CallbackElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ArrayElement))))))))))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement)))))))))))))
`;

exports[`refractor plugins normalize-security-requirements given OpenAPI.security fixed field is defined and Operation.security is not defined should inherit Security Requirements from OpenAPI.security field 1`] = `
(OpenApi3_1Element
(MemberElement
(StringElement)
(OpenapiElement))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement))))))
(MemberElement
(StringElement)
(PathsElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(CallbackElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement))))))))))))))
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement
(MemberElement
(StringElement)
(ArrayElement
(StringElement)
(StringElement)))))))))))))
`;

exports[`refractor plugins normalize-security-requirements given OpenAPI.security fixed field is not defined and Operation.security is defined should do nothing 1`] = `
(OpenApi3_1Element
(MemberElement
(StringElement)
(OpenapiElement))
(MemberElement
(StringElement)
(PathsElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(CallbackElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ArrayElement
(SecurityRequirementElement))))))))))))))))))
`;

exports[`refractor plugins normalize-security-requirements given OpenAPI.security fixed field is not defined and Operation.security is not defined should do nothing 1`] = `
(OpenApi3_1Element
(MemberElement
(StringElement)
(OpenapiElement))
(MemberElement
(StringElement)
(PathsElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(CallbackElement
(MemberElement
(StringElement)
(PathItemElement
(MemberElement
(StringElement)
(OperationElement)))))))))))))))
`;
Loading

0 comments on commit 5ca21e3

Please sign in to comment.