Merge pull request #4363 from huffman/block-restricted-users

Add permission-checking to edit entities
This commit is contained in:
Brad Hefta-Gaub 2015-03-03 11:04:46 -08:00
commit b88d52a310
10 changed files with 74 additions and 47 deletions

View file

@ -44,7 +44,7 @@ Agent::Agent(const QByteArray& packet) :
// be the parent of the script engine so it gets moved when we do // be the parent of the script engine so it gets moved when we do
_scriptEngine.setParent(this); _scriptEngine.setParent(this);
_scriptEngine.getEntityScriptingInterface()->setPacketSender(&_entityEditSender); DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
DependencyManager::set<ResouceCacheSharedItems>(); DependencyManager::set<ResouceCacheSharedItems>();
DependencyManager::set<SoundCache>(); DependencyManager::set<SoundCache>();
@ -68,8 +68,8 @@ void Agent::readPendingDatagrams() {
// PacketType_JURISDICTION, first byte is the node type... // PacketType_JURISDICTION, first byte is the node type...
switch (receivedPacket[headerBytes]) { switch (receivedPacket[headerBytes]) {
case NodeType::EntityServer: case NodeType::EntityServer:
_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener()-> DependencyManager::get<EntityScriptingInterface>()->getJurisdictionListener()->
queueReceivedPacket(matchedNode, receivedPacket); queueReceivedPacket(matchedNode, receivedPacket);
break; break;
} }
} }
@ -211,10 +211,12 @@ void Agent::run() {
_scriptEngine.registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data()); _scriptEngine.registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
_scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer); _scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer);
_entityViewer.setJurisdictionListener(_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener()); _entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
_entityViewer.init(); _entityViewer.init();
_scriptEngine.getEntityScriptingInterface()->setEntityTree(_entityViewer.getTree()); entityScriptingInterface->setEntityTree(_entityViewer.getTree());
_scriptEngine.setScriptContents(scriptContents); _scriptEngine.setScriptContents(scriptContents);
_scriptEngine.run(); _scriptEngine.run();

View file

@ -18,6 +18,7 @@
#include <AccountManager.h> #include <AccountManager.h>
#include <AddressManager.h> #include <AddressManager.h>
#include <Assignment.h> #include <Assignment.h>
#include <EntityScriptingInterface.h>
#include <LogHandler.h> #include <LogHandler.h>
#include <LogUtils.h> #include <LogUtils.h>
#include <LimitedNodeList.h> #include <LimitedNodeList.h>
@ -53,6 +54,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
auto addressManager = DependencyManager::set<AddressManager>(); auto addressManager = DependencyManager::set<AddressManager>();
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned); auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned);
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
// make up a uuid for this child so the parent can tell us apart. This id will be changed // make up a uuid for this child so the parent can tell us apart. This id will be changed
// when the domain server hands over an assignment. // when the domain server hands over an assignment.

View file

@ -81,6 +81,8 @@ var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect"; var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to edit on this domain."
var modelURLs = [ var modelURLs = [
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx", HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx", HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx",
@ -177,25 +179,29 @@ var toolBar = (function () {
that.setActive = function(active) { that.setActive = function(active) {
if (active != isActive) { if (active != isActive) {
isActive = active; if (active && !Entities.canAdjustLocks()) {
if (!isActive) { Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
entityListTool.setVisible(false);
gridTool.setVisible(false);
grid.setEnabled(false);
propertiesTool.setVisible(false);
selectionManager.clearSelections();
cameraManager.disable();
} else { } else {
hasShownPropertiesTool = false; isActive = active;
cameraManager.enable(); if (!isActive) {
entityListTool.setVisible(true); entityListTool.setVisible(false);
gridTool.setVisible(true); gridTool.setVisible(false);
grid.setEnabled(true); grid.setEnabled(false);
propertiesTool.setVisible(true); propertiesTool.setVisible(false);
Window.setFocus(); selectionManager.clearSelections();
cameraManager.disable();
} else {
hasShownPropertiesTool = false;
cameraManager.enable();
entityListTool.setVisible(true);
gridTool.setVisible(true);
grid.setEnabled(true);
propertiesTool.setVisible(true);
Window.setFocus();
}
} }
} }
toolBar.selectTool(activeButton, active); toolBar.selectTool(activeButton, isActive);
}; };
var RESIZE_INTERVAL = 50; var RESIZE_INTERVAL = 50;
@ -400,6 +406,12 @@ var toolBar = (function () {
that.setActive(false); that.setActive(false);
}); });
Entities.canAdjustLocksChanged.connect(function(canAdjustLocks) {
if (isActive && !canAdjustLocks) {
that.setActive(false);
}
});
that.cleanup = function () { that.cleanup = function () {
toolBar.cleanup(); toolBar.cleanup();
}; };

View file

@ -241,6 +241,7 @@ bool setupEssentials(int& argc, char** argv) {
auto dialogsManager = DependencyManager::set<DialogsManager>(); auto dialogsManager = DependencyManager::set<DialogsManager>();
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>(); auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
auto resouceCacheSharedItems = DependencyManager::set<ResouceCacheSharedItems>(); auto resouceCacheSharedItems = DependencyManager::set<ResouceCacheSharedItems>();
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
#if defined(Q_OS_MAC) || defined(Q_OS_WIN) #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
auto speechRecognizer = DependencyManager::set<SpeechRecognizer>(); auto speechRecognizer = DependencyManager::set<SpeechRecognizer>();
#endif #endif
@ -1766,8 +1767,10 @@ void Application::init() {
tree->setSimulation(&_physicsEngine); tree->setSimulation(&_physicsEngine);
_physicsEngine.init(&_entityEditSender); _physicsEngine.init(&_entityEditSender);
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity, connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity,
ScriptEngine::getEntityScriptingInterface(), &EntityScriptingInterface::entityCollisionWithEntity); entityScriptingInterface.data(), &EntityScriptingInterface::entityCollisionWithEntity);
// connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts // connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts
connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity, connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity,
@ -1775,7 +1778,7 @@ void Application::init() {
// connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing // connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing
// of events related clicking, hovering over, and entering entities // of events related clicking, hovering over, and entering entities
_entities.connectSignalsToSlots(ScriptEngine::getEntityScriptingInterface()); _entities.connectSignalsToSlots(entityScriptingInterface.data());
_entityClipboardRenderer.init(); _entityClipboardRenderer.init();
_entityClipboardRenderer.setViewFrustum(getViewFrustum()); _entityClipboardRenderer.setViewFrustum(getViewFrustum());
@ -3439,8 +3442,9 @@ void joystickFromScriptValue(const QScriptValue &object, Joystick* &out) {
void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) { void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) {
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
// we can use the same ones from the application. // we can use the same ones from the application.
scriptEngine->getEntityScriptingInterface()->setPacketSender(&_entityEditSender); auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
scriptEngine->getEntityScriptingInterface()->setEntityTree(_entities.getTree()); entityScriptingInterface->setPacketSender(&_entityEditSender);
entityScriptingInterface->setEntityTree(_entities.getTree());
// AvatarManager has some custom types // AvatarManager has some custom types
AvatarManager::registerMetaTypes(scriptEngine); AvatarManager::registerMetaTypes(scriptEngine);

View file

@ -19,6 +19,8 @@ EntityScriptingInterface::EntityScriptingInterface() :
_nextCreatorTokenID(0), _nextCreatorTokenID(0),
_entityTree(NULL) _entityTree(NULL)
{ {
auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
} }
void EntityScriptingInterface::queueEntityMessage(PacketType packetType, void EntityScriptingInterface::queueEntityMessage(PacketType packetType,

View file

@ -17,6 +17,7 @@
#include <QtCore/QObject> #include <QtCore/QObject>
#include <CollisionInfo.h> #include <CollisionInfo.h>
#include <DependencyManager.h>
#include <Octree.h> #include <Octree.h>
#include <OctreeScriptingInterface.h> #include <OctreeScriptingInterface.h>
#include <RegisteredMetaTypes.h> #include <RegisteredMetaTypes.h>
@ -48,7 +49,7 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
/// handles scripting of Entity commands from JS passed to assigned clients /// handles scripting of Entity commands from JS passed to assigned clients
class EntityScriptingInterface : public OctreeScriptingInterface { class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency {
Q_OBJECT Q_OBJECT
public: public:
EntityScriptingInterface(); EntityScriptingInterface();
@ -111,6 +112,8 @@ public slots:
signals: signals:
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
void canAdjustLocksChanged(bool canAdjustLocks);
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mouseReleaseOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void mouseReleaseOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);

View file

@ -96,6 +96,13 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) {
} }
} }
void LimitedNodeList::setThisNodeCanAdjustLocks(bool canAdjustLocks) {
if (_thisNodeCanAdjustLocks != canAdjustLocks) {
_thisNodeCanAdjustLocks = canAdjustLocks;
emit canAdjustLocksChanged(canAdjustLocks);
}
}
QUdpSocket& LimitedNodeList::getDTLSSocket() { QUdpSocket& LimitedNodeList::getDTLSSocket() {
if (!_dtlsSocket) { if (!_dtlsSocket) {
// DTLS socket getter called but no DTLS socket exists, create it now // DTLS socket getter called but no DTLS socket exists, create it now

View file

@ -84,8 +84,8 @@ public:
const QUuid& getSessionUUID() const { return _sessionUUID; } const QUuid& getSessionUUID() const { return _sessionUUID; }
void setSessionUUID(const QUuid& sessionUUID); void setSessionUUID(const QUuid& sessionUUID);
bool getThisNodeCanAdjustLocks() { return _thisNodeCanAdjustLocks; } bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
void setThisNodeCanAdjustLocks(bool canAdjustLocks) { _thisNodeCanAdjustLocks = canAdjustLocks; } void setThisNodeCanAdjustLocks(bool canAdjustLocks);
void rebindNodeSocket(); void rebindNodeSocket();
QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getNodeSocket() { return _nodeSocket; }
@ -196,6 +196,8 @@ signals:
void localSockAddrChanged(const HifiSockAddr& localSockAddr); void localSockAddrChanged(const HifiSockAddr& localSockAddr);
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr); void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
void canAdjustLocksChanged(bool canAdjustLocks);
void dataSent(const quint8 channel_type, const int bytes); void dataSent(const quint8 channel_type, const int bytes);
void dataReceived(const quint8 channel_type, const int bytes); void dataReceived(const quint8 channel_type, const int bytes);

View file

@ -44,8 +44,6 @@
#include "MIDIEvent.h" #include "MIDIEvent.h"
EntityScriptingInterface ScriptEngine::_entityScriptingInterface;
static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){
qDebug() << "script:print()<<" << context->argument(0).toString(); qDebug() << "script:print()<<" << context->argument(0).toString();
QString message = context->argument(0).toString() QString message = context->argument(0).toString()
@ -314,7 +312,8 @@ void ScriptEngine::init() {
auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>(); auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
_entityScriptingInterface.init(); auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
entityScriptingInterface->init();
// register various meta-types // register various meta-types
registerMetaTypes(this); registerMetaTypes(this);
@ -352,7 +351,7 @@ void ScriptEngine::init() {
registerGlobalObject("Script", this); registerGlobalObject("Script", this);
registerGlobalObject("Audio", &AudioScriptingInterface::getInstance()); registerGlobalObject("Audio", &AudioScriptingInterface::getInstance());
registerGlobalObject("Controller", _controllerScriptingInterface); registerGlobalObject("Controller", _controllerScriptingInterface);
registerGlobalObject("Entities", &_entityScriptingInterface); registerGlobalObject("Entities", entityScriptingInterface.data());
registerGlobalObject("Quat", &_quatLibrary); registerGlobalObject("Quat", &_quatLibrary);
registerGlobalObject("Vec3", &_vec3Library); registerGlobalObject("Vec3", &_vec3Library);
registerGlobalObject("Uuid", &_uuidLibrary); registerGlobalObject("Uuid", &_uuidLibrary);
@ -470,6 +469,7 @@ void ScriptEngine::run() {
int thisFrame = 0; int thisFrame = 0;
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
qint64 lastUpdate = usecTimestampNow(); qint64 lastUpdate = usecTimestampNow();
@ -489,13 +489,13 @@ void ScriptEngine::run() {
break; break;
} }
if (!_isFinished && _entityScriptingInterface.getEntityPacketSender()->serversExist()) { if (!_isFinished && entityScriptingInterface->getEntityPacketSender()->serversExist()) {
// release the queue of edit entity messages. // release the queue of edit entity messages.
_entityScriptingInterface.getEntityPacketSender()->releaseQueuedMessages(); entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();
// since we're in non-threaded mode, call process so that the packets are sent // since we're in non-threaded mode, call process so that the packets are sent
if (!_entityScriptingInterface.getEntityPacketSender()->isThreaded()) { if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
_entityScriptingInterface.getEntityPacketSender()->process(); entityScriptingInterface->getEntityPacketSender()->process();
} }
} }
@ -622,13 +622,13 @@ void ScriptEngine::run() {
// kill the avatar identity timer // kill the avatar identity timer
delete _avatarIdentityTimer; delete _avatarIdentityTimer;
if (_entityScriptingInterface.getEntityPacketSender()->serversExist()) { if (entityScriptingInterface->getEntityPacketSender()->serversExist()) {
// release the queue of edit entity messages. // release the queue of edit entity messages.
_entityScriptingInterface.getEntityPacketSender()->releaseQueuedMessages(); entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();
// since we're in non-threaded mode, call process so that the packets are sent // since we're in non-threaded mode, call process so that the packets are sent
if (!_entityScriptingInterface.getEntityPacketSender()->isThreaded()) { if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
_entityScriptingInterface.getEntityPacketSender()->process(); entityScriptingInterface->getEntityPacketSender()->process();
} }
} }

View file

@ -31,8 +31,6 @@
#include "ScriptUUID.h" #include "ScriptUUID.h"
#include "Vec3.h" #include "Vec3.h"
class EntityScriptingInterface;
const QString NO_SCRIPT(""); const QString NO_SCRIPT("");
const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5); const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5);
@ -46,9 +44,6 @@ public:
~ScriptEngine(); ~ScriptEngine();
/// Access the EntityScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
static EntityScriptingInterface* getEntityScriptingInterface() { return &_entityScriptingInterface; }
ArrayBufferClass* getArrayBufferClass() { return _arrayBufferClass; } ArrayBufferClass* getArrayBufferClass() { return _arrayBufferClass; }
/// sets the script contents, will return false if failed, will fail if script is already running /// sets the script contents, will return false if failed, will fail if script is already running
@ -153,8 +148,6 @@ private:
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot); QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
void stopTimer(QTimer* timer); void stopTimer(QTimer* timer);
static EntityScriptingInterface _entityScriptingInterface;
AbstractControllerScriptingInterface* _controllerScriptingInterface; AbstractControllerScriptingInterface* _controllerScriptingInterface;
AvatarData* _avatarData; AvatarData* _avatarData;
QString _scriptName; QString _scriptName;