Redo client plugins 51/27451/11
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 12 Sep 2014 13:45:36 +0000 (15:45 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Thu, 16 Oct 2014 07:58:50 +0000 (09:58 +0200)
Let plugin make decision based on last and current client session.
Plugin can change PluginResult.

Change-Id: Ia985feaf1d60a8c1ebf858ba0d4e0d6f2cc6fa40

src/client-common/cache/CapacityCache.cpp
src/client-common/cache/CapacityCache.h
src/client-common/plugins/NaiveInterpreter.h
src/client-common/plugins/PluginInterface.h

index c4cf680..04f1cb5 100644 (file)
 namespace Cynara {
 
 int CapacityCache::get(const ClientSession &session, const PolicyKey &key) {
-    //This can be very time heavy. This part is welcomed to be optimized.
-    if (session != m_session) {
-        LOGD("Session changed from %s to %s.", m_session.c_str(), session.c_str());
-        clear();
-        m_session = session;
-        return CYNARA_API_CACHE_MISS;
-    }
     auto resultIt = m_keyValue.find(keyToString(key));
     //Do we have entry in cache?
     if (resultIt == m_keyValue.end()) {
@@ -51,23 +44,33 @@ int CapacityCache::get(const ClientSession &session, const PolicyKey &key) {
                 key.user().toString().c_str(),
                 key.privilege().toString().c_str());
 
-        auto pluginIt = m_plugins.find(resultIt->second.first.policyType());
+        auto &cachedValue = resultIt->second;
+        auto &policyResult = std::get<0>(cachedValue);
+
+        auto pluginIt = m_plugins.find(policyResult.policyType());
         if (pluginIt == m_plugins.end()) {
             LOGE("No plugin registered for given PolicyType : %" PRIu16,
-                    resultIt->second.first.policyType());
+                    policyResult.policyType());
             return CYNARA_API_ACCESS_DENIED;
         }
 
         //Is it still usable?
         InterpreterInterfacePtr plugin = pluginIt->second;
-        if (plugin->isUsable(resultIt->second.first)) {
+        auto &prevSession = std::get<1>(cachedValue);
+        auto usageIt = std::get<2>(cachedValue);
+        bool updateSession = false;
+        if (plugin->isUsable(session, prevSession, updateSession, policyResult)) {
             LOGD("Entry usable.");
-            m_keyUsage.splice(m_keyUsage.begin(), m_keyUsage, resultIt->second.second);
-            return plugin->toResult(resultIt->second.first);
+            m_keyUsage.splice(m_keyUsage.begin(), m_keyUsage, usageIt);
+
+            if (updateSession) {
+                prevSession = session;
+            }
+
+            return plugin->toResult(session, policyResult);
         }
         //Remove unusable entry
         LOGD("Entry not usable");
-        auto usageIt = resultIt->second.second;
         m_keyUsage.erase(usageIt);
         m_keyValue.erase(resultIt);
         return CYNARA_API_CACHE_MISS;
@@ -77,7 +80,6 @@ int CapacityCache::get(const ClientSession &session, const PolicyKey &key) {
 void CapacityCache::clear(void) {
     m_keyUsage.clear();
     m_keyValue.clear();
-    m_session.clear();
 }
 
 std::string CapacityCache::keyToString(const PolicyKey &key) {
@@ -103,12 +105,6 @@ void CapacityCache::evict(void) {
 int CapacityCache::update(const ClientSession &session,
                           const PolicyKey &key,
                           const PolicyResult &result) {
-    //This can be very time heavy. This part is welcomed to be optimized.
-    if (session != m_session) {
-        LOGD("Session changed from %s to %s.", m_session.c_str(), session.c_str());
-        clear();
-        m_session = session;
-    }
 
     auto pluginIt = m_plugins.find(result.policyType());
 
@@ -120,18 +116,21 @@ int CapacityCache::update(const ClientSession &session,
     }
     auto plugin = pluginIt->second;
 
-    if (m_capacity != 0) {
-        if (plugin->isCacheable(result)) {
+    PolicyResult storedResult = result;
+
+    if (m_capacity > 0) {
+        if (plugin->isCacheable(session, storedResult)) {
             LOGD("Entry cacheable");
             if (m_keyValue.size() == m_capacity) {
                 LOGD("Capacity reached.");
                 evict();
             }
-            m_keyUsage.push_front(keyToString(key));
-            m_keyValue[keyToString(key)] = std::make_pair(result, m_keyUsage.begin());
+            std::string cacheKey = keyToString(key);
+            m_keyUsage.push_front(cacheKey);
+            m_keyValue[cacheKey] = std::make_tuple(storedResult, session, m_keyUsage.begin());
         }
     }
-    return plugin->toResult(result);
+    return plugin->toResult(session, storedResult);
 }
 
 } // namespace Cynara
index 5bb083e..4218078 100644 (file)
@@ -24,6 +24,7 @@
 #define  SRC_CLIENT_COMMON_CACHE_CAPACITYCACHE_H_
 
 #include <list>
+#include <tuple>
 #include <unordered_map>
 
 #include <cache/CacheInterface.h>
@@ -46,15 +47,13 @@ public:
 private:
     typedef std::list<std::string> KeyUsageList;
     typedef std::unordered_map<std::string,
-        std::pair<PolicyResult,
-                  KeyUsageList::iterator>> KeyValueMap;
+        std::tuple<PolicyResult, ClientSession, KeyUsageList::iterator>> KeyValueMap;
 
     static std::string keyToString(const PolicyKey &key);
     void evict(void);
 
 
     std::size_t m_capacity;
-    ClientSession m_session;
 
     KeyUsageList m_keyUsage;
     KeyValueMap m_keyValue;
index 04d05de..e306ab7 100644 (file)
 namespace Cynara {
 
 class NaiveInterpreter : public InterpreterInterface {
-    bool isUsable(const PolicyResult &result UNUSED) {
+    bool isUsable(const ClientSession &session UNUSED, const ClientSession &prevSession UNUSED,
+                  bool &updateSession UNUSED, PolicyResult &result UNUSED) {
         return true;
     }
-    bool isCacheable(const PolicyResult &result UNUSED) {
+    bool isCacheable(const ClientSession &session UNUSED,
+                     const PolicyResult &result UNUSED) {
         return true;
     }
-    int toResult(const PolicyResult &result) {
+    int toResult(const ClientSession &session UNUSED, PolicyResult &result) {
         if (result.policyType() == PredefinedPolicyType::ALLOW)
             return CYNARA_API_ACCESS_ALLOWED;
         else
index 5f3a947..54bd341 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <memory>
 
+#include <types/ClientSession.h>
 #include <types/PolicyResult.h>
 
 namespace Cynara {
@@ -34,13 +35,14 @@ typedef std::shared_ptr<InterpreterInterface> InterpreterInterfacePtr;
 
 class InterpreterInterface {
 public:
-    virtual bool isCacheable(const PolicyResult &result) = 0;
-    virtual bool isUsable(const PolicyResult &result) = 0;
-    virtual int toResult(const PolicyResult &result) = 0;
+    virtual bool isCacheable(const ClientSession &session, const PolicyResult &result) = 0;
+    virtual bool isUsable(const ClientSession &session, const ClientSession &prevSession,
+                          bool &updateSession, PolicyResult &result) = 0;
+    virtual int toResult(const ClientSession &session, PolicyResult &result) = 0;
 
     virtual ~InterpreterInterface() {};
 };
 
-}
+} // namespace Cynara
 
 #endif // SRC_CLIENT_COMMON_PLUGINS_PLUGININTERFACE_H_