#include "colnodapi.h" Q_LOGGING_CATEGORY(colnod, "colnod.api"); ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const qint64 &lastSync, const bool &dryMode, const QString &userName, const QString &password) :mReqMan(reqMan), mUserName(userName), mPassword(password), mDryMode(dryMode) { mLastSync.set_timestamp(lastSync); mData = std::make_shared(); // ----------------------------------- mReqMan->setIgnoreSsl(true); // ----------------------------------- } void ColnodAPI::downloadData() { // Have to get Login auto login = requestLogin(); connect(login.get(), &serversdk::Request::finished, this, [=](){ // TODO: error handling // Get token AuthToken token; token.fromJson(login->responseData()); authToken = token.id(); // if I have all data emit downloadDataFinished connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady); getTokensUpdated(mLastSync); getTokensDeleted(mLastSync); getSubjectsUpdated(mLastSync); getSubjectsDeleted(mLastSync); }); } void ColnodAPI::processData(const std::shared_ptr &data) { qInfo(colnod) << tab << "-> DATA PROCESSED TO COLNOD:"; qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS UPDATED"; qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; qInfo(colnod) << dash; connect(this, &ColnodAPI::partOfDataProcessFinished, this, &ColnodAPI::isDataProcessFinished); if ( !data->updatedTokens.isEmpty() && !mDryMode) { setTokens(data->updatedTokens); } else { emit partOfDataProcessFinished(); } if ( !data->deletedTokens.isEmpty() && !mDryMode) { deleteTokens(data->deletedTokens); } else { emit partOfDataProcessFinished(); } } std::shared_ptr ColnodAPI::requestLogin() { Q_ASSERT(mReqMan); LoginResp login; login.set_username(userName()); // password QString encodedPassword = QCryptographicHash::hash( password().toLocal8Bit(), // -> bytearray QCryptographicHash::Sha512 // SHA 512 ).toHex().toUpper(); login.set_password(encodedPassword); auto loginRequest = composeRequest("/AaaManager/authSession", login.jsonData()); loginRequest->setUserName(login.username()); loginRequest->setPassword(login.password()); mReqMan->processRequest(loginRequest); return loginRequest; } void ColnodAPI::getTokensUpdated(const Timestamp &time) { auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ saveUpdatedTokens(request->responseData()); emit partOfDataReady(mData); }); } void ColnodAPI::getTokensDeleted(const Timestamp &time) { auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ saveDeletedTokens(request->responseData()); emit partOfDataReady(); }); } void ColnodAPI::getSubjectsUpdated(const Timestamp &time) { auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ saveUpdatedSubjects(request->responseData()); emit partOfDataReady(); }); } void ColnodAPI::getSubjectsDeleted(const Timestamp &time) { auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ saveDeletedSubjects(request->responseData()); emit partOfDataReady(); }); } void ColnodAPI::setTokens(const QHash> &tokens) { auto request = composeRequest("/TokenManager/setTokens", Token::tokensToColnodJson(tokens)); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ if (checkResponse(request->responseData())) { emit partOfDataProcessFinished(); } else { qWarning(colnod) << "Tokens wasn't updated"; // TODO: error: data wasnt upload to colnod } }); } void ColnodAPI::deleteTokens(const QList &ids) { auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids)); request->setUserName(authToken); mReqMan->processRequest(request); connect(request.get(), &serversdk::Request::finished, [=](){ if (checkResponse(request->responseData())) { emit partOfDataProcessFinished(); } else { qWarning(colnod) << "Tokens wasn't deleted"; // TODO: error: data wasnt upload to colnod } }); } std::shared_ptr ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data) { QString url = mHost + endpoint; return std::make_shared("POST", url, data); } QString ColnodAPI::password() const { return mPassword; } void ColnodAPI::setPassword(const QString &password) { mPassword = password; } qint64 ColnodAPI::lastSync() const { return mLastSync.timestamp(); } void ColnodAPI::setlastSync(const qint64 &lastSync) { mLastSync.set_timestamp(lastSync); } QString ColnodAPI::userName() const { return mUserName; } void ColnodAPI::setUserName(const QString &userName) { mUserName = userName; } void ColnodAPI::areDataReady() { if (++amountData == 4) { qInfo(colnod) << tab << "-> COLNOD DATA:"; qInfo(colnod) << tab << tab << mData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; qInfo(colnod) << tab << tab << mData->deletedTokens.size() << "TOKENS DELETED"; qInfo(colnod) << tab << tab << mData->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; qInfo(colnod) << tab << tab << mData->deletedSubjects.size() << "SUBJECTS DELETED"; qInfo(colnod) << dash; emit downloadDataFinished(mData); newData(); } } void ColnodAPI::isDataProcessFinished() { if (++amountProccessesFinished == 2) { emit dataProcessFinished(); } } void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData) { mData->loadTokensFromJson(responseData); } void ColnodAPI::saveDeletedTokens(const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { mData->deletedTokens.append(item.toString()); } } void ColnodAPI::saveUpdatedSubjects(const QByteArray &responseData) { mData->loadSubjectsFormJson(responseData); } void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { mData->deletedSubjects.append(item.toString()); } } void ColnodAPI::newData() { mData = std::make_shared(); } bool ColnodAPI::checkResponse(const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); return doc.object().contains("items"); }