|
|
|
@ -9,40 +9,26 @@ const proxyName = "omadaProxyHandler";
|
|
|
|
|
const logger = createLogger(proxyName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function login(loginUrl, username, password, cversion) {
|
|
|
|
|
let params;
|
|
|
|
|
if (cversion < "4.0.0") {
|
|
|
|
|
// change the parameters of the query string
|
|
|
|
|
params = JSON.stringify({
|
|
|
|
|
"method": "login",
|
|
|
|
|
"params": {
|
|
|
|
|
"name": username,
|
|
|
|
|
"password": password
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
params = JSON.stringify({
|
|
|
|
|
"username": username,
|
|
|
|
|
"password": password
|
|
|
|
|
});
|
|
|
|
|
async function login(loginUrl, username, password, controllerVersionMajor) {
|
|
|
|
|
const params = {
|
|
|
|
|
username: username,
|
|
|
|
|
password: password
|
|
|
|
|
}
|
|
|
|
|
const authResponse = await httpProxy(loginUrl, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: params,
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const data = JSON.parse(authResponse[2]);
|
|
|
|
|
const status = authResponse[0];
|
|
|
|
|
let token;
|
|
|
|
|
if (data.errorCode === 0) {
|
|
|
|
|
token = data.result.token;
|
|
|
|
|
} else {
|
|
|
|
|
token = null;
|
|
|
|
|
if (controllerVersionMajor < 4) {
|
|
|
|
|
params.method = "login";
|
|
|
|
|
params.name = username;
|
|
|
|
|
}
|
|
|
|
|
return [status, token ?? data];
|
|
|
|
|
|
|
|
|
|
const [status, contentType, data] = await httpProxy(loginUrl, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify(params),
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [status, JSON.parse(data.toString())];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -57,108 +43,121 @@ export default async function omadaProxyHandler(req, res) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (widget) {
|
|
|
|
|
let cid;
|
|
|
|
|
let cversion;
|
|
|
|
|
let connectedAp;
|
|
|
|
|
let activeuser;
|
|
|
|
|
let connectedSwitches;
|
|
|
|
|
let connectedGateways;
|
|
|
|
|
|
|
|
|
|
let alerts;
|
|
|
|
|
let loginUrl;
|
|
|
|
|
let siteName;
|
|
|
|
|
let requestresponse;
|
|
|
|
|
|
|
|
|
|
const {url} = widget;
|
|
|
|
|
|
|
|
|
|
const controllerInfoUrl = `${widget.url}/api/info`;
|
|
|
|
|
const controllerInfoURL = `${widget.url}/api/info`;
|
|
|
|
|
|
|
|
|
|
const cInfoResponse = await httpProxy(controllerInfoUrl, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
let [status, contentType, data] = await httpProxy(controllerInfoURL, {
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cInfoResponse[0] === 500) {
|
|
|
|
|
logger.debug("Getting controller version ends with Error 500");
|
|
|
|
|
return res.status(cInfoResponse[0]).json({error: {message: "HTTP Error", controllerInfoUrl, data: cInfoResponse[2]}});
|
|
|
|
|
|
|
|
|
|
if (status !== 200) {
|
|
|
|
|
logger.error("Unable to retrieve Omada controller info");
|
|
|
|
|
return res.status(status).json({error: {message: `HTTP Error ${status}`, url: controllerInfoURL, data: data}});
|
|
|
|
|
}
|
|
|
|
|
const cidresult = cInfoResponse[2];
|
|
|
|
|
|
|
|
|
|
const cId = JSON.parse(data).result.omadacId;
|
|
|
|
|
let controllerVersion;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
cid = JSON.parse(cidresult).result.omadacId;
|
|
|
|
|
cversion = JSON.parse(cidresult).result.controllerVer;
|
|
|
|
|
controllerVersion = JSON.parse(data).result.controllerVer;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
cversion = "3.2.17"
|
|
|
|
|
// fallback to this random version?
|
|
|
|
|
controllerVersion = "3.2.17"
|
|
|
|
|
}
|
|
|
|
|
if (cversion < "4.0.0") {
|
|
|
|
|
loginUrl = `${widget.url}/api/user/login?ajax`;
|
|
|
|
|
} else if (cversion < "5.0.0") {
|
|
|
|
|
loginUrl = `${widget.url}/api/v2/login`;
|
|
|
|
|
} else {
|
|
|
|
|
loginUrl = `${widget.url}/${cid}/api/v2/login`;
|
|
|
|
|
|
|
|
|
|
const controllerVersionMajor = parseInt(controllerVersion.split('.')[0], 10)
|
|
|
|
|
|
|
|
|
|
if (![3,4,5].includes(controllerVersionMajor)) {
|
|
|
|
|
return res.status(500).json({error: {message: "Error determining controller version", data}});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let loginUrl;
|
|
|
|
|
|
|
|
|
|
switch (controllerVersionMajor) {
|
|
|
|
|
case 3:
|
|
|
|
|
loginUrl = `${widget.url}/api/user/login?ajax`;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
loginUrl = `${widget.url}/api/v2/login`;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
loginUrl = `${widget.url}/${cId}/api/v2/login`;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
requestresponse = await login(loginUrl, widget.username, widget.password, cversion);
|
|
|
|
|
|
|
|
|
|
const [loginStatus, loginResponseData] = await login(loginUrl, widget.username, widget.password, controllerVersionMajor);
|
|
|
|
|
|
|
|
|
|
if (requestresponse[1].errorCode) {
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: "Error logging in", url, data: requestresponse[1]}});
|
|
|
|
|
if (loginStatus !== 200 || loginResponseData.errorCode > 0) {
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: "Error logging in to Oamda controller", url: loginUrl, data: loginResponseData}});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const token = requestresponse[1];
|
|
|
|
|
// Switching to the site we want to gather stats from
|
|
|
|
|
// First, we get the list of sites
|
|
|
|
|
const token = loginResponseData.result.token;
|
|
|
|
|
|
|
|
|
|
// List sites
|
|
|
|
|
let sitesUrl;
|
|
|
|
|
let body;
|
|
|
|
|
let params;
|
|
|
|
|
let headers;
|
|
|
|
|
let method;
|
|
|
|
|
let sitetoswitch;
|
|
|
|
|
if (cversion < "4.0.0") {
|
|
|
|
|
sitesUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
|
|
|
|
|
body = JSON.stringify({
|
|
|
|
|
"method": "getUserSites",
|
|
|
|
|
"params": {
|
|
|
|
|
"userName": widget.username
|
|
|
|
|
}});
|
|
|
|
|
params = { "token": token };
|
|
|
|
|
headers = { };
|
|
|
|
|
method = "POST";
|
|
|
|
|
} else if (cversion < "5.0.0") {
|
|
|
|
|
sitesUrl = `${widget.url}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
body = {};
|
|
|
|
|
params = {"token": token};
|
|
|
|
|
headers = {"Csrf-Token": token };
|
|
|
|
|
method = "GET";
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
sitesUrl = `${widget.url}/${cid}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
body = {};
|
|
|
|
|
headers = { "Csrf-Token": token };
|
|
|
|
|
method = "GET";
|
|
|
|
|
params = { };
|
|
|
|
|
let body = {};
|
|
|
|
|
let params = { token };
|
|
|
|
|
let headers = { "Csrf-Token": token };
|
|
|
|
|
let method = "GET";
|
|
|
|
|
|
|
|
|
|
switch (controllerVersionMajor) {
|
|
|
|
|
case 3:
|
|
|
|
|
sitesUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
|
|
|
|
|
body = {
|
|
|
|
|
"method": "getUserSites",
|
|
|
|
|
"params": {
|
|
|
|
|
"userName": widget.username
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
method = "POST";
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
sitesUrl = `${widget.url}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
sitesUrl = `${widget.url}/${cId}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
requestresponse = await httpProxy(sitesUrl, {
|
|
|
|
|
|
|
|
|
|
[status, contentType, data] = await httpProxy(sitesUrl, {
|
|
|
|
|
method,
|
|
|
|
|
params,
|
|
|
|
|
body: body.toString(),
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
headers,
|
|
|
|
|
});
|
|
|
|
|
const listresult = JSON.parse(requestresponse[2]);
|
|
|
|
|
if (listresult.errorCode !== 0) {
|
|
|
|
|
logger.debug(`HTTTP ${requestresponse[0]} getting sites list: ${requestresponse[2].msg}`);
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: "Error getting sites list", url, data: requestresponse[2]}});
|
|
|
|
|
|
|
|
|
|
const sitesResponseData = JSON.parse(data);
|
|
|
|
|
|
|
|
|
|
let site;
|
|
|
|
|
|
|
|
|
|
let connectedAp;
|
|
|
|
|
let activeUser;
|
|
|
|
|
let connectedSwitches;
|
|
|
|
|
let connectedGateways;
|
|
|
|
|
let alerts;
|
|
|
|
|
|
|
|
|
|
if (sitesResponseData.errorCode > 0) {
|
|
|
|
|
logger.debug(`HTTTP ${status} getting sites list: ${requestresponse[2].msg}`);
|
|
|
|
|
return res.status(status).json({error: {message: "Error getting sites list", url, data: requestresponse[2]}});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Switching site is really needed only for Omada 3.x.x controllers
|
|
|
|
|
// on modern controller, we need to call two different endpoints
|
|
|
|
|
// on older controller, we can call one endpoint
|
|
|
|
|
|
|
|
|
|
let switchUrl;
|
|
|
|
|
if (controllerVersionMajor === 3) {
|
|
|
|
|
|
|
|
|
|
if (cversion < "4.0.0") {
|
|
|
|
|
sitetoswitch = listresult.result.siteList.filter(site => site.name === widget.site);
|
|
|
|
|
siteName = sitetoswitch[0].siteName;
|
|
|
|
|
// Switching site is really needed only for Omada 3.x.x controllers
|
|
|
|
|
|
|
|
|
|
let switchUrl;
|
|
|
|
|
|
|
|
|
|
site = listresult.result.siteList.filter(site => site.name === widget.site);
|
|
|
|
|
siteName = site[0].siteName;
|
|
|
|
|
switchUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
|
|
|
|
|
method = "POST";
|
|
|
|
|
body = JSON.stringify({
|
|
|
|
@ -181,12 +180,7 @@ export default async function omadaProxyHandler(req, res) {
|
|
|
|
|
logger.debug(`HTTTP ${requestresponse[0]} getting sites list: ${requestresponse[2]}`);
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: "Error switching site", url, data: requestresponse[2]}});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OK now we are on the correct site. Let's get the stats
|
|
|
|
|
// on modern controller, we need to call two different endpoints
|
|
|
|
|
// on older controller, we can call one endpoint
|
|
|
|
|
if (cversion < "4.0.0") {
|
|
|
|
|
|
|
|
|
|
const statsUrl = `${widget.url}/web/v1/controller?getGlobalStat=&token=${token}`;
|
|
|
|
|
const statResponse = await httpProxy(statsUrl, {
|
|
|
|
|
method: "POST",
|
|
|
|
@ -205,68 +199,61 @@ export default async function omadaProxyHandler(req, res) {
|
|
|
|
|
return res.status(statResponse[0]).json({error: {message: "Error getting stats", url, data: statResponse[2]}});
|
|
|
|
|
}
|
|
|
|
|
connectedAp = data.result.connectedAp;
|
|
|
|
|
activeuser = data.result.activeUser;
|
|
|
|
|
activeUser = data.result.activeUser;
|
|
|
|
|
alerts = data.result.alerts;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
let siteStatsUrl;
|
|
|
|
|
let response;
|
|
|
|
|
sitetoswitch = listresult.result.data.filter(site => site.name === widget.site);
|
|
|
|
|
} else if (controllerVersionMajor === 4 || controllerVersionMajor === 5) {
|
|
|
|
|
site = sitesResponseData.result.data.find(site => site.name === widget.site);
|
|
|
|
|
|
|
|
|
|
if (sitetoswitch.length === 0) {
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: `Site ${widget.site} is not found`, url, data: requestresponse[2]}});
|
|
|
|
|
if (site.length === 0) {
|
|
|
|
|
return res.status(requestresponse[0]).json({error: {message: `Site ${widget.site} is not found`, url, data}});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// On 5.0.0, the field we need is id, on 4.x.x, it's key ...
|
|
|
|
|
siteName = sitetoswitch[0].id ?? sitetoswitch[0].key;
|
|
|
|
|
if (cversion < "5.0.0") {
|
|
|
|
|
siteStatsUrl = `${url}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
} else {
|
|
|
|
|
siteStatsUrl = `${url}/${cid}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
}
|
|
|
|
|
response = await httpProxy(siteStatsUrl, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
const siteName = (controllerVersionMajor === 5) ? site.id : site.key;
|
|
|
|
|
const siteStatsUrl = (controllerVersionMajor === 4) ?
|
|
|
|
|
`${url}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000` :
|
|
|
|
|
`${url}/${cId}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
|
|
|
|
|
[status, contentType, data] = await httpProxy(siteStatsUrl, {
|
|
|
|
|
headers: {
|
|
|
|
|
"Csrf-Token": token,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const clientresult = JSON.parse(response[2]);
|
|
|
|
|
if (clientresult.errorCode !== 0) {
|
|
|
|
|
logger.debug(`HTTTP ${listresult.errorCode} getting clients stats for site ${widget.site} with message ${listresult.msg}`);
|
|
|
|
|
return res.status(500).send(response[2]);
|
|
|
|
|
const siteResponseData = JSON.parse(data);
|
|
|
|
|
|
|
|
|
|
if (status !== 200 || siteResponseData.errorCode > 0) {
|
|
|
|
|
logger.debug(`HTTP ${status} getting stats for site ${widget.site} with message ${listresult.msg}`);
|
|
|
|
|
return res.status(500).send(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
activeuser = clientresult.result.totalClientNum;
|
|
|
|
|
connectedAp = clientresult.result.connectedApNum;
|
|
|
|
|
connectedGateways = clientresult.result.connectedGatewayNum;
|
|
|
|
|
connectedSwitches = clientresult.result.connectedSwitchNum;
|
|
|
|
|
activeUser = siteResponseData.result.totalClientNum;
|
|
|
|
|
connectedAp = siteResponseData.result.connectedApNum;
|
|
|
|
|
connectedGateways = siteResponseData.result.connectedGatewayNum;
|
|
|
|
|
connectedSwitches = siteResponseData.result.connectedSwitchNum;
|
|
|
|
|
|
|
|
|
|
const alertUrl = (controllerVersionMajor === 4) ?
|
|
|
|
|
`${url}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000` :
|
|
|
|
|
`${url}/${cId}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
|
|
|
|
|
let alertUrl;
|
|
|
|
|
if (cversion >= "5.0.0") {
|
|
|
|
|
alertUrl = `${url}/${cid}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
} else {
|
|
|
|
|
alertUrl = `${url}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000`;
|
|
|
|
|
}
|
|
|
|
|
response = await httpProxy(alertUrl, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
[status, contentType, data] = await httpProxy(alertUrl, {
|
|
|
|
|
headers: {
|
|
|
|
|
"Csrf-Token": token,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
const alertresult = JSON.parse(response[2]);
|
|
|
|
|
alerts = alertresult.result.alertNum;
|
|
|
|
|
const alertResponseData = JSON.parse(data);
|
|
|
|
|
alerts = alertResponseData.result.alertNum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res.send(JSON.stringify({
|
|
|
|
|
"connectedAp": connectedAp,
|
|
|
|
|
"activeUser": activeuser,
|
|
|
|
|
"alerts": alerts,
|
|
|
|
|
"connectedGateways": connectedGateways,
|
|
|
|
|
"connectedSwitches": connectedSwitches,
|
|
|
|
|
connectedAp,
|
|
|
|
|
activeUser,
|
|
|
|
|
alerts,
|
|
|
|
|
connectedGateways,
|
|
|
|
|
connectedSwitches,
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
|
|
|
|
}
|
|
|
|
|