Add logic side implementation of simple check 18/35218/5
authorZofia Abramowska <z.abramowska@samsung.com>
Mon, 9 Feb 2015 15:14:34 +0000 (16:14 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Thu, 12 Feb 2015 14:18:16 +0000 (15:18 +0100)
Add implementation of client and service logic side implementation
of simple check API and request and response handling.

Change-Id: Ie59fb86e20fae383196025580b164c15e855bc62

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

index c171cce..9f738fb 100644 (file)
 #include <protocol/ProtocolClient.h>
 #include <request/CheckRequest.h>
 #include <request/pointers.h>
+#include <request/SimpleCheckRequest.h>
 #include <response/CheckResponse.h>
 #include <response/pointers.h>
+#include <response/SimpleCheckResponse.h>
 #include <sockets/SocketClient.h>
 
 #include <logic/Logic.h>
@@ -65,12 +67,10 @@ int Logic::check(const std::string &client, const ClientSession &session, const
 
     PolicyKey key(client, user, privilege);
     int ret = m_cache->get(session, key);
-    //Any other situation than cache miss
     if (ret != CYNARA_API_CACHE_MISS) {
         return ret;
     }
 
-    //No value in Cache
     PolicyResult result;
     ret = requestResult(key, result);
     if (ret != CYNARA_API_SUCCESS) {
@@ -83,11 +83,24 @@ int Logic::check(const std::string &client, const ClientSession &session, const
 
 int Logic::simpleCheck(const std::string &client, const ClientSession &session,
                        const std::string &user, const std::string &privilege) {
-    (void)client;
-    (void)session;
-    (void)user;
-    (void)privilege;
-    return CYNARA_API_ACCESS_NOT_RESOLVED;
+    if (!ensureConnection())
+        return CYNARA_API_SERVICE_NOT_AVAILABLE;
+
+    PolicyKey key(client, user, privilege);
+    int ret = m_cache->get(session, key);
+    if (ret != CYNARA_API_CACHE_MISS) {
+        return ret;
+    }
+
+    PolicyResult result;
+    ret = requestSimpleResult(key, result);
+    if (ret != CYNARA_API_SUCCESS) {
+        if (ret != CYNARA_API_ACCESS_NOT_RESOLVED)
+            LOGE("Error fetching response for simpleCheck.");
+        return ret;
+    }
+
+    return m_cache->update(session, key, result);
 }
 
 bool Logic::ensureConnection(void) {
@@ -100,33 +113,55 @@ bool Logic::ensureConnection(void) {
     return false;
 }
 
-int Logic::requestResult(const PolicyKey &key, PolicyResult &result) {
+template <typename Req, typename Res>
+std::shared_ptr<Res> Logic::requestResponse(const PolicyKey &key) {
     ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber();
 
     //Ask cynara service
-    CheckResponsePtr checkResponse;
-    RequestPtr request = std::make_shared<CheckRequest>(key, sequenceNumber);
+    std::shared_ptr<Res> reqResponse;
+    RequestPtr request = std::make_shared<Req>(key, sequenceNumber);
     ResponsePtr response;
     while (!(response = m_socket->askCynaraServer(request))) {
         onDisconnected();
         if (!m_socket->connect())
-            return CYNARA_API_SERVICE_NOT_AVAILABLE;
+            return nullptr;
     }
 
-    checkResponse = std::dynamic_pointer_cast<CheckResponse>(response);
+    reqResponse = std::dynamic_pointer_cast<Res>(response);
+    return reqResponse;
+}
+
+int Logic::requestResult(const PolicyKey &key, PolicyResult &result) {
+    auto checkResponse = requestResponse<CheckRequest, CheckResponse>(key);
     if (!checkResponse) {
-        LOGC("Critical error. Casting Response to CheckResponse failed.");
-        return CYNARA_API_ACCESS_DENIED;
+        LOGC("Critical error. Requesting CheckResponse failed.");
+        return CYNARA_API_SERVICE_NOT_AVAILABLE;
     }
-
     LOGD("checkResponse: policyType = %" PRIu16 ", metadata = %s",
          checkResponse->m_resultRef.policyType(),
          checkResponse->m_resultRef.metadata().c_str());
-
     result = checkResponse->m_resultRef;
     return CYNARA_API_SUCCESS;
 }
 
+int Logic::requestSimpleResult(const PolicyKey &key, PolicyResult &result) {
+    auto simpleCheckResponse = requestResponse<SimpleCheckRequest, SimpleCheckResponse>(key);
+    if (!simpleCheckResponse) {
+        LOGC("Critical error. Requesting SimpleCheckResponse failed.");
+        return CYNARA_API_SERVICE_NOT_AVAILABLE;
+    }
+
+    if (simpleCheckResponse->getReturnValue() != CYNARA_API_SUCCESS)
+        return simpleCheckResponse->getReturnValue();
+
+    LOGD("SimpleCheckResponse: policyType = %" PRIu16 ", metadata = %s",
+         simpleCheckResponse->getResult().policyType(),
+         simpleCheckResponse->getResult().metadata().c_str());
+
+    result = simpleCheckResponse->getResult();
+    return CYNARA_API_SUCCESS;
+}
+
 void Logic::onDisconnected(void) {
     m_cache->clear();
 }
index 695f7cd..e98f950 100644 (file)
@@ -56,7 +56,10 @@ private:
 
     void onDisconnected(void);
     bool ensureConnection(void);
+    template <typename Req, typename Res>
+    std::shared_ptr<Res> requestResponse(const PolicyKey &key);
     int requestResult(const PolicyKey &key, PolicyResult &result);
+    int requestSimpleResult(const PolicyKey &key, PolicyResult &result);
 };
 
 } // namespace Cynara
index 5e3f82a..95656e5 100644 (file)
@@ -16,6 +16,7 @@
 /**
  * @file        src/service/logic/Logic.cpp
  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
  * @version     1.0
  * @brief       This file implements main class of logic layer in cynara service
  */
@@ -51,6 +52,7 @@
 #include <request/RequestContext.h>
 #include <request/SetPoliciesRequest.h>
 #include <request/SignalRequest.h>
+#include <request/SimpleCheckRequest.h>
 #include <response/AdminCheckResponse.h>
 #include <response/AgentRegisterResponse.h>
 #include <response/CancelResponse.h>
@@ -58,6 +60,7 @@
 #include <response/CodeResponse.h>
 #include <response/DescriptionListResponse.h>
 #include <response/ListResponse.h>
+#include <response/SimpleCheckResponse.h>
 #include <types/Policy.h>
 
 #include <main/Cynara.h>
@@ -367,6 +370,60 @@ void Logic::execute(RequestContextPtr context, SetPoliciesRequestPtr request) {
                             request->sequenceNumber()));
 }
 
+void Logic::execute(RequestContextPtr context, SimpleCheckRequestPtr request) {
+    int retValue = CYNARA_API_SUCCESS;
+    PolicyResult result;
+    PolicyKey key = request->key();
+    result = m_storage->checkPolicy(key);
+
+    switch (result.policyType()) {
+    case PredefinedPolicyType::ALLOW:
+        LOGD("simple check of policy key <%s> returned ALLOW", key.toString().c_str());
+        break;
+    case PredefinedPolicyType::DENY:
+        LOGD("simple check of policy key <%s> returned DENY", key.toString().c_str());
+        break;
+    default: {
+        ExternalPluginPtr plugin = m_pluginManager->getPlugin(result.policyType());
+        if (!plugin) {
+            LOGE("Plugin not found for policy: [0x%x]", result.policyType());
+            result = PolicyResult(PredefinedPolicyType::DENY);
+            retValue = CYNARA_API_SUCCESS;
+            break;
+        }
+
+        ServicePluginInterfacePtr servicePlugin =
+                std::dynamic_pointer_cast<ServicePluginInterface>(plugin);
+        if (!servicePlugin) {
+            LOGE("Couldn't cast plugin pointer to ServicePluginInterface");
+            result = PolicyResult(PredefinedPolicyType::DENY);
+            retValue = CYNARA_API_SUCCESS;
+            break;
+        }
+
+        AgentType requiredAgent;
+        PluginData pluginData;
+        auto ret = servicePlugin->check(key.client().toString(), key.user().toString(),
+                                        key.privilege().toString(), result, requiredAgent,
+                                        pluginData);
+        switch (ret) {
+        case ServicePluginInterface::PluginStatus::ANSWER_READY:
+            LOGD("simple check of policy key <%s> in plugin returned [" PRIu16 "]",
+                 key.toString().c_str(), result.policyType());
+            break;
+        case ServicePluginInterface::PluginStatus::ANSWER_NOTREADY:
+            retValue = CYNARA_API_ACCESS_NOT_RESOLVED;
+            break;
+        default:
+            result = PolicyResult(PredefinedPolicyType::DENY);
+            retValue = CYNARA_API_SUCCESS;
+        }
+    }
+    }
+    context->returnResponse(context, std::make_shared<SimpleCheckResponse>(retValue, result,
+                                                                  request->sequenceNumber()));
+}
+
 void Logic::checkPoliciesTypes(const std::map<PolicyBucketId, std::vector<Policy>> &policies,
                                bool allowBucket, bool allowNone) {
     for (const auto &group : policies) {
index fc577bd..444f734 100644 (file)
@@ -16,6 +16,7 @@
 /**
  * @file        src/service/logic/Logic.h
  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
  * @version     1.0
  * @brief       This file defines main class of logic layer in cynara service
  */
@@ -82,6 +83,7 @@ public:
     virtual void execute(RequestContextPtr context, RemoveBucketRequestPtr request);
     virtual void execute(RequestContextPtr context, SetPoliciesRequestPtr request);
     virtual void execute(RequestContextPtr context, SignalRequestPtr request);
+    virtual void execute(RequestContextPtr context, SimpleCheckRequestPtr request);
 
     virtual void contextClosed(RequestContextPtr context);