encrypt security image

This commit is contained in:
David Kelly 2017-08-23 15:01:09 -07:00
parent f655bf2713
commit 138534c3ff
13 changed files with 141 additions and 53 deletions

View file

@ -24,7 +24,7 @@ Item {
HifiConstants { id: hifi; }
id: root;
// 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.
@ -36,7 +36,8 @@ Item {
Hifi.QmlCommerce {
id: commerce;
onSecurityImageResult: {
//passphrasePageSecurityImage.source = gridModel.getImagePathFromImageID(imageID);
passphrasePageSecurityImage.source = "";
passphrasePageSecurityImage.source = "image://security/securityImage";
}
onPassphraseSetupStatusResult: {
@ -104,7 +105,8 @@ Item {
width: height;
fillMode: Image.PreserveAspectFit;
mipmap: true;
source: "image://security/securityImage";
cache: false;
onVisibleChanged: {
commerce.getSecurityImage();
}
@ -124,7 +126,7 @@ Item {
color: hifi.colors.faintGray;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}

View file

@ -29,10 +29,14 @@ Item {
id: commerce;
onSecurityImageResult: {
if (image) { // "If security image is set up"
var path = securityImageModel.getImagePathFromImageID(1);
if (exists) { // "If security image is set up"
var path = "image://security/securityImage";
topSecurityImage.source = "";
topSecurityImage.source = path;
changeSecurityImageImage.source = "";
changeSecurityImageImage.source = path;
changePassphraseImage.source = "";
changePassphraseImage.source = path;
}
}
@ -87,6 +91,8 @@ Item {
width: height;
fillMode: Image.PreserveAspectFit;
mipmap: true;
source: "image://security/securityImage";
cache: false;
}
// "Security picture" text below pic
RalewayRegular {
@ -103,7 +109,7 @@ Item {
color: hifi.colors.faintGray;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}
@ -144,8 +150,10 @@ Item {
anchors.left: parent.left;
height: parent.height;
width: height;
source: "image://security/securityImage";
fillMode: Image.PreserveAspectFit;
mipmap: true;
cache: false;
}
// "Change Passphrase" button
HifiControlsUit.Button {
@ -181,6 +189,8 @@ Item {
width: height;
fillMode: Image.PreserveAspectFit;
mipmap: true;
cache: false;
source: "image://security/securityImage";
}
// "Change Security Image" button
HifiControlsUit.Button {

View file

@ -28,17 +28,6 @@ Item {
Hifi.QmlCommerce {
id: commerce;
onSecurityImageResult: {
// for now just hardwire the index
securityImageGrid.currentIndex = 1;
//if (imageID > 0) {
// for (var itr = 0; itr < gridModel.count; itr++) {
// var thisValue = gridModel.get(itr).securityImageEnumValue;
// if (thisValue === imageID) {
// securityImageGrid.currentIndex = itr;
// break;
// }
// }
//}
}
}

View file

@ -38,7 +38,7 @@ Rectangle {
id: commerce;
onSecurityImageResult: {
if (image) { // Success submitting new security image
if (exists) { // Success submitting new security image
if (root.justSubmitted) {
root.resetSubmitButton();
root.visible = false;
@ -183,7 +183,8 @@ Rectangle {
root.justSubmitted = true;
securityImageSubmitButton.text = "Submitting...";
securityImageSubmitButton.enabled = false;
commerce.chooseSecurityImage(securityImageSelection.getImagePathFromImageID(1));
var securityImagePath = securityImageSelection.getImagePathFromImageID(securityImageSelection.getSelectedImageIndex())
commerce.chooseSecurityImage(securityImagePath);
}
}
}

View file

@ -33,7 +33,7 @@ Rectangle {
id: commerce;
onSecurityImageResult: {
if (!image) { // "If security image is not set up"
if (!exists) { // "If security image is not set up"
if (root.activeView !== "notSetUp") {
root.activeView = "notSetUp";
}
@ -104,7 +104,7 @@ Rectangle {
width: walletSetupLightboxContainer.width - 50;
height: walletSetupLightboxContainer.height - 50;
}
//
// TITLE BAR START
@ -226,7 +226,7 @@ Rectangle {
//
// TAB CONTENTS END
//
//
// TAB BUTTONS START
//
@ -283,7 +283,7 @@ Rectangle {
onEntered: parent.color = hifi.colors.blueHighlight;
onExited: parent.color = root.activeView === "walletHome" ? hifi.colors.blueAccent : hifi.colors.black;
}
onVisibleChanged: {
if (visible) {
commerce.getSecurityImage();
@ -382,7 +382,7 @@ Rectangle {
onEntered: parent.color = hifi.colors.blueHighlight;
onExited: parent.color = root.activeView === "security" ? hifi.colors.blueAccent : hifi.colors.black;
}
onVisibleChanged: {
if (visible) {
commerce.getSecurityImage();

View file

@ -22,16 +22,17 @@ import "../../../controls" as HifiControls
Item {
HifiConstants { id: hifi; }
id: root;
Hifi.QmlCommerce {
id: commerce;
onSecurityImageResult: {
if (image) { // "If security image is set up"
var path = securityImageModel.getImagePathFromImageID(1);
securityImage.source = path;
if (exists) {
// just set the source again (to be sure the change was noticed)
securityImage.source = "";
securityImage.source = "image://security/securityImage";
}
}
@ -43,7 +44,7 @@ Item {
SecurityImageModel {
id: securityImageModel;
}
Connections {
target: GlobalServices
onMyUsernameChanged: {
@ -66,7 +67,7 @@ Item {
anchors.left: parent.left;
anchors.right: hfcBalanceContainer.left;
}
// HFC Balance Container
Item {
id: hfcBalanceContainer;
@ -99,8 +100,8 @@ Item {
color: hifi.colors.darkGray;
// Alignment
horizontalAlignment: Text.AlignRight;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
onVisibleChanged: {
if (visible) {
commerce.balance();
@ -124,7 +125,7 @@ Item {
color: hifi.colors.darkGray;
// Alignment
horizontalAlignment: Text.AlignRight;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}
// "balance" text above field
@ -142,7 +143,7 @@ Item {
color: hifi.colors.faintGray;
// Alignment
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}
@ -170,6 +171,8 @@ Item {
width: height;
fillMode: Image.PreserveAspectFit;
mipmap: true;
cache: false;
source: "image://security/securityImage";
}
// "Security picture" text below pic
RalewayRegular {
@ -186,7 +189,7 @@ Item {
color: hifi.colors.faintGray;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}
@ -222,7 +225,7 @@ Item {
anchors.bottomMargin: 8;
anchors.left: parent.left;
anchors.right: parent.right;
// some placeholder stuff
RalewayRegular {
text: homeMessage.visible ? "you <b>CANNOT</b> scroll through this." : "you <b>CAN</b> scroll through this";
@ -234,10 +237,10 @@ Item {
color: hifi.colors.darkGray;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
verticalAlignment: Text.AlignVCenter;
}
}
HifiControlsUit.Button {
id: toggleFullHistoryButton;
color: hifi.buttons.black;
@ -322,7 +325,7 @@ Item {
homeMessageButtons.visible = false;
}
}
}
}
}
//

View file

@ -40,7 +40,7 @@ Rectangle {
}
onSecurityImageResult: {
if (!image && root.lastPage === "securityImage") {
if (!exists && root.lastPage === "securityImage") {
// ERROR! Invalid security image.
securityImageContainer.visible = true;
choosePassphraseContainer.visible = false;
@ -327,7 +327,8 @@ Rectangle {
text: "Next";
onClicked: {
root.lastPage = "securityImage";
commerce.chooseSecurityImage(securityImageSelection.getImagePathFromImageID(1));
var securityImagePath = securityImageSelection.getImagePathFromImageID(securityImageSelection.getSelectedImageIndex())
commerce.chooseSecurityImage(securityImagePath);
securityImageContainer.visible = false;
choosePassphraseContainer.visible = true;
}

View file

@ -183,6 +183,7 @@
#include "ui/UpdateDialog.h"
#include "ui/overlays/Overlays.h"
#include "ui/DomainConnectionModel.h"
#include "ui/ImageProvider.h"
#include "Util.h"
#include "InterfaceParentFinder.h"
#include "ui/OctreeStatsProvider.h"
@ -2144,6 +2145,9 @@ void Application::initializeUi() {
qApp->quit();
});
// register the pixmap image provider (used only for security image, for now)
engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider());
setupPreferences();
// For some reason there is already an "Application" object in the QML context,
@ -3736,7 +3740,7 @@ bool Application::shouldPaint() {
(float)paintDelaySamples / paintDelayUsecs << "us";
}
#endif
// Throttle if requested
if (displayPlugin->isThrottled() && (_lastTimeUpdated.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
return false;
@ -6276,7 +6280,7 @@ bool Application::askToReplaceDomainContent(const QString& url) {
OffscreenUi::warning("Unable to replace content", "You do not have permissions to replace domain content",
QMessageBox::Ok, QMessageBox::Ok);
}
QJsonObject messageProperties = {
QJsonObject messageProperties = {
{ "status", methodDetails },
{ "content_set_url", url }
};
@ -6359,7 +6363,7 @@ void Application::showAssetServerWidget(QString filePath) {
void Application::addAssetToWorldFromURL(QString url) {
qInfo(interfaceapp) << "Download model and add to world from" << url;
QString filename;
if (url.contains("filename")) {
filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL.

View file

@ -29,11 +29,11 @@ public:
signals:
void buyResult(QJsonObject result);
// Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and
// 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(QJsonObject result);
void inventoryResult(QJsonObject result);
void securityImageResult(QPixmap* image);
void securityImageResult(bool exists);
void loginStatusResult(bool isLoggedIn);
void passphraseSetupStatusResult(bool passphraseIsSetup);
void keyFilePathResult(const QString& path);

View file

@ -13,11 +13,14 @@
#include "Ledger.h"
#include "Wallet.h"
#include "Application.h"
#include "ui/ImageProvider.h"
#include <PathUtils.h>
#include <OffscreenUi.h>
#include <QFile>
#include <QCryptographicHash>
#include <QQmlContext>
#include <openssl/ssl.h>
#include <openssl/err.h>
@ -402,10 +405,17 @@ void Wallet::chooseSecurityImage(const QString& filename) {
// encrypt it and save.
if (encryptFile(path, imageFilePath())) {
emit securityImageResult(_securityImage);
qCDebug(commerce) << "emitting pixmap";
// inform the image provider
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
imageProvider->setSecurityImage(_securityImage);
emit securityImageResult(true);
} else {
qCDebug(commerce) << "failed to encrypt security image";
emit securityImageResult(nullptr);
emit securityImageResult(false);
}
}
void Wallet::getSecurityImage() {
@ -414,7 +424,7 @@ void Wallet::getSecurityImage() {
// if already decrypted, don't do it again
if (_securityImage) {
emit securityImageResult(_securityImage);
emit securityImageResult(true);
return;
}
@ -424,10 +434,16 @@ void Wallet::getSecurityImage() {
_securityImage = new QPixmap();
_securityImage->loadFromData(data, dataLen, "jpg");
qCDebug(commerce) << "created pixmap from encrypted file";
emit securityImageResult(_securityImage);
// inform the image provider
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
imageProvider->setSecurityImage(_securityImage);
emit securityImageResult(true);
} else {
qCDebug(commerce) << "failed to decrypt security image (maybe none saved yet?)";
emit securityImageResult(nullptr);
emit securityImageResult(false);
}
}
void Wallet::getKeyFilePath() {

View file

@ -36,7 +36,7 @@ public:
QByteArray getSalt() { return _salt; }
signals:
void securityImageResult(QPixmap* image);
void securityImageResult(bool exists) ;
void keyFilePathResult(const QString& path);
protected:

View file

@ -0,0 +1,29 @@
//
// ImageProvider.cpp
// interface/src/ui
//
// Created by David Kelly on 8/23/2017.
// 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 "ImageProvider.h"
#include <QDebug>
const QString ImageProvider::PROVIDER_NAME = "security";
QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
// adjust the internal pixmap to have the requested size
if (id == "securityImage" && _securityImage) {
*size = _securityImage->size();
if (requestedSize.width() > 0 && requestedSize.height() > 0) {
return _securityImage->scaled(requestedSize.width(), requestedSize.height(), Qt::KeepAspectRatio);
} else {
return _securityImage->copy();
}
}
return QPixmap();
}

View file

@ -0,0 +1,33 @@
//
// ImageProvider.h
//
// Created by David Kelly on 2017/08/23
// 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
//
#pragma once
#ifndef hifi_ImageProvider_h
#define hifi_ImageProvider_h
#include <QQuickImageProvider>
class ImageProvider: public QQuickImageProvider {
public:
static const QString PROVIDER_NAME;
ImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {}
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize);
void setSecurityImage(QPixmap* pixmap) { _securityImage = pixmap; }
protected:
QPixmap* _securityImage;
};
#endif //hifi_ImageProvider_h