raml2html-slate-theme
Version:
A raml2html template for rendering RAML to a Slate like layout
249 lines (222 loc) • 8.7 kB
JavaScript
/**
* Builds an array of curl commands for the given method and security schemes
* @param {object} methodParams The set of parameters describing a methof
* @param {string} methodParams.method The HTTP method
* @param {string} methodParams.baseUri The base URI
* @param {string} methodParams.path The path
* @param {array<string>} methodParams.params An array of serialized key-value pairs that make up the query string parameters
* @param {array<string>} methodParams.headers An array of serialized HTTP headers
* @param {*} methodParams.payload The payload to send in the request
* @param {array<object>} methodParams.securedBy An array of security references from the RAML
* @param {object} securitySchemes A hash of Security Scheme objects as generated by RAML
* @return {array<string>}
*/
function forMethod (methodParams, securitySchemes) {
let commands = []
if (securitySchemes && methodParams.securedBy) {
commands = securedCommands(methodParams, securitySchemes)
}
if (commands.length === 0) {
commands = unsecuredCommands(methodParams)
}
return commands
}
/**
* Builds a curl command string without security
* @param {object} methodParams See definition in forMethod
*/
function unsecuredCommands (methodParams) {
return buildCurlCommands(methodParams)
}
/**
* Builds curl commands with security schemes
* @param {object} methodParams See definition in forMethod
* @param {object} securitySchemes A hash of Security Scheme objects as generated by RAML
* @return {array<string>}
*/
function securedCommands (methodParams, securitySchemes) {
let commands = []
methodParams.securedBy.forEach((methodScheme) => {
if (methodScheme) {
const securityScheme = securitySchemes[methodScheme.schemeName]
if (securityScheme) {
commands = commands.concat(buildCurlCommands(methodParams, securityScheme))
}
} else {
commands = unsecuredCommands(methodParams)
}
})
return commands
}
/**
* Builds one or more curl commands for a method and set of security schemes
* @param {object} methodParams The set of parameters describing a methof
* @param {string} methodParams.method The HTTP method
* @param {string} methodParams.baseUri The base URI
* @param {string} methodParams.path The path
* @param {array<string>} methodParams.params An array of serialized key-value pairs that make up the query string parameters
* @param {array<string>} methodParams.headers An array of sewrialized HTTP headers
* @param {*} methodParams.payload The payload to send in the request
* @param {object} securityScheme A Security Scheme object as generated by RAML
* @return {array<string>} An array of strings that represents the possible curl commands
*/
function buildCurlCommands (methodParams, securityScheme) {
const curlAuthFunctions = {
'Basic Authentication': curlBasicAuth,
'Digest Authentication': curlDigestAuth,
'Pass Through': curlPassThroughAuth,
'OAuth 1.0': curlOAuth1,
'OAuth 2.0': curlOAuth2,
null: curlNullAuth
}
securityScheme = securityScheme || { type: 'null' }
const authFunction = curlAuthFunctions[securityScheme.type] ||
curlCustomAuth(securityScheme.type) ||
curlNullAuth
const curlCommands = authFunction(securityScheme).map((curlProps) => {
let params = methodParams.params.slice()
if (curlProps.params) { params = params.concat(curlProps.params) }
params = params.join('&')
params = params === '' ? '' : `?${params}`
let headers = methodParams.headers.slice()
if (curlProps.headers) { headers = headers.concat(curlProps.headers) }
if (headers.length > 0) { headers.unshift('') }
headers = headers.join(' \\\n\t')
let options = ''
if (curlProps.options) {
curlProps.options.unshift('')
options = curlProps.options.join(' \\\n\t')
}
return `curl -X ${methodParams.method.toUpperCase()} "${methodParams.baseUri}${methodParams.path}${params}"${headers}${methodParams.payload}${options}`
})
return curlCommands
}
/**
* Check if the secruityScheme type is x-{custom}
* @param {String} type The value of the type firled from the RAML securityScheme
* @return {*} The curlXCustomAuth function or false, depending on
* whether the scheme is a custom one or not.
*/
function curlCustomAuth (type) {
return type.startsWith('x-') ? curlXCustomAuth : false
}
/**
* Extracts the first example from a RAML object with examples
*
* @param {*} thingWithExamples An object that has both RAML type and examples
* @return {String}
*/
function exampleOrDefault (thingWithExamples) {
return (thingWithExamples.examples && thingWithExamples.examples.length > 0)
? thingWithExamples.examples[0].value
: thingWithExamples.type
}
/**
* Handler for applying options for null auth
* @return {Object[]} An array of 1 empty object, as no options should apply
*/
function curlNullAuth () {
return [{}]
}
/**
* Handler for applying options for HTTP Basic auth
* @return {Object[]} An array of 1 object with the curl options for HTTP Basic auth
*/
function curlBasicAuth () {
return [{ options: ['--user username:password'] }]
}
/**
* Handler for applying options for HTTP Digest auth
* @return {Object[]} An array of 1 object with the curl options for HTTP Digest auth
*/
function curlDigestAuth () {
return [{ options: ['--user username:password', '--digest'] }]
}
/**
* Handler for applying options for Pass Through auth
*
* Per the RAML 1.0 Spec:
* You MUST provide a value for every header or queryParameter defined in describedBy and passed along with the request without modification.
* @return {Object[]} An array of 1 object with the headers and query params for Pass Through auth
*/
function curlPassThroughAuth (securityScheme) {
const headers = securityScheme.describedBy.headers || []
const params = securityScheme.describedBy.queryParameters || []
return [
{
headers: headers.map((header) => `-H "${header.name}: ${exampleOrDefault(header)}"`),
params: params.map((query) => `${query.name}=${exampleOrDefault(query)}`)
}
]
}
/**
* Handler for applying options for Custom auth
* @param {object} Security Scheme object as generate by RAML
* @return {Object[]} An array of 1 object with the additional headers for the custom auth as described by the security scheme
*/
function curlXCustomAuth (securityScheme) {
const headers = securityScheme.describedBy.headers || []
return [{
headers: headers.map((header) => `-H "${header.name}: ${exampleOrDefault(header)}"`)
}]
}
/**
* Handler for applying options for OAuth1 auth
* @param {object} Security Scheme object as generate by RAML
* @return {Object[]} An array of 2 objects, one containing the headers, the other, query string parameters, for the OAuth 1 auth
*/
function curlOAuth1 (scheme) {
let signatureMethod = 'RSA-SHA1'
if (scheme.settings && scheme.settings.signatures) {
signatureMethod = scheme.settings.signatures[0]
}
const parameters = {
oauth_consumer_key: 'consumer_key',
oauth_token: 'token',
oauth_signature_method: signatureMethod,
oauth_signature: 'computed_signature',
oauth_timestamp: 'timestamp',
oauth_nonce: 'nonce',
oauth_version: '1.0'
}
const headerParams = Object
.keys(parameters)
.map(key => `${encodeURIComponent(key)}="${encodeURIComponent(parameters[key])}"`)
.join(',\\\n\t')
const queryStringParams = Object
.keys(parameters)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(parameters[key])}`)
return [
{
headers: [`-H 'Authorization: OAuth realm="API",\\\n\t${headerParams}'`]
},
{
params: queryStringParams
}
]
}
/**
* Handler for applying options for OAuth2 auth
* @param {object} Security Scheme object as generate by RAML
* @return {Object[]} An array of 2 objects, one containing the headers, the other, query string parameters, for the OAuth 2 auth as described by the security scheme
*/
function curlOAuth2 (scheme) {
const result = []
if (scheme.describedBy.headers) {
const header = scheme.describedBy.headers[0]
result.push({
headers: [`-H "${header.name}: Bearer ${header.type}"`]
})
}
if (scheme.describedBy.queryParameters) {
const query = scheme.describedBy.queryParameters[0]
result.push({
params: [`${query.name}=${query.type}`]
})
}
return result
}
module.exports = {
forMethod
}