mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
add remotelyCallable and remoteCallerID to provide additional security to Entities.callEntityServerMethod()
This commit is contained in:
parent
fb7f6df694
commit
a7e21d7e76
4 changed files with 39 additions and 8 deletions
|
@ -248,7 +248,7 @@ void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer<Recei
|
|||
params << paramString;
|
||||
}
|
||||
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
|
||||
class EntitiesScriptEngineProvider {
|
||||
public:
|
||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList()) = 0;
|
||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||
const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) = 0;
|
||||
virtual QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl&
|
|||
doWithEnvironment(entityID, sandboxURL, operation);
|
||||
}
|
||||
|
||||
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) {
|
||||
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
#ifdef THREAD_DEBUGGING
|
||||
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
||||
|
@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
|||
QMetaObject::invokeMethod(this, "callEntityScriptMethod",
|
||||
Q_ARG(const EntityItemID&, entityID),
|
||||
Q_ARG(const QString&, methodName),
|
||||
Q_ARG(const QStringList&, params));
|
||||
Q_ARG(const QStringList&, params),
|
||||
Q_ARG(const QUuid&, remoteCallerID));
|
||||
return;
|
||||
}
|
||||
#ifdef THREAD_DEBUGGING
|
||||
|
@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
|||
if (isEntityScriptRunning(entityID)) {
|
||||
EntityScriptDetails details = _entityScripts[entityID];
|
||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||
if (entityScript.property(methodName).isFunction()) {
|
||||
|
||||
// If this is a remote call, we need to check to see if the function is remotely callable
|
||||
// we do this by checking for the existance of the 'remotelyCallable' property on the
|
||||
// entityScript. And we confirm that the method name is included. If this fails, the
|
||||
// function will not be called.
|
||||
bool callAllowed = false;
|
||||
if (remoteCallerID == QUuid()) {
|
||||
callAllowed = true;
|
||||
} else {
|
||||
if (entityScript.property("remotelyCallable").isArray()) {
|
||||
auto callables = entityScript.property("remotelyCallable");
|
||||
auto callableCount = callables.property("length").toInteger();
|
||||
for (int i = 0; i < callableCount; i++) {
|
||||
auto callable = callables.property(i).toString();
|
||||
if (callable == methodName) {
|
||||
callAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!callAllowed) {
|
||||
qDebug() << "Method [" << methodName << "] not remotely callable.";
|
||||
}
|
||||
}
|
||||
|
||||
if (callAllowed && entityScript.property(methodName).isFunction()) {
|
||||
QScriptValueList args;
|
||||
args << entityID.toScriptValue(this);
|
||||
args << qScriptValueFromSequence(this, params);
|
||||
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
||||
}
|
||||
|
||||
QScriptValue oldData = this->globalObject().property("remoteCallerID");
|
||||
this->globalObject().setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
|
||||
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
||||
this->globalObject().setProperty("remoteCallerID", oldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,8 @@ public:
|
|||
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
|
||||
Q_INVOKABLE void unloadAllEntityScripts();
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||
const QStringList& params = QStringList()) override;
|
||||
const QStringList& params = QStringList(),
|
||||
const QUuid& remoteCallerID = QUuid()) override;
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
|
||||
|
||||
|
|
Loading…
Reference in a new issue