diff --git a/UIs/BeetRoundWidgets/dialogs/settingsdialog.cpp b/UIs/BeetRoundWidgets/dialogs/settingsdialog.cpp index f4f129f..cef8c59 100644 --- a/UIs/BeetRoundWidgets/dialogs/settingsdialog.cpp +++ b/UIs/BeetRoundWidgets/dialogs/settingsdialog.cpp @@ -27,12 +27,12 @@ void SettingsDialog::createContent() { serverLayout->addWidget(m_urlEdit, 0, 1); QLabel* emailLabel = new QLabel("Email:"); m_emailEdit = new QLineEdit(); - m_emailEdit->setEnabled(false); + // m_emailEdit->setEnabled(false); serverLayout->addWidget(emailLabel, 1, 0); serverLayout->addWidget(m_emailEdit, 1, 1); QLabel* passwordLabel = new QLabel("Password:"); m_passwordEdit = new QLineEdit(); - m_passwordEdit->setEnabled(false); + // m_passwordEdit->setEnabled(false); m_passwordEdit->setEchoMode(QLineEdit::Password); serverLayout->addWidget(passwordLabel, 2, 0); serverLayout->addWidget(m_passwordEdit, 2, 1); diff --git a/UIs/BeetRoundWidgets/mainwindow.cpp b/UIs/BeetRoundWidgets/mainwindow.cpp index 9e503cc..e01b6df 100644 --- a/UIs/BeetRoundWidgets/mainwindow.cpp +++ b/UIs/BeetRoundWidgets/mainwindow.cpp @@ -572,4 +572,5 @@ void MainWindow::initServerConnection() { &GenericCore::onCreateOnlineAccountTriggered); connect(m_editItemDialog.get(), &EditItemDialog::sendInviteMailTriggered, m_core.get(), &GenericCore::onSendInviteMailTriggered); + emit m_core->loginAndStoreAuthToken(); } diff --git a/libs/BeetRoundCore/formats/jsonparser.cpp b/libs/BeetRoundCore/formats/jsonparser.cpp index ba35875..854e2ec 100644 --- a/libs/BeetRoundCore/formats/jsonparser.cpp +++ b/libs/BeetRoundCore/formats/jsonparser.cpp @@ -71,7 +71,7 @@ QByteArray JsonParser::itemValuesListToJson(const QList& itemVa return jsonDoc.toJson(QJsonDocument::Compact); } -QByteArray JsonParser::ToJsonObject(const QHash& values, +QByteArray JsonParser::toJsonDoc(const QHash& values, const QString& objectName) { QJsonDocument jsonDoc; QJsonObject rootObject; diff --git a/libs/BeetRoundCore/formats/jsonparser.h b/libs/BeetRoundCore/formats/jsonparser.h index d62db09..10eb576 100644 --- a/libs/BeetRoundCore/formats/jsonparser.h +++ b/libs/BeetRoundCore/formats/jsonparser.h @@ -19,7 +19,7 @@ class JsonParser { const QString& rootValueName = ""); static QByteArray itemValuesListToJson(const QList& itemValuesList, const QString& objectName = ""); - static QByteArray ToJsonObject(const QHash& Values, + static QByteArray toJsonDoc(const QHash& Values, const QString& objectName = ""); static ModelItemValues serverUserCredentialsToItemValues(const QJsonDocument& jsonDoc); diff --git a/libs/BeetRoundCore/genericcore.cpp b/libs/BeetRoundCore/genericcore.cpp index 31f81d2..3fddcbe 100644 --- a/libs/BeetRoundCore/genericcore.cpp +++ b/libs/BeetRoundCore/genericcore.cpp @@ -156,6 +156,12 @@ bool GenericCore::isSyncServerSetup() const { } } +void GenericCore::onLoginSuccessful() { + qInfo() << "Login successful."; + emit displayStatusMessage("Login successful."); + emit sendGetRequest(GetCurrentBiddingRound); +} + void GenericCore::onBiddingsChanged(const QList biddings) { qInfo() << "onBiddingsChanged: biddings:" << biddings.count(); // NEXT merge biddings into model @@ -166,7 +172,7 @@ void GenericCore::onCreateOnlineAccountTriggered(const QString& mailAddress) { qInfo() << "Creating online account for:" << mailAddress; QHash hash; hash.insert("email", mailAddress); - const QByteArray jsonDoc = JsonParser::ToJsonObject(hash, "user"); + const QByteArray jsonDoc = JsonParser::toJsonDoc(hash, "user"); emit sendPostRequest(RegisterUser, jsonDoc); } @@ -256,6 +262,7 @@ void GenericCore::applyServerConfiguration() { if (!urlValue.isEmpty()) { const QString emailValue = serverSettings.value("email").toString(); const QString passwordValue = serverSettings.value("password").toString(); - m_serverCommunicator->setServerConfiguration(urlValue, emailValue, passwordValue); + const QString authToken = serverSettings.value("token").toString(); + m_serverCommunicator->setServerConfiguration(urlValue, emailValue, passwordValue, authToken); } } diff --git a/libs/BeetRoundCore/genericcore.h b/libs/BeetRoundCore/genericcore.h index 45a3c89..47acdfc 100644 --- a/libs/BeetRoundCore/genericcore.h +++ b/libs/BeetRoundCore/genericcore.h @@ -47,6 +47,8 @@ class GenericCore : public QObject { bool isSyncServerSetup() const; public slots: + void onLoginSuccessful(); + void onBiddingsChanged(const QList biddings); void onCreateOnlineAccountTriggered(const QString& mailAddress); @@ -59,6 +61,7 @@ class GenericCore : public QObject { void displayStatusMessage(QString message); /// *** server communication *** + void loginAndStoreAuthToken(); /// request signals void sendGetRequest(GetRequestTypes type, QVariant data = QVariant()); void sendPostRequest(PostRequestTypes type, QByteArray data); diff --git a/libs/BeetRoundCore/model/metadata.h b/libs/BeetRoundCore/model/metadata.h index e2de431..d4401ae 100644 --- a/libs/BeetRoundCore/model/metadata.h +++ b/libs/BeetRoundCore/model/metadata.h @@ -91,7 +91,7 @@ enum GetRequestTypes { GetBiddingsOfSpecificRound, GetBiddingsOfHighestRound }; -enum PostRequestTypes { RegisterUser, MailInvite }; +enum PostRequestTypes { LogInAdmin, RegisterUser, MailInvite }; /// functions static UserRoles GET_ROLE_FOR_COLUMN(const int column) { diff --git a/libs/BeetRoundCore/network/apiroutes.h b/libs/BeetRoundCore/network/apiroutes.h index e1ad0e8..963681a 100644 --- a/libs/BeetRoundCore/network/apiroutes.h +++ b/libs/BeetRoundCore/network/apiroutes.h @@ -5,12 +5,14 @@ // TODO add namespace -static const QString ROUTE_LOG_IN = "/log_in"; +static const QString ROUTE_USER_LOG_IN = "/log_in"; static const QString apiPrefix = "/api/"; static const QString ROUTE_ITEMS = apiPrefix + "items"; +static const QString ROUTE_ADMIN_LOG_IN = apiPrefix + "log_in"; + static const QString ROUTE_REGISTER_USER = apiPrefix + "users"; static const QString ROUTE_MAIL_INVITE = apiPrefix + "invite"; diff --git a/libs/BeetRoundCore/network/servercommunicator.cpp b/libs/BeetRoundCore/network/servercommunicator.cpp index 8e672af..4a96662 100644 --- a/libs/BeetRoundCore/network/servercommunicator.cpp +++ b/libs/BeetRoundCore/network/servercommunicator.cpp @@ -10,6 +10,8 @@ #include "../structs.h" #include "apiroutes.h" +#include "../data/settingshandler.h" + using namespace Qt::StringLiterals; ServerCommunicator::ServerCommunicator(GenericCore* core) @@ -19,6 +21,9 @@ ServerCommunicator::ServerCommunicator(GenericCore* core) m_restManager = std::make_shared(&m_netManager); m_serviceApi = std::make_shared(); + connect(core, &GenericCore::loginAndStoreAuthToken, this, &ServerCommunicator::onLoginTriggered); + connect(this, &ServerCommunicator::loginSuccessful, core, &GenericCore::onLoginSuccessful); + connect(m_core, &GenericCore::sendGetRequest, this, &ServerCommunicator::onSendGetRequestTriggered); connect(m_core, &GenericCore::sendPostRequest, this, @@ -51,15 +56,21 @@ void ServerCommunicator::setUrl(const QUrl& url) { void ServerCommunicator::setServerConfiguration(const QString url, const QString email, - const QString password) { + const QString password, + const QString authToken) { setUrl(url); - m_email = email; - m_password = password; + m_email = email; + m_password = password; + m_authToken = authToken; + + if (!m_authToken.isEmpty()) { + m_serviceApi->setBearerToken(authToken.toLatin1()); + } } QString ServerCommunicator::getUserLoginUrl() const { - const QString logInUrl = m_serviceApi->baseUrl().toString() + ROUTE_LOG_IN; + const QString logInUrl = m_serviceApi->baseUrl().toString() + ROUTE_USER_LOG_IN; return logInUrl; } @@ -96,6 +107,7 @@ void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type, return; } + m_serviceApi->setBearerToken(m_authToken.toLatin1()); const QNetworkRequest request = m_serviceApi->createRequest(path); m_restManager->get(request, this, [this, type](QRestReply& reply) { @@ -145,6 +157,9 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type, const QByteArray data) { QString path; switch (type) { + case LogInAdmin: + path = ROUTE_ADMIN_LOG_IN; + break; case RegisterUser: path = ROUTE_REGISTER_USER; break; @@ -162,6 +177,7 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type, return; } + m_serviceApi->setBearerToken(m_authToken.toLatin1()); const QNetworkRequest request = m_serviceApi->createRequest(path); m_restManager->post(request, data, this, [this, type](QRestReply& reply) { @@ -188,6 +204,10 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type, void ServerCommunicator::onPostReplySuccessful(const PostRequestTypes type, const QJsonDocument doc) { switch (type) { + case LogInAdmin: + qInfo() << "Admin successfully logged in:" << type; + handleLogInReply(doc); + break; case RegisterUser: qInfo() << "Register user successful:" << type; onlineUserAccountReply(doc); @@ -207,7 +227,34 @@ void ServerCommunicator::onPostReplyFailure(const PostRequestTypes type, const QString message = QString("Request of type %1 returned: %2").arg(QString::number(type), errorString); // NEXT improve error message to the UI; - m_core->displayStatusMessage(message); + emit m_core->displayStatusMessage(message); +} + +QByteArray ServerCommunicator::createLoginBody() { + QHash values; + values.insert("email", m_email); + values.insert("password", m_password); + return JsonParser::toJsonDoc(values, "admin"); +} + +void ServerCommunicator::handleLogInReply(const QJsonDocument jsonDoc) { + QJsonObject rootObject = jsonDoc.object(); + bool hasErrors = rootObject.contains(QString("errors")); + if (hasErrors) { + qCritical() << "Reply has error(s)!"; + QString errorString = rootObject["errors"].toString(); + emit m_core->displayStatusMessage(errorString); + } else { + qInfo() << "Reply has no error(s)!"; + const QJsonObject dataObject = rootObject["data"].toObject(); + const QString authToken = dataObject["token"].toString(); + m_authToken = authToken; + + SettingsHandler::saveSettings({{"token", authToken}}, "Server"); + + emit loginSuccessful(); + emit m_core->displayStatusMessage("Successfully logged in."); + } } void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) { @@ -245,3 +292,30 @@ void ServerCommunicator::mailInviteSentReply(const QJsonDocument jsonDoc) { qInfo() << "Invitation mail successfully sent."; emit m_core->displayStatusMessage("Invitation mail successfully sent."); } + +void ServerCommunicator::onLoginTriggered() { + qInfo() << "Login triggered..."; + if (m_email.isEmpty() || m_password.isEmpty()) { + emit m_core->displayStatusMessage( + "Missing email or password in settings! Not trying to log in."); + return; + } + if (m_authToken.isEmpty()) { + /// get new authToken + qWarning() << "Creating a new authToken!"; + const QByteArray loginBody = createLoginBody(); + onSendPostRequestTriggered(LogInAdmin, loginBody); + + } else { + /// try authToken + qWarning() << "Validity check of token not implemented yet!!!"; + qInfo() << "Assuming validity of token..."; + + emit loginSuccessful(); + // TODO try validity of token and trigger log_in if not valid + // try default route to test access; + // if (access denied) { + // m_apiClient->sendAPIRequestPost(ROUTE_LOG_IN_ADMIN, ); + // } + } +} diff --git a/libs/BeetRoundCore/network/servercommunicator.h b/libs/BeetRoundCore/network/servercommunicator.h index 525850d..56dfb31 100644 --- a/libs/BeetRoundCore/network/servercommunicator.h +++ b/libs/BeetRoundCore/network/servercommunicator.h @@ -22,10 +22,15 @@ class ServerCommunicator : public QObject { QUrl url() const; void setUrl(const QUrl& url); - void setServerConfiguration(const QString url, const QString email, const QString password); + void setServerConfiguration(const QString url, + const QString email, + const QString password, + const QString authToken); QString getUserLoginUrl() const; public slots: + void onLoginTriggered(); + void onSendGetRequestTriggered(const GetRequestTypes type, QVariant data); void onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc); void onGetReplyFailure(const GetRequestTypes type, const QString errorString); @@ -44,6 +49,8 @@ class ServerCommunicator : public QObject { void deleteRequestSuccessful(const QByteArray responseData); void deleteRequestFailure(const QString errorString); + void loginSuccessful(); + void currentBiddingRoundChanged(int round, bool isRunning); void biddingsChanged(QList biddings); void onlineUserAccountReceived(const QString mailAddress, @@ -59,9 +66,13 @@ class ServerCommunicator : public QObject { QString m_email; QString m_password; - // QString m_authToken; + QString m_authToken; + + QByteArray createLoginBody(); /// reply parser + void handleLogInReply(const QJsonDocument jsonDoc); + void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc); void currentBiddingsReply(const QJsonDocument jsonDoc); void onlineUserAccountReply(const QJsonDocument jsonDoc);