diff --git a/eetsend/main.cpp b/eetsend/main.cpp index bb178da..9c2408f 100644 --- a/eetsend/main.cpp +++ b/eetsend/main.cpp @@ -22,6 +22,7 @@ int main(int argc, char *argv[]) request.setRezim(EetRequest::STANDARD); EetSender sender; + sender.setPlayground(true); sender.setupSigner("/home/pepa/Dokumenty/dev/eet/121212.p12", "eet"); sender.sendRequest(&request); diff --git a/libEet/eetresult.cpp b/libEet/eetresult.cpp index fa987df..700b5cf 100644 --- a/libEet/eetresult.cpp +++ b/libEet/eetresult.cpp @@ -65,6 +65,26 @@ void EetResult::setReciveDate(const QDateTime &reciveDate) m_reciveDate = reciveDate; } +QString EetResult::pkp() const +{ + return m_pkp; +} + +void EetResult::setPkp(const QString &pkp) +{ + m_pkp = pkp; +} + +QString EetResult::bkp() const +{ + return m_bkp; +} + +void EetResult::setBkp(const QString &bkp) +{ + m_bkp = bkp; +} + EetMessage::EetMessage(QObject *parent) :QObject(parent) { diff --git a/libEet/eetresult.h b/libEet/eetresult.h index 27dade4..c9d56d9 100644 --- a/libEet/eetresult.h +++ b/libEet/eetresult.h @@ -36,9 +36,13 @@ public: { RESPONSE_OK = 0, DATA_ERROR, + USER_CERT_ERROR, SERVER_ERROR, + SERVICE_CERT_ERROR, + INVALID_SIGNATURE, SSL_ERROR, - TIMEDOUT + TIMEDOUT, + OFFLINE }; explicit EetResult(QObject *parent = 0); @@ -61,11 +65,19 @@ public: QDateTime reciveDate() const; void setReciveDate(const QDateTime &reciveDate); + QString pkp() const; + void setPkp(const QString &pkp); + + QString bkp() const; + void setBkp(const QString &bkp); + private: ResponseStatus m_status; QUuid m_uuid; QDateTime m_reciveDate; QString m_fik; + QString m_pkp; + QString m_bkp; EetMessageList m_warnings; EetMessageList m_errors; }; diff --git a/libEet/eetsender.cpp b/libEet/eetsender.cpp index 5cffd36..1f7c285 100644 --- a/libEet/eetsender.cpp +++ b/libEet/eetsender.cpp @@ -6,12 +6,9 @@ #include "eettemplate.h" #include -#include -#include -#include #include #include -#include +#include const QString EetSender::ms_nsDef = "declare namespace eet = \"http://fs.mfcr.cz/eet/schema/v3\";\n" "declare namespace ds = \"http://www.w3.org/2000/09/xmldsig#\";\n" @@ -20,24 +17,36 @@ const QString EetSender::ms_nsDef = "declare namespace eet = \"http://fs.mfcr.cz "declare namespace senc = \"http://schemas.xmlsoap.org/soap/encoding/\";\n" "declare namespace senv = \"http://schemas.xmlsoap.org/soap/envelope/\";\n"; +bool EetSender::m_online = true; + EetSender::EetSender(QObject *parent) : QObject(parent) { m_signer = nullptr; m_resut = nullptr; m_checkSignature = true; + m_resut = new EetResult(this); + m_manager = new QNetworkAccessManager(this); connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); - connect(m_manager, &QNetworkAccessManager::sslErrors, [this](QNetworkReply *rep, QList errs){ - emit serviceCertError(); + connect(m_manager, &QNetworkAccessManager::sslErrors, [this](QNetworkReply *rep, QList){ + m_resut->setStatus(EetResult::SSL_ERROR); + emit sendFinished(); + rep->deleteLater(); }); + + m_serviceUrl = PRODUCTION_URL; + m_timer = new QTimer(this); + m_timer->setInterval(1000); + m_timer->setSingleShot(true); } void EetSender::sendRequest(EetRequest *request) { if (m_signer == nullptr) { - emit certError(); + m_resut->setStatus(EetResult::USER_CERT_ERROR); + emit sendFinished(); return; } @@ -45,6 +54,7 @@ void EetSender::sendRequest(EetRequest *request) EetTemplate tempBody(BODY_TEMPLATE); tempBody.setSigner(m_signer); + tempBody.setResult(m_resut); QString strBody = tempBody.fillTemplate(request); QByteArray digest = m_signer->sha256HashData(strBody.toUtf8()); @@ -61,12 +71,26 @@ void EetSender::sendRequest(EetRequest *request) QString strRequest = tempRequest.fillTemplate(val); - QNetworkRequest req(QUrl("https://pg.eet.cz/eet/services/EETServiceSOAP/v3")); - m_manager->post(req, strRequest.toUtf8()); + QNetworkRequest req(QUrl(m_serviceUrl.toStdString().c_str())); - QFile file("/home/pepa/Dokumenty/dev/eet/req.xml"); - file.open(QIODevice::WriteOnly); - file.write(strRequest.toUtf8()); + qDebug() << strRequest; + + if (m_online) + { + QNetworkReply *rep = m_manager->post(req, strRequest.toUtf8()); + m_timer->start(); + connect(m_timer, &QTimer::timeout, [this, rep](){ + rep->abort(); + m_resut->setStatus(EetResult::TIMEDOUT); + emit sendFinished(); + }); + } + else + { + m_resut->setStatus(EetResult::OFFLINE); + m_timer->stop(); + emit sendFinished(); + } } void EetSender::setupSigner(const QString &certPath, const QString &passwd) @@ -90,11 +114,21 @@ bool EetSender::checkSignature() const return m_checkSignature; } +void EetSender::setPlayground(bool pg) +{ + m_serviceUrl = (pg ? PLAYGROUND_URL : PRODUCTION_URL); +} + EetResult *EetSender::resut() const { return m_resut; } +void EetSender::setTimeout(int timeout) +{ + m_timer->setInterval(timeout); +} + bool EetSender::verifySignature(const QByteArray &repData) { QString queryString("//senv:Envelope/senv:Header/wsse:Security/ds:Signature/ds:SignedInfo"); @@ -130,7 +164,7 @@ bool EetSender::verifySignature(const QByteArray &repData) if (res != QCA::ConvertGood) { - emit serviceCertError(); + m_resut->setStatus(EetResult::SERVICE_CERT_ERROR); return false; } @@ -138,7 +172,7 @@ bool EetSender::verifySignature(const QByteArray &repData) if (!pubKey.canVerify()) { - emit serviceCertError(); + m_resut->setStatus(EetResult::SERVICE_CERT_ERROR); return false; } @@ -146,7 +180,7 @@ bool EetSender::verifySignature(const QByteArray &repData) if (!signValid) { - emit signInvalid(); + m_resut->setStatus(EetResult::INVALID_SIGNATURE); return false; } @@ -155,38 +189,66 @@ bool EetSender::verifySignature(const QByteArray &repData) void EetSender::replyFinished(QNetworkReply *reply) { + m_timer->stop(); if (reply->error() != QNetworkReply::NoError) { - emit sendError(); + m_resut->setStatus(EetResult::SERVER_ERROR); + emit sendFinished(); reply->deleteLater(); return; } QByteArray repData = reply->readAll(); - /*QFile file("/home/pepa/Dokumenty/dev/eet/reply.xml"); - file.open(QIODevice::ReadOnly); - repData = file.readAll();*/ - - if (m_checkSignature && !verifySignature(repData)) - { - return; - } + qDebug() << QString(repData); QXmlQuery q; q.setFocus(QString(repData)); + QXmlResultItems items; QString result; - QString queryString("//senv:Envelope/senv:Body/eet:Odpoved/eet:Hlavicka/@uuid_zpravy/data(.)"); + QString queryString = "//senv:Envelope/senv:Body/eet:Odpoved/eet:Chyba"; q.setQuery(ms_nsDef + queryString); - q.evaluateTo(&result); - result = result.trimmed(); + q.evaluateTo(&items); - if (m_resut == nullptr) + EetMessageList errors; + QXmlItem item = items.next(); + while (!item.isNull()) { - m_resut = new EetResult(this); + EetMessage *mesg = new EetMessage(m_resut); + queryString = "./@kod/data(.)"; + q.setQuery(ms_nsDef + queryString); + q.setFocus(item); + q.evaluateTo(&result); + result = result.trimmed(); + + mesg->setCode(result.toInt()); + + queryString = "./string()"; + q.setQuery(ms_nsDef + queryString); + q.setFocus(item); + q.evaluateTo(&result); + result = result.trimmed(); + + mesg->setMessage(result); + errors.append(mesg); + + item = items.next(); } + m_resut->setErrors(errors); + + if (m_checkSignature && errors.isEmpty() && !verifySignature(repData)) + { + emit sendFinished(); + return; + } + + queryString = "//senv:Envelope/senv:Body/eet:Odpoved/eet:Hlavicka/@uuid_zpravy/data(.)"; + q.setQuery(ms_nsDef + queryString); + q.evaluateTo(&result); + result = result.trimmed(); + m_resut->setUuid(QUuid(result)); queryString = "//senv:Envelope/senv:Body/eet:Odpoved/eet:Hlavicka/@dat_prij/data(.)"; @@ -201,13 +263,12 @@ void EetSender::replyFinished(QNetworkReply *reply) result = result.trimmed(); m_resut->setFik(result); - QXmlResultItems items; queryString = "//senv:Envelope/senv:Body/eet:Odpoved/eet:Varovani"; q.setQuery(ms_nsDef + queryString); q.evaluateTo(&items); EetMessageList warnings; - QXmlItem item = items.next(); + item = items.next(); while (!item.isNull()) { EetMessage *mesg = new EetMessage(m_resut); @@ -219,7 +280,7 @@ void EetSender::replyFinished(QNetworkReply *reply) mesg->setCode(result.toInt()); - queryString = "./text(.)"; + queryString = "./string()"; q.setQuery(ms_nsDef + queryString); q.setFocus(item); q.evaluateTo(&result); @@ -233,37 +294,16 @@ void EetSender::replyFinished(QNetworkReply *reply) m_resut->setWarnings(warnings); - queryString = "//senv:Envelope/senv:Body/eet:Odpoved/eet:Chyba"; - q.setQuery(ms_nsDef + queryString); - q.evaluateTo(&items); - - EetMessageList errors; - item = items.next(); - while (!item.isNull()) + if (errors.isEmpty()) { - EetMessage *mesg = new EetMessage(m_resut); - queryString = "./@kod/data(.)"; - q.setQuery(ms_nsDef + queryString); - q.setFocus(item); - q.evaluateTo(&result); - result = result.trimmed(); - - mesg->setCode(result.toInt()); - - queryString = "./text(.)"; - q.setQuery(ms_nsDef + queryString); - q.setFocus(item); - q.evaluateTo(&result); - result = result.trimmed(); - - mesg->setMessage(result); - errors.append(mesg); - - item = items.next(); + m_resut->setReciveDate(QDateTime::currentDateTime()); + } + else + { + m_resut->setStatus(EetResult::DATA_ERROR); } - m_resut->setErrors(errors); - emit responseRecieved(m_resut); + emit sendFinished(); reply->deleteLater(); } diff --git a/libEet/eetsender.h b/libEet/eetsender.h index fa7d5ec..93a2fd0 100644 --- a/libEet/eetsender.h +++ b/libEet/eetsender.h @@ -2,35 +2,75 @@ #define EETSENDER_H #include +#include #include "eetcpp_global.h" #include "eetrequest.h" #include "eetresult.h" +#define PRODUCTION_URL "https://prod.eet.cz/eet/services/EETServiceSOAP/v3" +#define PLAYGROUND_URL "https://pg.eet.cz/eet/services/EETServiceSOAP/v3" + class QNetworkAccessManager; class QNetworkReply; class EetSigner; +/** + * @brief The EetSender class Performs send actions. + */ class EETCPPSHARED_EXPORT EetSender : public QObject { Q_OBJECT public: explicit EetSender(QObject *parent = 0); + /** + * @brief Sends request to EET web service + * @param request EET data + */ void sendRequest(EetRequest *request); + /** + * @brief Setup certificate for signing EET request data. + * @param certPath Path to certificate p12 file. File must contain private key. + * @param passwd Password for accesing p12 file. + */ void setupSigner(const QString &certPath, const QString &passwd); + /** + * @brief Sets verifing signature of response data. + * @param checkSignature true if you wish to verify. + */ void setCheckSignature(bool checkSignature); + /** + * @brief Returns signature verifing state. + * @return true if verify. + */ bool checkSignature() const; + /** + * @brief Sets comunication with playground EET portal. + * @param pg true if you wish to communicate with playground portal. + */ + void setPlayground(bool pg); + + /** + * @brief Returns comunication result. + * @return result + */ EetResult *resut() const; + void setTimeout(int timeout); + + static bool m_online; + private: static const QString ms_nsDef; EetSigner *m_signer; QNetworkAccessManager *m_manager; + QTimer *m_timer; bool m_checkSignature; EetResult *m_resut; + QString m_serviceUrl; bool verifySignature(const QByteArray &repData); @@ -38,11 +78,7 @@ private slots: void replyFinished(QNetworkReply *reply); signals: - void certError(); - void sendError(); - void responseRecieved(EetResult *result); - void signInvalid(); - void serviceCertError(); + void sendFinished(); public slots: }; diff --git a/libEet/eettemplate.cpp b/libEet/eettemplate.cpp index 2734d90..7ef6761 100644 --- a/libEet/eettemplate.cpp +++ b/libEet/eettemplate.cpp @@ -1,3 +1,4 @@ +#include "eetresult.h" #include "eettemplate.h" #include @@ -5,6 +6,7 @@ EetTemplate::EetTemplate(QObject *parent) : QObject(parent) { + m_result = nullptr; } EetTemplate::EetTemplate(const QString &tmp, QObject *parent) : QObject(parent) @@ -14,6 +16,7 @@ EetTemplate::EetTemplate(const QString &tmp, QObject *parent) : QObject(parent) QTextStream stream(&tmpFile); m_template = stream.readAll(); + m_result = nullptr; } QString EetTemplate::fillTemplate(EetRequest *request) @@ -39,6 +42,12 @@ QString EetTemplate::fillTemplate(EetRequest *request) splitedBkp += base16bkp[i]; } + if (m_result != nullptr) + { + m_result->setPkp(base64Sign); + m_result->setBkp(splitedBkp.toUpper()); + } + QMap varMap; varMap["pkp"] = base64Sign; varMap["bkp"] = splitedBkp.toUpper(); @@ -131,3 +140,8 @@ QString EetTemplate::getPkpString(EetRequest *request) request->property("celk_trzba").toString()); return ret; } + +void EetTemplate::setResult(EetResult *result) +{ + m_result = result; +} diff --git a/libEet/eettemplate.h b/libEet/eettemplate.h index b2e5256..cb8c620 100644 --- a/libEet/eettemplate.h +++ b/libEet/eettemplate.h @@ -12,6 +12,8 @@ #define REQUEST_TEMPLATE ":/res/template_request.txt" #define SIGNATURE_TEMPLATE ":/res/template_signature.txt" +class EetResult; + class EetTemplate : public QObject { Q_OBJECT @@ -22,6 +24,7 @@ public: QString fillTemplate(EetRequest *request); QString fillTemplate(QMap map); void setSigner(EetSigner *signer) { m_signer = signer; } + void setResult(EetResult *result); signals: @@ -32,6 +35,7 @@ private: QString fillTemplateInternal(EetRequest *request, QMap *map); QString getPkpString(EetRequest *request); EetSigner *m_signer; + EetResult *m_result; }; #endif // EETTEMPLATE_H diff --git a/libEet/libEet.pro b/libEet/libEet.pro index d689782..55df752 100644 --- a/libEet/libEet.pro +++ b/libEet/libEet.pro @@ -4,11 +4,7 @@ # #------------------------------------------------- -win32 { - QCA_PATH = d:/prac/qt/lib/qca -} - -QT += network xml xmlpatterns +QT += network xmlpatterns QT -= gui