From 2e36c409124a1f22f66fe546ad5f96ab59ed6d5b Mon Sep 17 00:00:00 2001 From: Kasen IO Date: Sat, 7 Dec 2019 18:20:46 -0500 Subject: [PATCH] added QML + C++ system for whitelists --- .../security/EntityScriptWhitelist.qml | 110 ++++++++++++++++++ interface/src/Menu.cpp | 14 +++ interface/src/Menu.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 29 ++++- 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml diff --git a/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml b/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml new file mode 100644 index 0000000000..45a8368ce4 --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml @@ -0,0 +1,110 @@ +// +// ScriptWhitelist.qml +// interface/resources/qml/hifi/dialogs/security +// +// Created by Kasen IO on 2019.12.05 | realities.dev | kasenvr@gmail.com +// Copyright 2019 Kasen IO +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// Security Settings for the Entity Script Whitelist + +import Hifi 1.0 as Hifi +import QtQuick 2.8 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.12 +import stylesUit 1.0 as HifiStylesUit +import controlsUit 1.0 as HiFiControls +import PerformanceEnums 1.0 +import "../../../windows" + + +Rectangle { + + function getWhitelistAsText() { + var whitelist = Settings.getValue("private/settingsSafeURLS"); + // var arrayWhitelist = whitelist.split(/\s*,\s*/); + // var whitelistText = arrayWhitelist.join("\n"); + return whitelist; + } + + function setWhiteListAsText(whitelistText) { + console.info('SETTINGCURRENTVALUE: ', Settings.getValue('private/settingsSafeURLS'), whitelistText.text) + Settings.setValue("private/settingsSafeURLS", whitelistText.text); + console.info('SETVALUE: ', Settings.getValue('private/settingsSafeURLS'), whitelistText.text) + } + + anchors.fill: parent + width: parent.width; + height: 120; + color: "#80010203"; + + HifiStylesUit.RalewayRegular { + id: titleText; + text: "Entity Script Whitelist" + // Text size + size: 24; + // Style + color: "white"; + elide: Text.ElideRight; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 60; + } + + Rectangle { + id: textAreaRectangle; + color: "black"; + width: parent.width; + height: 250; + anchors.top: titleText.bottom; + + ScrollView { + id: textAreaScrollView + anchors.fill: parent; + width: parent.width + height: parent.height + contentWidth: parent.width + contentHeight: parent.height + clip: false; + + TextArea { + id: whitelistTextArea + text: getWhitelistAsText(); + width: parent.width; + height: parent.height; + font.family: "Ubuntu"; + font.pointSize: 12; + color: "white"; + } + } + + Button { + id: saveChanges + // anchors.top: whitelistTextArea.bottom; + anchors.topMargin: 5; + anchors.leftMargin: 20; + // anchors.right: whitelistTextArea.right; + anchors.rightMargin: 20; + x: textAreaRectangle.x + textAreaRectangle.width - width - 5; + y: textAreaRectangle.y + textAreaRectangle.height - height; + contentItem: Text { + text: saveChanges.text + font.family: "Ubuntu"; + font.pointSize: 12; + opacity: enabled ? 1.0 : 0.3 + color: "black" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + text: "Save Changes" + onClicked: setWhiteListAsText(whitelistTextArea) + } + } +} \ No newline at end of file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 508c44fbd1..9bc1dae56e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -286,6 +286,20 @@ Menu::Menu() { hmd->toggleShouldShowTablet(); } }); + + // Settings > Entity Script Whitelist + action = addActionToQMenuAndActionHash(settingsMenu, "Entity Script Whitelist"); + connect(action, &QAction::triggered, [] { + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + auto hmd = DependencyManager::get(); + + DependencyManager::get()->clearCache(); + tablet->pushOntoStack("hifi/dialogs/security/EntityScriptWhitelist.qml"); + + if (!hmd->getShouldShowTablet()) { + hmd->toggleShouldShowTablet(); + } + }); // Settings > Developer Menu addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menu", 0, false, this, SLOT(toggleDeveloperMenus())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index ea118ec5dd..37b3f971fc 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -181,6 +181,7 @@ namespace MenuOption { const QString RunningScripts = "Running Scripts..."; const QString RunTimingTests = "Run Timing Tests"; const QString ScriptedMotorControl = "Enable Scripted Motor Control"; + const QString EntityScriptWhitelist = "Entity Script Whitelist"; const QString ShowTrackedObjects = "Show Tracked Objects"; const QString SelfieCamera = "Selfie"; const QString SendWrongDSConnectVersion = "Send wrong DS connect version"; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index f205b016d1..78b483e3b3 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -84,6 +84,11 @@ #include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? #include "MIDIEvent.h" +#include "SettingHandle.h" +// #include "SettingManager.h" +// #include "SettingInterface.h" +// #include "SettingHelpers.h" + const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { "com.highfidelity.experimental.enableExtendedJSExceptions" }; @@ -2362,10 +2367,30 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co QList safeURLS = { "https://FAKEURL.t43wt4g4g44FAKE" }; safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + // PULL SAFEURLS FROM INTERFACE.JSON Settings + + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + // qDebug() << "raw value" << raw; + // qDebug() << "raw value as list" << raw.toList(); + QStringList settingsSafeURLS = raw.toString().split(QRegExp("[\r\n]+")); + safeURLS += settingsSafeURLS; + + // QVariantList settingsSafeURLS = Setting::Handle("private/settingsSafeURLS").get(); + // qCDebug(scriptengine) << "ESWsafeURLS" << safeURLS; + + // for (QVariantList::iterator surl = settingsSafeURLS.begin(); surl != settingsSafeURLS.end(); surl++) + // { + // safeURLS += (*surl).toString(); + // } + + // for (const auto& s : settingsSafeURLS) safeURLS << s.toString(); + + // END PULL SAFEURLS FROM INTERFACE.JSON Settings + bool isInWhitelist = false; // assume unsafe for (const auto& str : safeURLS) { // qDebug() << "CHECKING" << entityID.toString() << scriptOrURL << "AGAINST" << str; - qDebug() << "SCRIPTOURL STARTSWITH" << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" + qCDebug(scriptengine) << "SCRIPT URL STARTSWITH" << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" << scriptOrURL.startsWith(str); if (scriptOrURL.startsWith(str)) { isInWhitelist = true; @@ -2373,7 +2398,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } } if (!isInWhitelist) { - qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; + qCDebug(scriptengine) << "(disabled entity script)" << entityID.toString() << scriptOrURL; exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } else { QTimer timeout;