Merge PR #929: Drop AWS cloud support

This commit is contained in:
jenkins 2022-12-02 12:15:24 +01:00
commit 67886a68ab
176 changed files with 3 additions and 3180 deletions

View File

@ -33,8 +33,6 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
QSettings settings;
m_discovery = new NymeaDiscovery(this);
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
m_discovery->setAwsClient(AWSClient::instance());
m_engine = new Engine(this);

View File

@ -20,8 +20,6 @@ NymeaAppService::NymeaAppService(int argc, char **argv):
QSettings settings;
NymeaDiscovery *discovery = new NymeaDiscovery(this);
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
discovery->setAwsClient(AWSClient::instance());
settings.beginGroup("ConfiguredHosts");
foreach (const QString &childGroup, settings.childGroups()) {

File diff suppressed because it is too large Load Diff

View File

@ -1,253 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef AWSCLIENT_H
#define AWSCLIENT_H
#include <QObject>
#include <QNetworkRequest>
#include <QDate>
#include <QAbstractListModel>
#include <QPointer>
class QNetworkAccessManager;
class AWSDevice: public QObject {
Q_OBJECT
Q_PROPERTY(QString id READ id CONSTANT)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(bool online READ online NOTIFY onlineChanged)
public:
AWSDevice(const QString &id, const QString &name, bool online = false, QObject *parent = nullptr);
QString id() const;
QString name() const;
void setName(const QString &name);
bool online() const;
void setOnline(bool online);
signals:
void onlineChanged();
void nameChanged();
private:
QString m_id;
QString m_name;
bool m_online;
};
class AWSDevices: public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
public:
enum Roles {
RoleName,
RoleId,
RoleOnline
};
AWSDevices(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
bool busy() const;
void setBusy(bool busy);
Q_INVOKABLE AWSDevice* getDevice(const QString &uuid) const;
Q_INVOKABLE AWSDevice* get(int index) const;
void insert(AWSDevice *device);
void remove(const QString &uuid);
void clear();
signals:
void countChanged();
void busyChanged();
private:
QList<AWSDevice*> m_list;
bool m_busy = false;
};
class AWSConfiguration {
public:
QByteArray clientId;
QString poolId;
QString identityPoolId;
QString certificateEndpoint;
QString certificateApiKey;
QString certificateVendorId;
QString mqttEndpoint;
QString region;
QString apiEndpoint;
QString pushNotificationSystem;
};
class AWSClient : public QObject
{
Q_OBJECT
Q_PROPERTY(bool isLoggedIn READ isLoggedIn NOTIFY isLoggedInChanged)
Q_PROPERTY(QString username READ username NOTIFY isLoggedInChanged)
Q_PROPERTY(bool confirmationPending READ confirmationPending NOTIFY confirmationPendingChanged)
Q_PROPERTY(QString userId READ userId NOTIFY isLoggedInChanged)
Q_PROPERTY(QByteArray idToken READ idToken NOTIFY isLoggedInChanged)
Q_PROPERTY(AWSDevices* awsDevices READ awsDevices CONSTANT)
Q_PROPERTY(QStringList availableConfigs READ availableConfigs CONSTANT)
Q_PROPERTY(QString config READ config WRITE setConfig NOTIFY configChanged)
public:
enum LoginError {
LoginErrorNoError,
LoginErrorInvalidUserOrPass,
LoginErrorInvalidCode,
LoginErrorUserExists,
LoginErrorLimitExceeded,
LoginErrorUnknownError,
LoginErrorNetworkError
};
Q_ENUM(LoginError)
static AWSClient* instance();
bool isLoggedIn() const;
QString username() const;
QString userId() const;
AWSDevices* awsDevices() const;
bool confirmationPending() const;
Q_INVOKABLE bool login(const QString &username, const QString &password);
Q_INVOKABLE void logout();
Q_INVOKABLE void signup(const QString &username, const QString &password);
Q_INVOKABLE void confirmRegistration(const QString &code);
Q_INVOKABLE void forgotPassword(const QString &username);
Q_INVOKABLE void confirmForgotPassword(const QString &username, const QString &code, const QString &newPassword);
Q_INVOKABLE void deleteAccount();
Q_INVOKABLE void unpairDevice(const QString &coreId);
Q_INVOKABLE void fetchDevices();
Q_INVOKABLE bool postToMQTT(const QString &coreId, const QString &nonce, QPointer<QObject> sender, std::function<void(bool)> callback);
Q_INVOKABLE void getId();
Q_INVOKABLE void registerPushNotificationEndpoint(const QString &registrationId, const QString &deviceDisplayName, const QString mobileDeviceId, const QString &mobileDeviceManufacturer, const QString &mobileDeviceModel);
bool tokensExpired() const;
QByteArray idToken() const;
QString cognitoIdentityId() const;
void fetchCertificate(const QString &uuid, std::function<void(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint)> callback);
QStringList availableConfigs() const;
QString config() const;
void setConfig(const QString &config);
signals:
void loginResult(LoginError error);
void signupResult(LoginError error);
void confirmationResult(LoginError error);
void forgotPasswordResult(LoginError error);
void confirmForgotPasswordResult(LoginError error);
void deleteAccountResult(LoginError error);
void isLoggedInChanged();
void confirmationPendingChanged();
void devicesFetched();
void configChanged();
private:
explicit AWSClient(QObject *parent = nullptr);
static AWSClient* s_instance;
bool refreshAccessToken();
void getCredentialsForIdentity(const QString &identityId);
void connectMQTT();
private:
QNetworkAccessManager *m_nam = nullptr;
QString m_userId;
QString m_username;
QString m_password;
bool m_loginInProgress = false;
bool m_confirmationPending = false;
QByteArray m_accessToken;
QDateTime m_accessTokenExpiry;
QByteArray m_idToken;
QByteArray m_refreshToken;
QByteArray m_identityId;
QByteArray m_accessKeyId;
QByteArray m_secretKey;
QByteArray m_sessionToken;
QDateTime m_sessionTokenExpiry;
class QueuedCall {
public:
QueuedCall(const QString &method): method(method) { }
QueuedCall(const QString &method, const QString &arg1): method(method), arg1(arg1) { }
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, const QString &arg3, const QString &arg4, const QString &arg5): method(method), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) { }
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, QPointer<QObject> sender, std::function<void(bool)> callback): method(method), arg1(arg1), arg2(arg2), sender(sender), callback(callback) {}
QString method;
QString arg1;
QString arg2;
QString arg3;
QString arg4;
QString arg5;
QPointer<QObject> sender;
std::function<void(bool)> callback;
static void enqueue(QList<QueuedCall> &queue, const QueuedCall &call) {
foreach (const QueuedCall &existingCall, queue) {
if (existingCall.method == call.method &&
existingCall.arg1 == call.arg1 &&
existingCall.arg2 == call.arg2 &&
existingCall.arg3 == call.arg3 &&
&existingCall.callback == &call.callback) {
return; // Already in queue
}
}
queue.append(call);
}
};
void cancelCallQueue();
QList<QueuedCall> m_callQueue;
QHash<QString, AWSConfiguration> m_configs;
QString m_usedConfig = "";
AWSDevices *m_devices;
};
#endif // AWSCLIENT_H

View File

@ -1,165 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudtransport.h"
#include "awsclient.h"
#include "remoteproxyconnection.h"
#include <QUrlQuery>
#include <QHostInfo>
#include <QPointer>
#include <QCoreApplication>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcCloud)
using namespace remoteproxyclient;
CloudTransport::CloudTransport(AWSClient *awsClient, QObject *parent):
NymeaTransportInterface(parent),
m_awsClient(awsClient)
{
m_remoteproxyConnection = new RemoteProxyConnection(QUuid::createUuid(), qApp->applicationName(), this);
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::remoteConnectionEstablished, this,[this]() {
qCDebug(dcCloud) << "CloudTransport: Remote connection established.";
emit connected();
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::disconnected, this,[this]() {
qCDebug(dcCloud) << "CloudTransport: Disconnected.";
emit disconnected();
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::stateChanged, this,[](RemoteProxyConnection::State state) {
qCDebug(dcCloud) << "Proxy state changed:" << state;
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::ready, this,[this]() {
qCDebug(dcCloud) << "Proxy ready. Authenticating channel.";
m_remoteproxyConnection->authenticate(m_awsClient->idToken(), m_nonce);
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::dataReady, this, [this](const QByteArray &data) {
emit dataReady(data);
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::errorOccurred, this, [] (QAbstractSocket::SocketError error) {
qCDebug(dcCloud) << "Remote proxy Error:" << error;
// emit NymeaTransportInterface::error(QAbstractSocket::ConnectionRefusedError);
});
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::sslErrors, this, &CloudTransport::sslErrors);
}
bool CloudTransport::connect(const QUrl &url)
{
if (!m_awsClient->isLoggedIn()) {
qWarning() << "Not logged in to AWS, cannot connect";
return false;
}
qCDebug(dcCloud) << "Connecting to" << url;
m_url = url;
m_nonce = QUuid::createUuid().toString();
bool postResult = m_awsClient->postToMQTT(url.host(), m_nonce, QPointer<QObject>(this), [this](bool success) {
if (success) {
qCDebug(dcCloud) << "MQTT Post done. Connecting to remote proxy";
m_remoteproxyConnection->connectServer(QUrl("wss://remoteproxy.nymea.io"));
} else {
qCDebug(dcCloud) << "Posting to MQTT failed";
emit error(QAbstractSocket::HostNotFoundError);
}
});
if (!postResult) {
qWarning() << "Failed to post to MQTT. Cannot continue";
return false;
}
return true;
}
QUrl CloudTransport::url() const
{
return m_url;
}
void CloudTransport::disconnect()
{
qCDebug(dcCloud) << "CloudTransport: Disconnecting from server.";
m_remoteproxyConnection->disconnectServer();
}
NymeaTransportInterface::ConnectionState CloudTransport::connectionState() const
{
switch (m_remoteproxyConnection->state()) {
case RemoteProxyConnection::StateRemoteConnected:
return NymeaTransportInterface::ConnectionStateConnected;
case RemoteProxyConnection::StateInitializing:
case RemoteProxyConnection::StateHostLookup:
case RemoteProxyConnection::StateConnecting:
case RemoteProxyConnection::StateConnected:
case RemoteProxyConnection::StateAuthenticating:
case RemoteProxyConnection::StateReady:
case RemoteProxyConnection::StateAuthenticated:
return NymeaTransportInterface::ConnectionStateConnecting;
case RemoteProxyConnection::StateDisconnected:
case RemoteProxyConnection::StateDiconnecting:
return NymeaTransportInterface::ConnectionStateDisconnected;
}
return ConnectionStateDisconnected;
}
void CloudTransport::sendData(const QByteArray &data)
{
// qCDebug(dcCloud) << "Cloud transport: Sending data:" << data;
m_remoteproxyConnection->sendData(data);
}
void CloudTransport::ignoreSslErrors(const QList<QSslError> &errors)
{
qCDebug(dcCloud) << "CloudTransport: Ignoring SSL errors" << errors;
m_remoteproxyConnection->ignoreSslErrors(errors);
}
CloudTransportFactory::CloudTransportFactory()
{
}
NymeaTransportInterface *CloudTransportFactory::createTransport(QObject *parent) const
{
return new CloudTransport(AWSClient::instance(), parent);
}
QStringList CloudTransportFactory::supportedSchemes() const
{
return {"cloud"};
}

View File

@ -1,72 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDTRANSPORT_H
#define CLOUDTRANSPORT_H
#include "nymeatransportinterface.h"
#include <QObject>
#include <QUrl>
class AWSClient;
namespace remoteproxyclient {
class RemoteProxyConnection;
}
class CloudTransportFactory: public NymeaTransportInterfaceFactory
{
public:
CloudTransportFactory();
NymeaTransportInterface* createTransport(QObject *parent = nullptr) const override;
QStringList supportedSchemes() const override;
};
class CloudTransport : public NymeaTransportInterface
{
Q_OBJECT
public:
explicit CloudTransport(AWSClient *awsClient, QObject *parent = nullptr);
bool connect(const QUrl &url) override;
QUrl url() const override;
void disconnect() override;
ConnectionState connectionState() const override;
void sendData(const QByteArray &data) override;
void ignoreSslErrors(const QList<QSslError> &errors) override;
private:
QUrl m_url;
AWSClient *m_awsClient = nullptr;
remoteproxyclient::RemoteProxyConnection *m_remoteproxyConnection = nullptr;
QString m_nonce;
};
#endif // CLOUDTRANSPORT_H

View File

@ -32,7 +32,6 @@
#include "upnpdiscovery.h"
#include "zeroconfdiscovery.h"
#include "bluetoothservicediscovery.h"
#include "connection/awsclient.h"
#include "../nymeahost.h"
#include <QUuid>
@ -50,14 +49,6 @@ NymeaDiscovery::NymeaDiscovery(QObject *parent) : QObject(parent)
m_nymeaHosts = new NymeaHosts(this);
loadFromDisk();
m_cloudPollTimer.setInterval(5000);
connect(&m_cloudPollTimer, &QTimer::timeout, this, [this](){
if (m_awsClient && m_awsClient->isLoggedIn()) {
m_awsClient->fetchDevices();
}
});
}
NymeaDiscovery::~NymeaDiscovery()
@ -98,12 +89,6 @@ void NymeaDiscovery::setDiscovering(bool discovering)
m_bluetooth->discover();
}
// start polling cloud
m_cloudPollTimer.start();
// If we're logged in, poll right away
if (m_awsClient && m_awsClient->isLoggedIn()) {
m_awsClient->fetchDevices();
}
} else {
if (m_upnp) {
@ -113,8 +98,6 @@ void NymeaDiscovery::setDiscovering(bool discovering)
if (m_bluetooth) {
m_bluetooth->stopDiscovery();
}
m_cloudPollTimer.stop();
}
emit discoveringChanged();
@ -125,23 +108,6 @@ NymeaHosts *NymeaDiscovery::nymeaHosts() const
return m_nymeaHosts;
}
AWSClient *NymeaDiscovery::awsClient() const
{
return m_awsClient;
}
void NymeaDiscovery::setAwsClient(AWSClient *awsClient)
{
if (m_awsClient != awsClient) {
m_awsClient = awsClient;
emit awsClientChanged();
}
if (m_awsClient) {
connect(m_awsClient, &AWSClient::devicesFetched, this, &NymeaDiscovery::syncCloudDevices);
}
}
void NymeaDiscovery::cacheHost(NymeaHost *host)
{
QSettings settings;
@ -231,52 +197,6 @@ void NymeaDiscovery::setUpnpDiscoveryEnabled(bool upnpDiscoveryEnabled)
}
}
void NymeaDiscovery::syncCloudDevices()
{
for (int i = 0; i < m_awsClient->awsDevices()->rowCount(); i++) {
AWSDevice *d = m_awsClient->awsDevices()->get(i);
NymeaHost *host = m_nymeaHosts->find(d->id());
bool alreayAdded = host != nullptr;
if (!alreayAdded) {
host = new NymeaHost();
host->setUuid(d->id());
}
host->setName(d->name());
QUrl url;
url.setScheme("cloud");
url.setHost(d->id());
Connection *conn = host->connections()->find(url);
if (!conn) {
conn = new Connection(url, Connection::BearerTypeCloud, true, d->id());
qCDebug(dcDiscovery) << "Adding new connection to host:" << host->name() << conn->url().toString();
host->connections()->addConnection(conn);
}
conn->setOnline(d->online());
if (!alreayAdded) {
qCDebug(dcDiscovery) << "Adding new host:" << d->name() << d->id();
m_nymeaHosts->addHost(host);
}
}
QList<NymeaHost*> hostsToRemove;
for (int i = 0; i < m_nymeaHosts->rowCount(); i++) {
NymeaHost *host = m_nymeaHosts->get(i);
for (int j = 0; j < host->connections()->rowCount(); j++) {
if (host->connections()->get(j)->bearerType() == Connection::BearerTypeCloud) {
if (m_awsClient->awsDevices()->getDevice(host->uuid().toString()) == nullptr) {
host->connections()->removeConnection(j);
break;
}
}
}
if (host->connections()->rowCount() == 0) {
hostsToRemove.append(host);
}
}
while (!hostsToRemove.isEmpty()) {
m_nymeaHosts->removeHost(hostsToRemove.takeFirst());
}
}
void NymeaDiscovery::loadFromDisk()
{

View File

@ -35,7 +35,6 @@
#include <QTimer>
#include <QUuid>
#include "connection/awsclient.h"
#include "connection/nymeahost.h"
class NymeaHosts;
@ -52,8 +51,6 @@ class NymeaDiscovery : public QObject
Q_PROPERTY(bool zeroconfDiscoveryEnabled READ zeroconfDiscoveryEnable WRITE setZeroconfDiscoveryEnabled NOTIFY zeroconfDiscoveryEnabledChanged)
Q_PROPERTY(bool upnpDiscoveryEnabled READ upnpDiscoveryEnabled WRITE setUpnpDiscoveryEnabled NOTIFY upnpDiscoveryEnabledChanged)
Q_PROPERTY(AWSClient* awsClient READ awsClient WRITE setAwsClient NOTIFY awsClientChanged)
Q_PROPERTY(NymeaHosts* nymeaHosts READ nymeaHosts CONSTANT)
public:
@ -65,9 +62,6 @@ public:
NymeaHosts *nymeaHosts() const;
AWSClient* awsClient() const;
void setAwsClient(AWSClient *awsClient);
Q_INVOKABLE void cacheHost(NymeaHost* host);
bool zeroconfDiscoveryEnable() const;
@ -81,7 +75,6 @@ public slots:
signals:
void discoveringChanged();
void awsClientChanged();
void serverUuidResolved(const QUuid &uuid, const QString &url);
@ -90,8 +83,6 @@ signals:
void upnpDiscoveryEnabledChanged(bool upnpDiscoveryEnabled);
private slots:
void syncCloudDevices();
void loadFromDisk();
void updateActiveBearers();
@ -100,14 +91,10 @@ private:
bool m_discovering = false;
NymeaHosts *m_nymeaHosts = nullptr;
AWSClient *m_awsClient = nullptr;
UpnpDiscovery *m_upnp = nullptr;
ZeroconfDiscovery *m_zeroConf = nullptr;
BluetoothServiceDiscovery *m_bluetooth = nullptr;
QTimer m_cloudPollTimer;
QList<QUuid> m_pendingHostResolutions;
bool m_zeroconfDiscoveryEnabled = true;

View File

@ -1,177 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "sigv4utils.h"
#include <QDateTime>
#include <QCryptographicHash>
#include <QMessageAuthenticationCode>
#include <QtDebug>
#include <QUrlQuery>
#include <QList>
SigV4Utils::SigV4Utils()
{
}
void SigV4Utils::signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString &region, const QString &service, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray &payload)
{
QByteArray dateTime;
if (request.rawHeaderList().contains("X-Amz-Date")) {
dateTime = request.rawHeader("X-AMZ-Date");
} else {
dateTime = SigV4Utils::getCurrentDateTime();
request.setRawHeader("X-Amz-Date", dateTime);
}
if (!sessionToken.isEmpty()) {
request.setRawHeader("x-amz-security-token", sessionToken);
}
QByteArray canonicalRequest = SigV4Utils::getCanonicalRequest(operation, request, payload);
// qDebug() << "canonical request:" << qUtf8Printable(canonicalRequest);
QByteArray stringToSign = SigV4Utils::getStringToSign(canonicalRequest, dateTime, region.toUtf8(), service.toUtf8());
// qDebug() << "string to sign:" << stringToSign;
QByteArray signature = SigV4Utils::getSignature(stringToSign, secretAccessKey, dateTime, region, service);
// qDebug() << "signature:" << signature;
QByteArray authorizeHeader = SigV4Utils::getAuthorizationHeader(accessKeyId, dateTime, region, service, request, signature);
request.setRawHeader("Authorization", authorizeHeader);
}
QByteArray SigV4Utils::getCurrentDateTime()
{
return QDateTime::currentDateTime().toUTC().toString("yyyyMMddThhmmssZ").toUtf8();
}
QByteArray SigV4Utils::getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray &region, const QByteArray &service, const QByteArray &payload)
{
QByteArray algorithm = "AWS4-HMAC-SHA256";
QByteArray dateTime = getCurrentDateTime();
QByteArray credentialScope = getCredentialScope(dateTime, region, service);
QByteArray canonicalQueryString;
canonicalQueryString += "X-Amz-Algorithm=AWS4-HMAC-SHA256";
canonicalQueryString += "&X-Amz-Credential=" + QByteArray(accessKeyId + '/' + credentialScope).toPercentEncoding();
canonicalQueryString += "&X-Amz-Date=" + dateTime;
if (request.rawHeaderList().count() > 0){
canonicalQueryString += "&X-Amz-SignedHeaders=" + request.rawHeaderList().join(';').toLower();
}
QByteArray canonicalRequest = getCanonicalRequest(QNetworkAccessManager::GetOperation, request, payload);
QByteArray stringToSign = getStringToSign(canonicalRequest, dateTime, region, service);
QByteArray signature = getSignature(stringToSign, secretAccessKey, dateTime, region, service);
canonicalQueryString += "&X-Amz-Signature=" + signature;
if (!sessionToken.isEmpty()) {
canonicalQueryString += "&X-Amz-Security-Token=" + sessionToken.toPercentEncoding();
}
return canonicalQueryString;
}
QByteArray SigV4Utils::getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray &region, const QByteArray &service)
{
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
return QMessageAuthenticationCode::hash("aws4_request",
QMessageAuthenticationCode::hash(service,
QMessageAuthenticationCode::hash(region,
QMessageAuthenticationCode::hash(date, "AWS4"+key,
hashAlgorithm), hashAlgorithm), hashAlgorithm), hashAlgorithm);
}
QByteArray SigV4Utils::getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload)
{
QByteArray canonicalRequest;
QByteArray method;
switch (operation) {
case QNetworkAccessManager::GetOperation:
method = "GET";
break;
case QNetworkAccessManager::PostOperation:
method = "POST";
break;
default:
Q_ASSERT_X(false, "Network operation not implemented", "SigV4Utils");
}
QByteArray uri = request.url().path(QUrl::FullyEncoded).toUtf8();
QUrlQuery query(request.url());
QList<QPair<QString, QString> > queryItems = query.queryItems();
QStringList queryItemStrings;
for (int i = 0; i < queryItems.count(); i++) {
QPair<QString, QString> queryItem = queryItems.at(i);
queryItemStrings.append(queryItem.first + '=' + queryItem.second);
}
queryItemStrings.sort(Qt::CaseInsensitive);
QByteArray canonicalQueryString = queryItemStrings.join('&').toUtf8();
QByteArray canonicalHeaders;
foreach(const QByteArray &headerName, request.rawHeaderList()) {
canonicalHeaders += headerName.toLower() + ':' + request.rawHeader(headerName) + '\n';
}
QByteArray payloadHash = QCryptographicHash::hash(payload, QCryptographicHash::Sha256).toHex();
canonicalRequest = method + '\n' + uri + '\n' + canonicalQueryString + '\n' + canonicalHeaders + '\n' + request.rawHeaderList().join(';').toLower() + '\n' + payloadHash;
return canonicalRequest;
}
QByteArray SigV4Utils::getCredentialScope(const QByteArray &dateTime, const QByteArray &region, const QByteArray &service)
{
QByteArray credentialScope = dateTime.left(8) + '/' + region + '/' + service + "/aws4_request";
return credentialScope;
}
QByteArray SigV4Utils::getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray &region, const QByteArray &service)
{
QByteArray algorithm = "AWS4-HMAC-SHA256";
QByteArray credentialScope = getCredentialScope(dateTime, region, service);
QByteArray stringToSign = algorithm + '\n' + dateTime + '\n' + credentialScope + '\n' + QCryptographicHash::hash(canonicalRequest, QCryptographicHash::Sha256).toHex();
return stringToSign;
}
QByteArray SigV4Utils::getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString &region, const QString &service)
{
QByteArray signingKey = getSignatureKey(secretAccessKey, dateTime.left(8), region.toUtf8(), service.toUtf8());
QByteArray signature = QMessageAuthenticationCode::hash(stringToSign, signingKey, QCryptographicHash::Sha256).toHex();
return signature;
}
QByteArray SigV4Utils::getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString &region, const QString &service, const QNetworkRequest &request, const QByteArray &signature)
{
QByteArray authHeader = "AWS4-HMAC-SHA256 Credential=" + accessKeyId + '/' + dateTime.left(8) + '/' + region.toUtf8() + '/' + service.toUtf8() + '/' + "aws4_request, SignedHeaders=" + request.rawHeaderList().join(';').toLower() + ", Signature=" + signature;
return authHeader;
}

View File

@ -1,61 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef SIGV4UTILS_H
#define SIGV4UTILS_H
#include <QString>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
class SigV4Utils
{
public:
SigV4Utils();
// Signes a request by adding the "X-AMZ-Date" (if not present) and "X-AMZ-Signature" headers
static void signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString &region, const QString &service, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken = QByteArray(), const QByteArray &payload = QByteArray());
static QByteArray getCurrentDateTime();
static QByteArray getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray &region, const QByteArray &service, const QByteArray &payload);
static QByteArray getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload);
static QByteArray getCanonicalHeaders(const QNetworkRequest &request);
static QByteArray getCredentialScope(const QByteArray &dateTime, const QByteArray &region, const QByteArray &service);
static QByteArray getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray &region, const QByteArray &service);
static QByteArray getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray &region, const QByteArray &service);
static QByteArray getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString &region, const QString &service);
static QByteArray getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString &region, const QString &service, const QNetworkRequest &request, const QByteArray &signature);
};
#endif // SIGV4UTILS_H

View File

@ -35,7 +35,6 @@
#include "logmanager.h"
#include "tagsmanager.h"
#include "configuration/nymeaconfiguration.h"
#include "connection/awsclient.h"
#include "system/systemcontroller.h"
#include "configuration/networkmanager.h"
@ -56,19 +55,7 @@ Engine::Engine(QObject *parent) :
connect(m_thingManager, &ThingManager::fetchingDataChanged, this, &Engine::onThingManagerFetchingChanged);
connect(m_jsonRpcClient, &JsonRpcClient::connectedChanged, this, [this]() {
qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected() << "AWS status:" << AWSClient::instance()->awsDevices()->rowCount();
if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) {
if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid()) == nullptr) {
m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId());
}
}
});
connect(m_jsonRpcClient, &JsonRpcClient::cloudConnectionStateChanged, this, [this](){
if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) {
if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid()) == nullptr) {
m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId());
}
}
qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected();
});
}
@ -112,22 +99,6 @@ SystemController *Engine::systemController() const
return m_systemController;
}
void Engine::deployCertificate()
{
if (!m_jsonRpcClient->connected()) {
qWarning() << "JSONRPC not connected. Cannot deploy certificate";
return;
}
if (!AWSClient::instance()->isLoggedIn()) {
qWarning() << "Not logged in at AWS. Cannot deploy certificate";
return;
}
AWSClient::instance()->fetchCertificate(m_jsonRpcClient->serverUuid(), [this](const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint){
qDebug() << "Certificate received" << certificate << publicKey << privateKey;
m_jsonRpcClient->deployCertificate(rootCA, certificate, publicKey, privateKey, endpoint);
});
}
void Engine::onConnectedChanged()
{
qDebug() << "Engine: connected changed:" << m_jsonRpcClient->connected();

View File

@ -68,8 +68,6 @@ public:
NymeaConfiguration *nymeaConfiguration() const;
SystemController *systemController() const;
Q_INVOKABLE void deployCertificate();
private:
JsonRpcClient *m_jsonRpcClient;
ThingManager *m_thingManager;

View File

@ -36,7 +36,6 @@
#include "connection/tcpsockettransport.h"
#include "connection/websockettransport.h"
#include "connection/bluetoothtransport.h"
#include "connection/cloudtransport.h"
#include "connection/tunnelproxytransport.h"
#include <QJsonDocument>
@ -61,7 +60,6 @@ JsonRpcClient::JsonRpcClient(QObject *parent) :
m_connection->registerTransport(new TcpSocketTransportFactory());
m_connection->registerTransport(new WebsocketTransportFactory());
m_connection->registerTransport(new BluetoothTransportFactoy());
m_connection->registerTransport(new CloudTransportFactory());
m_connection->registerTransport(new TunnelProxyTransportFactory());
connect(m_connection, &NymeaConnection::availableBearerTypesChanged, this, &JsonRpcClient::availableBearerTypesChanged);
@ -174,13 +172,6 @@ bool JsonRpcClient::tokenExists(const QString &serverUuid) const
return settings.contains(QUuid(serverUuid).toString());
}
void JsonRpcClient::getCloudConnectionStatus()
{
JsonRpcReply *reply = createReply("JSONRPC.IsCloudConnected", QVariantMap(), this, "isCloudConnectedReply");
m_replies.insert(reply->commandId(), reply);
sendRequest(reply->requestMap());
}
void JsonRpcClient::setNotificationsEnabledResponse(int commandId, const QVariantMap &params)
{
qCDebug(dcJsonRpc()) << "Notification configuration response:" << commandId << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
@ -224,34 +215,9 @@ void JsonRpcClient::notificationReceived(const QVariantMap &data)
return;
}
if (data.value("notification").toString() == "JSONRPC.CloudConnectedChanged") {
QMetaEnum connectionStateEnum = QMetaEnum::fromType<CloudConnectionState>();
m_cloudConnectionState = static_cast<CloudConnectionState>(connectionStateEnum.keyToValue(data.value("params").toMap().value("connectionState").toByteArray().data()));
emit cloudConnectionStateChanged();
return;
}
qCWarning(dcJsonRpc()) << "JsonRpcClient: Unhandled notification received" << data;
}
void JsonRpcClient::isCloudConnectedReply(int /*commandId*/, const QVariantMap &data)
{
// qDebug() << "Cloud is connected" << data;
QMetaEnum connectionStateEnum = QMetaEnum::fromType<CloudConnectionState>();
m_cloudConnectionState = static_cast<CloudConnectionState>(connectionStateEnum.keyToValue(data.value("connectionState").toByteArray().data()));
emit cloudConnectionStateChanged();
}
void JsonRpcClient::setupRemoteAccessReply(int commandId, const QVariantMap &data)
{
qDebug() << "Setup Remote Access reply" << commandId << data;
}
void JsonRpcClient::deployCertificateReply(int commandId, const QVariantMap &data)
{
qDebug() << "deploy certificate reply:" << commandId << data;
}
void JsonRpcClient::getVersionsReply(int /*commandId*/, const QVariantMap &data)
{
m_serverQtVersion = data.value("qtVersion").toString();
@ -317,23 +283,6 @@ bool JsonRpcClient::authenticated() const
return m_authenticated;
}
JsonRpcClient::CloudConnectionState JsonRpcClient::cloudConnectionState() const
{
return m_cloudConnectionState;
}
void JsonRpcClient::deployCertificate(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint)
{
QVariantMap params;
params.insert("rootCA", rootCA);
params.insert("certificatePEM", certificate);
params.insert("publicKey", publicKey);
params.insert("privateKey", privateKey);
params.insert("endpoint", endpoint);
sendCommand("JSONRPC.SetupCloudConnection", params, this, "deployCertificateReply");
}
QHash<QString, QString> JsonRpcClient::cacheHashes() const
{
return m_cacheHashes;
@ -424,15 +373,6 @@ int JsonRpcClient::requestPushButtonAuth(const QString &deviceName)
return reply->commandId();
}
int JsonRpcClient::setupRemoteAccess(const QString &idToken, const QString &userId)
{
qDebug() << "Calling SetupRemoteAccess";
QVariantMap params;
params.insert("idToken", idToken);
params.insert("userId", userId);
return sendCommand("JSONRPC.SetupRemoteAccess", params, this, "setupRemoteAccessReply");
}
bool JsonRpcClient::ensureServerVersion(const QString &jsonRpcVersion)
{
return QVersionNumber(m_jsonRpcVersion) >= QVersionNumber::fromString(jsonRpcVersion);
@ -731,7 +671,7 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap &params)
}
QVersionNumber minimumRequiredVersion = QVersionNumber(5, 0);
QVersionNumber maximumMajorVersion = QVersionNumber(6);
QVersionNumber maximumMajorVersion = QVersionNumber(7);
if (m_jsonRpcVersion < minimumRequiredVersion) {
qCWarning(dcJsonRpc()) << "Nymea core doesn't support minimum required version. Required:" << minimumRequiredVersion << "Found:" << m_jsonRpcVersion;
emit invalidMinimumVersion(m_jsonRpcVersion.toString(), minimumRequiredVersion.toString());
@ -829,8 +769,6 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap &params)
}
setNotificationsEnabled();
getCloudConnectionStatus();
}
JsonRpcReply::JsonRpcReply(int commandId, QString nameSpace, QString method, QVariantMap params, QPointer<QObject> caller, const QString &callback):

View File

@ -55,7 +55,6 @@ class JsonRpcClient : public QObject
Q_PROPERTY(bool authenticationRequired READ authenticationRequired NOTIFY authenticationRequiredChanged)
Q_PROPERTY(bool pushButtonAuthAvailable READ pushButtonAuthAvailable NOTIFY pushButtonAuthAvailableChanged)
Q_PROPERTY(bool authenticated READ authenticated NOTIFY authenticatedChanged)
Q_PROPERTY(CloudConnectionState cloudConnectionState READ cloudConnectionState NOTIFY cloudConnectionStateChanged)
Q_PROPERTY(QString serverVersion READ serverVersion NOTIFY handshakeReceived)
Q_PROPERTY(QString jsonRpcVersion READ jsonRpcVersion NOTIFY handshakeReceived)
Q_PROPERTY(QString serverUuid READ serverUuid NOTIFY handshakeReceived)
@ -67,14 +66,6 @@ class JsonRpcClient : public QObject
Q_PROPERTY(UserInfo::PermissionScopes permissions READ permissions NOTIFY permissionsChanged)
public:
enum CloudConnectionState {
CloudConnectionStateDisabled,
CloudConnectionStateUnconfigured,
CloudConnectionStateConnecting,
CloudConnectionStateConnected
};
Q_ENUM(CloudConnectionState)
explicit JsonRpcClient(QObject *parent = nullptr);
void registerNotificationHandler(QObject *handler, const QString &nameSpace, const QString &method);
@ -93,8 +84,6 @@ public:
bool authenticationRequired() const;
bool pushButtonAuthAvailable() const;
bool authenticated() const;
CloudConnectionState cloudConnectionState() const;
void deployCertificate(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint);
QHash<QString, QString> cacheHashes() const;
// Note: This does not reflect the actual permission scopes of the user but is translated to effective permissions
// That, is, if the user has the admin permission, all of the other scopes will be set too even if they might not be explicitly set
@ -119,7 +108,6 @@ public:
Q_INVOKABLE int createUser(const QString &username, const QString &password, const QString &displayName, const QString &email);
Q_INVOKABLE int authenticate(const QString &username, const QString &password, const QString &deviceName);
Q_INVOKABLE int requestPushButtonAuth(const QString &deviceName);
Q_INVOKABLE int setupRemoteAccess(const QString &idToken, const QString &userId);
signals:
@ -142,7 +130,6 @@ signals:
void pushButtonAuthFailed();
void createUserSucceeded();
void createUserFailed(const QString &error);
void cloudConnectionStateChanged();
void serverQtVersionChanged();
void serverNameChanged();
void permissionsChanged();
@ -170,7 +157,6 @@ private:
bool m_authenticationRequired = false;
bool m_pushButtonAuthAvailable = false;
bool m_authenticated = false;
CloudConnectionState m_cloudConnectionState = CloudConnectionStateDisabled;
int m_pendingPushButtonTransaction = -1;
QString m_serverUuid;
QVersionNumber m_jsonRpcVersion;
@ -185,7 +171,6 @@ private:
QString m_username;
void setNotificationsEnabled();
void getCloudConnectionStatus();
// json handler
Q_INVOKABLE void processAuthenticate(int commandId, const QVariantMap &data);
@ -194,9 +179,6 @@ private:
Q_INVOKABLE void setNotificationsEnabledResponse(int commandId, const QVariantMap &params);
Q_INVOKABLE void notificationReceived(const QVariantMap &data);
Q_INVOKABLE void isCloudConnectedReply(int commandId, const QVariantMap &data);
Q_INVOKABLE void setupRemoteAccessReply(int commandId, const QVariantMap &data);
Q_INVOKABLE void deployCertificateReply(int commandId, const QVariantMap &data);
Q_INVOKABLE void getVersionsReply(int commandId, const QVariantMap &data);
void sendRequest(const QVariantMap &request);

View File

@ -93,7 +93,6 @@
#include "ruletemplates/statedescriptortemplate.h"
#include "ruletemplates/ruleactiontemplate.h"
#include "ruletemplates/ruleactionparamtemplate.h"
#include "connection/awsclient.h"
#include "models/thingmodel.h"
#include "models/sortfilterproxymodel.h"
#include "system/systemcontroller.h"
@ -156,14 +155,6 @@ static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEn
return new Interfaces();
}
static QObject* awsClientProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return AWSClient::instance();
}
static QObject* typesProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
@ -297,9 +288,6 @@ void registerQmlTypes() {
qmlRegisterUncreatableType<WirelessAccessPoints>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
qmlRegisterType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPointsProxy");
qmlRegisterSingletonType<AWSClient>(uri, 1, 0, "AWSClient", awsClientProvider);
qmlRegisterUncreatableType<AWSDevice>(uri, 1, 0, "AWSDevice", "Can't create this in QML. Get it from AWSClient");
qmlRegisterType<RuleTemplates>(uri, 1, 0, "RuleTemplates");
qmlRegisterType<RuleTemplatesFilterModel>(uri, 1, 0, "RuleTemplatesFilterModel");
qmlRegisterUncreatableType<RuleTemplate>(uri, 1, 0, "RuleTemplate", "Get them from RuleTemplates");

View File

@ -124,7 +124,6 @@ SOURCES += \
$${PWD}/connection/websockettransport.cpp \
$${PWD}/connection/tcpsockettransport.cpp \
$${PWD}/connection/bluetoothtransport.cpp \
$${PWD}/connection/awsclient.cpp \
$${PWD}/connection/discovery/nymeadiscovery.cpp \
$${PWD}/connection/discovery/upnpdiscovery.cpp \
$${PWD}/connection/discovery/zeroconfdiscovery.cpp \
@ -165,8 +164,6 @@ SOURCES += \
$${PWD}/ruletemplates/ruleactiontemplate.cpp \
$${PWD}/ruletemplates/stateevaluatortemplate.cpp \
$${PWD}/ruletemplates/statedescriptortemplate.cpp \
$${PWD}/connection/cloudtransport.cpp \
$${PWD}/connection/sigv4utils.cpp \
$${PWD}/ruletemplates/ruleactionparamtemplate.cpp \
$${PWD}/configuration/serverconfiguration.cpp \
$${PWD}/configuration/serverconfigurations.cpp \
@ -290,8 +287,6 @@ HEADERS += \
$${PWD}/connection/websockettransport.h \
$${PWD}/connection/tcpsockettransport.h \
$${PWD}/connection/bluetoothtransport.h \
$${PWD}/connection/awsclient.h \
$${PWD}/connection/sigv4utils.h \
$${PWD}/connection/discovery/nymeadiscovery.h \
$${PWD}/connection/discovery/upnpdiscovery.h \
$${PWD}/connection/discovery/zeroconfdiscovery.h \
@ -333,7 +328,6 @@ HEADERS += \
$${PWD}/ruletemplates/ruleactiontemplate.h \
$${PWD}/ruletemplates/stateevaluatortemplate.h \
$${PWD}/ruletemplates/statedescriptortemplate.h \
$${PWD}/connection/cloudtransport.h \
$${PWD}/ruletemplates/ruleactionparamtemplate.h \
$${PWD}/configuration/serverconfiguration.h \
$${PWD}/configuration/serverconfigurations.h \

View File

@ -93,13 +93,11 @@
<file>ui/system/PluginsPage.qml</file>
<file>ui/system/PluginParamsPage.qml</file>
<file>ui/system/AboutNymeaPage.qml</file>
<file>ui/system/CloudSettingsPage.qml</file>
<file>ui/system/ConnectionInterfacesPage.qml</file>
<file>ui/system/ConnectionInterfaceDelegate.qml</file>
<file>ui/appsettings/AboutPage.qml</file>
<file>ui/appsettings/AppSettingsPage.qml</file>
<file>ui/appsettings/DeveloperOptionsPage.qml</file>
<file>ui/appsettings/CloudLoginPage.qml</file>
<file>ui/fonts/Ubuntu-B.ttf</file>
<file>ui/fonts/Ubuntu-BI.ttf</file>
<file>ui/fonts/Ubuntu-C.ttf</file>

View File

@ -100,12 +100,6 @@ ApplicationWindow {
value: settings.units === "metric" ? Types.UnitSystemMetric : Types.UnitSystemImperial
}
Binding {
target: AWSClient
property: "config"
value: "cloudEnvironment" in app ? app.cloudEnvironment : settings.cloudEnvironment
}
Binding {
target: PushNotifications
property: "enabled"
@ -141,7 +135,6 @@ ApplicationWindow {
property NymeaDiscovery nymeaDiscovery: NymeaDiscovery {
objectName: "discovery"
awsClient: AWSClient
bluetoothDiscoveryEnabled: false// PlatformPermissions.bluetoothPermission === PlatformPermissions.PermissionStatusGranted
}

View File

@ -61,48 +61,4 @@ SettingsPageBase {
text: qsTr("Configure logging categories")
onClicked: pageStack.push(Qt.resolvedUrl("../appsettings/LoggingCategories.qml"))
}
SettingsPageSectionHeader {
text: qsTr("Advanced options")
visible: settings.showHiddenOptions
}
RowLayout {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
visible: settings.showHiddenOptions
Label {
Layout.fillWidth: true
text: qsTr("Cloud environment")
}
ComboBox {
currentIndex: model.indexOf(app.settings.cloudEnvironment)
model: AWSClient.availableConfigs
onActivated: {
app.settings.cloudEnvironment = model[index];
}
}
}
SettingsPageSectionHeader {
text: qsTr("nymea:cloud")
}
Label {
Layout.fillWidth: true
Layout.leftMargin: Style.margins
Layout.rightMargin: Style.margins
text: qsTr("Note: nymea:cloud is deprecated and will be removed in a future version.")
wrapMode: Text.WordWrap
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Cloud login")
subText: qsTr("Log into %1:cloud and manage connected %1 systems").arg(Configuration.systemName)
iconName: "../images/connections/cloud.svg"
onClicked: pageStack.push(Qt.resolvedUrl("CloudLoginPage.qml"))
}
}

View File

@ -186,27 +186,4 @@ SettingsPageBase {
popup.open()
}
}
SettingsPageSectionHeader {
text: qsTr("nymea:cloud")
}
Label {
Layout.fillWidth: true
Layout.leftMargin: Style.margins
Layout.rightMargin: Style.margins
text: qsTr("Note: nymea:cloud based remote connection is deprecated and will be removed in a future version.")
wrapMode: Text.WordWrap
}
NymeaItemDelegate {
Layout.fillWidth: true
iconName: "../images/connections/cloud.svg"
text: qsTr("Cloud")
subText: qsTr("Connect this %1 system to %1:cloud").arg(Configuration.systemName)
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin)
onClicked: pageStack.push(Qt.resolvedUrl("CloudSettingsPage.qml"))
}
}

View File

@ -1,3 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = testrunner unit
SUBDIRS = testrunner

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea

View File

@ -1,9 +0,0 @@
GET
/
host:example.amazonaws.com
my-header1:value2,value2,value1
x-amz-date:20150830T123600Z
host;my-header1;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,6 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value2
My-Header1:value2
My-Header1:value1
X-Amz-Date:20150830T123600Z

View File

@ -1,7 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value2
My-Header1:value2
My-Header1:value1
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
dc7f04a3abfde8d472b0ab1a418b741b7c67174dad1551b4117b15527fbe966c

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=ba17b383a53190154eb5fa66a1b836cc297cc0a3d70a5d00705980573d8ff790

View File

@ -1,9 +0,0 @@
GET
/
host:example.amazonaws.com
my-header1:value1,value2,value3
x-amz-date:20150830T123600Z
host;my-header1;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,6 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value1
value2
value3
X-Amz-Date:20150830T123600Z

View File

@ -1,7 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value1
value2
value3
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=ba17b383a53190154eb5fa66a1b836cc297cc0a3d70a5d00705980573d8ff790

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
b7b6cbfd8a0430b78891e986784da2630c8a135a8595cec25b26ea94f926ee55

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01

View File

@ -1,9 +0,0 @@
GET
/
host:example.amazonaws.com
my-header1:value4,value1,value3,value2
x-amz-date:20150830T123600Z
host;my-header1;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,7 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value4
My-Header1:value1
My-Header1:value3
My-Header1:value2
X-Amz-Date:20150830T123600Z

View File

@ -1,8 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1:value4
My-Header1:value1
My-Header1:value3
My-Header1:value2
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
31ce73cd3f3d9f66977ad3dd957dc47af14df92fcd8509f59b349e9137c58b86

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;my-header2;x-amz-date, Signature=acc3ed3afb60bb290fc8d2dd0098b9911fcaa05412b367055dee359757a9c736

View File

@ -1,10 +0,0 @@
GET
/
host:example.amazonaws.com
my-header1:value1
my-header2:"a b c"
x-amz-date:20150830T123600Z
host;my-header1;my-header2;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,5 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1: value1
My-Header2: "a b c"
X-Amz-Date:20150830T123600Z

View File

@ -1,6 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
My-Header1: value1
My-Header2: "a b c"
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;my-header2;x-amz-date, Signature=acc3ed3afb60bb290fc8d2dd0098b9911fcaa05412b367055dee359757a9c736

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
a726db9b0df21c14f559d0a978e563112acb1b9e05476f0a6a1c7d68f28605c7

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f

View File

@ -1,8 +0,0 @@
GET
/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
6a968768eefaa713e2a6b16b589a8ea192661f098f37349f4e2c0082757446f9

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb

View File

@ -1,8 +0,0 @@
GET
/
Param1=value1
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
1e24db194ed7d0eec2de28d7369675a243488e08526e8c1c73571282f7c517ab

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500

View File

@ -1,8 +0,0 @@
GET
/
Param1=value1&Param2=value2
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?Param2=value2&Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?Param2=value2&Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
816cd5b414d056048ba4f7c5386d6e0533120fb1fcfa93762cf0fc39e2cf19e0

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=eedbc4e291e521cf13422ffca22be7d2eb8146eecf653089df300a15b2382bd1

View File

@ -1,8 +0,0 @@
GET
/
Param1=Value1&Param1=value2
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?Param1=value2&Param1=Value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?Param1=value2&Param1=Value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=eedbc4e291e521cf13422ffca22be7d2eb8146eecf653089df300a15b2382bd1

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
704b4cef673542d84cdff252633f065e8daeba5f168b77116f8b1bcaf3d38f89

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5772eed61e12b33fae39ee5e7012498b51d56abc0abb7c60486157bd471c4694

View File

@ -1,8 +0,0 @@
GET
/
Param1=value1&Param1=value2
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?Param1=value2&Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?Param1=value2&Param1=value1 HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5772eed61e12b33fae39ee5e7012498b51d56abc0abb7c60486157bd471c4694

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
c968629d70850097a2d8781c9bf7edcb988b04cac14cca9be4acc3595f884606

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197

View File

@ -1,8 +0,0 @@
GET
/
-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
c30d4703d9f799439be92736156d47ccfb2d879ddf56f5befa6d1d6aab979177

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,8 +0,0 @@
GET
/
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04

View File

@ -1,8 +0,0 @@
GET
/
%E1%88%B4=bar
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /?ሴ=bar HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /?ሴ=bar HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
eb30c5bed55734080471a834cc727ae56beb50e5f39d1bff6d0d38cb192a7073

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,8 +0,0 @@
GET
/
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET / HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,8 +0,0 @@
GET
/
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /example1/example2/../.. HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /example1/example2/../.. HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,8 +0,0 @@
GET
/
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /example/.. HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /example/.. HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,4 +0,0 @@
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/service/aws4_request
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63

View File

@ -1 +0,0 @@
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

View File

@ -1,8 +0,0 @@
GET
/
host:example.amazonaws.com
x-amz-date:20150830T123600Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@ -1,3 +0,0 @@
GET /./ HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z

View File

@ -1,4 +0,0 @@
GET /./ HTTP/1.1
Host:example.amazonaws.com
X-Amz-Date:20150830T123600Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31

Some files were not shown because too many files have changed in this diff Show More