X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=src%2Fjira-agent.cpp;fp=src%2Fjira-agent.cpp;h=c4d0e04eb3f3869b1a1517903110561d057445e3;hb=d483bd8e6523c23c6f1d8908a2e0611c2bc9ff4f;hp=0000000000000000000000000000000000000000;hpb=7dfa3fe589d1722d49681f42cdb0bf1e6efb5223;p=sven%2Fvym.git diff --git a/src/jira-agent.cpp b/src/jira-agent.cpp new file mode 100644 index 0000000..c4d0e04 --- /dev/null +++ b/src/jira-agent.cpp @@ -0,0 +1,293 @@ +#include "jira-agent.h" + +#include "branchitem.h" +#include "mainwindow.h" +#include "vymmodel.h" + +#include +#include +#include + +extern Main *mainWindow; +extern QDir vymBaseDir; +extern Settings settings; +extern QTextStream vout; +extern bool debug; + +bool JiraAgent::available() +{ + if (!QSslSocket::supportsSsl()) + return false; + if ( settings.value("/atlassian/jira/servers/size", 0).toInt() < 1) + return false; + + return true; +} + +JiraAgent::JiraAgent() +{ + //qDebug ()<< "Constr. JiraAgent"; + + init(); +} + +JiraAgent::~JiraAgent() +{ + //qDebug() << "Destr. JiraAgent"; + + if (killTimer) + delete killTimer; +} + +void JiraAgent::init() +{ + jobType = Undefined; + jobStep = -1; + abortJob = false; + + killTimer = nullptr; + + networkManager = new QNetworkAccessManager(this); + + modelID = 0; // invalid ID + + killTimer = new QTimer(this); + killTimer->setInterval(15000); + killTimer->setSingleShot(true); + + QObject::connect(killTimer, SIGNAL(timeout()), this, SLOT(timeout())); + + // Reset credentials, these are server specific beginning in 2.9.18 + authUsingPATInt = true; + personalAccessTokenInt = QString(); + userNameInt = QString(); + passwordInt = QString(); + serverNameInt = QString(); + + // Set API rest point. baseUrlInt later on depends on different JIRA system + apiUrl = "/rest/api/2"; + +} + +void JiraAgent::setJobType(JobType jt) +{ + jobType = jt; +} + +bool JiraAgent::setBranch(BranchItem *bi) +{ + if (!bi) { + abortJob = true; + return false; + } else { + branchID = bi->getID(); + modelID = bi->getModel()->getModelID(); + return true; + } +} + + +bool JiraAgent::setTicket(const QString &id) +{ + // Find ID part in parameter: + QRegExp re("(\\w+[-|\\s]\\d+)"); + if (re.indexIn(id) < 0) { + qWarning() << "JiraAgent::setTicket invalid ID: " << id; + abortJob = true; + return false; + } + + ticketID = re.cap(1); + ticketID.replace(" ", "-"); + + bool foundPattern = false; + + settings.beginGroup("/atlassian/jira"); + + // Try to find baseUrl of server by looking through patterns in ticket IDs: + int size = settings.beginReadArray("servers"); + for (int i = 0; i < size; ++i) { + settings.setArrayIndex(i); + foreach (QString p, settings.value("pattern").toString().split(",")) { + if (ticketID.contains(p)) { + foundPattern = true; + + baseUrlInt = settings.value("baseUrl","-").toString(); + serverNameInt = settings.value("name","-").toString(); + + // Read credentials for this server + authUsingPATInt = + settings.value("authUsingPAT", true).toBool(); + if (authUsingPATInt) + personalAccessTokenInt = + settings.value("PAT", "undefined").toString(); + else { + userNameInt = + settings.value("username", "user_johnDoe").toString(); + passwordInt = + settings.value("password", "").toString(); + } + break; + } + } + } + settings.endArray(); + settings.endGroup(); + + return foundPattern; +} + +QString JiraAgent::serverName() +{ + if (baseUrlInt.isEmpty()) + return QString(); + else + return serverNameInt; +} + +QString JiraAgent::url() +{ + return baseUrlInt + "/browse/" + ticketID; +} + +void JiraAgent::startJob() +{ + if (jobStep > 0) { + unknownStepWarning(); + finishJob(); + } else { + jobStep = 0; + continueJob(); + } +} + +void JiraAgent::continueJob() +{ + if (abortJob) { + finishJob(); + return; + } + + jobStep++; + + // qDebug() << "JA::contJob " << jobType << " Step: " << jobStep << "TicketID: " << ticketID; + + switch(jobType) { + case GetTicketInfo: + switch(jobStep) { + case 1: + // if (!requestedURL.toString().startsWith("http")) + // requestedURL.setPath("https://" + requestedURL.path()); + startGetTicketRequest(); + break; + case 2: { + QJsonDocument jsdoc = QJsonDocument (jsobj); + + // Insert references to original branch and model + jsobj["vymBranchId"] = QJsonValue(branchID); + jsobj["vymTicketUrl"] = QJsonValue(url()); + + emit (jiraTicketReady(QJsonObject(jsobj))); + finishJob(); + } + break; + default: + unknownStepWarning(); + break; + }; + break; + default: + qWarning() << "JiraAgent::continueJob unknown jobType " << jobType; + } +} + +void JiraAgent::finishJob() +{ + deleteLater(); +} + +void JiraAgent::unknownStepWarning() +{ + qWarning() << "JA::contJob unknow step in jobType = " + << jobType + << "jobStep = " << jobStep; +} + +void JiraAgent::startGetTicketRequest() +{ + QUrl u = QUrl(baseUrlInt + apiUrl + "/issue/" + ticketID); + + QNetworkRequest request = QNetworkRequest(u); + + // Basic authentication in header + QString headerData; + if (authUsingPATInt) + headerData = QString("Bearer %1").arg(personalAccessTokenInt); + else { + QString concatenated = userNameInt + ":" + passwordInt; + QByteArray data = concatenated.toLocal8Bit().toBase64(); + headerData = "Basic " + data; + } + + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + + if (debug) + qDebug() << "JA::startGetTicketRequest: url = " + request.url().toString(); + + killTimer->start(); + + connect(networkManager, &QNetworkAccessManager::finished, + this, &JiraAgent::ticketReceived); + + networkManager->get(request); +} + +void JiraAgent::ticketReceived(QNetworkReply *reply) +{ + // qDebug() << "JA::ticketReceived"; + + killTimer->stop(); + + networkManager->disconnect(); + + QString r = reply->readAll(); + + if (reply->error()) { + if (reply->error() == QNetworkReply::AuthenticationRequiredError) + QMessageBox::warning( + nullptr, tr("Warning"), + tr("Authentication problem when contacting JIRA")); + + qWarning() << "JiraAgent::ticketRReveived reply error"; + qWarning() << "Error: " << reply->error(); + vout << "reply: " << Qt::endl << r << Qt::endl; + finishJob(); + return; + } + + QJsonDocument jsdoc; + jsdoc = QJsonDocument::fromJson(r.toUtf8()); + jsobj = jsdoc.object(); + continueJob(); +} + +void JiraAgent::timeout() +{ + qWarning() << "JiraAgent timeout!! jobType = " << jobType; +} + +#ifndef QT_NO_SSL +void JiraAgent::sslErrors(QNetworkReply *reply, const QList &errors) +{ + QString errorString; + foreach (const QSslError &error, errors) { + if (!errorString.isEmpty()) + errorString += '\n'; + errorString += error.errorString(); + } + + reply->ignoreSslErrors(); + qWarning() << "JiraAgent: One or more SSL errors has occurred: " << errorString; + qWarning() << "Errors ignored."; +} +#endif