src/plugins/validate-semantic/validators/2and3/security.js
export const validate2And3SecurityRequirementsHaveDefinitions = () => (system) => {
const { allSecurityRequirements, allSecurityDefinitions } = system.validateSelectors
return Promise.all([allSecurityRequirements(), allSecurityDefinitions()])
.then(([requirementNodes, definitionNodes]) => {
const definedSecuritySchemes = definitionNodes
.map(node => node.key)
return requirementNodes.reduce((acc, node) => {
const value = node.node
const requiredSecurityDefinitions = Object.keys(value) || []
requiredSecurityDefinitions.forEach(name => {
if(definedSecuritySchemes.indexOf(name) < 0) {
acc.push({
message: "Security requirements must match a security definition",
path: [...node.path],
level: "error",
})
}
})
return acc
}, [])
})
}
export const validate2And3UnusedSecuritySchemes = () => (system) => {
const { allSecurityRequirements, allSecurityDefinitions } = system.validateSelectors
return Promise.all([allSecurityRequirements(), allSecurityDefinitions()])
.then(([securityRequirements, securitySchemes]) => {
// Get just the names of security schemes used in `security`
const usedSecurities = securityRequirements
.map(node => Object.keys(node.node) || [])
.reduce(function(a, b) {
// flatten!
return a.concat(b)
}, [])
return securitySchemes.reduce((acc, node) => {
if(usedSecurities.indexOf(node.key) < 0) {
acc.push({
message: "Security scheme was defined but never used. To apply security, use the `security` section in operations or on the root level of your API definition.",
path: node.path,
level: "warning",
})
}
return acc
}, [])
})
}