From 02129e0543919831cbfa26b44008f7ccac1a3035 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 25 Mar 2019 16:14:48 -0700 Subject: [PATCH] no-op refactor in prep for multiple entities per cert --- .../src/entities/EntityServer.cpp | 99 ++++++++----------- .../ui/overlays/ContextOverlayInterface.cpp | 3 +- libraries/entities/src/EntityTree.cpp | 21 ++-- libraries/entities/src/EntityTree.h | 4 +- 4 files changed, 54 insertions(+), 73 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 581d854909..f2cad1e400 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -474,73 +474,58 @@ void EntityServer::startDynamicDomainVerification() { QHash localMap(tree->getEntityCertificateIDMap()); QHashIterator i(localMap); - qCDebug(entities) << localMap.size() << "entities in _entityCertificateIDMap"; + qCDebug(entities) << localMap.size() << "certificates present."; while (i.hasNext()) { i.next(); const auto& certificateID = i.key(); const auto& entityID = i.value(); - EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); + // Examine each cert: + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); + QJsonObject request; + request["certificate_id"] = certificateID; + networkRequest.setUrl(requestURL); - if (entity) { - if (!entity->getProperties().verifyStaticCertificateProperties()) { - qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << entityID << "failed" - << "static certificate verification."; - // Delete the entity if it doesn't pass static certificate verification - tree->withWriteLock([&] { - tree->deleteEntity(entityID, true); - }); - } else { - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); - QJsonObject request; - request["certificate_id"] = certificateID; - networkRequest.setUrl(requestURL); + QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); - QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + connect(networkReply, &QNetworkReply::finished, this, [this, entityID, networkReply] { + EntityTreePointer tree = std::static_pointer_cast(_tree); - connect(networkReply, &QNetworkReply::finished, this, [this, entityID, networkReply] { - EntityTreePointer tree = std::static_pointer_cast(_tree); + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + networkReply->deleteLater(); - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); - - if (networkReply->error() == QNetworkReply::NoError) { - QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); - if (jsonObject["domain_id"].toString() != thisDomainID) { - EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); - if (!entity) { - qCDebug(entities) << "Entity undergoing dynamic domain verification is no longer available:" << entityID; - networkReply->deleteLater(); - return; - } - if (entity->getAge() > (_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS/MSECS_PER_SECOND)) { - qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() - << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << entityID; - tree->withWriteLock([&] { - tree->deleteEntity(entityID, true); - }); - } else { - qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << entityID; - } - } else { - qCDebug(entities) << "Entity passed dynamic domain verification:" << entityID; - } - } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; NOT deleting entity" << entityID - << "More info:" << jsonObject; - } - - networkReply->deleteLater(); - }); + if (networkReply->error() != QNetworkReply::NoError) { + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; NOT deleting entity" << entityID + << "More info:" << jsonObject; + return; } - } else { - qCWarning(entities) << "During DDV, an entity with ID" << entityID << "was NOT found in the Entity Tree!"; - } + QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); + if (jsonObject["domain_id"].toString() == thisDomainID) { + // Entity belongs here. Nothing to do. + return; + } + // Entity does not belong here: + EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); + if (!entity) { + qCDebug(entities) << "Entity undergoing dynamic domain verification is no longer available:" << entityID; + return; + } + if (entity->getAge() <= (_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS / MSECS_PER_SECOND)) { + qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << entityID; + return; + } + qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() + << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << entityID; + tree->withWriteLock([&] { + tree->deleteEntity(entityID, true); + }); + }); } int nextInterval = qrand() % ((_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS + 1) - _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS) + _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index e5cec70f64..794feddd8a 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -422,8 +422,7 @@ void ContextOverlayInterface::handleChallengeOwnershipReplyPacket(QSharedPointer QString certID(packet->read(certIDByteArraySize)); QString text(packet->read(textByteArraySize)); - EntityItemID id; - bool verificationSuccess = DependencyManager::get()->getTree()->verifyNonce(certID, text, id); + bool verificationSuccess = DependencyManager::get()->getTree()->verifyNonce(certID, text); if (verificationSuccess) { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8bf7c92b1f..11e392f590 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1423,9 +1423,7 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) { QTimer* _challengeOwnershipTimeoutTimer = new QTimer(this); - connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [=](const QString& certID) { - QReadLocker locker(&_entityCertificateIDMapLock); - EntityItemID id = _entityCertificateIDMap.value(certID); + connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [=](const EntityItemID& id) { if (entityItemID == id && _challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1455,12 +1453,7 @@ QByteArray EntityTree::computeNonce(const QString& certID, const QString ownerKe return nonceBytes; } -bool EntityTree::verifyNonce(const QString& certID, const QString& nonce, EntityItemID& id) { - { - QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); - id = _entityCertificateIDMap.value(certID); - } - +bool EntityTree::verifyNonce(const QString& certID, const QString& nonce) { QString actualNonce, key; { QWriteLocker locker(&_certNonceMapLock); @@ -1645,10 +1638,14 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString text(message.read(textByteArraySize)); - emit killChallengeOwnershipTimeoutTimer(certID); + EntityItemID id; + { + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + id = _entityCertificateIDMap.value(certID); + } + emit killChallengeOwnershipTimeoutTimer(id); - EntityItemID id; - if (!verifyNonce(certID, text, id)) { + if (!verifyNonce(certID, text)) { if (!id.isNull()) { deleteEntity(id, true); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index e627a07d13..63e1197970 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -253,7 +253,7 @@ public: static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME; QByteArray computeNonce(const QString& certID, const QString ownerKey); - bool verifyNonce(const QString& certID, const QString& nonce, EntityItemID& id); + bool verifyNonce(const QString& certID, const QString& nonce); QUuid getMyAvatarSessionUUID() { return _myAvatar ? _myAvatar->getSessionUUID() : QUuid(); } void setMyAvatar(std::shared_ptr myAvatar) { _myAvatar = myAvatar; } @@ -290,7 +290,7 @@ signals: void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload); void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID); void clearingEntities(); - void killChallengeOwnershipTimeoutTimer(const QString& certID); + void killChallengeOwnershipTimeoutTimer(const EntityItemID& certID); protected: