mirror of
https://github.com/nextcloud/desktop.git
synced 2026-01-14 02:01:28 +00:00
For this to work we also now need to store the fileId from the sync root folder, otherwise we would never know about new files inside the configured sync root Signed-off-by: Jyrki Gadinger <nilsding@nilsding.org>
224 lines
5.8 KiB
C++
224 lines
5.8 KiB
C++
/*
|
|
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include <QLoggingCategory>
|
|
#include <QSignalSpy>
|
|
#include <QTest>
|
|
#include <cstdint>
|
|
#include <functional>
|
|
|
|
#include "pushnotificationstestutils.h"
|
|
#include "pushnotifications.h"
|
|
|
|
Q_LOGGING_CATEGORY(lcFakeWebSocketServer, "nextcloud.test.fakewebserver", QtInfoMsg)
|
|
|
|
FakeWebSocketServer::FakeWebSocketServer(quint16 port, QObject *parent)
|
|
: QObject(parent)
|
|
, _webSocketServer(new QWebSocketServer(QStringLiteral("Fake Server"), QWebSocketServer::NonSecureMode, this))
|
|
{
|
|
if (!_webSocketServer->listen(QHostAddress::LocalHost, port)) {
|
|
Q_UNREACHABLE();
|
|
}
|
|
connect(_webSocketServer, &QWebSocketServer::newConnection, this, &FakeWebSocketServer::onNewConnection);
|
|
connect(_webSocketServer, &QWebSocketServer::closed, this, &FakeWebSocketServer::closed);
|
|
qCInfo(lcFakeWebSocketServer) << "Open fake websocket server on port:" << port;
|
|
_processTextMessageSpy = std::make_unique<QSignalSpy>(this, &FakeWebSocketServer::processTextMessage);
|
|
}
|
|
|
|
FakeWebSocketServer::~FakeWebSocketServer()
|
|
{
|
|
close();
|
|
}
|
|
|
|
QWebSocket *FakeWebSocketServer::authenticateAccount(const OCC::AccountPtr account, std::function<void(OCC::PushNotifications *pushNotifications)> beforeAuthentication, std::function<void(void)> afterAuthentication)
|
|
{
|
|
const auto pushNotifications = account->pushNotifications();
|
|
Q_ASSERT(pushNotifications);
|
|
QSignalSpy readySpy(pushNotifications, &OCC::PushNotifications::ready);
|
|
|
|
beforeAuthentication(pushNotifications);
|
|
|
|
// Wait for authentication
|
|
if (!waitForTextMessages()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Right authentication data should be sent
|
|
if (textMessagesCount() != 2) {
|
|
return nullptr;
|
|
}
|
|
|
|
const auto socket = socketForTextMessage(0);
|
|
const auto userSent = textMessage(0);
|
|
const auto passwordSent = textMessage(1);
|
|
|
|
if (userSent != account->credentials()->user() || passwordSent != account->credentials()->password()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Sent authenticated
|
|
socket->sendTextMessage("authenticated");
|
|
|
|
// Wait for ready signal
|
|
readySpy.wait();
|
|
if (readySpy.count() != 1 || !account->pushNotifications()->isReady()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Wait for notify_file_id opt-in
|
|
if (!waitForTextMessages()) {
|
|
return nullptr;
|
|
}
|
|
|
|
afterAuthentication();
|
|
|
|
return socket;
|
|
}
|
|
|
|
void FakeWebSocketServer::close()
|
|
{
|
|
if (_webSocketServer->isListening()) {
|
|
qCInfo(lcFakeWebSocketServer) << "Close fake websocket server";
|
|
|
|
_webSocketServer->close();
|
|
qDeleteAll(_clients.begin(), _clients.end());
|
|
}
|
|
}
|
|
|
|
void FakeWebSocketServer::processTextMessageInternal(const QString &message)
|
|
{
|
|
auto client = qobject_cast<QWebSocket *>(sender());
|
|
emit processTextMessage(client, message);
|
|
}
|
|
|
|
void FakeWebSocketServer::onNewConnection()
|
|
{
|
|
qCInfo(lcFakeWebSocketServer) << "New connection on fake websocket server";
|
|
|
|
auto socket = _webSocketServer->nextPendingConnection();
|
|
|
|
connect(socket, &QWebSocket::textMessageReceived, this, &FakeWebSocketServer::processTextMessageInternal);
|
|
connect(socket, &QWebSocket::disconnected, this, &FakeWebSocketServer::socketDisconnected);
|
|
|
|
_clients << socket;
|
|
}
|
|
|
|
void FakeWebSocketServer::socketDisconnected()
|
|
{
|
|
qCInfo(lcFakeWebSocketServer) << "Socket disconnected";
|
|
|
|
auto client = qobject_cast<QWebSocket *>(sender());
|
|
|
|
if (client) {
|
|
_clients.removeAll(client);
|
|
client->deleteLater();
|
|
}
|
|
}
|
|
|
|
bool FakeWebSocketServer::waitForTextMessages() const
|
|
{
|
|
return _processTextMessageSpy->wait();
|
|
}
|
|
|
|
uint32_t FakeWebSocketServer::textMessagesCount() const
|
|
{
|
|
return _processTextMessageSpy->count();
|
|
}
|
|
|
|
QString FakeWebSocketServer::textMessage(int messageNumber) const
|
|
{
|
|
Q_ASSERT(0 <= messageNumber && messageNumber < _processTextMessageSpy->count());
|
|
return _processTextMessageSpy->at(messageNumber).at(1).toString();
|
|
}
|
|
|
|
QWebSocket *FakeWebSocketServer::socketForTextMessage(int messageNumber) const
|
|
{
|
|
Q_ASSERT(0 <= messageNumber && messageNumber < _processTextMessageSpy->count());
|
|
return _processTextMessageSpy->at(messageNumber).at(0).value<QWebSocket *>();
|
|
}
|
|
|
|
void FakeWebSocketServer::clearTextMessages()
|
|
{
|
|
_processTextMessageSpy->clear();
|
|
}
|
|
|
|
OCC::AccountPtr FakeWebSocketServer::createAccount(const QString &username, const QString &password)
|
|
{
|
|
auto account = OCC::Account::create();
|
|
|
|
QStringList typeList;
|
|
typeList.append("files");
|
|
typeList.append("activities");
|
|
typeList.append("notifications");
|
|
|
|
QString websocketUrl("ws://localhost:12345");
|
|
|
|
QVariantMap endpointsMap;
|
|
endpointsMap["websocket"] = websocketUrl;
|
|
|
|
QVariantMap notifyPushMap;
|
|
notifyPushMap["type"] = typeList;
|
|
notifyPushMap["endpoints"] = endpointsMap;
|
|
|
|
QVariantMap capabilitiesMap;
|
|
capabilitiesMap["notify_push"] = notifyPushMap;
|
|
|
|
account->setCapabilities(capabilitiesMap);
|
|
|
|
auto credentials = new CredentialsStub(username, password);
|
|
account->setCredentials(credentials);
|
|
|
|
return account;
|
|
}
|
|
|
|
CredentialsStub::CredentialsStub(const QString &user, const QString &password)
|
|
: _user(user)
|
|
, _password(password)
|
|
{
|
|
}
|
|
|
|
QString CredentialsStub::authType() const
|
|
{
|
|
return "";
|
|
}
|
|
|
|
QString CredentialsStub::user() const
|
|
{
|
|
return _user;
|
|
}
|
|
|
|
QString CredentialsStub::password() const
|
|
{
|
|
return _password;
|
|
}
|
|
|
|
QNetworkAccessManager *CredentialsStub::createQNAM() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
bool CredentialsStub::ready() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void CredentialsStub::fetchFromKeychain(const QString &appName)
|
|
{
|
|
Q_UNUSED(appName)
|
|
}
|
|
|
|
void CredentialsStub::askFromUser() { }
|
|
|
|
bool CredentialsStub::stillValid(QNetworkReply * /*reply*/)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void CredentialsStub::persist() { }
|
|
|
|
void CredentialsStub::invalidateToken() { }
|
|
|
|
void CredentialsStub::forgetSensitiveData() { }
|