From 70c346056b785a61df6a867271f29110a35a82ba Mon Sep 17 00:00:00 2001 From: nmaqsood Date: Tue, 23 Jul 2024 17:48:15 +0200 Subject: [PATCH 1/5] feat: added support for oauth and mtls. Also enable the option to choose key --- package.json | 2 +- src/3.2.0/wso2apim.js | 460 +++++++++++++++++++++--------------------- 2 files changed, 234 insertions(+), 228 deletions(-) diff --git a/package.json b/package.json index 4335c55..a9b6e25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-wso2-apim", - "version": "0.7.0", + "version": "0.7.1", "description": "Serverless Framework plugin for WSO2 API Manager", "main": "src/index.js", "scripts": { diff --git a/src/3.2.0/wso2apim.js b/src/3.2.0/wso2apim.js index 3e39d56..ee0f17a 100644 --- a/src/3.2.0/wso2apim.js +++ b/src/3.2.0/wso2apim.js @@ -9,41 +9,42 @@ // * Use no console.log() at this level, only Promises being returned // ---------------- -const axios = require('axios'); -const https = require('https'); -const qs = require('qs'); -const FormData = require('form-data'); -const fs = require('fs'); -const utils = require('../utils/utils'); +const axios = require("axios"); +const https = require("https"); +const qs = require("qs"); +const FormData = require("form-data"); +const fs = require("fs"); +const utils = require("../utils/utils"); // Parse your swagger online @ https://apitools.dev/swagger-parser/online/ -const parser = require('swagger-parser'); +const parser = require("swagger-parser"); // Register a new client async function registerClient(wso2APIM) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/client-registration/v0.17/register`; let { user, pass } = wso2APIM; - let authToken = user + ':' + pass; - let authTokenBase64 = Buffer.from(authToken).toString('base64'); + let authToken = user + ":" + pass; + let authTokenBase64 = Buffer.from(authToken).toString("base64"); var data = { - 'clientName': 'serverless-wso2-apim', - 'owner': user, - 'grantType': 'password refresh_token', - 'saasApp': true + clientName: "serverless-wso2-apim", + owner: user, + grantType: "password refresh_token", + saasApp: true, }; var config = { headers: { - 'Authorization': 'Basic ' + authTokenBase64, - 'Content-Type': 'application/json' + Authorization: "Basic " + authTokenBase64, + "Content-Type": "application/json", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve(res.data); }) @@ -52,42 +53,41 @@ async function registerClient(wso2APIM) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } - // Generate a new token async function generateToken(wso2APIM, clientId, clientSecret) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/oauth2/token`; let { user, pass } = wso2APIM; - let scope = 'apim:api_create apim:api_view apim:api_publish apim:api_delete'; - let authToken = clientId + ':' + clientSecret; - let authTokenBase64 = Buffer.from(authToken).toString('base64'); + let scope = "apim:api_create apim:api_view apim:api_publish apim:api_delete"; + let authToken = clientId + ":" + clientSecret; + let authTokenBase64 = Buffer.from(authToken).toString("base64"); var data = qs.stringify({ - 'grant_type': 'password', - 'username': user, - 'password': pass, - 'scope': scope + grant_type: "password", + username: user, + password: pass, + scope: scope, }); var config = { headers: { - 'Authorization': 'Basic ' + authTokenBase64, - 'Content-Type': 'application/x-www-form-urlencoded' + Authorization: "Basic " + authTokenBase64, + "Content-Type": "application/x-www-form-urlencoded", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve({ - accessToken: res.data.access_token + accessToken: res.data.access_token, }); }) .catch((err) => { @@ -95,8 +95,7 @@ async function generateToken(wso2APIM, clientId, clientSecret) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -104,19 +103,20 @@ async function generateToken(wso2APIM, clientId, clientSecret) { async function isAPIDeployed(wso2APIM, accessToken, apiName, apiVersion, apiContext) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis`; - let queryStr = 'query=name:' + apiName + ' version:' + apiVersion + ' context:' + apiContext; - url = url + '?' + queryStr; + let queryStr = "query=name:" + apiName + " version:" + apiVersion + " context:" + apiContext; + url = url + "?" + queryStr; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.get(url, config) + axios + .get(url, config) .then((res) => { resolve(res.data); }) @@ -125,8 +125,7 @@ async function isAPIDeployed(wso2APIM, accessToken, apiName, apiVersion, apiCont reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -136,28 +135,28 @@ async function isCertUploaded(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.get(url, config) + axios + .get(url, config) .then((res) => { resolve(res.data); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.responseCode != '404') { + if (err.responseCode != "404") { utils.renderError(err); } reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -171,39 +170,41 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { if (apiDef.backend.http.baseUrl) { backendBaseUrl = apiDef.backend.http.baseUrl; } - backendType = 'HTTP'; + backendType = "HTTP"; } // 2. JMS-based backend else if (apiDef.backend.jms) { if (apiDef.backend.jms.destination) { - backendBaseUrl = ['jms:', apiDef.backend.jms.destination].join('/'); - backendBaseUrl = [backendBaseUrl, qs.stringify(apiDef.backend.jms.parameters, { encode: false })].join('?'); + backendBaseUrl = ["jms:", apiDef.backend.jms.destination].join("/"); + backendBaseUrl = [backendBaseUrl, qs.stringify(apiDef.backend.jms.parameters, { encode: false })].join("?"); } - backendType = 'HTTP'; + backendType = "HTTP"; } // Construct mediation policies var mediationPolicies = []; if (apiDef.mediationPolicies) { if (apiDef.mediationPolicies.in) { - mediationPolicies.push({ 'name': apiDef.mediationPolicies.in, 'type': 'in' }); + mediationPolicies.push({ name: apiDef.mediationPolicies.in, type: "in" }); } if (apiDef.mediationPolicies.out) { - mediationPolicies.push({ 'name': apiDef.mediationPolicies.out, 'type': 'out' }); + mediationPolicies.push({ name: apiDef.mediationPolicies.out, type: "out" }); } if (apiDef.mediationPolicies.fault) { - mediationPolicies.push({ 'name': apiDef.mediationPolicies.fault, 'type': 'fault' }); + mediationPolicies.push({ name: apiDef.mediationPolicies.fault, type: "fault" }); } } let securityScheme = []; if (apiDef.securityScheme && apiDef.securityScheme.mutualssl && apiDef.securityScheme.mutualssl.enabled === true) { - securityScheme.push('mutualssl'); - securityScheme.push('mutualssl_mandatory'); + securityScheme.push("mutualssl"); + securityScheme.push("mutualssl_mandatory"); } - if(apiDef.securityScheme && apiDef.securityScheme.oauth2 && apiDef.securityScheme.oauth2.enabled === false) { - //do nothing + + if (apiDef.securityScheme && apiDef.securityScheme.oauth2 && apiDef.securityScheme.oauth2.enabled === true) { + securityScheme.push("oauth2"); + securityScheme.push("oauth_basic_auth_api_key_mandatory"); } else { - securityScheme.push('oauth2'); + securityScheme.push("oauth2"); } const wso2ApiDefinition = { id: apiId, @@ -212,43 +213,61 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { context: apiDef.rootContext, version: apiDef.version, operations: await constructAPIOperations(apiDef.swaggerSpec), - lifeCycleStatus: 'CREATED', + lifeCycleStatus: "CREATED", isDefaultVersion: false, enableStore: true, type: backendType, - transport: ['https'], - tags: [...apiDef.tags, 'serverless-wso2-apim'], - policies: ['Unlimited'], - apiThrottlingPolicy: 'Unlimited', + transport: ["https"], + tags: [...apiDef.tags, "serverless-wso2-apim"], + policies: ["Unlimited"], + apiThrottlingPolicy: "Unlimited", securityScheme, maxTps: { - production: (apiDef.maxTps) ? apiDef.maxTps : undefined + production: apiDef.maxTps ? apiDef.maxTps : undefined, }, visibility: apiDef.subscriberVisibility || apiDef.visibility, endpointConfig: { production_endpoints: { - url: backendBaseUrl + url: backendBaseUrl, }, - endpoint_type: (apiDef.backend.endpointType) ? apiDef.backend.endpointType : 'http' + sandbox_endpoints: { + url: backendBaseUrl, + }, + endpoint_type: apiDef.backend.endpointType ? apiDef.backend.endpointType : "http", }, - endpointImplementationType: 'ENDPOINT', + endpointImplementationType: "ENDPOINT", endpointSecurity: null, - gatewayEnvironments: [ gatewayEnv ], + gatewayEnvironments: [gatewayEnv], mediationPolicies: mediationPolicies, - additionalProperties: ((apiDef.apiProperties) && (Object.keys(apiDef.apiProperties).length > 0)) ? apiDef.apiProperties : undefined, - subscriptionAvailability: 'CURRENT_TENANT', + additionalProperties: apiDef.apiProperties && Object.keys(apiDef.apiProperties).length > 0 ? apiDef.apiProperties : undefined, + subscriptionAvailability: "CURRENT_TENANT", subscriptionAvailableTenants: [], - businessInformation: apiDef.businessInformation ? { - businessOwnerEmail: apiDef.businessInformation.businessOwnerEmail, - technicalOwnerEmail: apiDef.businessInformation.technicalOwnerEmail, - technicalOwner: apiDef.businessInformation.technicalOwner, - businessOwner: apiDef.businessInformation.businessOwner - } : { - businessOwnerEmail: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.email)) ? apiDef.swaggerSpec.info.contact.email : undefined, - technicalOwnerEmail: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.email)) ? apiDef.swaggerSpec.info.contact.email : undefined, - technicalOwner: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.name)) ? apiDef.swaggerSpec.info.contact.name : undefined, - businessOwner: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.name)) ? apiDef.swaggerSpec.info.contact.name : undefined, - } + keyManagers: apiDef.securityScheme?.oauth2?.keyManager, + businessInformation: apiDef.businessInformation + ? { + businessOwnerEmail: apiDef.businessInformation.businessOwnerEmail, + technicalOwnerEmail: apiDef.businessInformation.technicalOwnerEmail, + technicalOwner: apiDef.businessInformation.technicalOwner, + businessOwner: apiDef.businessInformation.businessOwner, + } + : { + businessOwnerEmail: + apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.email + ? apiDef.swaggerSpec.info.contact.email + : undefined, + technicalOwnerEmail: + apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.email + ? apiDef.swaggerSpec.info.contact.email + : undefined, + technicalOwner: + apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.name + ? apiDef.swaggerSpec.info.contact.name + : undefined, + businessOwner: + apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.name + ? apiDef.swaggerSpec.info.contact.name + : undefined, + }, }; if (apiDef.cors) { wso2ApiDefinition.corsConfiguration = constructCorsConfiguration(apiDef); @@ -257,18 +276,17 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { wso2ApiDefinition.visibleRoles = apiDef.subscriberVisibilityRoles; } if (apiDef.publisherVisibility) { - wso2ApiDefinition.accessControl = apiDef.publisherVisibility === 'PRIVATE' ? 'NONE' : apiDef.publisherVisibility; + wso2ApiDefinition.accessControl = apiDef.publisherVisibility === "PRIVATE" ? "NONE" : apiDef.publisherVisibility; } if (apiDef.publisherVisibilityRoles) { wso2ApiDefinition.accessControlRoles = apiDef.publisherVisibilityRoles; } - backendBaseUrl = ''; - backendType = ''; + backendBaseUrl = ""; + backendType = ""; return wso2ApiDefinition; - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -276,22 +294,15 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { function constructCorsConfiguration(apiDef) { const { origins, credentials, headers, methods } = apiDef.cors; const defaultAllowHeaders /* default WSO2 cors config */ = [ - 'Authorization', - 'Access-Control-Allow-Origin', - 'Content-Type', - 'SOAPAction', - ]; - const defaultAllowMethods /* default WSO2 cors config */ = [ - 'GET', - 'PUT', - 'POST', - 'DELETE', - 'PATCH', - 'OPTIONS', + "Authorization", + "Access-Control-Allow-Origin", + "Content-Type", + "SOAPAction", ]; + const defaultAllowMethods /* default WSO2 cors config */ = ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"]; return { corsConfigurationEnabled: true, - accessControlAllowOrigins: origins || ['*'], + accessControlAllowOrigins: origins || ["*"], accessControlAllowCredentials: credentials || false, accessControlAllowHeaders: headers || defaultAllowHeaders, accessControlAllowMethods: methods || defaultAllowMethods, @@ -310,15 +321,15 @@ async function constructAPIOperations(apiDef) { // Traverse through verb properties var authType = undefined; for (var verbProp in swaggerObj.paths[pathObj][verbObj]) { - if (verbProp.toLowerCase() === 'x-auth-type') { + if (verbProp.toLowerCase() === "x-auth-type") { authType = swaggerObj.paths[pathObj][verbObj][verbProp]; } } wso2Operations.push({ target: pathObj, verb: verbObj, - authType: (authType) ? authType : 'Any', - throttlingPolicy: 'Unlimited' + authType: authType ? authType : "Any", + throttlingPolicy: "Unlimited", }); } } @@ -334,38 +345,35 @@ async function createAPIDef(wso2APIM, accessToken, apiDef) { let { user, gatewayEnv } = wso2APIM; var data = await constructAPIDef(user, gatewayEnv, apiDef); - // TODO - dynamically retrieve swaggerSpec version - let queryStr = 'openAPIVersion=V3'; - url = url + '?' + queryStr; + let queryStr = "openAPIVersion=V3"; + url = url + "?" + queryStr; var config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'application/json' + Authorization: "Bearer " + accessToken, + "Content-Type": "application/json", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve({ apiId: res.data.id, apiName: res.data.name, apiContext: res.data.context, - apiStatus: res.data.status + apiStatus: res.data.status, }); }) .catch((err) => { - reject( - utils.renderError(err) - ); + reject(utils.renderError(err)); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -377,19 +385,20 @@ async function publishAPIDef(wso2APIM, accessToken, apiId) { var data = {}; var config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, params: { - 'apiId': apiId, - 'action': 'Publish' + apiId: apiId, + action: "Publish", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve(res); }) @@ -398,8 +407,7 @@ async function publishAPIDef(wso2APIM, accessToken, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -410,15 +418,16 @@ async function listInvokableAPIUrl(wso2APIM, accessToken, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/store/${wso2APIM.versionSlug}/apis/${apiId}`; var config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.get(url, config) + axios + .get(url, config) .then((res) => { resolve(res.data); }) @@ -427,46 +436,44 @@ async function listInvokableAPIUrl(wso2APIM, accessToken, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } - // Uploads backend certificate async function uploadCert(wso2APIM, accessToken, certAlias, cert, backendUrl) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates`; var data = new FormData(); - data.append('certificate', fs.createReadStream(cert)); - data.append('alias', certAlias); - data.append('endpoint', backendUrl); + data.append("certificate", fs.createReadStream(cert)); + data.append("alias", certAlias); + data.append("endpoint", backendUrl); var config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer " + accessToken, + "Content-Type": "multipart/form-data", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-exists-for-that-Alias error gracefully - if (err.response.data.code != '409') { + if (err.response.data.code != "409") { utils.renderError(err); } reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -479,16 +486,17 @@ async function updateAPIDef(wso2APIM, accessToken, apiDef, apiId) { var data = await constructAPIDef(user, gatewayEnv, apiDef, apiId); var config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'application/json' + Authorization: "Bearer " + accessToken, + "Content-Type": "application/json", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.put(url, data, config) + axios + .put(url, data, config) .then((res) => { resolve(res.data); }) @@ -497,8 +505,7 @@ async function updateAPIDef(wso2APIM, accessToken, apiDef, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -509,15 +516,16 @@ async function removeAPIDef(wso2APIM, accessToken, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.delete(url, config) + axios + .delete(url, config) .then((res) => { resolve(res.data); }) @@ -526,8 +534,7 @@ async function removeAPIDef(wso2APIM, accessToken, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -538,51 +545,51 @@ async function removeCert(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.delete(url, config) + axios + .delete(url, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.response.status != '404') { + if (err.response.status != "404") { utils.renderError(err); } reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } - // Updates backend certificate async function updateCert(wso2APIM, accessToken, certAlias, cert) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates/${certAlias}`; var data = new FormData(); - data.append('certificate', fs.createReadStream(cert)); + data.append("certificate", fs.createReadStream(cert)); let config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer " + accessToken, + "Content-Type": "multipart/form-data", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.put(url, data, config) + axios + .put(url, data, config) .then((res) => { resolve(res); }) @@ -591,8 +598,7 @@ async function updateCert(wso2APIM, accessToken, certAlias, cert) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -603,16 +609,17 @@ async function listCertInfo(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Accept': 'application/json' + Authorization: "Bearer " + accessToken, + Accept: "application/json", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.get(url, config) + axios + .get(url, config) .then((res) => { resolve(res.data); }) @@ -621,8 +628,7 @@ async function listCertInfo(wso2APIM, accessToken, certAlias) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -632,34 +638,34 @@ async function uploadClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates`; var data = new FormData(); - data.append('certificate', fs.createReadStream(cert)); - data.append('alias', certAlias); - data.append('tier', 'unlimited'); + data.append("certificate", fs.createReadStream(cert)); + data.append("alias", certAlias); + data.append("tier", "unlimited"); var config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer " + accessToken, + "Content-Type": "multipart/form-data", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.post(url, data, config) + axios + .post(url, data, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-exists-for-that-Alias error gracefully - if (err.response.data.code != '409') { + if (err.response.data.code != "409") { utils.renderError(err); } reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -670,16 +676,17 @@ async function listClientCertInfo(wso2APIM, accessToken, certAlias, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Accept': 'application/json' + Authorization: "Bearer " + accessToken, + Accept: "application/json", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.get(url, config) + axios + .get(url, config) .then((res) => { resolve(res.data); }) @@ -688,8 +695,7 @@ async function listClientCertInfo(wso2APIM, accessToken, certAlias, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -699,19 +705,20 @@ async function updateClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; var data = new FormData(); - data.append('certificate', fs.createReadStream(cert)); + data.append("certificate", fs.createReadStream(cert)); let config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer " + accessToken, + "Content-Type": "multipart/form-data", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.put(url, data, config) + axios + .put(url, data, config) .then((res) => { resolve(res); }) @@ -720,8 +727,7 @@ async function updateClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -732,28 +738,28 @@ async function removeClientCert(wso2APIM, accessToken, certAlias, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; let config = { headers: { - 'Authorization': 'Bearer ' + accessToken + Authorization: "Bearer " + accessToken, }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; return new Promise((resolve, reject) => { - axios.delete(url, config) + axios + .delete(url, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.response.status != '404') { + if (err.response.status != "404") { utils.renderError(err); } reject(err); }); }); - } - catch (err) { + } catch (err) { utils.renderError(err); } } @@ -767,34 +773,34 @@ async function removeClientCert(wso2APIM, accessToken, certAlias, apiId) { * @param {*} swaggerSpec * @returns */ - async function upsertSwaggerSpec(wso2APIM, accessToken, apiId, swaggerSpec) { +async function upsertSwaggerSpec(wso2APIM, accessToken, apiId, swaggerSpec) { try { const url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/swagger`; const config = { headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer " + accessToken, + "Content-Type": "multipart/form-data", }, httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + rejectUnauthorized: false, + }), }; const data = new FormData(); - data.append('apiDefinition', JSON.stringify(swaggerSpec)); + data.append("apiDefinition", JSON.stringify(swaggerSpec)); - return axios.put(url, data, config) - .then((_) => undefined).catch((err) => { + return axios + .put(url, data, config) + .then((_) => undefined) + .catch((err) => { utils.renderError(err); }); // eat the http response, not needed outside of this api layer - } - catch (err) { + } catch (err) { utils.renderError(err); throw err; } } - module.exports = { registerClient, generateToken, From 421eb7e81d2263fb96c074ab048c5d3b0f4ca985 Mon Sep 17 00:00:00 2001 From: nmaqsood Date: Tue, 23 Jul 2024 17:51:07 +0200 Subject: [PATCH 2/5] chore: updated unit test case --- src/3.2.0/wso2apim.spec.js | 671 ++++++++++++++++--------------------- 1 file changed, 291 insertions(+), 380 deletions(-) diff --git a/src/3.2.0/wso2apim.spec.js b/src/3.2.0/wso2apim.spec.js index 109dbae..bbcdea5 100644 --- a/src/3.2.0/wso2apim.spec.js +++ b/src/3.2.0/wso2apim.spec.js @@ -17,88 +17,88 @@ const { upsertSwaggerSpec, updateAPIDef, removeAPIDef, - listInvokableAPIUrl -} = require('./wso2apim'); -const axios = require('axios'); -const qs = require('qs'); + listInvokableAPIUrl, +} = require("./wso2apim"); +const axios = require("axios"); +const qs = require("qs"); afterEach(() => { jest.clearAllMocks(); }); -jest.mock('axios', () => ({ - post: jest.fn(() => Promise.resolve({ data: 'foo' })), - get: jest.fn(() => Promise.resolve({ data: 'foo' })), - put: jest.fn(() => Promise.resolve({ data: 'foo' })), - delete: jest.fn(() => Promise.resolve({ data: 'foo' })), +jest.mock("axios", () => ({ + post: jest.fn(() => Promise.resolve({ data: "foo" })), + get: jest.fn(() => Promise.resolve({ data: "foo" })), + put: jest.fn(() => Promise.resolve({ data: "foo" })), + delete: jest.fn(() => Promise.resolve({ data: "foo" })), })); const wso2APIM = { enabled: true, - host: 'wso2-apimanager.com', + host: "wso2-apimanager.com", port: 443, - versionSlug: 'v0.17', - user: 'foo', - pass: 'bar', - gatewayEnv: 'Local', + versionSlug: "v0.17", + user: "foo", + pass: "bar", + gatewayEnv: "Local", apidefs: [ { - name: 'MyAwesomeAPI', - description: 'My Awesome API', - rootContext: '/myawesomeapi', - version: 'v1', - visibility: 'PUBLIC', + name: "MyAwesomeAPI", + description: "My Awesome API", + rootContext: "/myawesomeapi", + version: "v1", + visibility: "PUBLIC", backend: { http: { - baseUrl: 'https://backend.url', - certChain: 'file://xxx.cer' - } + baseUrl: "https://backend.url", + certChain: "file://xxx.cer", + }, }, securityScheme: { mutualssl: { enabled: true, - clientCert: 'file://xxx.cer' - } + clientCert: "file://xxx.cer", + }, + oauth2: { enabled: true, keyManager: ["Resident Key Manager"] }, }, - tags: [ 'awesomeness', 'myawesomeapi'], + tags: ["awesomeness", "myawesomeapi"], maxTps: 999, swaggerSpec: { - 'openapi': '3.0.0', - 'info': { - 'title': 'MyAwesomeAPI', - 'version': 'v1', - 'contact': { - 'name': 'MyTeam', - 'email': 'myteam@myteam.com' - } + openapi: "3.0.0", + info: { + title: "MyAwesomeAPI", + version: "v1", + contact: { + name: "MyTeam", + email: "myteam@myteam.com", + }, }, - 'paths': { - '/*': { - 'post': { - 'responses': { - '201': { - 'description': 'Created' - } - } - } - } - } - } - } - ] + paths: { + "/*": { + post: { + responses: { + 201: { + description: "Created", + }, + }, + }, + }, + }, + }, + }, + ], }; -const apiId = '123456789'; - -describe('wso2apim-3.2.0', () => { +const apiId = "123456789"; - describe('registerClient()', () => { - it('should handle a successful response', async () => { +describe("wso2apim-3.2.0", () => { + describe("registerClient()", () => { + it("should handle a successful response", async () => { axios.post.mockImplementationOnce(() => Promise.resolve({ data: { - clientId: 'foo', - clientSecret: 'bar', + clientId: "foo", + clientSecret: "bar", }, }) ); @@ -108,149 +108,137 @@ describe('wso2apim-3.2.0', () => { expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/client-registration/v0.17/register`, { - clientName: 'serverless-wso2-apim', + clientName: "serverless-wso2-apim", owner: wso2APIM.user, - grantType: 'password refresh_token', + grantType: "password refresh_token", saasApp: true, }, expect.objectContaining({}) ); expect(response).toEqual({ - clientId: 'foo', - clientSecret: 'bar', + clientId: "foo", + clientSecret: "bar", }); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); expect(registerClient(wso2APIM)).rejects.toThrow(); }); }); - describe('generateToken()', () => { - it('should handle a successful response', async () => { - + describe("generateToken()", () => { + it("should handle a successful response", async () => { axios.post.mockImplementationOnce(() => Promise.resolve({ data: { - access_token: 'xxx' + access_token: "xxx", }, }) ); - const response = await generateToken(wso2APIM, 'foo123', 'xxxyyyzzz'); + const response = await generateToken(wso2APIM, "foo123", "xxxyyyzzz"); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/oauth2/token`, qs.stringify({ - 'grant_type': 'password', - 'username': wso2APIM.user, - 'password': wso2APIM.pass, - 'scope': 'apim:api_create apim:api_view apim:api_publish apim:api_delete' + grant_type: "password", + username: wso2APIM.user, + password: wso2APIM.pass, + scope: "apim:api_create apim:api_view apim:api_publish apim:api_delete", }), expect.objectContaining({}) ); expect(response).toEqual({ - accessToken: 'xxx', + accessToken: "xxx", }); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); - expect(generateToken(wso2APIM, 'foo123', 'xxxyyyzzz')).rejects.toThrow(); + expect(generateToken(wso2APIM, "foo123", "xxxyyyzzz")).rejects.toThrow(); }); }); - describe('isAPIDeployed()', () => { - it('should handle a successful response', async () => { - - const response = await isAPIDeployed(wso2APIM, 'xxx', wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext); + describe("isAPIDeployed()", () => { + it("should handle a successful response", async () => { + const response = await isAPIDeployed( + wso2APIM, + "xxx", + wso2APIM.apidefs[0].name, + wso2APIM.apidefs[0].version, + wso2APIM.apidefs[0].rootContext + ); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis?query=name:${wso2APIM.apidefs[0].name} version:${wso2APIM.apidefs[0].version} context:${wso2APIM.apidefs[0].rootContext}`, { headers: { - Authorization: 'Bearer xxx', + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.get.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.get.mockImplementationOnce(() => Promise.reject()); expect( - isAPIDeployed(wso2APIM, 'xxx', wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext) + isAPIDeployed(wso2APIM, "xxx", wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext) ).rejects.toThrow(); }); }); - describe('isCertUploaded()', () => { - it('should handle a successful response', async () => { - - const response = await isCertUploaded(wso2APIM, 'xxx', 'alias'); + describe("isCertUploaded()", () => { + it("should handle a successful response", async () => { + const response = await isCertUploaded(wso2APIM, "xxx", "alias"); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: 'Bearer xxx', + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.get.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.get.mockImplementationOnce(() => Promise.reject()); - expect( - isCertUploaded(wso2APIM, 'xxx', 'alias') - ).rejects.toThrow(); + expect(isCertUploaded(wso2APIM, "xxx", "alias")).rejects.toThrow(); }); }); - describe('createAPIDef()', () => { - it('should handle a successful response', async () => { - + describe("createAPIDef()", () => { + it("should handle a successful response", async () => { axios.post.mockImplementationOnce(() => Promise.resolve({ data: { id: apiId, name: wso2APIM.apidefs[0].name, context: wso2APIM.apidefs[0].rootContext, - status: 'CREATED' - } + status: "CREATED", + }, }) ); - const response = await createAPIDef( - wso2APIM, - 'xxx', - wso2APIM.apidefs[0] - ); + const response = await createAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0]); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis?openAPIVersion=V3`, expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx', - 'Content-Type': 'application/json', + Authorization: "Bearer xxx", + "Content-Type": "application/json", }, httpsAgent: expect.objectContaining({}), } @@ -260,308 +248,248 @@ describe('wso2apim-3.2.0', () => { apiId, apiName: wso2APIM.apidefs[0].name, apiContext: wso2APIM.apidefs[0].rootContext, - apiStatus: 'CREATED' + apiStatus: "CREATED", }); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); - expect(createAPIDef(wso2APIM, 'xxx', wso2APIM.apidefs[0])).rejects.toThrow(); + expect(createAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0])).rejects.toThrow(); }); - }); - describe('publishAPIDef()', () => { - it('should handle a successful response', async () => { - - const response = await publishAPIDef( - wso2APIM, - 'xxx', - apiId - ); + describe("publishAPIDef()", () => { + it("should handle a successful response", async () => { + const response = await publishAPIDef(wso2APIM, "xxx", apiId); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/change-lifecycle`, expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx' + Authorization: "Bearer xxx", }, params: { - 'apiId': apiId, - 'action': 'Publish' + apiId: apiId, + action: "Publish", }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual('foo'); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); - expect(publishAPIDef(wso2APIM, 'xxx', apiId)).rejects.toThrow(); + expect(publishAPIDef(wso2APIM, "xxx", apiId)).rejects.toThrow(); }); - }); - describe('listInvokableAPIUrl()', () => { - it('should handle a successful response', async () => { - - const response = await listInvokableAPIUrl( - wso2APIM, - 'xxx', - apiId - ); + describe("listInvokableAPIUrl()", () => { + it("should handle a successful response", async () => { + const response = await listInvokableAPIUrl(wso2APIM, "xxx", apiId); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/store/${wso2APIM.versionSlug}/apis/${apiId}`, { headers: { - Authorization: 'Bearer xxx' + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.get.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.get.mockImplementationOnce(() => Promise.reject()); - expect(listInvokableAPIUrl(wso2APIM, 'xxx', apiId)).rejects.toThrow(); + expect(listInvokableAPIUrl(wso2APIM, "xxx", apiId)).rejects.toThrow(); }); - }); - describe('uploadCert()', () => { - it('should handle a successful response', async () => { - + describe("uploadCert()", () => { + it("should handle a successful response", async () => { const response = await uploadCert( wso2APIM, - 'xxx', - 'alias', + "xxx", + "alias", wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl ); - expect(response.data).toEqual('foo'); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); - expect(uploadCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl)).rejects.toThrow(); + expect( + uploadCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl) + ).rejects.toThrow(); }); - }); - describe('uploadClientCert()', () => { - it('should handle a successful response', async () => { - + describe("uploadClientCert()", () => { + it("should handle a successful response", async () => { const response = await uploadClientCert( wso2APIM, - 'xxx', - 'alias', + "xxx", + "alias", wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, - '123' + "123" ); - expect(response.data).toEqual('foo'); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.post.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.post.mockImplementationOnce(() => Promise.reject()); - expect(uploadClientCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert,'123')).rejects.toThrow(); + expect( + uploadClientCert( + wso2APIM, + "xxx", + "alias", + wso2APIM.apidefs[0].backend.http.certChain, + wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, + "123" + ) + ).rejects.toThrow(); }); - }); - describe('updateAPIDef()', () => { - - it('should handle a successful response', async () => { - - const response = await updateAPIDef( - wso2APIM, - 'xxx', - wso2APIM.apidefs[0], - apiId - ); + describe("updateAPIDef()", () => { + it("should handle a successful response", async () => { + const response = await updateAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0], apiId); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`, expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx', - 'Content-Type': 'application/json', + Authorization: "Bearer xxx", + "Content-Type": "application/json", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.put.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.put.mockImplementationOnce(() => Promise.reject()); - expect(updateAPIDef(wso2APIM, 'xxx', wso2APIM.apidefs[0], apiId)).rejects.toThrow(); + expect(updateAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0], apiId)).rejects.toThrow(); }); - }); - describe('removeAPIDef()', () => { - it('should handle a successful response', async () => { - - const response = await removeAPIDef( - wso2APIM, - 'xxx', - apiId - ); + describe("removeAPIDef()", () => { + it("should handle a successful response", async () => { + const response = await removeAPIDef(wso2APIM, "xxx", apiId); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`, { headers: { - Authorization: 'Bearer xxx', + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), - }); - expect(response).toEqual('foo'); + } + ); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.delete.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.delete.mockImplementationOnce(() => Promise.reject()); - expect(removeAPIDef(wso2APIM, 'xxx', apiId)).rejects.toThrow(); + expect(removeAPIDef(wso2APIM, "xxx", apiId)).rejects.toThrow(); }); - }); - describe('removeCert()', () => { - it('should handle a successful response', async () => { - - const response = await removeCert( - wso2APIM, - 'xxx', - 'alias' - ); + describe("removeCert()", () => { + it("should handle a successful response", async () => { + const response = await removeCert(wso2APIM, "xxx", "alias"); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: 'Bearer xxx', + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), - }); - expect(response.data).toEqual('foo'); + } + ); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.delete.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.delete.mockImplementationOnce(() => Promise.reject()); - expect(removeCert(wso2APIM, 'xxx', 'alias')).rejects.toThrow(); + expect(removeCert(wso2APIM, "xxx", "alias")).rejects.toThrow(); }); - }); - describe('removeClientCert()', () => { - it('should handle a successful response', async () => { - - const response = await removeClientCert( - wso2APIM, - 'xxx', - 'alias', - '123' - ); + describe("removeClientCert()", () => { + it("should handle a successful response", async () => { + const response = await removeClientCert(wso2APIM, "xxx", "alias", "123"); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/123/client-certificates/alias`, { headers: { - Authorization: 'Bearer xxx', + Authorization: "Bearer xxx", }, httpsAgent: expect.objectContaining({}), - }); - expect(response.data).toEqual('foo'); + } + ); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.delete.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.delete.mockImplementationOnce(() => Promise.reject()); - expect(removeClientCert(wso2APIM, 'xxx', 'alias', '123')).rejects.toThrow(); + expect(removeClientCert(wso2APIM, "xxx", "alias", "123")).rejects.toThrow(); }); - }); - describe('updateCert()', () => { - - it('should handle a successful response', async () => { - - const response = await updateCert( - wso2APIM, - 'xxx', - 'alias', - wso2APIM.apidefs[0].backend.http.certChain - ); + describe("updateCert()", () => { + it("should handle a successful response", async () => { + const response = await updateCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates/alias`, expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx', - 'Content-Type': 'multipart/form-data', + Authorization: "Bearer xxx", + "Content-Type": "multipart/form-data", }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual('foo'); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.put.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.put.mockImplementationOnce(() => Promise.reject()); - expect(updateCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain)).rejects.toThrow(); + expect(updateCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain)).rejects.toThrow(); }); - }); - describe('updateClientCert()', () => { - - it('should handle a successful response', async () => { - + describe("updateClientCert()", () => { + it("should handle a successful response", async () => { const response = await updateClientCert( wso2APIM, - 'xxx', - 'alias', + "xxx", + "alias", wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, - '123' + "123" ); expect(axios.put).toHaveBeenCalledWith( @@ -569,217 +497,200 @@ describe('wso2apim-3.2.0', () => { expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx', - 'Content-Type': 'multipart/form-data', + Authorization: "Bearer xxx", + "Content-Type": "multipart/form-data", }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual('foo'); + expect(response.data).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.put.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.put.mockImplementationOnce(() => Promise.reject()); - expect(updateClientCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, '123')).rejects.toThrow(); + expect( + updateClientCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, "123") + ).rejects.toThrow(); }); - }); - describe('listCertInfo()', () => { - it('should handle a successful response', async () => { - - const response = await listCertInfo( - wso2APIM, - 'xxx', - 'alias' - ); + describe("listCertInfo()", () => { + it("should handle a successful response", async () => { + const response = await listCertInfo(wso2APIM, "xxx", "alias"); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: 'Bearer xxx', - Accept: 'application/json' + Authorization: "Bearer xxx", + Accept: "application/json", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.get.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.get.mockImplementationOnce(() => Promise.reject()); - expect(listCertInfo(wso2APIM, 'xxx', 'alias')).rejects.toThrow(); + expect(listCertInfo(wso2APIM, "xxx", "alias")).rejects.toThrow(); }); - }); - describe('listClientCertInfo()', () => { - it('should handle a successful response', async () => { - - const response = await listClientCertInfo( - wso2APIM, - 'xxx', - 'alias', - '123' - ); + describe("listClientCertInfo()", () => { + it("should handle a successful response", async () => { + const response = await listClientCertInfo(wso2APIM, "xxx", "alias", "123"); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/123/client-certificates/alias`, { headers: { - Authorization: 'Bearer xxx', - Accept: 'application/json' + Authorization: "Bearer xxx", + Accept: "application/json", }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual('foo'); + expect(response).toEqual("foo"); }); - it('should handle a faulty response', async () => { - axios.get.mockImplementationOnce(() => - Promise.reject() - ); + it("should handle a faulty response", async () => { + axios.get.mockImplementationOnce(() => Promise.reject()); - expect(listClientCertInfo(wso2APIM, 'xxx', 'alias', '123')).rejects.toThrow(); + expect(listClientCertInfo(wso2APIM, "xxx", "alias", "123")).rejects.toThrow(); }); - }); - describe('upsertSwaggerSpec()', () => { - it('should handle a successful response', async () => { - const response = await upsertSwaggerSpec(wso2APIM, 'xxx', 'id001', wso2APIM.apidefs[0].swaggerSpec); + describe("upsertSwaggerSpec()", () => { + it("should handle a successful response", async () => { + const response = await upsertSwaggerSpec(wso2APIM, "xxx", "id001", wso2APIM.apidefs[0].swaggerSpec); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/id001/swagger`, expect.objectContaining({}), { headers: { - Authorization: 'Bearer xxx', - 'Content-Type': 'multipart/form-data' + Authorization: "Bearer xxx", + "Content-Type": "multipart/form-data", }, - httpsAgent: expect.objectContaining({}) + httpsAgent: expect.objectContaining({}), } ); }); - it('should handle a faulty response', async () => { + it("should handle a faulty response", async () => { axios.put.mockImplementationOnce(() => Promise.reject()); - expect(upsertSwaggerSpec(wso2APIM, 'xxx', 'id001', wso2APIM.apidefs[0].swaggerSpec)).rejects.toThrow(); + expect(upsertSwaggerSpec(wso2APIM, "xxx", "id001", wso2APIM.apidefs[0].swaggerSpec)).rejects.toThrow(); }); }); - describe('cors configuration', () => { - - it('no cors', async () => { + describe("cors configuration", () => { + it("no cors", async () => { const apiDef = await constructAPIDef(wso2APIM.user, wso2APIM.gatewayEnv, wso2APIM.apidefs[0]); expect(apiDef.corsConfiguration).toBeUndefined(); }); - it('only origin', async () => { - const config = {...wso2APIM, apidefs: [{...wso2APIM.apidefs[0], cors: { - origins: ['https://www.example.com'] - }}]}; + it("only origin", async () => { + const config = { + ...wso2APIM, + apidefs: [ + { + ...wso2APIM.apidefs[0], + cors: { + origins: ["https://www.example.com"], + }, + }, + ], + }; const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.corsConfiguration).toEqual({ corsConfigurationEnabled: true, - accessControlAllowOrigins: [ 'https://www.example.com' ], + accessControlAllowOrigins: ["https://www.example.com"], accessControlAllowCredentials: false, - accessControlAllowHeaders: [ - 'Authorization', - 'Access-Control-Allow-Origin', - 'Content-Type', - 'SOAPAction' - ], - accessControlAllowMethods: [ 'GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'OPTIONS' ] + accessControlAllowHeaders: ["Authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction"], + accessControlAllowMethods: ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"], }); }); - it('fully specified', async () => { - const config = {...wso2APIM, apidefs: [{...wso2APIM.apidefs[0], cors: { - origins: ['https://www.example.com', 'https://www.example.org'], - credentials: true, - headers: ['Authorization', 'x-custom'], - methods: ['GET'] - }}]}; + it("fully specified", async () => { + const config = { + ...wso2APIM, + apidefs: [ + { + ...wso2APIM.apidefs[0], + cors: { + origins: ["https://www.example.com", "https://www.example.org"], + credentials: true, + headers: ["Authorization", "x-custom"], + methods: ["GET"], + }, + }, + ], + }; const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.corsConfiguration).toEqual({ corsConfigurationEnabled: true, - accessControlAllowOrigins: [ 'https://www.example.com', 'https://www.example.org' ], + accessControlAllowOrigins: ["https://www.example.com", "https://www.example.org"], accessControlAllowCredentials: true, - accessControlAllowHeaders: ['Authorization', 'x-custom'], - accessControlAllowMethods: ['GET'] + accessControlAllowHeaders: ["Authorization", "x-custom"], + accessControlAllowMethods: ["GET"], }); }); }); - describe('business information', () => { - it('businessInformation provided', async () => { + describe("business information", () => { + it("businessInformation provided", async () => { const config = { ...wso2APIM, apidefs: [ { ...wso2APIM.apidefs[0], businessInformation: { - technicalOwnerEmail: 'technical@email.com', - businessOwnerEmail: 'business@email.com', - technicalOwner: 'NL NN/Techical/Owner', - businessOwner: 'NL NN/Business/Owner', + technicalOwnerEmail: "technical@email.com", + businessOwnerEmail: "business@email.com", + technicalOwner: "NL NN/Techical/Owner", + businessOwner: "NL NN/Business/Owner", }, }, ], }; - const apiDef = await constructAPIDef( - config.user, - config.gatewayEnv, - config.apidefs[0] - ); + const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.businessInformation).toEqual({ - technicalOwnerEmail: 'technical@email.com', - businessOwnerEmail: 'business@email.com', - technicalOwner: 'NL NN/Techical/Owner', - businessOwner: 'NL NN/Business/Owner', + technicalOwnerEmail: "technical@email.com", + businessOwnerEmail: "business@email.com", + technicalOwner: "NL NN/Techical/Owner", + businessOwner: "NL NN/Business/Owner", }); }); - it('businessInformation not provided', async () => { + it("businessInformation not provided", async () => { const config = { ...wso2APIM, apidefs: [ { - ...wso2APIM.apidefs[0] + ...wso2APIM.apidefs[0], }, ], }; - const apiDef = await constructAPIDef( - config.user, - config.gatewayEnv, - config.apidefs[0] - ); + const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.businessInformation).toEqual({ - technicalOwnerEmail: 'myteam@myteam.com', - businessOwnerEmail: 'myteam@myteam.com', - technicalOwner: 'MyTeam', - businessOwner: 'MyTeam', + technicalOwnerEmail: "myteam@myteam.com", + businessOwnerEmail: "myteam@myteam.com", + technicalOwner: "MyTeam", + businessOwner: "MyTeam", }); }); }); - }); From fbcd89702e5a8536486309850f0c6d35af3dcf1a Mon Sep 17 00:00:00 2001 From: nmaqsood Date: Tue, 23 Jul 2024 18:19:39 +0200 Subject: [PATCH 3/5] chore: added new e2e test --- src/3.2.0/wso2apim.js | 456 ++++++------ src/3.2.0/wso2apim.spec.js | 672 ++++++++++-------- .../cert.cer | 18 + .../serverless.yml | 90 +++ 4 files changed, 715 insertions(+), 521 deletions(-) create mode 100644 src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/cert.cer create mode 100644 src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml diff --git a/src/3.2.0/wso2apim.js b/src/3.2.0/wso2apim.js index ee0f17a..6e185c6 100644 --- a/src/3.2.0/wso2apim.js +++ b/src/3.2.0/wso2apim.js @@ -9,42 +9,41 @@ // * Use no console.log() at this level, only Promises being returned // ---------------- -const axios = require("axios"); -const https = require("https"); -const qs = require("qs"); -const FormData = require("form-data"); -const fs = require("fs"); -const utils = require("../utils/utils"); +const axios = require('axios'); +const https = require('https'); +const qs = require('qs'); +const FormData = require('form-data'); +const fs = require('fs'); +const utils = require('../utils/utils'); // Parse your swagger online @ https://apitools.dev/swagger-parser/online/ -const parser = require("swagger-parser"); +const parser = require('swagger-parser'); // Register a new client async function registerClient(wso2APIM) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/client-registration/v0.17/register`; let { user, pass } = wso2APIM; - let authToken = user + ":" + pass; - let authTokenBase64 = Buffer.from(authToken).toString("base64"); + let authToken = user + ':' + pass; + let authTokenBase64 = Buffer.from(authToken).toString('base64'); var data = { - clientName: "serverless-wso2-apim", - owner: user, - grantType: "password refresh_token", - saasApp: true, + 'clientName': 'serverless-wso2-apim', + 'owner': user, + 'grantType': 'password refresh_token', + 'saasApp': true }; var config = { headers: { - Authorization: "Basic " + authTokenBase64, - "Content-Type": "application/json", + 'Authorization': 'Basic ' + authTokenBase64, + 'Content-Type': 'application/json' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve(res.data); }) @@ -53,41 +52,42 @@ async function registerClient(wso2APIM) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } + // Generate a new token async function generateToken(wso2APIM, clientId, clientSecret) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/oauth2/token`; let { user, pass } = wso2APIM; - let scope = "apim:api_create apim:api_view apim:api_publish apim:api_delete"; - let authToken = clientId + ":" + clientSecret; - let authTokenBase64 = Buffer.from(authToken).toString("base64"); + let scope = 'apim:api_create apim:api_view apim:api_publish apim:api_delete'; + let authToken = clientId + ':' + clientSecret; + let authTokenBase64 = Buffer.from(authToken).toString('base64'); var data = qs.stringify({ - grant_type: "password", - username: user, - password: pass, - scope: scope, + 'grant_type': 'password', + 'username': user, + 'password': pass, + 'scope': scope }); var config = { headers: { - Authorization: "Basic " + authTokenBase64, - "Content-Type": "application/x-www-form-urlencoded", + 'Authorization': 'Basic ' + authTokenBase64, + 'Content-Type': 'application/x-www-form-urlencoded' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve({ - accessToken: res.data.access_token, + accessToken: res.data.access_token }); }) .catch((err) => { @@ -95,7 +95,8 @@ async function generateToken(wso2APIM, clientId, clientSecret) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -103,20 +104,19 @@ async function generateToken(wso2APIM, clientId, clientSecret) { async function isAPIDeployed(wso2APIM, accessToken, apiName, apiVersion, apiContext) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis`; - let queryStr = "query=name:" + apiName + " version:" + apiVersion + " context:" + apiContext; - url = url + "?" + queryStr; + let queryStr = 'query=name:' + apiName + ' version:' + apiVersion + ' context:' + apiContext; + url = url + '?' + queryStr; let config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .get(url, config) + axios.get(url, config) .then((res) => { resolve(res.data); }) @@ -125,7 +125,8 @@ async function isAPIDeployed(wso2APIM, accessToken, apiName, apiVersion, apiCont reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -135,28 +136,28 @@ async function isCertUploaded(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .get(url, config) + axios.get(url, config) .then((res) => { resolve(res.data); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.responseCode != "404") { + if (err.responseCode != '404') { utils.renderError(err); } reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -170,36 +171,35 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { if (apiDef.backend.http.baseUrl) { backendBaseUrl = apiDef.backend.http.baseUrl; } - backendType = "HTTP"; + backendType = 'HTTP'; } // 2. JMS-based backend else if (apiDef.backend.jms) { if (apiDef.backend.jms.destination) { - backendBaseUrl = ["jms:", apiDef.backend.jms.destination].join("/"); - backendBaseUrl = [backendBaseUrl, qs.stringify(apiDef.backend.jms.parameters, { encode: false })].join("?"); + backendBaseUrl = ['jms:', apiDef.backend.jms.destination].join('/'); + backendBaseUrl = [backendBaseUrl, qs.stringify(apiDef.backend.jms.parameters, { encode: false })].join('?'); } - backendType = "HTTP"; + backendType = 'HTTP'; } // Construct mediation policies var mediationPolicies = []; if (apiDef.mediationPolicies) { if (apiDef.mediationPolicies.in) { - mediationPolicies.push({ name: apiDef.mediationPolicies.in, type: "in" }); + mediationPolicies.push({ 'name': apiDef.mediationPolicies.in, 'type': 'in' }); } if (apiDef.mediationPolicies.out) { - mediationPolicies.push({ name: apiDef.mediationPolicies.out, type: "out" }); + mediationPolicies.push({ 'name': apiDef.mediationPolicies.out, 'type': 'out' }); } if (apiDef.mediationPolicies.fault) { - mediationPolicies.push({ name: apiDef.mediationPolicies.fault, type: "fault" }); + mediationPolicies.push({ 'name': apiDef.mediationPolicies.fault, 'type': 'fault' }); } } let securityScheme = []; if (apiDef.securityScheme && apiDef.securityScheme.mutualssl && apiDef.securityScheme.mutualssl.enabled === true) { - securityScheme.push("mutualssl"); - securityScheme.push("mutualssl_mandatory"); + securityScheme.push('mutualssl'); + securityScheme.push('mutualssl_mandatory'); } - if (apiDef.securityScheme && apiDef.securityScheme.oauth2 && apiDef.securityScheme.oauth2.enabled === true) { securityScheme.push("oauth2"); securityScheme.push("oauth_basic_auth_api_key_mandatory"); @@ -213,61 +213,44 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { context: apiDef.rootContext, version: apiDef.version, operations: await constructAPIOperations(apiDef.swaggerSpec), - lifeCycleStatus: "CREATED", + lifeCycleStatus: 'CREATED', isDefaultVersion: false, enableStore: true, type: backendType, - transport: ["https"], - tags: [...apiDef.tags, "serverless-wso2-apim"], - policies: ["Unlimited"], - apiThrottlingPolicy: "Unlimited", + transport: ['https'], + tags: [...apiDef.tags, 'serverless-wso2-apim'], + policies: ['Unlimited'], + apiThrottlingPolicy: 'Unlimited', securityScheme, maxTps: { - production: apiDef.maxTps ? apiDef.maxTps : undefined, + production: (apiDef.maxTps) ? apiDef.maxTps : undefined }, visibility: apiDef.subscriberVisibility || apiDef.visibility, endpointConfig: { production_endpoints: { - url: backendBaseUrl, + url: backendBaseUrl }, - sandbox_endpoints: { - url: backendBaseUrl, - }, - endpoint_type: apiDef.backend.endpointType ? apiDef.backend.endpointType : "http", + endpoint_type: (apiDef.backend.endpointType) ? apiDef.backend.endpointType : 'http' }, - endpointImplementationType: "ENDPOINT", + endpointImplementationType: 'ENDPOINT', endpointSecurity: null, - gatewayEnvironments: [gatewayEnv], + gatewayEnvironments: [ gatewayEnv ], mediationPolicies: mediationPolicies, - additionalProperties: apiDef.apiProperties && Object.keys(apiDef.apiProperties).length > 0 ? apiDef.apiProperties : undefined, - subscriptionAvailability: "CURRENT_TENANT", - subscriptionAvailableTenants: [], + additionalProperties: ((apiDef.apiProperties) && (Object.keys(apiDef.apiProperties).length > 0)) ? apiDef.apiProperties : undefined, + subscriptionAvailability: 'CURRENT_TENANT', keyManagers: apiDef.securityScheme?.oauth2?.keyManager, - businessInformation: apiDef.businessInformation - ? { - businessOwnerEmail: apiDef.businessInformation.businessOwnerEmail, - technicalOwnerEmail: apiDef.businessInformation.technicalOwnerEmail, - technicalOwner: apiDef.businessInformation.technicalOwner, - businessOwner: apiDef.businessInformation.businessOwner, - } - : { - businessOwnerEmail: - apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.email - ? apiDef.swaggerSpec.info.contact.email - : undefined, - technicalOwnerEmail: - apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.email - ? apiDef.swaggerSpec.info.contact.email - : undefined, - technicalOwner: - apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.name - ? apiDef.swaggerSpec.info.contact.name - : undefined, - businessOwner: - apiDef.swaggerSpec.info && apiDef.swaggerSpec.info.contact && apiDef.swaggerSpec.info.contact.name - ? apiDef.swaggerSpec.info.contact.name - : undefined, - }, + subscriptionAvailableTenants: [], + businessInformation: apiDef.businessInformation ? { + businessOwnerEmail: apiDef.businessInformation.businessOwnerEmail, + technicalOwnerEmail: apiDef.businessInformation.technicalOwnerEmail, + technicalOwner: apiDef.businessInformation.technicalOwner, + businessOwner: apiDef.businessInformation.businessOwner + } : { + businessOwnerEmail: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.email)) ? apiDef.swaggerSpec.info.contact.email : undefined, + technicalOwnerEmail: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.email)) ? apiDef.swaggerSpec.info.contact.email : undefined, + technicalOwner: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.name)) ? apiDef.swaggerSpec.info.contact.name : undefined, + businessOwner: ((apiDef.swaggerSpec.info) && (apiDef.swaggerSpec.info.contact) && (apiDef.swaggerSpec.info.contact.name)) ? apiDef.swaggerSpec.info.contact.name : undefined, + } }; if (apiDef.cors) { wso2ApiDefinition.corsConfiguration = constructCorsConfiguration(apiDef); @@ -276,17 +259,18 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { wso2ApiDefinition.visibleRoles = apiDef.subscriberVisibilityRoles; } if (apiDef.publisherVisibility) { - wso2ApiDefinition.accessControl = apiDef.publisherVisibility === "PRIVATE" ? "NONE" : apiDef.publisherVisibility; + wso2ApiDefinition.accessControl = apiDef.publisherVisibility === 'PRIVATE' ? 'NONE' : apiDef.publisherVisibility; } if (apiDef.publisherVisibilityRoles) { wso2ApiDefinition.accessControlRoles = apiDef.publisherVisibilityRoles; } - backendBaseUrl = ""; - backendType = ""; + backendBaseUrl = ''; + backendType = ''; return wso2ApiDefinition; - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -294,15 +278,22 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { function constructCorsConfiguration(apiDef) { const { origins, credentials, headers, methods } = apiDef.cors; const defaultAllowHeaders /* default WSO2 cors config */ = [ - "Authorization", - "Access-Control-Allow-Origin", - "Content-Type", - "SOAPAction", + 'Authorization', + 'Access-Control-Allow-Origin', + 'Content-Type', + 'SOAPAction', + ]; + const defaultAllowMethods /* default WSO2 cors config */ = [ + 'GET', + 'PUT', + 'POST', + 'DELETE', + 'PATCH', + 'OPTIONS', ]; - const defaultAllowMethods /* default WSO2 cors config */ = ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"]; return { corsConfigurationEnabled: true, - accessControlAllowOrigins: origins || ["*"], + accessControlAllowOrigins: origins || ['*'], accessControlAllowCredentials: credentials || false, accessControlAllowHeaders: headers || defaultAllowHeaders, accessControlAllowMethods: methods || defaultAllowMethods, @@ -321,15 +312,15 @@ async function constructAPIOperations(apiDef) { // Traverse through verb properties var authType = undefined; for (var verbProp in swaggerObj.paths[pathObj][verbObj]) { - if (verbProp.toLowerCase() === "x-auth-type") { + if (verbProp.toLowerCase() === 'x-auth-type') { authType = swaggerObj.paths[pathObj][verbObj][verbProp]; } } wso2Operations.push({ target: pathObj, verb: verbObj, - authType: authType ? authType : "Any", - throttlingPolicy: "Unlimited", + authType: (authType) ? authType : 'Any', + throttlingPolicy: 'Unlimited' }); } } @@ -345,35 +336,38 @@ async function createAPIDef(wso2APIM, accessToken, apiDef) { let { user, gatewayEnv } = wso2APIM; var data = await constructAPIDef(user, gatewayEnv, apiDef); + // TODO - dynamically retrieve swaggerSpec version - let queryStr = "openAPIVersion=V3"; - url = url + "?" + queryStr; + let queryStr = 'openAPIVersion=V3'; + url = url + '?' + queryStr; var config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "application/json", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'application/json' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve({ apiId: res.data.id, apiName: res.data.name, apiContext: res.data.context, - apiStatus: res.data.status, + apiStatus: res.data.status }); }) .catch((err) => { - reject(utils.renderError(err)); + reject( + utils.renderError(err) + ); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -385,20 +379,19 @@ async function publishAPIDef(wso2APIM, accessToken, apiId) { var data = {}; var config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, params: { - apiId: apiId, - action: "Publish", + 'apiId': apiId, + 'action': 'Publish' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve(res); }) @@ -407,7 +400,8 @@ async function publishAPIDef(wso2APIM, accessToken, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -418,16 +412,15 @@ async function listInvokableAPIUrl(wso2APIM, accessToken, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/store/${wso2APIM.versionSlug}/apis/${apiId}`; var config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .get(url, config) + axios.get(url, config) .then((res) => { resolve(res.data); }) @@ -436,44 +429,46 @@ async function listInvokableAPIUrl(wso2APIM, accessToken, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } + // Uploads backend certificate async function uploadCert(wso2APIM, accessToken, certAlias, cert, backendUrl) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates`; var data = new FormData(); - data.append("certificate", fs.createReadStream(cert)); - data.append("alias", certAlias); - data.append("endpoint", backendUrl); + data.append('certificate', fs.createReadStream(cert)); + data.append('alias', certAlias); + data.append('endpoint', backendUrl); var config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "multipart/form-data", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'multipart/form-data' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-exists-for-that-Alias error gracefully - if (err.response.data.code != "409") { + if (err.response.data.code != '409') { utils.renderError(err); } reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -486,17 +481,16 @@ async function updateAPIDef(wso2APIM, accessToken, apiDef, apiId) { var data = await constructAPIDef(user, gatewayEnv, apiDef, apiId); var config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "application/json", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'application/json' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .put(url, data, config) + axios.put(url, data, config) .then((res) => { resolve(res.data); }) @@ -505,7 +499,8 @@ async function updateAPIDef(wso2APIM, accessToken, apiDef, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -516,16 +511,15 @@ async function removeAPIDef(wso2APIM, accessToken, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`; let config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .delete(url, config) + axios.delete(url, config) .then((res) => { resolve(res.data); }) @@ -534,7 +528,8 @@ async function removeAPIDef(wso2APIM, accessToken, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -545,51 +540,51 @@ async function removeCert(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .delete(url, config) + axios.delete(url, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.response.status != "404") { + if (err.response.status != '404') { utils.renderError(err); } reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } + // Updates backend certificate async function updateCert(wso2APIM, accessToken, certAlias, cert) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates/${certAlias}`; var data = new FormData(); - data.append("certificate", fs.createReadStream(cert)); + data.append('certificate', fs.createReadStream(cert)); let config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "multipart/form-data", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'multipart/form-data' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .put(url, data, config) + axios.put(url, data, config) .then((res) => { resolve(res); }) @@ -598,7 +593,8 @@ async function updateCert(wso2APIM, accessToken, certAlias, cert) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -609,17 +605,16 @@ async function listCertInfo(wso2APIM, accessToken, certAlias) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/${certAlias}`; let config = { headers: { - Authorization: "Bearer " + accessToken, - Accept: "application/json", + 'Authorization': 'Bearer ' + accessToken, + 'Accept': 'application/json' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .get(url, config) + axios.get(url, config) .then((res) => { resolve(res.data); }) @@ -628,7 +623,8 @@ async function listCertInfo(wso2APIM, accessToken, certAlias) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -638,34 +634,34 @@ async function uploadClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates`; var data = new FormData(); - data.append("certificate", fs.createReadStream(cert)); - data.append("alias", certAlias); - data.append("tier", "unlimited"); + data.append('certificate', fs.createReadStream(cert)); + data.append('alias', certAlias); + data.append('tier', 'unlimited'); var config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "multipart/form-data", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'multipart/form-data' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .post(url, data, config) + axios.post(url, data, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-exists-for-that-Alias error gracefully - if (err.response.data.code != "409") { + if (err.response.data.code != '409') { utils.renderError(err); } reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -676,17 +672,16 @@ async function listClientCertInfo(wso2APIM, accessToken, certAlias, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; let config = { headers: { - Authorization: "Bearer " + accessToken, - Accept: "application/json", + 'Authorization': 'Bearer ' + accessToken, + 'Accept': 'application/json' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .get(url, config) + axios.get(url, config) .then((res) => { resolve(res.data); }) @@ -695,7 +690,8 @@ async function listClientCertInfo(wso2APIM, accessToken, certAlias, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -705,20 +701,19 @@ async function updateClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { try { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; var data = new FormData(); - data.append("certificate", fs.createReadStream(cert)); + data.append('certificate', fs.createReadStream(cert)); let config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "multipart/form-data", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'multipart/form-data' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .put(url, data, config) + axios.put(url, data, config) .then((res) => { resolve(res); }) @@ -727,7 +722,8 @@ async function updateClientCert(wso2APIM, accessToken, certAlias, cert, apiId) { reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -738,28 +734,28 @@ async function removeClientCert(wso2APIM, accessToken, certAlias, apiId) { let url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/client-certificates/${certAlias}`; let config = { headers: { - Authorization: "Bearer " + accessToken, + 'Authorization': 'Bearer ' + accessToken }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; return new Promise((resolve, reject) => { - axios - .delete(url, config) + axios.delete(url, config) .then((res) => { resolve(res); }) .catch((err) => { // Ignore Certificate-not-found-for-that-Alias error gracefully - if (err.response.status != "404") { + if (err.response.status != '404') { utils.renderError(err); } reject(err); }); }); - } catch (err) { + } + catch (err) { utils.renderError(err); } } @@ -773,34 +769,34 @@ async function removeClientCert(wso2APIM, accessToken, certAlias, apiId) { * @param {*} swaggerSpec * @returns */ -async function upsertSwaggerSpec(wso2APIM, accessToken, apiId, swaggerSpec) { + async function upsertSwaggerSpec(wso2APIM, accessToken, apiId, swaggerSpec) { try { const url = `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}/swagger`; const config = { headers: { - Authorization: "Bearer " + accessToken, - "Content-Type": "multipart/form-data", + 'Authorization': 'Bearer ' + accessToken, + 'Content-Type': 'multipart/form-data' }, httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), + rejectUnauthorized: false + }) }; const data = new FormData(); - data.append("apiDefinition", JSON.stringify(swaggerSpec)); + data.append('apiDefinition', JSON.stringify(swaggerSpec)); - return axios - .put(url, data, config) - .then((_) => undefined) - .catch((err) => { + return axios.put(url, data, config) + .then((_) => undefined).catch((err) => { utils.renderError(err); }); // eat the http response, not needed outside of this api layer - } catch (err) { + } + catch (err) { utils.renderError(err); throw err; } } + module.exports = { registerClient, generateToken, @@ -821,4 +817,4 @@ module.exports = { removeAPIDef, listInvokableAPIUrl, upsertSwaggerSpec, -}; +}; \ No newline at end of file diff --git a/src/3.2.0/wso2apim.spec.js b/src/3.2.0/wso2apim.spec.js index bbcdea5..f92ac6d 100644 --- a/src/3.2.0/wso2apim.spec.js +++ b/src/3.2.0/wso2apim.spec.js @@ -17,88 +17,89 @@ const { upsertSwaggerSpec, updateAPIDef, removeAPIDef, - listInvokableAPIUrl, -} = require("./wso2apim"); -const axios = require("axios"); -const qs = require("qs"); + listInvokableAPIUrl +} = require('./wso2apim'); +const axios = require('axios'); +const qs = require('qs'); afterEach(() => { jest.clearAllMocks(); }); -jest.mock("axios", () => ({ - post: jest.fn(() => Promise.resolve({ data: "foo" })), - get: jest.fn(() => Promise.resolve({ data: "foo" })), - put: jest.fn(() => Promise.resolve({ data: "foo" })), - delete: jest.fn(() => Promise.resolve({ data: "foo" })), +jest.mock('axios', () => ({ + post: jest.fn(() => Promise.resolve({ data: 'foo' })), + get: jest.fn(() => Promise.resolve({ data: 'foo' })), + put: jest.fn(() => Promise.resolve({ data: 'foo' })), + delete: jest.fn(() => Promise.resolve({ data: 'foo' })), })); const wso2APIM = { enabled: true, - host: "wso2-apimanager.com", + host: 'wso2-apimanager.com', port: 443, - versionSlug: "v0.17", - user: "foo", - pass: "bar", - gatewayEnv: "Local", + versionSlug: 'v0.17', + user: 'foo', + pass: 'bar', + gatewayEnv: 'Local', apidefs: [ { - name: "MyAwesomeAPI", - description: "My Awesome API", - rootContext: "/myawesomeapi", - version: "v1", - visibility: "PUBLIC", + name: 'MyAwesomeAPI', + description: 'My Awesome API', + rootContext: '/myawesomeapi', + version: 'v1', + visibility: 'PUBLIC', backend: { http: { - baseUrl: "https://backend.url", - certChain: "file://xxx.cer", - }, + baseUrl: 'https://backend.url', + certChain: 'file://xxx.cer' + } }, securityScheme: { mutualssl: { enabled: true, - clientCert: "file://xxx.cer", + clientCert: 'file://xxx.cer' }, - oauth2: { enabled: true, keyManager: ["Resident Key Manager"] }, + oauth2: { enabled: true, keyManager: ["Resident Key Manager"] } }, - tags: ["awesomeness", "myawesomeapi"], + tags: [ 'awesomeness', 'myawesomeapi'], maxTps: 999, swaggerSpec: { - openapi: "3.0.0", - info: { - title: "MyAwesomeAPI", - version: "v1", - contact: { - name: "MyTeam", - email: "myteam@myteam.com", - }, + 'openapi': '3.0.0', + 'info': { + 'title': 'MyAwesomeAPI', + 'version': 'v1', + 'contact': { + 'name': 'MyTeam', + 'email': 'myteam@myteam.com' + } }, - paths: { - "/*": { - post: { - responses: { - 201: { - description: "Created", - }, - }, - }, - }, - }, - }, - }, - ], + 'paths': { + '/*': { + 'post': { + 'responses': { + '201': { + 'description': 'Created' + } + } + } + } + } + } + } + ] }; -const apiId = "123456789"; +const apiId = '123456789'; + +describe('wso2apim-3.2.0', () => { -describe("wso2apim-3.2.0", () => { - describe("registerClient()", () => { - it("should handle a successful response", async () => { + describe('registerClient()', () => { + it('should handle a successful response', async () => { axios.post.mockImplementationOnce(() => Promise.resolve({ data: { - clientId: "foo", - clientSecret: "bar", + clientId: 'foo', + clientSecret: 'bar', }, }) ); @@ -108,137 +109,149 @@ describe("wso2apim-3.2.0", () => { expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/client-registration/v0.17/register`, { - clientName: "serverless-wso2-apim", + clientName: 'serverless-wso2-apim', owner: wso2APIM.user, - grantType: "password refresh_token", + grantType: 'password refresh_token', saasApp: true, }, expect.objectContaining({}) ); expect(response).toEqual({ - clientId: "foo", - clientSecret: "bar", + clientId: 'foo', + clientSecret: 'bar', }); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); expect(registerClient(wso2APIM)).rejects.toThrow(); }); }); - describe("generateToken()", () => { - it("should handle a successful response", async () => { + describe('generateToken()', () => { + it('should handle a successful response', async () => { + axios.post.mockImplementationOnce(() => Promise.resolve({ data: { - access_token: "xxx", + access_token: 'xxx' }, }) ); - const response = await generateToken(wso2APIM, "foo123", "xxxyyyzzz"); + const response = await generateToken(wso2APIM, 'foo123', 'xxxyyyzzz'); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/oauth2/token`, qs.stringify({ - grant_type: "password", - username: wso2APIM.user, - password: wso2APIM.pass, - scope: "apim:api_create apim:api_view apim:api_publish apim:api_delete", + 'grant_type': 'password', + 'username': wso2APIM.user, + 'password': wso2APIM.pass, + 'scope': 'apim:api_create apim:api_view apim:api_publish apim:api_delete' }), expect.objectContaining({}) ); expect(response).toEqual({ - accessToken: "xxx", + accessToken: 'xxx', }); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); - expect(generateToken(wso2APIM, "foo123", "xxxyyyzzz")).rejects.toThrow(); + expect(generateToken(wso2APIM, 'foo123', 'xxxyyyzzz')).rejects.toThrow(); }); }); - describe("isAPIDeployed()", () => { - it("should handle a successful response", async () => { - const response = await isAPIDeployed( - wso2APIM, - "xxx", - wso2APIM.apidefs[0].name, - wso2APIM.apidefs[0].version, - wso2APIM.apidefs[0].rootContext - ); + describe('isAPIDeployed()', () => { + it('should handle a successful response', async () => { + + const response = await isAPIDeployed(wso2APIM, 'xxx', wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis?query=name:${wso2APIM.apidefs[0].name} version:${wso2APIM.apidefs[0].version} context:${wso2APIM.apidefs[0].rootContext}`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx', }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.get.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.get.mockImplementationOnce(() => + Promise.reject() + ); expect( - isAPIDeployed(wso2APIM, "xxx", wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext) + isAPIDeployed(wso2APIM, 'xxx', wso2APIM.apidefs[0].name, wso2APIM.apidefs[0].version, wso2APIM.apidefs[0].rootContext) ).rejects.toThrow(); }); }); - describe("isCertUploaded()", () => { - it("should handle a successful response", async () => { - const response = await isCertUploaded(wso2APIM, "xxx", "alias"); + describe('isCertUploaded()', () => { + it('should handle a successful response', async () => { + + const response = await isCertUploaded(wso2APIM, 'xxx', 'alias'); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx', }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.get.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.get.mockImplementationOnce(() => + Promise.reject() + ); - expect(isCertUploaded(wso2APIM, "xxx", "alias")).rejects.toThrow(); + expect( + isCertUploaded(wso2APIM, 'xxx', 'alias') + ).rejects.toThrow(); }); }); - describe("createAPIDef()", () => { - it("should handle a successful response", async () => { + describe('createAPIDef()', () => { + it('should handle a successful response', async () => { + axios.post.mockImplementationOnce(() => Promise.resolve({ data: { id: apiId, name: wso2APIM.apidefs[0].name, context: wso2APIM.apidefs[0].rootContext, - status: "CREATED", - }, + status: 'CREATED' + } }) ); - const response = await createAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0]); + const response = await createAPIDef( + wso2APIM, + 'xxx', + wso2APIM.apidefs[0] + ); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis?openAPIVersion=V3`, expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", - "Content-Type": "application/json", + Authorization: 'Bearer xxx', + 'Content-Type': 'application/json', }, httpsAgent: expect.objectContaining({}), } @@ -248,248 +261,308 @@ describe("wso2apim-3.2.0", () => { apiId, apiName: wso2APIM.apidefs[0].name, apiContext: wso2APIM.apidefs[0].rootContext, - apiStatus: "CREATED", + apiStatus: 'CREATED' }); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); - expect(createAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0])).rejects.toThrow(); + expect(createAPIDef(wso2APIM, 'xxx', wso2APIM.apidefs[0])).rejects.toThrow(); }); + }); - describe("publishAPIDef()", () => { - it("should handle a successful response", async () => { - const response = await publishAPIDef(wso2APIM, "xxx", apiId); + describe('publishAPIDef()', () => { + it('should handle a successful response', async () => { + + const response = await publishAPIDef( + wso2APIM, + 'xxx', + apiId + ); expect(axios.post).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/change-lifecycle`, expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx' }, params: { - apiId: apiId, - action: "Publish", + 'apiId': apiId, + 'action': 'Publish' }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual("foo"); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); - expect(publishAPIDef(wso2APIM, "xxx", apiId)).rejects.toThrow(); + expect(publishAPIDef(wso2APIM, 'xxx', apiId)).rejects.toThrow(); }); + }); - describe("listInvokableAPIUrl()", () => { - it("should handle a successful response", async () => { - const response = await listInvokableAPIUrl(wso2APIM, "xxx", apiId); + describe('listInvokableAPIUrl()', () => { + it('should handle a successful response', async () => { + + const response = await listInvokableAPIUrl( + wso2APIM, + 'xxx', + apiId + ); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/store/${wso2APIM.versionSlug}/apis/${apiId}`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx' }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.get.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.get.mockImplementationOnce(() => + Promise.reject() + ); - expect(listInvokableAPIUrl(wso2APIM, "xxx", apiId)).rejects.toThrow(); + expect(listInvokableAPIUrl(wso2APIM, 'xxx', apiId)).rejects.toThrow(); }); + }); - describe("uploadCert()", () => { - it("should handle a successful response", async () => { + describe('uploadCert()', () => { + it('should handle a successful response', async () => { + const response = await uploadCert( wso2APIM, - "xxx", - "alias", + 'xxx', + 'alias', wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl ); - expect(response.data).toEqual("foo"); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); - expect( - uploadCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl) - ).rejects.toThrow(); + expect(uploadCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].backend.http.baseUrl)).rejects.toThrow(); }); + }); - describe("uploadClientCert()", () => { - it("should handle a successful response", async () => { + describe('uploadClientCert()', () => { + it('should handle a successful response', async () => { + const response = await uploadClientCert( wso2APIM, - "xxx", - "alias", + 'xxx', + 'alias', wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, - "123" + '123' ); - expect(response.data).toEqual("foo"); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.post.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.post.mockImplementationOnce(() => + Promise.reject() + ); - expect( - uploadClientCert( - wso2APIM, - "xxx", - "alias", - wso2APIM.apidefs[0].backend.http.certChain, - wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, - "123" - ) - ).rejects.toThrow(); + expect(uploadClientCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain, wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert,'123')).rejects.toThrow(); }); + }); - describe("updateAPIDef()", () => { - it("should handle a successful response", async () => { - const response = await updateAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0], apiId); + describe('updateAPIDef()', () => { + + it('should handle a successful response', async () => { + + const response = await updateAPIDef( + wso2APIM, + 'xxx', + wso2APIM.apidefs[0], + apiId + ); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`, expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", - "Content-Type": "application/json", + Authorization: 'Bearer xxx', + 'Content-Type': 'application/json', }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.put.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.put.mockImplementationOnce(() => + Promise.reject() + ); - expect(updateAPIDef(wso2APIM, "xxx", wso2APIM.apidefs[0], apiId)).rejects.toThrow(); + expect(updateAPIDef(wso2APIM, 'xxx', wso2APIM.apidefs[0], apiId)).rejects.toThrow(); }); + }); - describe("removeAPIDef()", () => { - it("should handle a successful response", async () => { - const response = await removeAPIDef(wso2APIM, "xxx", apiId); + describe('removeAPIDef()', () => { + it('should handle a successful response', async () => { + + const response = await removeAPIDef( + wso2APIM, + 'xxx', + apiId + ); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/${apiId}`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx', }, httpsAgent: expect.objectContaining({}), - } - ); - expect(response).toEqual("foo"); + }); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.delete.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.delete.mockImplementationOnce(() => + Promise.reject() + ); - expect(removeAPIDef(wso2APIM, "xxx", apiId)).rejects.toThrow(); + expect(removeAPIDef(wso2APIM, 'xxx', apiId)).rejects.toThrow(); }); + }); - describe("removeCert()", () => { - it("should handle a successful response", async () => { - const response = await removeCert(wso2APIM, "xxx", "alias"); + describe('removeCert()', () => { + it('should handle a successful response', async () => { + + const response = await removeCert( + wso2APIM, + 'xxx', + 'alias' + ); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx', }, httpsAgent: expect.objectContaining({}), - } - ); - expect(response.data).toEqual("foo"); + }); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.delete.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.delete.mockImplementationOnce(() => + Promise.reject() + ); - expect(removeCert(wso2APIM, "xxx", "alias")).rejects.toThrow(); + expect(removeCert(wso2APIM, 'xxx', 'alias')).rejects.toThrow(); }); + }); - describe("removeClientCert()", () => { - it("should handle a successful response", async () => { - const response = await removeClientCert(wso2APIM, "xxx", "alias", "123"); + describe('removeClientCert()', () => { + it('should handle a successful response', async () => { + + const response = await removeClientCert( + wso2APIM, + 'xxx', + 'alias', + '123' + ); expect(axios.delete).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/123/client-certificates/alias`, { headers: { - Authorization: "Bearer xxx", + Authorization: 'Bearer xxx', }, httpsAgent: expect.objectContaining({}), - } - ); - expect(response.data).toEqual("foo"); + }); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.delete.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.delete.mockImplementationOnce(() => + Promise.reject() + ); - expect(removeClientCert(wso2APIM, "xxx", "alias", "123")).rejects.toThrow(); + expect(removeClientCert(wso2APIM, 'xxx', 'alias', '123')).rejects.toThrow(); }); + }); - describe("updateCert()", () => { - it("should handle a successful response", async () => { - const response = await updateCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain); + describe('updateCert()', () => { + + it('should handle a successful response', async () => { + + const response = await updateCert( + wso2APIM, + 'xxx', + 'alias', + wso2APIM.apidefs[0].backend.http.certChain + ); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/endpoint-certificates/alias`, expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", - "Content-Type": "multipart/form-data", + Authorization: 'Bearer xxx', + 'Content-Type': 'multipart/form-data', }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual("foo"); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.put.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.put.mockImplementationOnce(() => + Promise.reject() + ); - expect(updateCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].backend.http.certChain)).rejects.toThrow(); + expect(updateCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].backend.http.certChain)).rejects.toThrow(); }); + }); - describe("updateClientCert()", () => { - it("should handle a successful response", async () => { + describe('updateClientCert()', () => { + + it('should handle a successful response', async () => { + const response = await updateClientCert( wso2APIM, - "xxx", - "alias", + 'xxx', + 'alias', wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, - "123" + '123' ); expect(axios.put).toHaveBeenCalledWith( @@ -497,200 +570,217 @@ describe("wso2apim-3.2.0", () => { expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", - "Content-Type": "multipart/form-data", + Authorization: 'Bearer xxx', + 'Content-Type': 'multipart/form-data', }, httpsAgent: expect.objectContaining({}), } ); - expect(response.data).toEqual("foo"); + expect(response.data).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.put.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.put.mockImplementationOnce(() => + Promise.reject() + ); - expect( - updateClientCert(wso2APIM, "xxx", "alias", wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, "123") - ).rejects.toThrow(); + expect(updateClientCert(wso2APIM, 'xxx', 'alias', wso2APIM.apidefs[0].securityScheme.mutualssl.clientCert, '123')).rejects.toThrow(); }); + }); - describe("listCertInfo()", () => { - it("should handle a successful response", async () => { - const response = await listCertInfo(wso2APIM, "xxx", "alias"); + describe('listCertInfo()', () => { + it('should handle a successful response', async () => { + + const response = await listCertInfo( + wso2APIM, + 'xxx', + 'alias' + ); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/certificates/alias`, { headers: { - Authorization: "Bearer xxx", - Accept: "application/json", + Authorization: 'Bearer xxx', + Accept: 'application/json' }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.get.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.get.mockImplementationOnce(() => + Promise.reject() + ); - expect(listCertInfo(wso2APIM, "xxx", "alias")).rejects.toThrow(); + expect(listCertInfo(wso2APIM, 'xxx', 'alias')).rejects.toThrow(); }); + }); - describe("listClientCertInfo()", () => { - it("should handle a successful response", async () => { - const response = await listClientCertInfo(wso2APIM, "xxx", "alias", "123"); + describe('listClientCertInfo()', () => { + it('should handle a successful response', async () => { + + const response = await listClientCertInfo( + wso2APIM, + 'xxx', + 'alias', + '123' + ); expect(axios.get).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/123/client-certificates/alias`, { headers: { - Authorization: "Bearer xxx", - Accept: "application/json", + Authorization: 'Bearer xxx', + Accept: 'application/json' }, httpsAgent: expect.objectContaining({}), } ); - expect(response).toEqual("foo"); + expect(response).toEqual('foo'); }); - it("should handle a faulty response", async () => { - axios.get.mockImplementationOnce(() => Promise.reject()); + it('should handle a faulty response', async () => { + axios.get.mockImplementationOnce(() => + Promise.reject() + ); - expect(listClientCertInfo(wso2APIM, "xxx", "alias", "123")).rejects.toThrow(); + expect(listClientCertInfo(wso2APIM, 'xxx', 'alias', '123')).rejects.toThrow(); }); + }); - describe("upsertSwaggerSpec()", () => { - it("should handle a successful response", async () => { - const response = await upsertSwaggerSpec(wso2APIM, "xxx", "id001", wso2APIM.apidefs[0].swaggerSpec); + describe('upsertSwaggerSpec()', () => { + it('should handle a successful response', async () => { + const response = await upsertSwaggerSpec(wso2APIM, 'xxx', 'id001', wso2APIM.apidefs[0].swaggerSpec); expect(axios.put).toHaveBeenCalledWith( `https://${wso2APIM.host}:${wso2APIM.port}/api/am/publisher/${wso2APIM.versionSlug}/apis/id001/swagger`, expect.objectContaining({}), { headers: { - Authorization: "Bearer xxx", - "Content-Type": "multipart/form-data", + Authorization: 'Bearer xxx', + 'Content-Type': 'multipart/form-data' }, - httpsAgent: expect.objectContaining({}), + httpsAgent: expect.objectContaining({}) } ); }); - it("should handle a faulty response", async () => { + it('should handle a faulty response', async () => { axios.put.mockImplementationOnce(() => Promise.reject()); - expect(upsertSwaggerSpec(wso2APIM, "xxx", "id001", wso2APIM.apidefs[0].swaggerSpec)).rejects.toThrow(); + expect(upsertSwaggerSpec(wso2APIM, 'xxx', 'id001', wso2APIM.apidefs[0].swaggerSpec)).rejects.toThrow(); }); }); - describe("cors configuration", () => { - it("no cors", async () => { + describe('cors configuration', () => { + + it('no cors', async () => { const apiDef = await constructAPIDef(wso2APIM.user, wso2APIM.gatewayEnv, wso2APIM.apidefs[0]); expect(apiDef.corsConfiguration).toBeUndefined(); }); - it("only origin", async () => { - const config = { - ...wso2APIM, - apidefs: [ - { - ...wso2APIM.apidefs[0], - cors: { - origins: ["https://www.example.com"], - }, - }, - ], - }; + it('only origin', async () => { + const config = {...wso2APIM, apidefs: [{...wso2APIM.apidefs[0], cors: { + origins: ['https://www.example.com'] + }}]}; const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.corsConfiguration).toEqual({ corsConfigurationEnabled: true, - accessControlAllowOrigins: ["https://www.example.com"], + accessControlAllowOrigins: [ 'https://www.example.com' ], accessControlAllowCredentials: false, - accessControlAllowHeaders: ["Authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction"], - accessControlAllowMethods: ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"], + accessControlAllowHeaders: [ + 'Authorization', + 'Access-Control-Allow-Origin', + 'Content-Type', + 'SOAPAction' + ], + accessControlAllowMethods: [ 'GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'OPTIONS' ] }); }); - it("fully specified", async () => { - const config = { - ...wso2APIM, - apidefs: [ - { - ...wso2APIM.apidefs[0], - cors: { - origins: ["https://www.example.com", "https://www.example.org"], - credentials: true, - headers: ["Authorization", "x-custom"], - methods: ["GET"], - }, - }, - ], - }; + it('fully specified', async () => { + const config = {...wso2APIM, apidefs: [{...wso2APIM.apidefs[0], cors: { + origins: ['https://www.example.com', 'https://www.example.org'], + credentials: true, + headers: ['Authorization', 'x-custom'], + methods: ['GET'] + }}]}; const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); expect(apiDef.corsConfiguration).toEqual({ corsConfigurationEnabled: true, - accessControlAllowOrigins: ["https://www.example.com", "https://www.example.org"], + accessControlAllowOrigins: [ 'https://www.example.com', 'https://www.example.org' ], accessControlAllowCredentials: true, - accessControlAllowHeaders: ["Authorization", "x-custom"], - accessControlAllowMethods: ["GET"], + accessControlAllowHeaders: ['Authorization', 'x-custom'], + accessControlAllowMethods: ['GET'] }); }); }); - describe("business information", () => { - it("businessInformation provided", async () => { + describe('business information', () => { + it('businessInformation provided', async () => { const config = { ...wso2APIM, apidefs: [ { ...wso2APIM.apidefs[0], businessInformation: { - technicalOwnerEmail: "technical@email.com", - businessOwnerEmail: "business@email.com", - technicalOwner: "NL NN/Techical/Owner", - businessOwner: "NL NN/Business/Owner", + technicalOwnerEmail: 'technical@email.com', + businessOwnerEmail: 'business@email.com', + technicalOwner: 'NL NN/Techical/Owner', + businessOwner: 'NL NN/Business/Owner', }, }, ], }; - const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); + const apiDef = await constructAPIDef( + config.user, + config.gatewayEnv, + config.apidefs[0] + ); expect(apiDef.businessInformation).toEqual({ - technicalOwnerEmail: "technical@email.com", - businessOwnerEmail: "business@email.com", - technicalOwner: "NL NN/Techical/Owner", - businessOwner: "NL NN/Business/Owner", + technicalOwnerEmail: 'technical@email.com', + businessOwnerEmail: 'business@email.com', + technicalOwner: 'NL NN/Techical/Owner', + businessOwner: 'NL NN/Business/Owner', }); }); - it("businessInformation not provided", async () => { + it('businessInformation not provided', async () => { const config = { ...wso2APIM, apidefs: [ { - ...wso2APIM.apidefs[0], + ...wso2APIM.apidefs[0] }, ], }; - const apiDef = await constructAPIDef(config.user, config.gatewayEnv, config.apidefs[0]); + const apiDef = await constructAPIDef( + config.user, + config.gatewayEnv, + config.apidefs[0] + ); expect(apiDef.businessInformation).toEqual({ - technicalOwnerEmail: "myteam@myteam.com", - businessOwnerEmail: "myteam@myteam.com", - technicalOwner: "MyTeam", - businessOwner: "MyTeam", + technicalOwnerEmail: 'myteam@myteam.com', + businessOwnerEmail: 'myteam@myteam.com', + technicalOwner: 'MyTeam', + businessOwner: 'MyTeam', }); }); }); -}); + +}); \ No newline at end of file diff --git a/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/cert.cer b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/cert.cer new file mode 100644 index 0000000..72cc9c3 --- /dev/null +++ b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/cert.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIJAOnghp4UWa/lMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV +BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0yMTA0MTExNDIwNDlaFw0zMTA0MDkxNDIw +NDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKm/cmcYhWOL4jn+1Y/eHLnF6dbNzzuxByF5I4Ei0Aa2 +vRnmmCFJLb9MI03Dj4H99RK7WEvx8g7YF4WqAZc3n9ztPrHu1sGnMGsnaPPpvCdl +BLo2AD6ZQ07K5O6jsKLIno/qQi4dUXvfQ5io11xeRbUTROQiTgOsVoWSYeIyeJmY +hmg4owtnoIBvZfWyXKrqy1nb8yNggDP8C35bUFXtOavdTCPrREe58l89wJggmukT +QqHFPmB7rpwOyJI9dSVavC8v/WbV/LbaS3auaTkUCHkQL5NIKZNyXOxbReDyJ0jS +7eMk2ZEQB+87HCfLORyB/zbj5jG6ftRu4TsVm/A8Ak0CAwEAAaMeMBwwGgYDVR0R +BBMwEYIPd3d3LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQB7NbyoQCaL +ijan0pyDRW3joDj2xXVEnHSEd8jeKdURY4ADIcb3+CFZ78IA+KHoG3m7yVAdebCw +HA3yRoZXgWc2fG92xMIJsOabF19k6grnaAkJR+/Zzh0CuXZWvkLETKjqZ7opx0jB +hW8ZnSxtaM/91rmW6gNOcnmLknBD2oiDjo1s9Ntax8UQtWgXgEWEE9tC4DeRUx4t +3RqmliCqWMLFb67mkWnsXYzbavHESVx2KmTzcnw4Q3xE2VyVvl5i1l34Tv2/QoPu +ntq9V6GqFmJbxPfWydIXYr7leCCnX9r65MSN3sDtV+/I7JUegR4z6UgeF1z7kuVo +GFKdTX4n4OyD +-----END CERTIFICATE----- diff --git a/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml new file mode 100644 index 0000000..9c894aa --- /dev/null +++ b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml @@ -0,0 +1,90 @@ +service: serverless-wso2-apim +provider: + name: aws + stackName: ${env:STACK_NAME} + deploymentBucket: + name: ${env:TEST_ID_NORMALIZED} +plugins: + - serverless-localstack + - serverless-deployment-bucket + - "../../../../../src" + +#⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇ Modify the configuration below to suit your test case. +#⬇⬇⬇ START HERE ⬇⬇⬇⬇ Help: https://github.com/ramgrandhi/serverless-wso2-apim#configuration-reference +#⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇ For a full list of env vars that you can use, refer `src/__tests__/e2e/e2e.test.js` +custom: + wso2apim: + enabled: true + host: ${env:WSO2_HOST} + port: ${env:WSO2_PORT} + user: ${env:WSO2_USER} + pass: ${env:WSO2_PASS} + gatewayEnv: ${env:WSO2_ENV} + apidefs: + - name: ${env:TEST_ID}-1 + description: ${env:TEST_ID}-1 + rootContext: /${env:TEST_ID}-1 + version: "v1" + visibility: "PRIVATE" + securityScheme: + mutualssl: + enabled: true + clientCert: 'file://cert.cer' + oauth2: + enabled: true + keyManager: + - 'Resident Key Manager' + backend: + http: + baseUrl: "https://baseUrl" + maxTps: 10 + tags: + - ${env:TEST_ID}-1 + swaggerSpec: + swagger: "2.0" + info: + title: ${env:TEST_ID}-1 + version: "v1" + contact: + name: ${env:TEST_ID}-1 + email: ${env:TEST_ID}-1 + paths: + /*: + post: + responses: + "201": + description: Created + x-auth-type: "None" + # - name: ${env:TEST_ID}-2 + # description: ${env:TEST_ID}-2 + # rootContext: /${env:TEST_ID}-2 + # version: "1" + # visibility: "PUBLIC" + # backend: + # http: + # baseUrl: "https://baseUrl" + # maxTps: 10 + # tags: + # - ${env:TEST_ID}-2 + # swaggerSpec: + # openapi: 3.0.0 + # info: + # title: ${env:TEST_ID}-2 + # version: "1" + # contact: + # name: ${env:TEST_ID}-2 + # email: ${env:TEST_ID}-2 + # paths: + # /*: + # post: + # responses: + # "201": + # description: Created + # x-auth-type: "None" + +# Optionally, add your other AWS provider-specific resources below. +# Make sure there is at least one resource listed below, otherwise stack deployment would fail. +resources: + Resources: + Topic: + Type: AWS::SNS::Topic From f076c09f704233f8867597f56a8b26122c20e23b Mon Sep 17 00:00:00 2001 From: nmaqsood Date: Tue, 23 Jul 2024 21:47:45 +0200 Subject: [PATCH 4/5] chore: updated documentation --- README.md | 4 +++- src/3.2.0/wso2apim.js | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 02c41e9..bbb11d5 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,9 @@ Serverless Framework plugin to manage APIs on [WSO2 API Manager](https://wso2.co > | `securityScheme.mutualssl.clientCert` | Required with mutualssl, your client certificate chain in PEM (base64) format.

It supports:
a. **File system** - Path must be relative to where `serverless.yml` is located.
b. **AWS Certificate ARN**
c. **AWS CloudFormation Export** - Exported value must contain a valid AWS Certificate ARN. | `file://certs/backend.cer`
(or)
`arn:aws:acm:..`
(or)
`!ImportValue xx` | > | `securityScheme.mutualssl.enabled` | Required with `securityScheme.mutualssl`. Expects `true` or `false`
. | > | `securityScheme.oauth2` | Requires `securityScheme.oauth2.enabled` to be defined.
. | -> | `securityScheme.oauth2.enabled` | Required with `securityScheme.oauth2`. Expects `true` or `false`
. | +> | `securityScheme.oauth2.enabled` | Required with `securityScheme.oauth2`. Expects `true` or `false`
. +> | `securityScheme.oauth2.mandatory` | Optional with `securityScheme.oauth2`. Expects `true` or `false`
. +> | `securityScheme.oauth2.keyManager` | Optional with `securityScheme.oauth2`. Array of keys to be used by API > | `mediationPolicies` | Optional, your choice of mediation policies (or) sequences. They can manipulate input/output/fault messages as described [here](https://docs.wso2.com/display/AM260/Adding+Mediation+Extensions). | | > | `mediationPolicies.in` | Input mediation policy, it manipulates the request going to your backend. | `log_in_message` | > | `mediationPolicies.out` | Output mediation policy, it manipulates the response going back to your API consumer. | `json_validator` | diff --git a/src/3.2.0/wso2apim.js b/src/3.2.0/wso2apim.js index 6e185c6..4c0c52f 100644 --- a/src/3.2.0/wso2apim.js +++ b/src/3.2.0/wso2apim.js @@ -202,9 +202,10 @@ async function constructAPIDef(user, gatewayEnv, apiDef, apiId) { } if (apiDef.securityScheme && apiDef.securityScheme.oauth2 && apiDef.securityScheme.oauth2.enabled === true) { securityScheme.push("oauth2"); - securityScheme.push("oauth_basic_auth_api_key_mandatory"); - } else { - securityScheme.push("oauth2"); + if (apiDef.securityScheme.oauth2.mandatory) { + securityScheme.push("oauth_basic_auth_api_key_mandatory"); + } + } const wso2ApiDefinition = { id: apiId, From a15697994af6eabb5de63c82ae29f7441294a88a Mon Sep 17 00:00:00 2001 From: nmaqsood Date: Wed, 24 Jul 2024 11:08:05 +0200 Subject: [PATCH 5/5] chore: updated e2e test --- .../valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml index 9c894aa..dd174de 100644 --- a/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml +++ b/src/__tests__/e2e/valid-mtls-enabled-and-oauth-enabled-3.2.0/serverless.yml @@ -32,6 +32,7 @@ custom: clientCert: 'file://cert.cer' oauth2: enabled: true + mandatory: true keyManager: - 'Resident Key Manager' backend: