Jelajahi Sumber

Omada Widget : No more legacy variable, the code detects the controller version and adapts the requests. Logic is not duplicated anymore

Benoit 2 tahun lalu
induk
melakukan
c3e9b8f870
1 mengubah file dengan 187 tambahan dan 201 penghapusan
  1. 187 201
      src/widgets/omada/proxy.js

+ 187 - 201
src/widgets/omada/proxy.js

@@ -1,6 +1,3 @@
-import cache from "memory-cache";
-
-import { addCookieToJar, setCookieHeader } from "../../utils/proxy/cookie-jar";
 
 import { httpProxy } from "utils/proxy/http";
 import getServiceWidget from "utils/config/service-helpers";
@@ -8,42 +5,43 @@ import createLogger from "utils/logger";
 import widgets from "widgets/widgets";
 
 const proxyName = "omadaProxyHandler";
-const tokenCacheKey = `${proxyName}__token`;
+// const tokenCacheKey = `${proxyName}__token`;
 const logger = createLogger(proxyName);
 
 
-async function login(loginUrl, username, password, legacy) {
-
-  if (legacy) {
-
-    const authResponse = await httpProxy(loginUrl,
-      {
-        method: "POST",
-        body: JSON.stringify({ "method": "login",
-          "params": {
-            "name": username,
-            "password": password
-          } }),
+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
+    });
+  }
+  const authResponse = await httpProxy(loginUrl, {
+      method: "POST",
+      body: params,
         headers: {
           "Content-Type": "application/json",
         },
-      }
-    );
-
-    const status = authResponse[0];
-    const data = JSON.parse(authResponse[2]);
-    const {token} = data.result;
-    try {
-      if (status === 200) {
-        cache.put(tokenCacheKey, token); // expiration -5 minutes
-      }
-    } catch (e) {
-      logger.error(`Error ${status} logging into Omada`, authResponse[2]);
-    }
-    return [status, token ?? data];
+      });
+  const data = JSON.parse(authResponse[2]);
+  const status = data.errorCode;
+  let token = null;
+  if (data.errorCode === 0) {
+    token = data.result.token;
+  } else {
+    token = null;
   }
-
-  return null
+  return [status, token ?? data];
 }
 
 
@@ -58,71 +56,137 @@ export default async function omadaProxyHandler(req, res) {
     }
 
     if (widget) {
-      if (widget.legacy) {
-        const loginUrl = `${widget.url}/api/user/login?ajax`;
-        let status;
-        let contentType;
-        let data;
-        let result;
-        let token;
-        // eslint-disable-next-line prefer-const
-        [status, token] = await login(loginUrl, widget.username, widget.password, widget.legacy);
-        if (status !== 200) {
-          logger.debug(`HTTTP ${status} logging into Omada api: ${token}`);
-          return res.status(status).send(token);
-        }
-        // Switching to the site we want to gather stats from
-        // First, we get the list of sites
-        const sitesUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
-        [status, contentType, data] = await httpProxy(sitesUrl, {
-          method: "POST",
-          params: { "token": token },
-          body: JSON.stringify({
-            "method": "getUserSites",
-            "params": {
-              "userName": widget.username
-            }
-          }),
-          headers: {
-            "Content-Type": "application/json",
-          },
-        });
-        const listresult = JSON.parse(data);
-        if (listresult.errorCode !== 0) {
-          logger.debug(`HTTTP ${listresult.errorCode} getting list of sites with message ${listresult.msg}`);
-          return res.status(status).send(data);
-        }
+      let status;
+      let token;
+      let cid;
+      let cversion;
+      let connectedAp;
+      let activeuser;
+      let alerts;
+      let loginUrl;
+      let siteName;
+      let requestresponse;
+      const {url} = widget;
+
+      const controllerInfoUrl = `${widget.url}/api/info`;
+      const cInfoResponse = await httpProxy(controllerInfoUrl, {
+        method: "GET",
+        headers: {
+          "Content-Type": "application/json",
+        },
+      });
 
-        const sites = JSON.parse(data);
+      const cidresult = cInfoResponse[2];
 
-        const sitetoswitch = sites.result.siteList.filter(site => site.name === widget.site);
+      try {
+        cid = JSON.parse(cidresult).result.omadacId;
+        cversion = JSON.parse(cidresult).result.controllerVer;
+      } catch (e) {
+        cversion = "3.2.17";
 
-        const { siteName } = sitetoswitch[0];
+      }
+      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 switchUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
+      [ status, token ] = await login(loginUrl, widget.username, widget.password, cversion);
 
-        [status, contentType, result] = await httpProxy(switchUrl, {
-          method: "POST",
-          params: { "token": token },
-          body: JSON.stringify({
-            "method": "switchSite",
-            "params": { "siteName": siteName, "userName": widget.username }
-          }),
-          headers: {
-            "Content-Type": "application/json",
-          },
-        });
-        const switchresult = JSON.parse(result);
+      if (status !== 0) {
+        const message = token.msg;
+
+        logger.debug(`HTTTP ${status} logging into Omada api: ${token}`);
+        return res.status(500).send(message);
+      }
+
+      // Switching to the site we want to gather stats from
+      // First, we get the list of 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}&currentPage=1&currentPageSize=1000`;
+        body = {};
+        params = { };
+        headers = {"Csrf-Token": token };
+        method = "GET";
 
+      } else {
+        sitesUrl = `${widget.url}/${cid}/api/v2/sites?token=${token}&currentPage=1&currentPageSize=1000`;
+        body = {};
+        headers = { "Csrf-Token": token };
+        method = "GET";
+        params = { };
+      }
+
+      const listResponse = await httpProxy(sitesUrl, {
+        method: method,
+        params: params,
+        body: body.toString(),
+        headers: headers,
+      });
+      const listresult = JSON.parse(listResponse[2]);
+
+      if (listresult.errorCode !== 0) {
+        logger.debug(`HTTTP ${listresult.errorCode} getting list of sites with message ${listresult.msg}`);
+        return res.status(status).send(data);
+      }
+
+      // Switching site is really needed only for Omada 3.x.x controllers
+
+      let switchUrl;
+
+      if (cversion < "4.0.0") {
+        sitetoswitch = listresult.result.siteList.filter(site => site.name === widget.site);
+        siteName = sitetoswitch[0].siteName;
+        switchUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`;
+        method = "POST";
+        body = JSON.stringify({
+          "method": "switchSite",
+          "params": {
+            "siteName": siteName,
+            "userName": widget.username
+          }
+        });
+        headers = { "Content-Type": "application/json" };
+        params = { "token": token };
+        const switchResponse = await httpProxy(switchUrl, {
+          method: method,
+          params: params,
+          body: body.toString(),
+          headers: headers,
+        });
+        console.log(cversion, "after switch", switchResponse[2].toString());
+        const switchresult = JSON.parse(switchResponse[2]);
         if (switchresult.errorCode !== 0) {
           logger.debug(`HTTTP ${switchresult.errorCode} switching site with message ${switchresult.msg}`);
-          return res.status(status).send(data);
+          return res.status(500).send(switchresult);
         }
+      }
 
-        const url = `${widget.url}/web/v1/controller?globalStat=&token=${token}`;
-
-        // eslint-disable-next-line prefer-const,no-unused-vars
-        [status, contentType, result] = await httpProxy(url, {
+      // 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") {
+        console.log(cversion, token,  "Legacy controller");
+        const statsUrl = `${widget.url}/web/v1/controller?getGlobalStat=&token=${token}`;
+        const statResponse = await httpProxy(statsUrl, {
           method: "POST",
           params: { "token": token },
           body: JSON.stringify({
@@ -133,145 +197,67 @@ export default async function omadaProxyHandler(req, res) {
           },
         });
 
-        data = JSON.parse(result);
-
-
+        const data = JSON.parse(statResponse[2]);
         if (data.errorCode !== 0) {
           return res.status(status).send(data);
         }
-
-        return res.send(data.result);
-      }
-      // code for modern API, not working yet
-      // Working on it but I can't test it
-        const {url} = widget;
-        const controllerInfoUrl = `${url}/api/info`;
-        const cInfoResponse = await httpProxy(controllerInfoUrl, {
+        connectedAp = data.result.connectedAp;
+        activeuser = data.result.activeUser;
+        alerts = data.result.alerts;
+        return res.send(JSON.stringify({
+          "connectedAp": connectedAp,
+          "activeUser": activeuser,
+          "alerts": alerts
+        }));
+      } else {
+        let siteStatsUrl;
+        let response;
+        console.log("Modern controller, getting the stats");
+        if (cversion < "5.0.0") {
+          siteStatsUrl = `${url}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}&currentPage=1&currentPageSize=1000`;
+        } else {
+          siteStatsUrl = `${url}/${cid}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}&currentPage=1&currentPageSize=1000`;
+        }
+        response = await httpProxy(siteStatsUrl, {
           method: "GET",
           headers: {
-            "Content-Type": "application/json",
+            "Csrf-Token": token,
           },
         });
-        const cidresult = cInfoResponse[2];
-
-        const cid = JSON.parse(cidresult).result.omadacId;
-        const cversion = JSON.parse(cidresult).result.controllerVer;
-        let loginUrl;
-        if (cversion >= "5.0.0"){
-          loginUrl = `${url}/${cid}/api/v2/login`;
-        } else {
-          loginUrl = `${url}/api/v2/login`;
+        console.log(response);
+        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(listresult);
         }
 
-        const params = {
-          method: "POST",
-          body: JSON.stringify({ "username": widget.username, "password": widget.password }),
-          headers: {"Content-Type": "application/json"} };
-        setCookieHeader(url, params);
-        const authResponse = await httpProxy(loginUrl,params);
-        addCookieToJar(url, authResponse[3]);
-        setCookieHeader(url, params);
+        activeuser = clientresult.result.totalClientNum;
+        connectedAp = clientresult.result.connectedApNum;
 
-        const status = authResponse[0];
-        const data = JSON.parse(authResponse[2]);
-        const {token} = data.result;
-        if (data.errorCode !== 0) {
-          logger.debug(`HTTTP ${data.errorCode} logging into Omada api: ${data.error}`);
-          return res.status(status).send(token);
-        }
-        let sitesUrl;
+        let alertUrl;
         if (cversion >= "5.0.0") {
-          sitesUrl = `${url}/${cid}/api/v2/sites?token=${token}&currentPage=1&currentPageSize=1000`;
+          alertUrl = `${url}/${cid}/api/v2/sites/${siteName}/alerts/num?token=${token}&currentPage=1&currentPageSize=1000`;
         } else {
-          sitesUrl = `${url}/api/v2/sites?token=${token}&currentPage=1&currentPageSize=1000`;
+          alertUrl = `${url}/api/v2/sites/${siteName}/alerts/num?token=${token}&currentPage=1&currentPageSize=1000`;
         }
-        let response;
-        response = await httpProxy(sitesUrl, {
+        response = await httpProxy(alertUrl, {
           method: "GET",
           headers: {
             "Csrf-Token": token,
           },
         });
-
-        const listresult = JSON.parse(response[2]);
-        if (listresult.errorCode !== 0) {
-          logger.debug(`HTTTP ${listresult.errorCode} getting list of sites with message ${listresult.msg}`);
-          return res.status(status).send(data);
-        }
-
-      const sites = JSON.parse(response[2]);
-
-      const sitetoswitch = sites.result.data.filter(site => site.name === widget.site);
-      const siteName = sitetoswitch[0].id;
-
-      let switchUrl;
-      if (cversion >= "5.0.0") {
-        switchUrl = `${url}/${cid}/api/v2/sites/${siteName}/cmd/switch?token=${token}`;
-      } else {
-        switchUrl = `${url}/api/v2/sites/${siteName}/cmd/switch?token=${token}`;
-      }
-      response = await httpProxy(switchUrl, {
-        method: "POST",
-        headers: {
-          "Csrf-Token": token,
-        },
-      });
-
-      const switchresult = JSON.parse(response[2]);
-      if (switchresult.errorCode !== 0) {
-
-        logger.debug(`HTTTP ${listresult.errorCode} switching to site ${widget.site} with message ${listresult.msg}`);
-        return res.status(status).send(data);
-      }
-
-      // get the number of devices connected to the site
-
-      let clientUrl;
-      if (cversion >= "5.0.0") {
-        clientUrl=`${url}/${cid}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}&currentPage=1&currentPageSize=1000`;
-      } else {
-        clientUrl=`${url}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}&currentPage=1&currentPageSize=1000`;
-      }
-      response = await httpProxy(clientUrl, {
-        method: "GET",
-        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(status).send(data);
+        const alertresult = JSON.parse(response[2]);
+        alerts = alertresult.result.alertNum;
       }
-      const activeuser = clientresult.result.totalClientNum;
-      const connectedAp = clientresult.result.connectedApNum;
-
-      let alertUrl;
-      if (cversion >= "5.0.0") {
-        alertUrl=`${url}/${cid}/api/v2/sites/${siteName}/alerts/num?token=${token}&currentPage=1&currentPageSize=1000`;
-      } else {
-        alertUrl=`${url}/api/v2/sites/${siteName}/alerts/num?token=${token}&currentPage=1&currentPageSize=1000`;
-      }
-      response = await httpProxy(alertUrl, {
-        method: "GET",
-        headers: {
-          "Csrf-Token": token,
-        },
-      });
-
-      const alertresult = JSON.parse(response[2]);
-      const alerts = alertresult.result.alertNum;
-
 
-
-      const returnvalue = JSON.stringify({
+      return res.send(JSON.stringify({
         "connectedAp": connectedAp,
         "activeUser": activeuser,
         "alerts": alerts
-      });
-      return res.send(returnvalue);
+      }));
     }
   }
 
   return res.status(400).json({ error: "Invalid proxy service type" });
+
 }