From 3d401129fbb005de82a064f88510149e6f05485f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 18 Aug 2017 10:03:00 -0700 Subject: [PATCH 1/3] checkpoint --- interface/resources/qml/controls/WebView.qml | 2 +- .../resources/qml/hifi/commerce/Checkout.qml | 19 +-- .../resources/qml/hifi/commerce/Inventory.qml | 12 +- interface/src/commerce/Ledger.cpp | 108 +++++++++++------- interface/src/commerce/Ledger.h | 34 ++++-- interface/src/commerce/QmlCommerce.cpp | 7 +- interface/src/commerce/QmlCommerce.h | 7 +- interface/src/commerce/Wallet.cpp | 13 ++- .../HFTabletWebEngineRequestInterceptor.cpp | 2 +- scripts/system/html/js/marketplacesInject.js | 6 +- 10 files changed, 127 insertions(+), 83 deletions(-) diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index 38136c7eec..23782983ce 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -73,7 +73,7 @@ Item { console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); }); - root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)"; + root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface WithHFC)"; } onFeaturePermissionRequested: { diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index b9d15b61e4..55bd6cb4c6 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -35,8 +35,8 @@ Rectangle { Hifi.QmlCommerce { id: commerce; onBuyResult: { - if (failureMessage.length) { - buyButton.text = "Buy Failed"; + if (result.status !== 'success') { + buyButton.text = result.message; buyButton.enabled = false; } else { if (urlHandler.canHandleUrl(itemHref)) { @@ -46,20 +46,21 @@ Rectangle { } } onBalanceResult: { - if (failureMessage.length) { - console.log("Failed to get balance", failureMessage); + if (result.status !== 'success') { + console.log("Failed to get balance", result.message); } else { balanceReceived = true; - hfcBalanceText.text = balance; - balanceAfterPurchase = balance - parseInt(itemPriceText.text, 10); + hfcBalanceText.text = result.data.balance; + balanceAfterPurchase = result.data.balance - parseInt(itemPriceText.text, 10); } } onInventoryResult: { - if (failureMessage.length) { - console.log("Failed to get inventory", failureMessage); + if (result.status !== 'success') { + console.log("Failed to get inventory", result.message); } else { inventoryReceived = true; - if (inventoryContains(inventory.assets, itemId)) { + console.log('inventory fixme', JSON.stringify(result)); + if (inventoryContains(result.data.assets, itemId)) { alreadyOwned = true; } else { alreadyOwned = false; diff --git a/interface/resources/qml/hifi/commerce/Inventory.qml b/interface/resources/qml/hifi/commerce/Inventory.qml index d7ffae7c3c..8f22e7de0f 100644 --- a/interface/resources/qml/hifi/commerce/Inventory.qml +++ b/interface/resources/qml/hifi/commerce/Inventory.qml @@ -30,17 +30,17 @@ Rectangle { Hifi.QmlCommerce { id: commerce; onBalanceResult: { - if (failureMessage.length) { - console.log("Failed to get balance", failureMessage); + if (result.status !== 'success') { + console.log("Failed to get balance", result.message); } else { - hfcBalanceText.text = balance; + hfcBalanceText.text = result.data.balance; } } onInventoryResult: { - if (failureMessage.length) { - console.log("Failed to get inventory", failureMessage); + if (result.status !== 'success') { + console.log("Failed to get inventory", result.message); } else { - inventoryContentsList.model = inventory.assets; + inventoryContentsList.model = result.data.assets; } } onSecurityImageResult: { diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 8d7d47aca0..55ee0e16e9 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -10,72 +10,100 @@ // #include +#include #include #include "AccountManager.h" #include "Wallet.h" #include "Ledger.h" #include "CommerceLogging.h" +// inventory answers {status: 'success', data: {assets: [{id: "guid", title: "name", preview: "url"}....]}} +// balance answers {status: 'success', data: {balance: integer}} +// buy and receive_at answer {status: 'success'} + +QJsonObject Ledger::apiResponse(const QString& label, QNetworkReply& reply) { + QByteArray response = reply.readAll(); + QJsonObject data = QJsonDocument::fromJson(response).object(); + qInfo(commerce) << label << "response" << QJsonDocument(data).toJson(QJsonDocument::Compact); + return data; +} +// Non-200 responses are not json: +QJsonObject Ledger::failResponse(const QString& label, QNetworkReply& reply) { + QString response = reply.readAll(); + qWarning(commerce) << "FAILED" << label << response; + QJsonObject result + { + { "status", "fail" }, + { "message", response } + }; + return result; +} +#define ApiHandler(NAME) void Ledger::NAME##Success(QNetworkReply& reply) { emit NAME##Result(apiResponse(#NAME, reply)); } +#define FailHandler(NAME) void Ledger::NAME##Failure(QNetworkReply& reply) { emit NAME##Result(failResponse(#NAME, reply)); } +#define Handler(NAME) ApiHandler(NAME) FailHandler(NAME) +Handler(buy) +Handler(receiveAt) +Handler(balance) +Handler(inventory) + +void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request) { + auto accountManager = DependencyManager::get(); + const QString URL = "/api/v1/commerce/"; + JSONCallbackParameters callbackParams(this, success, this, fail); + qCInfo(commerce) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact); + accountManager->sendRequest(URL + endpoint, + AccountManagerAuth::Required, + method, + callbackParams, + QJsonDocument(request).toJson()); +} + +void Ledger::signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail) { + auto wallet = DependencyManager::get(); + QString signature = key.isEmpty() ? "" : wallet->signWithKey(text, key); + QJsonObject request; + request[propertyName] = QString(text); + request["signature"] = signature; + send(endpoint, success, fail, QNetworkAccessManager::PutOperation, request); +} + +void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail) { + auto wallet = DependencyManager::get(); + QJsonObject request; + request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys()); + send(endpoint, success, fail, QNetworkAccessManager::PostOperation, request); +} + void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername) { QJsonObject transaction; transaction["hfc_key"] = hfc_key; - transaction["hfc"] = cost; + transaction["cost"] = cost; transaction["asset_id"] = asset_id; transaction["inventory_key"] = inventory_key; transaction["inventory_buyer_username"] = buyerUsername; QJsonDocument transactionDoc{ transaction }; auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); - - auto wallet = DependencyManager::get(); - QString signature = wallet->signWithKey(transactionString, hfc_key); - QJsonObject request; - request["transaction"] = QString(transactionString); - request["signature"] = signature; - - qCInfo(commerce) << "Transaction:" << QJsonDocument(request).toJson(QJsonDocument::Compact); - // FIXME: talk to server instead - if (_inventory.contains(asset_id)) { - // This is here more for testing than as a definition of semantics. - // When we have popcerts, you will certainly be able to buy a new instance of an item that you already own a different instance of. - // I'm not sure what the server should do for now in this project's MVP. - return emit buyResult("Already owned."); - } - if (initializedBalance() < cost) { - return emit buyResult("Insufficient funds."); - } - _balance -= cost; - QJsonObject inventoryAdditionObject; - inventoryAdditionObject["id"] = asset_id; - inventoryAdditionObject["title"] = "Test Title"; - inventoryAdditionObject["preview"] = "https://www.aspca.org/sites/default/files/cat-care_cat-nutrition-tips_overweight_body4_left.jpg"; - _inventory.push_back(inventoryAdditionObject); - emit buyResult(""); + signedSend("transaction", transactionString, hfc_key, "buy", "buySuccess", "buyFailure"); } -bool Ledger::receiveAt(const QString& hfc_key) { +bool Ledger::receiveAt(const QString& hfc_key, const QString& old_key) { auto accountManager = DependencyManager::get(); if (!accountManager->isLoggedIn()) { qCWarning(commerce) << "Cannot set receiveAt when not logged in."; - emit receiveAtResult("Not logged in"); + QJsonObject result{ { "status", "fail" }, { "message", "Not logged in" } }; + emit receiveAtResult(result); return false; // We know right away that we will fail, so tell the caller. } - auto username = accountManager->getAccountInfo().getUsername(); - qCInfo(commerce) << "Setting default receiving key for" << username; - emit receiveAtResult(""); // FIXME: talk to server instead. + + signedSend("public_key", hfc_key.toUtf8(), old_key, "receive_at", "receiveAtSuccess", "receiveAtFailure"); return true; // Note that there may still be an asynchronous signal of failure that callers might be interested in. } void Ledger::balance(const QStringList& keys) { - // FIXME: talk to server instead - qCInfo(commerce) << "Balance:" << initializedBalance(); - emit balanceResult(_balance, ""); + keysQuery("balance", "balanceSuccess", "balanceFailure"); } void Ledger::inventory(const QStringList& keys) { - // FIXME: talk to server instead - QJsonObject inventoryObject; - inventoryObject.insert("success", true); - inventoryObject.insert("assets", _inventory); - qCInfo(commerce) << "Inventory:" << inventoryObject; - emit inventoryResult(inventoryObject, ""); + keysQuery("inventory", "inventorySuccess", "inventoryFailure"); } + diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 74ed8c1ab3..e43b8453b9 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -14,9 +14,10 @@ #ifndef hifi_Ledger_h #define hifi_Ledger_h +#include #include -#include -#include +#include + class Ledger : public QObject, public Dependency { Q_OBJECT @@ -24,21 +25,32 @@ class Ledger : public QObject, public Dependency { public: void buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername = ""); - bool receiveAt(const QString& hfc_key); + bool receiveAt(const QString& hfc_key, const QString& old_key); void balance(const QStringList& keys); void inventory(const QStringList& keys); signals: - void buyResult(const QString& failureReason); - void receiveAtResult(const QString& failureReason); - void balanceResult(int balance, const QString& failureReason); - void inventoryResult(QJsonObject inventory, const QString& failureReason); + void buyResult(QJsonObject result); + void receiveAtResult(QJsonObject result); + void balanceResult(QJsonObject result); + void inventoryResult(QJsonObject result); + +public slots: + void buySuccess(QNetworkReply& reply); + void buyFailure(QNetworkReply& reply); + void receiveAtSuccess(QNetworkReply& reply); + void receiveAtFailure(QNetworkReply& reply); + void balanceSuccess(QNetworkReply& reply); + void balanceFailure(QNetworkReply& reply); + void inventorySuccess(QNetworkReply& reply); + void inventoryFailure(QNetworkReply& reply); private: - // These in-memory caches is temporary, until we start sending things to the server. - int _balance{ -1 }; - QJsonArray _inventory{}; - int initializedBalance() { if (_balance < 0) _balance = 100; return _balance; } + QJsonObject apiResponse(const QString& label, QNetworkReply& reply); + QJsonObject failResponse(const QString& label, QNetworkReply& reply); + void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request); + void keysQuery(const QString& endpoint, const QString& success, const QString& fail); + void signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail); }; #endif // hifi_Ledger_h diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 573740727f..abd0e52f78 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -31,14 +31,15 @@ void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUser auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - return emit buyResult("Uninitialized Wallet."); + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; + return emit buyResult(result); } QString key = keys[0]; // For now, we receive at the same key that pays for it. ledger->buy(key, cost, assetId, key, buyerUsername); // FIXME: until we start talking to server, report post-transaction balance and inventory so we can see log for testing. - balance(); - inventory(); + /*balance(); + inventory();*/ } void QmlCommerce::balance() { diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 5b702bfeff..bb067146ba 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -15,6 +15,7 @@ #ifndef hifi_QmlCommerce_h #define hifi_QmlCommerce_h +#include #include class QmlCommerce : public OffscreenQmlDialog { @@ -25,11 +26,11 @@ public: QmlCommerce(QQuickItem* parent = nullptr); signals: - void buyResult(const QString& failureMessage); + void buyResult(QJsonObject result); // Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and // because we can't scalably know of out-of-band changes (e.g., another machine interacting with the block chain). - void balanceResult(int balance, const QString& failureMessage); - void inventoryResult(QJsonObject inventory, const QString& failureMessage); + void balanceResult(QJsonObject result); + void inventoryResult(QJsonObject result); void securityImageResult(uint imageID); protected: diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index f47b174d88..05ccea3a59 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -205,7 +205,7 @@ bool Wallet::createIfNeeded() { qCDebug(commerce) << "read private key"; RSA_free(key); // K -- add the public key since we have a legit private key associated with it - _publicKeys.push_back(QUrl::toPercentEncoding(publicKey.toBase64())); + _publicKeys.push_back(publicKey.toBase64()); return false; } } @@ -216,16 +216,17 @@ bool Wallet::createIfNeeded() { bool Wallet::generateKeyPair() { qCInfo(commerce) << "Generating keypair."; auto keyPair = generateRSAKeypair(); - - _publicKeys.push_back(QUrl::toPercentEncoding(keyPair.first->toBase64())); - qCDebug(commerce) << "public key:" << _publicKeys.last(); + QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last(); + QString key = keyPair.first->toBase64(); + _publicKeys.push_back(key); + qCDebug(commerce) << "public key:" << key; // It's arguable whether we want to change the receiveAt every time, but: // 1. It's certainly needed the first time, when createIfNeeded answers true. // 2. It is maximally private, and we can step back from that later if desired. // 3. It maximally exercises all the machinery, so we are most likely to surface issues now. auto ledger = DependencyManager::get(); - return ledger->receiveAt(_publicKeys.last()); + return ledger->receiveAt(key, oldKey); } QStringList Wallet::listPublicKeys() { qCInfo(commerce) << "Enumerating public keys."; @@ -260,7 +261,7 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) { RSA_free(rsaPrivateKey); if (encryptReturn != -1) { - return QUrl::toPercentEncoding(signature.toBase64()); + return signature.toBase64(); } } return QString(); diff --git a/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp b/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp index 6ee8589615..405a402a8b 100644 --- a/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp +++ b/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp @@ -36,7 +36,7 @@ void HFTabletWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestI } static const QString USER_AGENT = "User-Agent"; - QString tokenString = "Chrome/48.0 (HighFidelityInterface)"; + QString tokenString = "Chrome/48.0 (HighFidelityInterface WithHFC)"; info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit()); } else { static const QString USER_AGENT = "User-Agent"; diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 80c8f8a0e4..41b57060cc 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -114,7 +114,7 @@ itemId: id, itemName: name, itemAuthor: author, - itemPrice: Math.round(Math.random() * 50), + itemPrice: price ? parseInt(price, 10) : Math.round(Math.random() * 50), itemHref: href })); } @@ -129,7 +129,7 @@ buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'), $(this).closest('.grid-item').find('.item-title').text(), $(this).closest('.grid-item').find('.creator').find('.value').text(), - 10, + $(this).closest('.grid-item').find('.item-cost').text(), $(this).attr('data-href')); }); } @@ -165,7 +165,7 @@ buyButtonClicked(window.location.pathname.split("/")[3], $('#top-center').find('h1').text(), $('#creator').find('.value').text(), - 10, + $('.item-cost').text(), href); }); addInventoryButton(); From bd37679b657f94e1a5d626110c7df7fec8f16e25 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 18 Aug 2017 14:03:40 -0700 Subject: [PATCH 2/3] working --- interface/resources/qml/TabletBrowser.qml | 2 +- .../qml/controls/TabletWebScreen.qml | 2 +- .../resources/qml/controls/TabletWebView.qml | 4 +- interface/resources/qml/controls/WebView.qml | 1 - interface/resources/qml/hifi/WebBrowser.qml | 2 +- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 2 - .../src/ui/types/HFTabletWebEngineProfile.cpp | 27 ----------- .../HFTabletWebEngineRequestInterceptor.cpp | 46 ------------------- .../ui/src/ui/types/HFWebEngineProfile.cpp | 2 - libraries/ui/src/ui/types/RequestFilters.cpp | 15 +++++- 10 files changed, 18 insertions(+), 85 deletions(-) delete mode 100644 libraries/ui/src/ui/types/HFTabletWebEngineProfile.cpp delete mode 100644 libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index c3d879c513..0b06a6e2a1 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -39,7 +39,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile; + profile: HFWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/TabletWebScreen.qml b/interface/resources/qml/controls/TabletWebScreen.qml index 68f8226e21..1de31aba41 100644 --- a/interface/resources/qml/controls/TabletWebScreen.qml +++ b/interface/resources/qml/controls/TabletWebScreen.qml @@ -31,7 +31,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile; + profile: HFWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 0a5a68717e..dd40b55b84 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -142,7 +142,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - web.headerHeight : parent.height - web.headerHeight anchors.top: buttons.bottom - profile: HFTabletWebEngineProfile; + profile: HFWebEngineProfile; property string userScriptUrl: "" @@ -182,8 +182,6 @@ Item { webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); }); - - webview.profile.httpUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; } onFeaturePermissionRequested: { diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index 23782983ce..3f2ac6363b 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -73,7 +73,6 @@ Item { console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); }); - root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface WithHFC)"; } onFeaturePermissionRequested: { diff --git a/interface/resources/qml/hifi/WebBrowser.qml b/interface/resources/qml/hifi/WebBrowser.qml index f639586668..af54c86bf4 100644 --- a/interface/resources/qml/hifi/WebBrowser.qml +++ b/interface/resources/qml/hifi/WebBrowser.qml @@ -147,7 +147,7 @@ Rectangle { width: parent.width; height: keyboardEnabled && keyboardRaised ? webViewHeight - keyboard.height : webViewHeight - profile: HFTabletWebEngineProfile; + profile: HFWebEngineProfile; property string userScriptUrl: "" diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 2012ebbe30..47b526c925 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -43,7 +43,6 @@ #include "types/FileTypeProfile.h" #include "types/HFWebEngineProfile.h" -#include "types/HFTabletWebEngineProfile.h" #include "types/SoundEffect.h" #include "Logging.h" @@ -328,7 +327,6 @@ void initializeQmlEngine(QQmlEngine* engine, QQuickWindow* window) { } rootContext->setContextProperty("FileTypeProfile", new FileTypeProfile(rootContext)); rootContext->setContextProperty("HFWebEngineProfile", new HFWebEngineProfile(rootContext)); - rootContext->setContextProperty("HFTabletWebEngineProfile", new HFTabletWebEngineProfile(rootContext)); rootContext->setContextProperty("Paths", DependencyManager::get().data()); } diff --git a/libraries/ui/src/ui/types/HFTabletWebEngineProfile.cpp b/libraries/ui/src/ui/types/HFTabletWebEngineProfile.cpp deleted file mode 100644 index a3e3906497..0000000000 --- a/libraries/ui/src/ui/types/HFTabletWebEngineProfile.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// HFTabletWebEngineProfile.h -// interface/src/networking -// -// Created by Dante Ruiz on 2017-03-31. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFTabletWebEngineProfile.h" -#include "HFTabletWebEngineRequestInterceptor.h" - -static const QString QML_WEB_ENGINE_NAME = "qmlTabletWebEngine"; - -HFTabletWebEngineProfile::HFTabletWebEngineProfile(QObject* parent) : QQuickWebEngineProfile(parent) { - - static const QString WEB_ENGINE_USER_AGENT = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; - - setHttpUserAgent(WEB_ENGINE_USER_AGENT); - setStorageName(QML_WEB_ENGINE_NAME); - - auto requestInterceptor = new HFTabletWebEngineRequestInterceptor(this); - setRequestInterceptor(requestInterceptor); -} - diff --git a/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp b/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp deleted file mode 100644 index 405a402a8b..0000000000 --- a/libraries/ui/src/ui/types/HFTabletWebEngineRequestInterceptor.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// HFTabletWebEngineRequestInterceptor.cpp -// interface/src/networking -// -// Created by Dante Ruiz on 2017-3-31. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFTabletWebEngineRequestInterceptor.h" -#include -#include "AccountManager.h" - -bool isTabletAuthableHighFidelityURL(const QUrl& url) { - static const QStringList HF_HOSTS = { - "highfidelity.com", "highfidelity.io", - "metaverse.highfidelity.com", "metaverse.highfidelity.io" - }; - - return url.scheme() == "https" && HF_HOSTS.contains(url.host()); -} - -void HFTabletWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo& info) { - // check if this is a request to a highfidelity URL - if (isTabletAuthableHighFidelityURL(info.requestUrl())) { - // if we have an access token, add it to the right HTTP header for authorization - auto accountManager = DependencyManager::get(); - - if (accountManager->hasValidAccessToken()) { - static const QString OAUTH_AUTHORIZATION_HEADER = "Authorization"; - - QString bearerTokenString = "Bearer " + accountManager->getAccountInfo().getAccessToken().token; - info.setHttpHeader(OAUTH_AUTHORIZATION_HEADER.toLocal8Bit(), bearerTokenString.toLocal8Bit()); - } - - static const QString USER_AGENT = "User-Agent"; - QString tokenString = "Chrome/48.0 (HighFidelityInterface WithHFC)"; - info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit()); - } else { - static const QString USER_AGENT = "User-Agent"; - QString tokenString = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; - info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit()); - } -} diff --git a/libraries/ui/src/ui/types/HFWebEngineProfile.cpp b/libraries/ui/src/ui/types/HFWebEngineProfile.cpp index a69d4d653b..685af45dad 100644 --- a/libraries/ui/src/ui/types/HFWebEngineProfile.cpp +++ b/libraries/ui/src/ui/types/HFWebEngineProfile.cpp @@ -18,8 +18,6 @@ static const QString QML_WEB_ENGINE_STORAGE_NAME = "qmlWebEngine"; HFWebEngineProfile::HFWebEngineProfile(QObject* parent) : QQuickWebEngineProfile(parent) { - static const QString WEB_ENGINE_USER_AGENT = "Chrome/48.0 (HighFidelityInterface)"; - setHttpUserAgent(WEB_ENGINE_USER_AGENT); setStorageName(QML_WEB_ENGINE_STORAGE_NAME); // we use the HFWebEngineRequestInterceptor to make sure that web requests are authenticated for the interface user diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index 3e72b8a8bd..6ef3effa4c 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -13,6 +13,7 @@ #include "NetworkingConstants.h" #include +#include #include "AccountManager.h" @@ -42,7 +43,8 @@ namespace { void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info) { // check if this is a request to a highfidelity URL - if (isAuthableHighFidelityURL(info.requestUrl())) { + bool isAuthable = isAuthableHighFidelityURL(info.requestUrl()); + if (isAuthable) { // if we have an access token, add it to the right HTTP header for authorization auto accountManager = DependencyManager::get(); @@ -53,6 +55,17 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info) info.setHttpHeader(OAUTH_AUTHORIZATION_HEADER.toLocal8Bit(), bearerTokenString.toLocal8Bit()); } } + static const QString USER_AGENT = "User-Agent"; + const QString tokenStringMobile{ "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36" }; + const QString tokenStringMetaverse{ "Chrome/48.0 (HighFidelityInterface)" }; + + // During the period in which we have HFC commerce in the system, but not applied everywhere: + const QString tokenStringCommerce{ "Chrome/48.0 (HighFidelityInterface WithHFC)" }; + static Setting::Handle _settingSwitch{ "inspectionMode", false }; + bool isMoney = _settingSwitch.get(); + + const QString tokenString = !isAuthable ? tokenStringMobile : (isMoney ? tokenStringCommerce : tokenStringMetaverse); + info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit()); } void RequestFilters::interceptFileType(QWebEngineUrlRequestInfo& info) { From 29b717e22d98d2f494b50dbc5a899a3d49888424 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 18 Aug 2017 14:08:04 -0700 Subject: [PATCH 3/3] remove dead code --- interface/src/commerce/QmlCommerce.cpp | 5 +---- interface/src/commerce/QmlCommerce.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index abd0e52f78..b3d6a5e67a 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -1,5 +1,5 @@ // -// Commerce.cpp +// QmlCommerce.cpp // interface/src/commerce // // Created by Howard Stearns on 8/4/17. @@ -37,9 +37,6 @@ void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUser QString key = keys[0]; // For now, we receive at the same key that pays for it. ledger->buy(key, cost, assetId, key, buyerUsername); - // FIXME: until we start talking to server, report post-transaction balance and inventory so we can see log for testing. - /*balance(); - inventory();*/ } void QmlCommerce::balance() { diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index bb067146ba..4112ab7177 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -1,5 +1,5 @@ // -// Commerce.h +// QmlCommerce.h // interface/src/commerce // // Guard for safe use of Commerce (Wallet, Ledger) by authorized QML.