This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
powersync-app/tests/unit/sigv4/testsigv4.cpp
2018-08-31 14:44:09 +02:00

151 lines
5.1 KiB
C++

#include <QtTest/QTest>
#include "connection/sigv4utils.h"
class TestSigV4: public QObject
{
Q_OBJECT
public:
TestSigV4(QObject* parent = nullptr);
private slots:
void canonicalRequest_data();
void canonicalRequest();
private:
QString m_region = "us-east-1";
QString m_service = "service";
QByteArray m_accessKeyId = "AKIDEXAMPLE";
QByteArray m_secretAccessKey = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY";
};
Q_DECLARE_METATYPE(QNetworkAccessManager::Operation)
TestSigV4::TestSigV4(QObject *parent): QObject(parent)
{
}
void TestSigV4::canonicalRequest_data() {
QTest::addColumn<QNetworkAccessManager::Operation>("method");
QTest::addColumn<QByteArray>("dateTime");
QTest::addColumn<QNetworkRequest>("request");
QTest::addColumn<QByteArray>("payload");
QTest::addColumn<QByteArray>("expectedCanonicalRequest");
QTest::addColumn<QByteArray>("expectedStringToSign");
QTest::addColumn<QByteArray>("expectedSignature");
QDir dir(TESTDATADIR);
foreach (const QString &subDirName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
QDir subDir(QString(TESTDATADIR) + '/' + subDirName);
if(subDir.entryList({"*.req"}).count() != 1) {
qWarning() << "Skipping folder:" << subDir.absolutePath();
continue;
}
QFile f(subDir.entryInfoList({"*.req"}).first().absoluteFilePath());
f.open(QFile::ReadOnly);
// line 1, read operation and path
QByteArray line = f.readLine();
QByteArray methodString = line.split(' ').first();
QNetworkAccessManager::Operation operation;
if (methodString == "GET") {
operation = QNetworkAccessManager::GetOperation;
} else if (methodString == "POST") {
operation = QNetworkAccessManager::PostOperation;
}
QByteArray path = line.split(' ').at(1);
QNetworkRequest request;
QByteArray host;
QByteArray dateTime;
// read headers
QByteArray lastHeaderName;
while (!f.atEnd()) {
QByteArray line = f.readLine().trimmed();
if (line.isEmpty()) {
break;
}
QByteArray header = QString(line).replace(QRegExp("[\\ ]{1,}"), " ").toUtf8();
if (!header.contains(':')) {
request.setRawHeader(lastHeaderName, request.rawHeader(lastHeaderName) + ',' + header);
continue;
}
QByteArray headerName = header.split(':').first().trimmed();
QByteArray headerValue = header.split(':').last().trimmed();
qDebug() << "working on header:" << headerName << headerValue;
if (headerName == "Host") {
host = headerValue;
}
if (headerName == "X-Amz-Date") {
dateTime = headerValue;
}
if (!request.hasRawHeader(headerName)) {
request.setRawHeader(headerName, headerValue);
} else {
request.setRawHeader(headerName, request.rawHeader(headerName) + ',' + headerValue);
}
lastHeaderName = headerName;
}
QByteArray payload;
if (!f.atEnd()) {
payload = f.readAll();
}
QUrl url = QUrl(QString("https://" + host + path));
request.setUrl(url);
// read creq file
QFile creq(subDir.entryInfoList({"*.creq"}).first().absoluteFilePath());
creq.open(QFile::ReadOnly);
// read sts file
QFile sts(subDir.entryInfoList({"*.sts"}).first().absoluteFilePath());
sts.open(QFile::ReadOnly);
// read authz file
QFile authz(subDir.entryInfoList({"*.authz"}).first().absoluteFilePath());
authz.open(QFile::ReadOnly);
QTest::newRow(f.fileName().split('/').last().toUtf8()) << operation << dateTime << request << payload << creq.readAll() << sts.readAll() << authz.readAll();
}
}
void TestSigV4::canonicalRequest()
{
QFETCH(QNetworkAccessManager::Operation, method);
QFETCH(QByteArray, dateTime);
QFETCH(QNetworkRequest, request);
QFETCH(QByteArray, payload);
QFETCH(QByteArray, expectedCanonicalRequest);
QFETCH(QByteArray, expectedStringToSign);
QFETCH(QByteArray, expectedSignature);
qDebug() << "Request:" << request.url() << "Host:" << request.url().host() << "Path:" << request.url().path() << "Query:" << request.url().query();
QByteArray canonicalRequest = SigV4Utils::getCanonicalRequest(method, request, payload);
QCOMPARE(canonicalRequest, expectedCanonicalRequest);
QByteArray stringTosign = SigV4Utils::getStringToSign(canonicalRequest, dateTime, m_region.toUtf8(), m_service.toUtf8());
QCOMPARE(stringTosign, expectedStringToSign);
QByteArray signature = SigV4Utils::getSignature(stringTosign, m_secretAccessKey, dateTime, m_region, m_service);
QByteArray signHeader = SigV4Utils::getAuthorizationHeader(m_accessKeyId, dateTime, m_region, m_service, request, signature);
QCOMPARE(signHeader, expectedSignature);
// qDebug() << "CanonicalRequest" << canonicalRequest;
}
#include "testsigv4.moc"
QTEST_MAIN(TestSigV4)