Handle agent response 04/29804/11
authorAdam Malinowski <a.malinowsk2@partner.samsung.com>
Mon, 3 Nov 2014 13:53:33 +0000 (14:53 +0100)
committerAdam Malinowski <a.malinowsk2@partner.samsung.com>
Sat, 15 Nov 2014 04:38:25 +0000 (05:38 +0100)
This patch handles response from agent of both types:
action and cancel.

Change-Id: I3168f4f7466c79bdcb9a3f6b1c3d6863ddcf952c

src/service/logic/Logic.cpp
src/service/logic/Logic.h

index 037deb8..4cf78eb 100644 (file)
@@ -37,6 +37,7 @@
 #include <exceptions/PluginNotFoundException.h>
 #include <exceptions/UnexpectedErrorException.h>
 #include <request/AdminCheckRequest.h>
+#include <request/AgentActionRequest.h>
 #include <request/AgentRegisterRequest.h>
 #include <request/CancelRequest.h>
 #include <request/CheckRequest.h>
@@ -57,6 +58,8 @@
 
 #include <cynara-plugin.h>
 
+#include <cynara-agent.h>
+
 #include "Logic.h"
 
 namespace Cynara {
@@ -85,6 +88,40 @@ void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) {
                             request->sequenceNumber()));
 }
 
+void Logic::execute(RequestContextPtr context, AgentActionRequestPtr request) {
+    AgentTalkerPtr talkerPtr = m_agentManager->getTalker(context->responseQueue(),
+                                                         request->sequenceNumber());
+    if (!talkerPtr) {
+        LOGD("Received response from agent with invalid request id: [%" PRIu16 "]",
+             request->sequenceNumber());
+        return;
+    }
+
+    CheckContextPtr checkContextPtr = m_checkRequestManager.getContext(talkerPtr);
+    if (!checkContextPtr) {
+        LOGE("No matching check context for agent talker.");
+        m_agentManager->removeTalker(talkerPtr);
+        return;
+    }
+
+    if (!checkContextPtr->cancelled()) {
+        PluginData data(request->data().begin(), request->data().end());
+        if (request->type() == CYNARA_MSG_TYPE_CANCEL) {
+            // Nothing to do for now
+        } else if (request->type() == CYNARA_MSG_TYPE_ACTION) {
+            update(checkContextPtr->m_key, checkContextPtr->m_checkId, data,
+                   checkContextPtr->m_requestContext, checkContextPtr->m_plugin);
+        } else {
+            LOGE("Invalid response type [%d] in response from agent <%s>",
+                 static_cast<int>(request->type()), talkerPtr->agentType().c_str());
+            // TODO: disconnect agent
+        }
+    }
+
+    m_agentManager->removeTalker(talkerPtr);
+    m_checkRequestManager.removeRequest(checkContextPtr);
+}
+
 void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) {
     auto result = m_agentManager->registerAgent(request->agentType(), context->responseQueue());
     context->returnResponse(context, std::make_shared<AgentRegisterResponse>(
@@ -191,6 +228,36 @@ bool Logic::pluginCheck(const RequestContextPtr &context, const PolicyKey &key,
     }
 }
 
+bool Logic::update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId,
+                   const PluginData &agentData, const RequestContextPtr &context,
+                   const ServicePluginInterfacePtr &plugin) {
+
+    LOGD("Check update: <%s>:[%" PRIu16 "]", key.toString().c_str(), checkId);
+
+    PolicyResult result;
+    bool answerReady = false;
+    auto ret = plugin->update(key.client().toString(), key.user().toString(),
+                              key.privilege().toString(), agentData, result);
+    switch (ret) {
+        case ServicePluginInterface::PluginStatus::SUCCESS:
+            answerReady = true;
+            break;
+        case ServicePluginInterface::PluginStatus::ERROR:
+            result = PolicyResult(PredefinedPolicyType::DENY);
+            answerReady = true;
+            break;
+        default:
+            throw PluginErrorException(key);
+    }
+
+    if (answerReady && context->responseQueue()) {
+        context->returnResponse(context, std::make_shared<CheckResponse>(result, checkId));
+        return true;
+    }
+
+    return false;
+}
+
 void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) {
     auto code = CodeResponse::Code::OK;
 
index dbbc7d6..57a862c 100644 (file)
@@ -32,6 +32,8 @@
 #include <request/pointers.h>
 #include <request/RequestTaker.h>
 
+#include <cynara-plugin.h>
+
 namespace Cynara {
 
 class Logic : public RequestTaker {
@@ -63,6 +65,7 @@ public:
     }
 
     virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request);
+    virtual void execute(RequestContextPtr context, AgentActionRequestPtr request);
     virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request);
     virtual void execute(RequestContextPtr context, CancelRequestPtr request);
     virtual void execute(RequestContextPtr context, CheckRequestPtr request);
@@ -84,6 +87,9 @@ private:
                ProtocolFrameSequenceNumber checkId, PolicyResult &result);
     bool pluginCheck(const RequestContextPtr &context, const PolicyKey &key,
                      ProtocolFrameSequenceNumber checkId, PolicyResult &result);
+    bool update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId,
+                const PluginData &agentData, const RequestContextPtr &request,
+                const ServicePluginInterfacePtr &plugin);
 
     void onPoliciesChanged(void);
 };