diff --git a/webserver.js b/webserver.js index 8bb3bf34..b2833312 100644 --- a/webserver.js +++ b/webserver.js @@ -7249,17 +7249,39 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF return false; } + var GetNodeRightsCache = {}; + var GetNodeRightsCacheCount = 0; + // Return the user rights for a given node obj.GetNodeRights = function (user, mesh, nodeid) { if ((user == null) || (mesh == null) || (nodeid == null)) { return 0; } if (typeof user == 'string') { user = obj.users[user]; } if (user == null) { return 0; } + var meshid; + if (typeof mesh == 'string') { meshid = mesh; } else if ((typeof mesh == 'object') && (typeof mesh._id == 'string')) { meshid = mesh._id; } else return 0; + + // Check if we have this in the cache + const cacheid = user._id + '/' + meshid + '/' + nodeid; + const cache = GetNodeRightsCache[cacheid]; + if (cache != null) { if (cache.t > Date.now()) { return cache.o; } else { GetNodeRightsCacheCount--; } } // Cache hit, or we need to update the cache + if (GetNodeRightsCacheCount > 2000) { GetNodeRightsCache = {}; GetNodeRightsCacheCount = 0; } // From time to time, flush the cache + var r = obj.GetMeshRights(user, mesh); - if (r == 0xFFFFFFFF) return removeUserRights(r, user); + if (r == 0xFFFFFFFF) { + const out = removeUserRights(r, user); + GetNodeRightsCache[cacheid] = { t: Date.now() + 10000, o: out }; + GetNodeRightsCacheCount++; + return out; + } // Check direct device rights using device data if ((user.links != null) && (user.links[nodeid] != null)) { r |= user.links[nodeid].rights; } // TODO: Deal with reverse permissions - if (r == 0xFFFFFFFF) return removeUserRights(r, user); + if (r == 0xFFFFFFFF) { + const out = removeUserRights(r, user); + GetNodeRightsCache[cacheid] = { t: Date.now() + 10000, o: out }; + GetNodeRightsCacheCount++; + return out; + } // Check direct device rights thru a user group for (var i in user.links) { @@ -7269,7 +7291,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF } } - return removeUserRights(r, user); + const out = removeUserRights(r, user); + GetNodeRightsCache[cacheid] = { t: Date.now() + 10000, o: out }; + GetNodeRightsCacheCount++; + return out; } // Returns a list of displatch targets for a given mesh