From a92e614aff44c154566704e826d012a590226f60 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 8 Feb 2018 10:35:34 -0800 Subject: [PATCH] Bugfix. --- .../InspectionCertificate.qml | 149 ++++++++++-------- .../ui/overlays/ContextOverlayInterface.cpp | 142 ++++++++--------- scripts/system/marketplaces/marketplaces.js | 3 +- 3 files changed, 153 insertions(+), 141 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index bef03bd4c1..f493747c5e 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -24,6 +24,7 @@ Rectangle { id: root; property string marketplaceUrl: ""; + property string entityId: ""; property string certificateId: ""; property string itemName: "--"; property string itemOwner: "--"; @@ -110,77 +111,81 @@ Rectangle { } onUpdateCertificateStatus: { - root.certificateStatus = certStatus; - if (root.certificateStatus === 1) { // CERTIFICATE_STATUS_VERIFICATION_SUCCESS - root.useGoldCert = true; - root.certTitleTextColor = hifi.colors.darkGray; - root.certTextColor = hifi.colors.white; - root.infoTextColor = hifi.colors.blueAccent; - titleBarText.text = "Certificate"; - popText.text = "PROOF OF PROVENANCE"; - showInMarketplaceButton.visible = true; - root.certInfoReplaceMode = 5; - // "Item Name" text will be set in "onCertificateInfoResult()" - // "Edition" text will be set in "onCertificateInfoResult()" - // "Owner" text will be set in "onCertificateInfoResult()" - // "Purchase Date" text will be set in "onCertificateInfoResult()" - // "Purchase Price" text will be set in "onCertificateInfoResult()" - errorText.text = ""; - } else if (root.certificateStatus === 2) { // CERTIFICATE_STATUS_VERIFICATION_TIMEOUT - root.useGoldCert = false; - root.certTitleTextColor = hifi.colors.redHighlight; - root.certTextColor = hifi.colors.redHighlight; - root.infoTextColor = hifi.colors.redHighlight; - titleBarText.text = "Request Timed Out"; - popText.text = ""; - showInMarketplaceButton.visible = false; - root.certInfoReplaceMode = 0; - root.itemName = ""; - root.itemEdition = ""; - root.itemOwner = ""; - root.dateOfPurchase = ""; - root.itemCost = ""; - errorText.text = "Your request to inspect this item timed out. Please try again later."; - } else if (root.certificateStatus === 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED - root.useGoldCert = false; - root.certTitleTextColor = hifi.colors.redHighlight; - root.certTextColor = hifi.colors.redHighlight; - root.infoTextColor = hifi.colors.redHighlight; - titleBarText.text = "Certificate\nNo Longer Valid"; - popText.text = ""; - showInMarketplaceButton.visible = true; - root.certInfoReplaceMode = 5; - // "Item Name" text will be set in "onCertificateInfoResult()" - // "Edition" text will be set in "onCertificateInfoResult()" - // "Owner" text will be set in "onCertificateInfoResult()" - // "Purchase Date" text will be set in "onCertificateInfoResult()" - // "Purchase Price" text will be set in "onCertificateInfoResult()" - errorText.text = "The information associated with this item has been modified and it no longer matches the original certified item."; - } else if (root.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED - root.useGoldCert = false; - root.certTitleTextColor = hifi.colors.redHighlight; - root.certTextColor = hifi.colors.redHighlight; - root.infoTextColor = hifi.colors.redHighlight; - titleBarText.text = "Invalid Certificate"; - popText.text = ""; - showInMarketplaceButton.visible = true; - root.certInfoReplaceMode = 4; - // "Item Name" text will be set in "onCertificateInfoResult()" - root.itemEdition = "Uncertified Copy" - // "Owner" text will be set in "onCertificateInfoResult()" - // "Purchase Date" text will be set in "onCertificateInfoResult()" - // "Purchase Price" text will be set in "onCertificateInfoResult()" - // "Error Text" text will be set in "onCertificateInfoResult()" - } else { - console.log("Unknown certificate status received from ledger signal!"); - } - - root.certificateStatusPending = false; - // We've gotten cert status - we are GO on getting the cert info - Commerce.certificateInfo(root.certificateId); + updateCertificateStatus(certStatus); } } + function updateCertificateStatus(status) { + root.certificateStatus = status; + if (root.certificateStatus === 1) { // CERTIFICATE_STATUS_VERIFICATION_SUCCESS + root.useGoldCert = true; + root.certTitleTextColor = hifi.colors.darkGray; + root.certTextColor = hifi.colors.white; + root.infoTextColor = hifi.colors.blueAccent; + titleBarText.text = "Certificate"; + popText.text = "PROOF OF PROVENANCE"; + showInMarketplaceButton.visible = true; + root.certInfoReplaceMode = 5; + // "Item Name" text will be set in "onCertificateInfoResult()" + // "Edition" text will be set in "onCertificateInfoResult()" + // "Owner" text will be set in "onCertificateInfoResult()" + // "Purchase Date" text will be set in "onCertificateInfoResult()" + // "Purchase Price" text will be set in "onCertificateInfoResult()" + errorText.text = ""; + } else if (root.certificateStatus === 2) { // CERTIFICATE_STATUS_VERIFICATION_TIMEOUT + root.useGoldCert = false; + root.certTitleTextColor = hifi.colors.redHighlight; + root.certTextColor = hifi.colors.redHighlight; + root.infoTextColor = hifi.colors.redHighlight; + titleBarText.text = "Request Timed Out"; + popText.text = ""; + showInMarketplaceButton.visible = false; + root.certInfoReplaceMode = 0; + root.itemName = ""; + root.itemEdition = ""; + root.itemOwner = ""; + root.dateOfPurchase = ""; + root.itemCost = ""; + errorText.text = "Your request to inspect this item timed out. Please try again later."; + } else if (root.certificateStatus === 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED + root.useGoldCert = false; + root.certTitleTextColor = hifi.colors.redHighlight; + root.certTextColor = hifi.colors.redHighlight; + root.infoTextColor = hifi.colors.redHighlight; + titleBarText.text = "Certificate\nNo Longer Valid"; + popText.text = ""; + showInMarketplaceButton.visible = true; + root.certInfoReplaceMode = 5; + // "Item Name" text will be set in "onCertificateInfoResult()" + // "Edition" text will be set in "onCertificateInfoResult()" + // "Owner" text will be set in "onCertificateInfoResult()" + // "Purchase Date" text will be set in "onCertificateInfoResult()" + // "Purchase Price" text will be set in "onCertificateInfoResult()" + errorText.text = "The information associated with this item has been modified and it no longer matches the original certified item."; + } else if (root.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED + root.useGoldCert = false; + root.certTitleTextColor = hifi.colors.redHighlight; + root.certTextColor = hifi.colors.redHighlight; + root.infoTextColor = hifi.colors.redHighlight; + titleBarText.text = "Invalid Certificate"; + popText.text = ""; + showInMarketplaceButton.visible = true; + root.certInfoReplaceMode = 4; + // "Item Name" text will be set in "onCertificateInfoResult()" + root.itemEdition = "Uncertified Copy" + // "Owner" text will be set in "onCertificateInfoResult()" + // "Purchase Date" text will be set in "onCertificateInfoResult()" + // "Purchase Price" text will be set in "onCertificateInfoResult()" + // "Error Text" text will be set in "onCertificateInfoResult()" + } else { + console.log("Unknown certificate status received from ledger signal!"); + } + + root.certificateStatusPending = false; + // We've gotten cert status - we are GO on getting the cert info + Commerce.certificateInfo(root.certificateId); + } + // This object is always used in a popup. // This MouseArea is used to prevent a user from being // able to click on a button/mouseArea underneath the popup. @@ -563,7 +568,12 @@ Rectangle { case 'inspectionCertificate_setCertificateId': resetCert(false); root.certificateId = message.certificateId; - sendToScript({method: 'inspectionCertificate_requestOwnershipVerification', certificateId: root.certificateId}); + if (message.entityId === "") { + updateCertificateStatus(1); // CERTIFICATE_STATUS_VERIFICATION_SUCCESS + } else { + root.entityId = message.entityId; + sendToScript({method: 'inspectionCertificate_requestOwnershipVerification', entity: root.entityId}); + } break; case 'inspectionCertificate_resetCert': resetCert(true); @@ -576,6 +586,7 @@ Rectangle { function resetCert(alsoResetCertID) { if (alsoResetCertID) { + root.entityId = ""; root.certificateId = ""; } root.certInfoReplaceMode = 5; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 4dacab8936..dd05e5c6a8 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -274,88 +274,88 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID auto nodeList = DependencyManager::get(); - if (entityProperties.getClientOnly()) { - if (entityProperties.verifyStaticCertificateProperties()) { - SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer); + if (entityProperties.verifyStaticCertificateProperties()) { + if (entityProperties.getClientOnly()) { + SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer); - if (entityServer) { - 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/transfer"); - QJsonObject request; - request["certificate_id"] = entityProperties.getCertificateID(); - networkRequest.setUrl(requestURL); + if (entityServer) { + 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/transfer"); + QJsonObject request; + request["certificate_id"] = entityProperties.getCertificateID(); + networkRequest.setUrl(requestURL); - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); - if (networkReply->error() == QNetworkReply::NoError) { - if (!jsonObject["invalid_reason"].toString().isEmpty()) { - qCDebug(entities) << "invalid_reason not empty"; - } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { - qCDebug(entities) << "'transfer_status' is 'failed'"; - } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { - qCDebug(entities) << "'transfer_status' is 'pending'"; - } else { - QString ownerKey = jsonObject["transfer_recipient_key"].toString(); - - QByteArray certID = entityProperties.getCertificateID().toUtf8(); - QByteArray text = DependencyManager::get()->getTree()->computeNonce(certID, ownerKey); - QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122(); - - int certIDByteArraySize = certID.length(); - int textByteArraySize = text.length(); - int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length(); - - auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest, - certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int), - true); - challengeOwnershipPacket->writePrimitive(certIDByteArraySize); - challengeOwnershipPacket->writePrimitive(textByteArraySize); - challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize); - challengeOwnershipPacket->write(certID); - challengeOwnershipPacket->write(text); - challengeOwnershipPacket->write(nodeToChallengeByteArray); - nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer); - - // Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time - if (thread() != QThread::currentThread()) { - QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer"); - return; + if (networkReply->error() == QNetworkReply::NoError) { + if (!jsonObject["invalid_reason"].toString().isEmpty()) { + qCDebug(entities) << "invalid_reason not empty"; + } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { + qCDebug(entities) << "'transfer_status' is 'failed'"; + } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { + qCDebug(entities) << "'transfer_status' is 'pending'"; } else { - startChallengeOwnershipTimer(); - } - } - } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << - "More info:" << networkReply->readAll(); - } + QString ownerKey = jsonObject["transfer_recipient_key"].toString(); - networkReply->deleteLater(); - }); - } else { - qCWarning(context_overlay) << "Couldn't get Entity Server!"; - } + QByteArray certID = entityProperties.getCertificateID().toUtf8(); + QByteArray text = DependencyManager::get()->getTree()->computeNonce(certID, ownerKey); + QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122(); + + int certIDByteArraySize = certID.length(); + int textByteArraySize = text.length(); + int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length(); + + auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest, + certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int), + true); + challengeOwnershipPacket->writePrimitive(certIDByteArraySize); + challengeOwnershipPacket->writePrimitive(textByteArraySize); + challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize); + challengeOwnershipPacket->write(certID); + challengeOwnershipPacket->write(text); + challengeOwnershipPacket->write(nodeToChallengeByteArray); + nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer); + + // Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer"); + return; + } else { + startChallengeOwnershipTimer(); + } + } + } else { + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << + "More info:" << networkReply->readAll(); + } + + networkReply->deleteLater(); + }); + } else { + qCWarning(context_overlay) << "Couldn't get Entity Server!"; + } } else { + // We don't currently verify ownership of entities that aren't Avatar Entities, + // so they always pass Ownership Verification. It's necessary to emit this signal + // so that the Inspection Certificate can continue its information-grabbing process. auto ledger = DependencyManager::get(); - _challengeOwnershipTimeoutTimer.stop(); - emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); - emit DependencyManager::get()->ownershipVerificationFailed(_lastInspectedEntity); - qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; + emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); } } else { - // We don't currently verify ownership of entities that aren't Avatar Entities, - // so they always pass Ownership Verification. It's necessary to emit this signal - // so that the Inspection Certificate can continue its information-grabbing process. auto ledger = DependencyManager::get(); - emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); + _challengeOwnershipTimeoutTimer.stop(); + emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); + emit DependencyManager::get()->ownershipVerificationFailed(_lastInspectedEntity); + qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; } } diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index cec139faae..fd1275a251 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -163,6 +163,7 @@ var selectionDisplay = null; // for gridTool.js to ignore var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID); tablet.sendToQml({ method: 'inspectionCertificate_setCertificateId', + entityId: currentEntityWithContextOverlay, certificateId: certificateId }); } @@ -584,7 +585,7 @@ var selectionDisplay = null; // for gridTool.js to ignore tablet.gotoHomeScreen(); break; case 'inspectionCertificate_requestOwnershipVerification': - ContextOverlay.requestOwnershipVerification(message.certificateId); + ContextOverlay.requestOwnershipVerification(message.entity); break; case 'inspectionCertificate_showInMarketplaceClicked': tablet.gotoWebScreen(message.marketplaceUrl, MARKETPLACES_INJECT_SCRIPT_URL);