mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 13:11:43 +02:00
Static verification changes - WIP
This commit is contained in:
parent
b2e54f46e1
commit
fb8f9e302d
2 changed files with 31 additions and 12 deletions
|
@ -25,12 +25,16 @@
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
|
|
||||||
void MixerAvatar::fetchAvatarFST() {
|
void MixerAvatar::fetchAvatarFST() {
|
||||||
_avatarFSTValid = false;
|
_verifyState = kNoncertified;
|
||||||
|
_certificateIdFromURL.clear();
|
||||||
|
_certificateIdFromFST.clear();
|
||||||
|
_marketplaceIdString.clear();
|
||||||
auto resourceManager = DependencyManager::get<ResourceManager>();
|
auto resourceManager = DependencyManager::get<ResourceManager>();
|
||||||
QUrl avatarURL = getSkeletonModelURL();
|
QUrl avatarURL = getSkeletonModelURL();
|
||||||
if (avatarURL.isEmpty()) {
|
if (avatarURL.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto avatarURLString = avatarURL.toDisplayString();
|
auto avatarURLString = avatarURL.toDisplayString();
|
||||||
// Match UUID + version
|
// Match UUID + version
|
||||||
static const QRegularExpression marketIdRegex{
|
static const QRegularExpression marketIdRegex{
|
||||||
|
@ -56,6 +60,7 @@ void MixerAvatar::fetchAvatarFST() {
|
||||||
fstRequest->send();
|
fstRequest->send();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(avatars) << "Couldn't create FST request for" << avatarURL;
|
qCDebug(avatars) << "Couldn't create FST request for" << avatarURL;
|
||||||
|
_verifyState = kError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +78,7 @@ void MixerAvatar::fstRequestComplete() {
|
||||||
generateFSTHash();
|
generateFSTHash();
|
||||||
QString& marketplacePublicKey = EntityItem::_marketplacePublicKey;
|
QString& marketplacePublicKey = EntityItem::_marketplacePublicKey;
|
||||||
bool staticVerification = validateFSTHash(marketplacePublicKey);
|
bool staticVerification = validateFSTHash(marketplacePublicKey);
|
||||||
_verifyState = staticVerification ? kStaticValidation : kNoncertified;
|
_verifyState = staticVerification ? kStaticValidation : kVerificationFailed;
|
||||||
|
|
||||||
if (_verifyState == kStaticValidation) {
|
if (_verifyState == kStaticValidation) {
|
||||||
static const QString POP_MARKETPLACE_API{ "/api/v1/commerce/proof_of_purchase_status/transfer" };
|
static const QString POP_MARKETPLACE_API{ "/api/v1/commerce/proof_of_purchase_status/transfer" };
|
||||||
|
@ -86,7 +91,7 @@ void MixerAvatar::fstRequestComplete() {
|
||||||
networkRequest.setUrl(requestURL);
|
networkRequest.setUrl(requestURL);
|
||||||
|
|
||||||
QJsonObject request;
|
QJsonObject request;
|
||||||
request["certificate_id"] = _certificateIdFromURL;
|
request["certificate_id"] = _certificateIdFromFST;
|
||||||
_verifyState = kRequestingOwner;
|
_verifyState = kRequestingOwner;
|
||||||
QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
||||||
networkReply->setParent(this);
|
networkReply->setParent(this);
|
||||||
|
@ -96,6 +101,8 @@ void MixerAvatar::fstRequestComplete() {
|
||||||
QJsonDocument responseJson = QJsonDocument::fromJson(responseString.toUtf8());
|
QJsonDocument responseJson = QJsonDocument::fromJson(responseString.toUtf8());
|
||||||
if (networkReply->error() == QNetworkReply::NoError) {
|
if (networkReply->error() == QNetworkReply::NoError) {
|
||||||
QMutexLocker certifyLocker(&_avatarCertifyLock);
|
QMutexLocker certifyLocker(&_avatarCertifyLock);
|
||||||
|
// TODO: move processing to slave thread.
|
||||||
|
_verifyState = kOwnerResponse;
|
||||||
if (responseJson["status"].toString() == "success") {
|
if (responseJson["status"].toString() == "success") {
|
||||||
auto jsonData = responseJson["data"];
|
auto jsonData = responseJson["data"];
|
||||||
// owner, owner key?
|
// owner, owner key?
|
||||||
|
@ -110,6 +117,9 @@ void MixerAvatar::fstRequestComplete() {
|
||||||
}
|
}
|
||||||
networkReply->deleteLater();
|
networkReply->deleteLater();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
_verifyState = kVerificationFailed;
|
||||||
|
qCDebug(avatars) << "Avatar" << getDisplayName() << "FAILED static certification";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_avatarRequest->deleteLater();
|
_avatarRequest->deleteLater();
|
||||||
|
@ -133,7 +143,7 @@ bool MixerAvatar::generateFSTHash() {
|
||||||
bool MixerAvatar::validateFSTHash(const QString& publicKey) {
|
bool MixerAvatar::validateFSTHash(const QString& publicKey) {
|
||||||
// Guess we should refactor this stuff into a Authorization namespace ...
|
// Guess we should refactor this stuff into a Authorization namespace ...
|
||||||
return EntityItemProperties::verifySignature(publicKey, _certificateHash,
|
return EntityItemProperties::verifySignature(publicKey, _certificateHash,
|
||||||
QByteArray::fromBase64(_certificateIdFromURL.toUtf8()));
|
QByteArray::fromBase64(_certificateIdFromFST.toUtf8()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray MixerAvatar::canonicalJson(const QString fstFile) {
|
QByteArray MixerAvatar::canonicalJson(const QString fstFile) {
|
||||||
|
@ -146,7 +156,6 @@ QByteArray MixerAvatar::canonicalJson(const QString fstFile) {
|
||||||
QStringListIterator fstLineIter(fstLines);
|
QStringListIterator fstLineIter(fstLines);
|
||||||
|
|
||||||
QJsonObject certifiedItems;
|
QJsonObject certifiedItems;
|
||||||
QJsonArray scriptsArray;
|
|
||||||
QStringList scripts;
|
QStringList scripts;
|
||||||
while (fstLineIter.hasNext()) {
|
while (fstLineIter.hasNext()) {
|
||||||
auto line = fstLineIter.next();
|
auto line = fstLineIter.next();
|
||||||
|
@ -155,15 +164,22 @@ QByteArray MixerAvatar::canonicalJson(const QString fstFile) {
|
||||||
QString key = lineMatch.captured(1);
|
QString key = lineMatch.captured(1);
|
||||||
if (key == "certificateID") {
|
if (key == "certificateID") {
|
||||||
_certificateIdFromFST = lineMatch.captured(2);
|
_certificateIdFromFST = lineMatch.captured(2);
|
||||||
|
} else if (key == "itemDescription") {
|
||||||
|
// Item description can be multiline - intermediate lines end in <CR>
|
||||||
|
QString itemDesc = lineMatch.captured(2);
|
||||||
|
while (itemDesc.endsWith('\r') && fstLineIter.hasNext()) {
|
||||||
|
itemDesc += '\n' + fstLineIter.next();
|
||||||
|
}
|
||||||
|
certifiedItems[key] = QJsonValue(itemDesc);
|
||||||
} else if (key == "limitedRun" || key == "editionNumber") {
|
} else if (key == "limitedRun" || key == "editionNumber") {
|
||||||
double value = lineMatch.captured(2).toDouble();
|
double value = lineMatch.captured(2).toDouble();
|
||||||
if (value != 0.0) {
|
if (value != 0.0) {
|
||||||
certifiedItems[key] = QJsonValue(value);
|
certifiedItems[key] = QJsonValue(value);
|
||||||
}
|
}
|
||||||
} else if (key == "script") {
|
} else if (key == "script") {
|
||||||
scripts.append(lineMatch.captured(2));
|
scripts.append(lineMatch.captured(2).trimmed());
|
||||||
} else {
|
} else {
|
||||||
certifiedItems[key] = QJsonValue(lineMatch.captured(2));
|
certifiedItems[key] = QJsonValue(lineMatch.captured(2).trimmed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +188,7 @@ QByteArray MixerAvatar::canonicalJson(const QString fstFile) {
|
||||||
certifiedItems["script"] = QJsonArray::fromStringList(scripts);
|
certifiedItems["script"] = QJsonArray::fromStringList(scripts);
|
||||||
}
|
}
|
||||||
QJsonDocument jsonDocCertifiedItems(certifiedItems);
|
QJsonDocument jsonDocCertifiedItems(certifiedItems);
|
||||||
//OK - this one works
|
//Example working form:
|
||||||
//return R"({"editionNumber":34,"filename":"http://mpassets.highfidelity.com/7f142fde-541a-4902-b33a-25fa89dfba21-v1/Bridger/Hifi_Toon_Male_3.fbx","itemArtist":"EgyMax","itemCategories":"Avatars","itemDescription":"This is my first avatar. I hope you like it. More will come","itemName":"Bridger","limitedRun":-1,"marketplaceID":"7f142fde-541a-4902-b33a-25fa89dfba21","texdir":"http://mpassets.highfidelity.com/7f142fde-541a-4902-b33a-25fa89dfba21-v1/Bridger/textures"})";
|
//return R"({"editionNumber":34,"filename":"http://mpassets.highfidelity.com/7f142fde-541a-4902-b33a-25fa89dfba21-v1/Bridger/Hifi_Toon_Male_3.fbx","itemArtist":"EgyMax","itemCategories":"Avatars","itemDescription":"This is my first avatar. I hope you like it. More will come","itemName":"Bridger","limitedRun":-1,"marketplaceID":"7f142fde-541a-4902-b33a-25fa89dfba21","texdir":"http://mpassets.highfidelity.com/7f142fde-541a-4902-b33a-25fa89dfba21-v1/Bridger/textures"})";
|
||||||
return jsonDocCertifiedItems.toJson(QJsonDocument::Compact);
|
return jsonDocCertifiedItems.toJson(QJsonDocument::Compact);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef hifi_MixerAvatar_h
|
#ifndef hifi_MixerAvatar_h
|
||||||
#define hifi_MixerAvatar_h
|
#define hifi_MixerAvatar_h
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
|
|
||||||
class ResourceRequest;
|
class ResourceRequest;
|
||||||
|
@ -25,13 +27,14 @@ public:
|
||||||
void setNeedsHeroCheck(bool needsHeroCheck = true) { _needsHeroCheck = needsHeroCheck; }
|
void setNeedsHeroCheck(bool needsHeroCheck = true) { _needsHeroCheck = needsHeroCheck; }
|
||||||
|
|
||||||
void fetchAvatarFST();
|
void fetchAvatarFST();
|
||||||
|
bool isCertifyFailed() const { return _verifyState == kVerificationFailed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _needsHeroCheck{ false };
|
bool _needsHeroCheck{ false };
|
||||||
|
|
||||||
// Avatar certification/verification
|
// Avatar certification/verification:
|
||||||
enum VerifyState { kNoncertified, kRequestingFST, kReceivedFST, kStaticValidation, kRequestingOwner, kChallengeClient, kVerified,
|
enum VerifyState { kNoncertified, kRequestingFST, kReceivedFST, kStaticValidation, kRequestingOwner, kOwnerResponse,
|
||||||
kVerificationFailed, kVerificationSucceeded, kError };
|
kChallengeClient, kVerified, kVerificationFailed, kVerificationSucceeded, kError };
|
||||||
Q_ENUM(VerifyState);
|
Q_ENUM(VerifyState);
|
||||||
VerifyState _verifyState { kNoncertified };
|
VerifyState _verifyState { kNoncertified };
|
||||||
QMutex _avatarCertifyLock;
|
QMutex _avatarCertifyLock;
|
||||||
|
@ -41,7 +44,7 @@ private:
|
||||||
QByteArray _certificateHash;
|
QByteArray _certificateHash;
|
||||||
QString _certificateIdFromURL;
|
QString _certificateIdFromURL;
|
||||||
QString _certificateIdFromFST;
|
QString _certificateIdFromFST;
|
||||||
bool _avatarFSTValid { false };
|
QJsonDocument _dynamicMarketResponse;
|
||||||
|
|
||||||
bool generateFSTHash();
|
bool generateFSTHash();
|
||||||
bool validateFSTHash(const QString& publicKey);
|
bool validateFSTHash(const QString& publicKey);
|
||||||
|
|
Loading…
Reference in a new issue