From 5743a5f91dd5ead0c4d2b511c4073542092f3b29 Mon Sep 17 00:00:00 2001 From: Nick O'Leary <knolleary@users.noreply.github.com> Date: Sun, 27 Dec 2020 21:34:21 +0000 Subject: [PATCH] Filter palette manager nodes based on allow/deny list --- .../editor-client/src/js/ui/palette-editor.js | 109 +++++++++++++++--- 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js index 147789940..3dbff87a3 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js @@ -329,21 +329,26 @@ RED.palette.editor = (function() { catalogueLoadStatus.push(err||v); if (!err) { if (v.modules) { - v.modules.forEach(function(m) { - loadedIndex[m.id] = m; - m.index = [m.id]; - if (m.keywords) { - m.index = m.index.concat(m.keywords); + var a = false; + v.modules = v.modules.filter(function(m) { + if (checkModuleAllowed(m.id,m.version,installAllowList,installDenyList)) { + loadedIndex[m.id] = m; + m.index = [m.id]; + if (m.keywords) { + m.index = m.index.concat(m.keywords); + } + if (m.types) { + m.index = m.index.concat(m.types); + } + if (m.updated_at) { + m.timestamp = new Date(m.updated_at).getTime(); + } else { + m.timestamp = 0; + } + m.index = m.index.join(",").toLowerCase(); + return true; } - if (m.types) { - m.index = m.index.concat(m.types); - } - if (m.updated_at) { - m.timestamp = new Date(m.updated_at).getTime(); - } else { - m.timestamp = 0; - } - m.index = m.index.join(",").toLowerCase(); + return false; }) loadedList = loadedList.concat(v.modules); } @@ -437,11 +442,87 @@ RED.palette.editor = (function() { return -1 * (A.info.timestamp-B.info.timestamp); } + var installAllowList = ['*']; + var installDenyList = []; + + function parseModuleList(list) { + list = list || ["*"]; + return list.map(rule => { + var m = /^(.+?)(?:@(.*))?$/.exec(rule); + var wildcardPos = m[1].indexOf("*"); + wildcardPos = wildcardPos===-1?Infinity:wildcardPos; + + return { + module: new RegExp("^"+m[1].replace(/\*/g,".*")+"$"), + version: m[2], + wildcardPos: wildcardPos + } + }) + } + + function checkAgainstList(module,version,list) { + for (var i=0;i<list.length;i++) { + var rule = list[i]; + if (rule.module.test(module)) { + // Without a full semver library in the editor, + // we skip the version check. + // Not ideal - but will get caught in the runtime + // if the user tries to install. + return rule; + } + } + } + + function checkModuleAllowed(module,version,allowList,denyList) { + if (!allowList && !denyList) { + // Default to allow + return true; + } + if (allowList.length === 0 && denyList.length === 0) { + return true; + } + + var allowedRule = checkAgainstList(module,version,allowList); + var deniedRule = checkAgainstList(module,version,denyList); + // console.log("A",allowedRule) + // console.log("D",deniedRule) + + if (allowedRule && !deniedRule) { + return true; + } + if (!allowedRule && deniedRule) { + return false; + } + if (!allowedRule && !deniedRule) { + return true; + } + if (allowedRule.wildcardPos !== deniedRule.wildcardPos) { + return allowedRule.wildcardPos > deniedRule.wildcardPos + } else { + // First wildcard in same position. + // Go with the longer matching rule. This isn't going to be 100% + // right, but we are deep into edge cases at this point. + return allowedRule.module.toString().length > deniedRule.module.toString().length + } + return false; + } function init() { if (RED.settings.get('externalModules.palette.allowInstall', true) === false) { return; } + var settingsAllowList = RED.settings.get("externalModules.palette.allowList") + var settingsDenyList = RED.settings.get("externalModules.palette.denyList") + if (settingsAllowList || settingsDenyList) { + installAllowList = settingsAllowList; + installDenyList = settingsDenyList + } + installAllowList = parseModuleList(installAllowList); + installDenyList = parseModuleList(installDenyList); + + console.log(installAllowList); + console.log(installDenyList); + createSettingsPane(); RED.userSettings.add({