Merge pull request #15207 from danteruiz/kick-ui

Case 21771: Possible Entity Scipt Ban Incident
This commit is contained in:
Shannon Romano 2019-03-21 13:10:54 -07:00 committed by GitHub
commit b82c808562
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 5 deletions

View file

@ -117,7 +117,6 @@ Rectangle {
if (loader.item.hasOwnProperty("gotoPreviousApp")) { if (loader.item.hasOwnProperty("gotoPreviousApp")) {
loader.item.gotoPreviousApp = true; loader.item.gotoPreviousApp = true;
} }
screenChanged("Web", url) screenChanged("Web", url)
}); });
} }

View file

@ -2342,6 +2342,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
return viewFrustum.getPosition(); return viewFrustum.getPosition();
}); });
DependencyManager::get<UsersScriptingInterface>()->setKickConfirmationOperator([this] (const QUuid& nodeID) { userKickConfirmation(nodeID); });
render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([this](const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) { render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([this](const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) {
bool isTablet = url == TabletScriptingInterface::QML; bool isTablet = url == TabletScriptingInterface::QML;
if (htmlContent) { if (htmlContent) {
@ -3290,6 +3292,40 @@ void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
#endif #endif
} }
void Application::userKickConfirmation(const QUuid& nodeID) {
auto avatarHashMap = DependencyManager::get<AvatarHashMap>();
auto avatar = avatarHashMap->getAvatarBySessionID(nodeID);
QString userName;
if (avatar) {
userName = avatar->getSessionDisplayName();
} else {
userName = nodeID.toString();
}
QString kickMessage = "Do you wish to kick " + userName + " from your domain";
ModalDialogListener* dlg = OffscreenUi::asyncQuestion("Kick User", kickMessage,
QMessageBox::Yes | QMessageBox::No);
if (dlg->getDialogItem()) {
QObject::connect(dlg, &ModalDialogListener::response, this, [=] (QVariant answer) {
QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr);
bool yes = (static_cast<QMessageBox::StandardButton>(answer.toInt()) == QMessageBox::Yes);
// ask the NodeList to kick the user with the given session ID
if (yes) {
DependencyManager::get<NodeList>()->kickNodeBySessionID(nodeID);
}
DependencyManager::get<UsersScriptingInterface>()->setWaitForKickResponse(false);
});
DependencyManager::get<UsersScriptingInterface>()->setWaitForKickResponse(true);
}
}
void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties) { void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties) {
surfaceContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data()); surfaceContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data());
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data()); surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());

View file

@ -593,6 +593,7 @@ private:
void toggleTabletUI(bool shouldOpen = false) const; void toggleTabletUI(bool shouldOpen = false) const;
static void setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties); static void setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties);
void userKickConfirmation(const QUuid& nodeID);
MainWindow* _window; MainWindow* _window;
QElapsedTimer& _sessionRunTimer; QElapsedTimer& _sessionRunTimer;

View file

@ -52,9 +52,16 @@ float UsersScriptingInterface::getAvatarGain(const QUuid& nodeID) {
} }
void UsersScriptingInterface::kick(const QUuid& nodeID) { void UsersScriptingInterface::kick(const QUuid& nodeID) {
// ask the NodeList to kick the user with the given session ID
if (_kickConfirmationOperator) {
bool waitingForKickResponse = _kickResponseLock.resultWithReadLock<bool>([&] { return _waitingForKickResponse; });
if (getCanKick() && !waitingForKickResponse) {
_kickConfirmationOperator(nodeID);
}
} else {
DependencyManager::get<NodeList>()->kickNodeBySessionID(nodeID); DependencyManager::get<NodeList>()->kickNodeBySessionID(nodeID);
} }
}
void UsersScriptingInterface::mute(const QUuid& nodeID) { void UsersScriptingInterface::mute(const QUuid& nodeID) {
// ask the NodeList to mute the user with the given session ID // ask the NodeList to mute the user with the given session ID

View file

@ -15,6 +15,7 @@
#define hifi_UsersScriptingInterface_h #define hifi_UsersScriptingInterface_h
#include <DependencyManager.h> #include <DependencyManager.h>
#include <shared/ReadWriteLockable.h>
/**jsdoc /**jsdoc
* @namespace Users * @namespace Users
@ -38,6 +39,12 @@ class UsersScriptingInterface : public QObject, public Dependency {
public: public:
UsersScriptingInterface(); UsersScriptingInterface();
void setKickConfirmationOperator(std::function<void(const QUuid& nodeID)> kickConfirmationOperator) {
_kickConfirmationOperator = kickConfirmationOperator;
}
bool getWaitForKickResponse() { return _kickResponseLock.resultWithReadLock<bool>([&] { return _waitingForKickResponse; }); }
void setWaitForKickResponse(bool waitForKickResponse) { _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = waitForKickResponse; }); }
public slots: public slots:
@ -195,6 +202,11 @@ signals:
private: private:
bool getRequestsDomainListData(); bool getRequestsDomainListData();
void setRequestsDomainListData(bool requests); void setRequestsDomainListData(bool requests);
std::function<void(const QUuid& nodeID)> _kickConfirmationOperator;
ReadWriteLockable _kickResponseLock;
bool _waitingForKickResponse { false };
}; };

View file

@ -240,6 +240,12 @@ class MessageBoxListener : public ModalDialogListener {
return static_cast<QMessageBox::StandardButton>(_result.toInt()); return static_cast<QMessageBox::StandardButton>(_result.toInt());
} }
protected slots:
virtual void onDestroyed() override {
ModalDialogListener::onDestroyed();
onSelected(QMessageBox::NoButton);
}
private slots: private slots:
void onSelected(int button) { void onSelected(int button) {
_result = button; _result = button;

View file

@ -34,6 +34,9 @@ class ModalDialogListener : public QObject {
Q_OBJECT Q_OBJECT
friend class OffscreenUi; friend class OffscreenUi;
public:
QQuickItem* getDialogItem() { return _dialog; };
protected: protected:
ModalDialogListener(QQuickItem* dialog); ModalDialogListener(QQuickItem* dialog);
virtual ~ModalDialogListener(); virtual ~ModalDialogListener();
@ -43,7 +46,7 @@ signals:
void response(const QVariant& value); void response(const QVariant& value);
protected slots: protected slots:
void onDestroyed(); virtual void onDestroyed();
protected: protected:
QQuickItem* _dialog; QQuickItem* _dialog;

View file

@ -368,6 +368,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
if (toolbarMode) { if (toolbarMode) {
#if !defined(DISABLE_QML) #if !defined(DISABLE_QML)
closeDialog();
// create new desktop window // create new desktop window
auto tabletRootWindow = new TabletRootWindow(); auto tabletRootWindow = new TabletRootWindow();
tabletRootWindow->initQml(QVariantMap()); tabletRootWindow->initQml(QVariantMap());