2017-07-03 09:30:10 +02:00
|
|
|
/*
|
2018-03-28 15:10:51 +02:00
|
|
|
* \copyright Copyright (c) 2016-2018 Governikus GmbH & Co. KG, Germany
|
2017-07-03 09:30:10 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "MessageDispatcher.h"
|
|
|
|
|
|
|
|
#include "messages/MsgHandlerAccessRights.h"
|
|
|
|
#include "messages/MsgHandlerApiLevel.h"
|
|
|
|
#include "messages/MsgHandlerAuth.h"
|
|
|
|
#include "messages/MsgHandlerBadState.h"
|
|
|
|
#include "messages/MsgHandlerCertificate.h"
|
|
|
|
#include "messages/MsgHandlerEnterCan.h"
|
|
|
|
#include "messages/MsgHandlerEnterPin.h"
|
2017-07-03 09:33:28 +02:00
|
|
|
#include "messages/MsgHandlerEnterPuk.h"
|
2017-07-03 09:30:10 +02:00
|
|
|
#include "messages/MsgHandlerInfo.h"
|
|
|
|
#include "messages/MsgHandlerInsertCard.h"
|
|
|
|
#include "messages/MsgHandlerInternalError.h"
|
|
|
|
#include "messages/MsgHandlerInvalid.h"
|
|
|
|
#include "messages/MsgHandlerReader.h"
|
|
|
|
#include "messages/MsgHandlerReaderList.h"
|
|
|
|
#include "messages/MsgHandlerUnknownCommand.h"
|
|
|
|
|
|
|
|
#include <QLoggingCategory>
|
|
|
|
|
|
|
|
Q_DECLARE_LOGGING_CATEGORY(jsonapi)
|
|
|
|
|
|
|
|
#define HANDLE_CURRENT_STATE(msgType, msgHandler) handleCurrentState(requestType, msgType, [&] {return msgHandler;});
|
|
|
|
|
|
|
|
using namespace governikus;
|
|
|
|
|
|
|
|
|
|
|
|
MessageDispatcher::MessageDispatcher()
|
|
|
|
: mContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray MessageDispatcher::init(const QSharedPointer<WorkflowContext>& pContext)
|
|
|
|
{
|
|
|
|
Q_ASSERT(!mContext.isActiveWorkflow());
|
|
|
|
|
|
|
|
mContext.setWorkflowContext(pContext);
|
|
|
|
|
|
|
|
if (mContext.getAuthContext())
|
|
|
|
{
|
|
|
|
return MsgHandlerAuth().getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray MessageDispatcher::createMsgReader(const QString& pName) const
|
|
|
|
{
|
|
|
|
return MsgHandlerReader(pName).getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray MessageDispatcher::finish()
|
|
|
|
{
|
|
|
|
Q_ASSERT(mContext.isActiveWorkflow());
|
|
|
|
|
|
|
|
QByteArray result;
|
|
|
|
if (auto authContext = mContext.getAuthContext())
|
|
|
|
{
|
|
|
|
result = MsgHandlerAuth(authContext).getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
mContext.clear();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray MessageDispatcher::processStateChange(const QString& pState)
|
|
|
|
{
|
|
|
|
if (!mContext.isActiveWorkflow() || pState.isEmpty())
|
|
|
|
{
|
|
|
|
qCritical(jsonapi) << "Unexpected condition:" << mContext.getWorkflowContext() << "|" << pState;
|
|
|
|
return MsgHandlerInternalError(QLatin1String("Unexpected condition")).getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto& msg = createForStateChange(MsgHandler::getStateMsgType(pState));
|
|
|
|
mContext.addStateMsg(msg.getType());
|
|
|
|
return msg.getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MsgHandler MessageDispatcher::createForStateChange(MsgType pStateType)
|
|
|
|
{
|
|
|
|
switch (pStateType)
|
|
|
|
{
|
|
|
|
case MsgType::ENTER_PIN:
|
|
|
|
return MsgHandlerEnterPin(mContext);
|
|
|
|
|
|
|
|
case MsgType::ENTER_CAN:
|
|
|
|
return MsgHandlerEnterCan(mContext);
|
|
|
|
|
2017-07-03 09:33:28 +02:00
|
|
|
case MsgType::ENTER_PUK:
|
|
|
|
return MsgHandlerEnterPuk(mContext);
|
|
|
|
|
2017-07-03 09:30:10 +02:00
|
|
|
case MsgType::ACCESS_RIGHTS:
|
|
|
|
return MsgHandlerAccessRights(mContext);
|
|
|
|
|
|
|
|
case MsgType::INSERT_CARD:
|
|
|
|
return MsgHandlerInsertCard(mContext);
|
|
|
|
|
|
|
|
default:
|
|
|
|
mContext.getWorkflowContext()->setStateApproved();
|
2017-07-03 09:33:28 +02:00
|
|
|
return MsgHandler::Void;
|
2017-07-03 09:30:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray MessageDispatcher::processCommand(const QByteArray& pMsg)
|
|
|
|
{
|
|
|
|
QJsonParseError jsonError;
|
|
|
|
const auto& json = QJsonDocument::fromJson(pMsg, &jsonError);
|
|
|
|
if (jsonError.error != QJsonParseError::NoError)
|
|
|
|
{
|
|
|
|
return MsgHandlerInvalid(jsonError).getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto& obj = json.object();
|
|
|
|
auto msg = createForCommand(obj);
|
|
|
|
msg.setRequest(obj);
|
|
|
|
return msg.getOutput();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MsgHandler MessageDispatcher::createForCommand(const QJsonObject& pObj)
|
|
|
|
{
|
|
|
|
const auto& cmd = pObj.value(QLatin1String("cmd")).toString();
|
|
|
|
if (cmd.isEmpty())
|
|
|
|
{
|
|
|
|
return MsgHandlerInvalid(QLatin1String("Command cannot be undefined"));
|
|
|
|
}
|
|
|
|
|
|
|
|
auto requestType = Enum<MsgCmdType>::fromString(cmd, MsgCmdType::UNDEFINED);
|
|
|
|
switch (requestType)
|
|
|
|
{
|
|
|
|
case MsgCmdType::UNDEFINED:
|
|
|
|
return MsgHandlerUnknownCommand(cmd);
|
|
|
|
|
|
|
|
case MsgCmdType::CANCEL:
|
|
|
|
return cancel();
|
|
|
|
|
|
|
|
case MsgCmdType::ACCEPT:
|
|
|
|
return accept();
|
|
|
|
|
|
|
|
case MsgCmdType::GET_API_LEVEL:
|
|
|
|
return MsgHandlerApiLevel(mContext);
|
|
|
|
|
|
|
|
case MsgCmdType::SET_API_LEVEL:
|
|
|
|
return MsgHandlerApiLevel(pObj, mContext);
|
|
|
|
|
|
|
|
case MsgCmdType::GET_READER:
|
|
|
|
return MsgHandlerReader(pObj);
|
|
|
|
|
|
|
|
case MsgCmdType::GET_READER_LIST:
|
|
|
|
return MsgHandlerReaderList();
|
|
|
|
|
|
|
|
case MsgCmdType::GET_INFO:
|
|
|
|
return MsgHandlerInfo();
|
|
|
|
|
|
|
|
case MsgCmdType::RUN_AUTH:
|
|
|
|
return mContext.isActiveWorkflow() ? MsgHandler(MsgHandlerBadState(requestType)) : MsgHandler(MsgHandlerAuth(pObj));
|
|
|
|
|
|
|
|
case MsgCmdType::GET_CERTIFICATE:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ACCESS_RIGHTS, MsgHandlerCertificate(mContext));
|
|
|
|
|
|
|
|
case MsgCmdType::SET_PIN:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ENTER_PIN, MsgHandlerEnterPin(pObj, mContext));
|
|
|
|
|
|
|
|
case MsgCmdType::SET_CAN:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ENTER_CAN, MsgHandlerEnterCan(pObj, mContext));
|
|
|
|
|
2017-09-15 10:23:30 +02:00
|
|
|
case MsgCmdType::SET_PUK:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ENTER_PUK, MsgHandlerEnterPuk(pObj, mContext));
|
|
|
|
|
2017-07-03 09:30:10 +02:00
|
|
|
case MsgCmdType::GET_ACCESS_RIGHTS:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ACCESS_RIGHTS, MsgHandlerAccessRights(mContext));
|
|
|
|
|
|
|
|
case MsgCmdType::SET_ACCESS_RIGHTS:
|
|
|
|
return HANDLE_CURRENT_STATE(MsgType::ACCESS_RIGHTS, MsgHandlerAccessRights(pObj, mContext));
|
|
|
|
}
|
|
|
|
|
|
|
|
return MsgHandlerInternalError(QLatin1String("Cannot process request"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MsgHandler MessageDispatcher::handleCurrentState(MsgCmdType pCmdType, MsgType pMsgType, const std::function<MsgHandler()>& pFunc)
|
|
|
|
{
|
|
|
|
if (mContext.getLastStateMsg() == pMsgType)
|
|
|
|
{
|
|
|
|
return pFunc();
|
|
|
|
}
|
|
|
|
|
|
|
|
return MsgHandlerBadState(pCmdType);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MsgHandler MessageDispatcher::cancel()
|
|
|
|
{
|
|
|
|
if (mContext.isActiveWorkflow())
|
|
|
|
{
|
|
|
|
Q_EMIT mContext.getWorkflowContext()->fireCancelWorkflow();
|
2017-07-03 09:33:28 +02:00
|
|
|
return MsgHandler::Void;
|
2017-07-03 09:30:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return MsgHandlerBadState(MsgCmdType::CANCEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MsgHandler MessageDispatcher::accept()
|
|
|
|
{
|
|
|
|
if (mContext.getLastStateMsg() == MsgType::ACCESS_RIGHTS)
|
|
|
|
{
|
|
|
|
mContext.getWorkflowContext()->setStateApproved();
|
2017-07-03 09:33:28 +02:00
|
|
|
return MsgHandler::Void;
|
2017-07-03 09:30:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return MsgHandlerBadState(MsgCmdType::ACCEPT);
|
|
|
|
}
|